package subsonic import ( "net/http/httptest" "testing" ) func TestShareLifecycle(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("description", "Check this out") q.Set("f", "json") resp := getPath(t, srv.URL, "/rest/createShare.view", q) j := decodeJSON(t, resp) shares := j["shares"].(map[string]any)["share"].([]any) if len(shares) != 1 { t.Fatalf("createShare shares = %v, want 1", shares) } share := shares[0].(map[string]any) if share["url"] == nil || share["url"] == "" { t.Fatalf("share missing url: %v", share) } shareID := share["id"].(string) entries, ok := share["entry"].([]any) if !ok || len(entries) != 1 { t.Fatalf("share entries = %v, want 1", share["entry"]) } q2 := baseParams("alice", "password123") q2.Set("f", "json") resp = getPath(t, srv.URL, "/rest/getShares.view", q2) j = decodeJSON(t, resp) shares = j["shares"].(map[string]any)["share"].([]any) if len(shares) != 1 { t.Fatalf("getShares = %v, want 1", shares) } q3 := baseParams("alice", "password123") q3.Set("id", shareID) q3.Set("description", "Updated description") resp = getPath(t, srv.URL, "/rest/updateShare.view", q3) x := decodeXML(t, resp) if x.Status != "ok" { t.Fatalf("updateShare failed: %+v", x) } q4 := baseParams("alice", "password123") q4.Set("id", shareID) resp = getPath(t, srv.URL, "/rest/deleteShare.view", q4) x = decodeXML(t, resp) if x.Status != "ok" { t.Fatalf("deleteShare failed: %+v", x) } } func TestShareOtherUserCannotModify(t *testing.T) { s, _ := newTestServer(t) createTestUser(t, s, "owner", "password123", false) createTestUser(t, s, "other", "password123", false) seedLibrary(t, s) srv := httptest.NewServer(s.Router()) defer srv.Close() q := baseParams("owner", "password123") q.Add("id", firstSong(t, s).ID) q.Set("f", "json") resp := getPath(t, srv.URL, "/rest/createShare.view", q) j := decodeJSON(t, resp) shares := j["shares"].(map[string]any)["share"].([]any) shareID := shares[0].(map[string]any)["id"].(string) q2 := baseParams("other", "password123") q2.Set("id", shareID) resp = getPath(t, srv.URL, "/rest/deleteShare.view", q2) x := decodeXML(t, resp) if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrUnauthorized { t.Fatalf("expected error 50 deleting another user's share, got %+v", x) } } func TestCreateShareMissingID(t *testing.T) { s, srv := newTestRecorderServer(t) createTestUser(t, s, "alice", "password123", false) resp := getPath(t, srv.URL, "/rest/createShare.view", baseParams("alice", "password123")) x := decodeXML(t, resp) if x.Status != "failed" || x.Error == nil || x.Error.Code != ErrMissingParameter { t.Fatalf("expected error 10, got %+v", x) } }