package api import ( "context" "encoding/json" "net/http" "net/http/httptest" "slices" "testing" ) // The integration test runs the same alternation through Postgres's ~*, so the // one pattern is exercised in both regex dialects it has to work in. func TestHandleListSuspectSources_Integration(t *testing.T) { h, pool := testHandlers(t) truncateLibrary(t, pool) admin := seedUser(t, pool, "suspect-admin", "pw", true) artist := seedArtist(t, pool, "Gorillaz") humanz := seedAlbum(t, pool, artist.ID, "Humanz", 2017) seedTrack(t, pool, humanz.ID, artist.ID, "Saturnz Barz (Official Video)", 1, 180_000) seedTrack(t, pool, humanz.ID, artist.ID, "Momentz (Visualizer)", 2, 200_000) seedTrack(t, pool, humanz.ID, artist.ID, "Andromeda [Audio]", 3, 190_000) seedTrack(t, pool, humanz.ID, artist.ID, "Chain Reaction", 4, 190_000) seedTrack(t, pool, humanz.ID, artist.ID, "Busted and Blue", 5, 190_000) gone := seedTrack(t, pool, humanz.ID, artist.ID, "Ascension (Lyric Video)", 6, 156_000) if _, err := pool.Exec(context.Background(), `UPDATE tracks SET missing_since = now() WHERE id = $1`, gone.ID); err != nil { t.Fatalf("mark missing: %v", err) } req := httptest.NewRequest(http.MethodGet, "/api/admin/library/suspect-sources?limit=50", nil) req = withUser(req, admin) w := httptest.NewRecorder() h.handleListSuspectSources(w, req) if w.Code != http.StatusOK { t.Fatalf("status %d: %s", w.Code, w.Body.String()) } var resp adminSuspectSourcesResponse if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("decode: %v", err) } // Three present files carry a marker. "Chain Reaction" and "Busted and // Blue" carry none, and the lyric video's file is missing. if resp.Total != 3 { t.Errorf("total = %d, want 3", resp.Total) } if len(resp.Groups) != 1 { t.Fatalf("groups = %d, want 1 (one folder)", len(resp.Groups)) } got := map[string][]string{} for _, tr := range resp.Groups[0].Tracks { got[tr.Title] = tr.Markers } want := map[string][]string{ "Saturnz Barz (Official Video)": {"music video"}, "Momentz (Visualizer)": {"visualiser"}, "Andromeda [Audio]": {"[Audio]"}, } if len(got) != len(want) { t.Fatalf("tracks = %v, want %v", got, want) } for title, labels := range want { if !slices.Equal(got[title], labels) { t.Errorf("%s: markers %v, want %v", title, got[title], labels) } } }