194 lines
5.8 KiB
Go
194 lines
5.8 KiB
Go
package subsonic
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
func TestInternetRadioLifecycle(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "admin", "password123", true)
|
|
|
|
q := baseParams("admin", "password123")
|
|
q.Set("name", "Test Station")
|
|
q.Set("streamUrl", "http://example.com/stream.mp3")
|
|
resp := getPath(t, srv.URL, "/rest/createInternetRadioStation.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("createInternetRadioStation failed: %+v", x)
|
|
}
|
|
|
|
q2 := baseParams("admin", "password123")
|
|
q2.Set("f", "json")
|
|
resp = getPath(t, srv.URL, "/rest/getInternetRadioStations.view", q2)
|
|
j := decodeJSON(t, resp)
|
|
stations := j["internetRadioStations"].(map[string]any)["internetRadioStation"].([]any)
|
|
if len(stations) != 1 {
|
|
t.Fatalf("stations = %v, want 1", stations)
|
|
}
|
|
stationID := stations[0].(map[string]any)["id"].(string)
|
|
|
|
q3 := baseParams("admin", "password123")
|
|
q3.Set("id", stationID)
|
|
resp = getPath(t, srv.URL, "/rest/deleteInternetRadioStation.view", q3)
|
|
x = decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("deleteInternetRadioStation failed: %+v", x)
|
|
}
|
|
}
|
|
|
|
func TestInternetRadioRequiresAdmin(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
|
|
q := baseParams("alice", "password123")
|
|
q.Set("name", "X")
|
|
q.Set("streamUrl", "http://example.com/x.mp3")
|
|
resp := getPath(t, srv.URL, "/rest/createInternetRadioStation.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrUnauthorized {
|
|
t.Fatalf("expected error 50 for non-admin, got %+v", x)
|
|
}
|
|
}
|
|
|
|
func TestChatMessages(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
|
|
q := baseParams("alice", "password123")
|
|
q.Set("message", "hello world")
|
|
resp := getPath(t, srv.URL, "/rest/addChatMessage.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("addChatMessage failed: %+v", x)
|
|
}
|
|
|
|
q2 := baseParams("alice", "password123")
|
|
q2.Set("f", "json")
|
|
resp = getPath(t, srv.URL, "/rest/getChatMessages.view", q2)
|
|
j := decodeJSON(t, resp)
|
|
messages := j["chatMessages"].(map[string]any)["chatMessage"].([]any)
|
|
if len(messages) != 1 {
|
|
t.Fatalf("messages = %v, want 1", messages)
|
|
}
|
|
msg := messages[0].(map[string]any)
|
|
if msg["message"] != "hello world" || msg["username"] != "alice" {
|
|
t.Fatalf("message = %v, want hello world from alice", msg)
|
|
}
|
|
}
|
|
|
|
func TestBookmarkLifecycle(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
seedLibrary(t, s)
|
|
song := firstSong(t, s)
|
|
|
|
q := baseParams("alice", "password123")
|
|
q.Set("id", song.ID)
|
|
q.Set("position", "5000")
|
|
q.Set("comment", "resume here")
|
|
resp := getPath(t, srv.URL, "/rest/createBookmark.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("createBookmark failed: %+v", x)
|
|
}
|
|
|
|
q2 := baseParams("alice", "password123")
|
|
q2.Set("f", "json")
|
|
resp = getPath(t, srv.URL, "/rest/getBookmarks.view", q2)
|
|
j := decodeJSON(t, resp)
|
|
bookmarks := j["bookmarks"].(map[string]any)["bookmark"].([]any)
|
|
if len(bookmarks) != 1 {
|
|
t.Fatalf("bookmarks = %v, want 1", bookmarks)
|
|
}
|
|
bm := bookmarks[0].(map[string]any)
|
|
if bm["comment"] != "resume here" {
|
|
t.Fatalf("bookmark comment = %v", bm["comment"])
|
|
}
|
|
|
|
q3 := baseParams("alice", "password123")
|
|
q3.Set("id", song.ID)
|
|
resp = getPath(t, srv.URL, "/rest/deleteBookmark.view", q3)
|
|
x = decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("deleteBookmark failed: %+v", x)
|
|
}
|
|
}
|
|
|
|
func TestPlayQueueRoundTrip(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
seedLibrary(t, s)
|
|
song := firstSong(t, s)
|
|
|
|
q := baseParams("alice", "password123")
|
|
q.Add("id", song.ID)
|
|
q.Set("current", song.ID)
|
|
q.Set("position", "1234")
|
|
resp := getPath(t, srv.URL, "/rest/savePlayQueue.view", q)
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "ok" {
|
|
t.Fatalf("savePlayQueue failed: %+v", x)
|
|
}
|
|
|
|
q2 := baseParams("alice", "password123")
|
|
q2.Set("f", "json")
|
|
resp = getPath(t, srv.URL, "/rest/getPlayQueue.view", q2)
|
|
j := decodeJSON(t, resp)
|
|
pq := j["playQueue"].(map[string]any)
|
|
if pq["current"] != song.ID {
|
|
t.Fatalf("playQueue.current = %v, want %v", pq["current"], song.ID)
|
|
}
|
|
entries, ok := pq["entry"].([]any)
|
|
if !ok || len(entries) != 1 {
|
|
t.Fatalf("playQueue entries = %v, want 1", pq["entry"])
|
|
}
|
|
}
|
|
|
|
func TestGetPlayQueueEmpty(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
|
|
q := baseParams("alice", "password123")
|
|
q.Set("f", "json")
|
|
resp := getPath(t, srv.URL, "/rest/getPlayQueue.view", q)
|
|
j := decodeJSON(t, resp)
|
|
if j["status"] != "ok" {
|
|
t.Fatalf("empty getPlayQueue should still succeed, got %v", j)
|
|
}
|
|
}
|
|
|
|
func TestScanStatusAndStartScan(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "admin", "password123", true)
|
|
seedLibrary(t, s)
|
|
|
|
q := baseParams("admin", "password123")
|
|
q.Set("f", "json")
|
|
resp := getPath(t, srv.URL, "/rest/getScanStatus.view", q)
|
|
j := decodeJSON(t, resp)
|
|
status := j["scanStatus"].(map[string]any)
|
|
if status["scanning"] != false {
|
|
t.Fatalf("scanning = %v, want false when idle", status["scanning"])
|
|
}
|
|
if count, ok := status["count"].(float64); !ok || count < 2 {
|
|
t.Fatalf("count = %v, want >= 2 (seeded songs)", status["count"])
|
|
}
|
|
|
|
resp = getPath(t, srv.URL, "/rest/startScan.view", q)
|
|
j = decodeJSON(t, resp)
|
|
if j["status"] != "ok" {
|
|
t.Fatalf("startScan failed: %v", j)
|
|
}
|
|
}
|
|
|
|
func TestStartScanRequiresAdmin(t *testing.T) {
|
|
s, srv := newTestRecorderServer(t)
|
|
createTestUser(t, s, "alice", "password123", false)
|
|
|
|
resp := getPath(t, srv.URL, "/rest/startScan.view", baseParams("alice", "password123"))
|
|
x := decodeXML(t, resp)
|
|
if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrUnauthorized {
|
|
t.Fatalf("expected error 50 for non-admin startScan, got %+v", x)
|
|
}
|
|
}
|