147 lines
4.5 KiB
Go
147 lines
4.5 KiB
Go
package subsonic
|
|
|
|
import (
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"git.noroutes.net/NoRoutes/vibetunes/internal/database"
|
|
)
|
|
|
|
func TestPlaylistLifecycle(t *testing.T) {
|
|
s, db := newTestServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
seedLibrary(t, s)
|
|
srv := httptest.NewServer(s.Router())
|
|
defer srv.Close()
|
|
|
|
songs, err := database.ListSongs(db, 2, 0)
|
|
if err != nil || len(songs) != 2 {
|
|
t.Fatalf("ListSongs: %v %v", songs, err)
|
|
}
|
|
|
|
// Create
|
|
q := baseParams("alice", "password123")
|
|
q.Set("name", "My Playlist")
|
|
q.Add("songId", songs[0].ID)
|
|
q.Set("f", "json")
|
|
resp := getPath(t, srv.URL, "/rest/createPlaylist.view", q)
|
|
j := decodeJSON(t, resp)
|
|
playlist := j["playlist"].(map[string]any)
|
|
if playlist["name"] != "My Playlist" {
|
|
t.Fatalf("created playlist name = %v", playlist["name"])
|
|
}
|
|
playlistID := playlist["id"].(string)
|
|
if entrySongs, ok := playlist["entry"].([]any); !ok || len(entrySongs) != 1 {
|
|
t.Fatalf("created playlist entries = %v, want 1", playlist["entry"])
|
|
}
|
|
|
|
// getPlaylists lists it
|
|
resp = getPath(t, srv.URL, "/rest/getPlaylists.view", q)
|
|
j = decodeJSON(t, resp)
|
|
playlists := j["playlists"].(map[string]any)["playlist"].([]any)
|
|
if len(playlists) != 1 {
|
|
t.Fatalf("getPlaylists = %v, want 1", playlists)
|
|
}
|
|
|
|
// getPlaylist shows the one song
|
|
q2 := baseParams("alice", "password123")
|
|
q2.Set("id", playlistID)
|
|
q2.Set("f", "json")
|
|
resp = getPath(t, srv.URL, "/rest/getPlaylist.view", q2)
|
|
j = decodeJSON(t, resp)
|
|
got := j["playlist"].(map[string]any)
|
|
if entries, ok := got["entry"].([]any); !ok || len(entries) != 1 {
|
|
t.Fatalf("getPlaylist entries = %v, want 1", got["entry"])
|
|
}
|
|
|
|
// updatePlaylist: rename, add second song
|
|
q3 := baseParams("alice", "password123")
|
|
q3.Set("playlistId", playlistID)
|
|
q3.Set("name", "Renamed")
|
|
q3.Add("songIdToAdd", songs[1].ID)
|
|
resp = getPath(t, srv.URL, "/rest/updatePlaylist.view", q3)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("updatePlaylist failed: %+v", x)
|
|
}
|
|
|
|
resp = getPath(t, srv.URL, "/rest/getPlaylist.view", q2)
|
|
j = decodeJSON(t, resp)
|
|
got = j["playlist"].(map[string]any)
|
|
if got["name"] != "Renamed" {
|
|
t.Fatalf("playlist name after update = %v, want Renamed", got["name"])
|
|
}
|
|
if entries, ok := got["entry"].([]any); !ok || len(entries) != 2 {
|
|
t.Fatalf("entries after add = %v, want 2", got["entry"])
|
|
}
|
|
|
|
// updatePlaylist: remove index 0
|
|
q4 := baseParams("alice", "password123")
|
|
q4.Set("playlistId", playlistID)
|
|
q4.Add("songIndexToRemove", "0")
|
|
getPath(t, srv.URL, "/rest/updatePlaylist.view", q4)
|
|
|
|
resp = getPath(t, srv.URL, "/rest/getPlaylist.view", q2)
|
|
j = decodeJSON(t, resp)
|
|
got = j["playlist"].(map[string]any)
|
|
if entries, ok := got["entry"].([]any); !ok || len(entries) != 1 {
|
|
t.Fatalf("entries after remove = %v, want 1", got["entry"])
|
|
}
|
|
|
|
// deletePlaylist
|
|
q5 := baseParams("alice", "password123")
|
|
q5.Set("id", playlistID)
|
|
resp = getPath(t, srv.URL, "/rest/deletePlaylist.view", q5)
|
|
x = decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("deletePlaylist failed: %+v", x)
|
|
}
|
|
|
|
resp = getPath(t, srv.URL, "/rest/getPlaylists.view", q)
|
|
j = decodeJSON(t, resp)
|
|
pls := j["playlists"].(map[string]any)
|
|
if _, ok := pls["playlist"]; ok {
|
|
t.Fatalf("expected no playlists after delete, got %v", pls)
|
|
}
|
|
}
|
|
|
|
func TestPlaylistPermissions(t *testing.T) {
|
|
s, db := newTestServer(t)
|
|
owner := createTestUser(t, s, "owner", "password123", false)
|
|
createTestUser(t, s, "other", "password123", false)
|
|
srv := httptest.NewServer(s.Router())
|
|
defer srv.Close()
|
|
|
|
p, err := database.CreatePlaylist(db, owner.ID, "Private", "", false)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
q := baseParams("other", "password123")
|
|
q.Set("id", p.ID)
|
|
resp := getPath(t, srv.URL, "/rest/getPlaylist.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrUnauthorized {
|
|
t.Fatalf("expected error 50 accessing another user's private playlist, got %+v", x)
|
|
}
|
|
|
|
resp = getPath(t, srv.URL, "/rest/deletePlaylist.view", q)
|
|
x = decodeXML(t, resp)
|
|
if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrUnauthorized {
|
|
t.Fatalf("expected error 50 deleting another user's playlist, got %+v", x)
|
|
}
|
|
}
|
|
|
|
func TestGetPlaylistNotFound(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
|
|
q := baseParams("alice", "password123")
|
|
q.Set("id", "pl_doesnotexist")
|
|
resp := getPath(t, srv.URL, "/rest/getPlaylist.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrNotFound {
|
|
t.Fatalf("expected error 70, got %+v", x)
|
|
}
|
|
}
|