Rewrites the internal/api comment blocks to rule 32: task, milestone and rule ids gone, the stories behind them restated as the constraint they left, stale references corrected (the stream secret is wired from config, the timezone handler already refreshes the scheduler, the Android app is the native client, the design docs cited are not in the repo). Also rewraps comment lines over 80 columns left by the earlier batches. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
113 lines
3.5 KiB
Go
113 lines
3.5 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
// Generic registry-driven system-playlist endpoints.
|
|
func newSystemPlaylistRouter(h *handlers) chi.Router {
|
|
r := chi.NewRouter()
|
|
r.Route("/api", func(api chi.Router) {
|
|
// No real auth.RequireUser middleware: like every other api
|
|
// handler test, auth is supplied via withUser() context and the
|
|
// handlers self-guard with requireUser() (prelude.go). The real
|
|
// middleware needs a live session and would 401 the injected
|
|
// test user.
|
|
api.Post("/playlists/system/{kind}/refresh", h.handleSystemPlaylistRefresh)
|
|
api.Get("/playlists/system/{kind}/shuffle", h.handleSystemPlaylistShuffle)
|
|
})
|
|
return r
|
|
}
|
|
|
|
func TestSystemRefresh_ForYou_Returns200(t *testing.T) {
|
|
if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" {
|
|
t.Skip("MINSTREL_TEST_DATABASE_URL not set")
|
|
}
|
|
h, pool := testHandlers(t)
|
|
user := seedUser(t, pool, "sysforyou", "pw", false)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/playlists/system/for_you/refresh", nil)
|
|
req = withUser(req, user)
|
|
rec := httptest.NewRecorder()
|
|
newSystemPlaylistRouter(h).ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want 200; body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp systemRefreshResp
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
if resp.TrackIDs == nil {
|
|
t.Errorf("track_ids = nil, want [] (empty array, not null)")
|
|
}
|
|
if int(resp.TrackCount) != len(resp.TrackIDs) {
|
|
t.Errorf("track_count=%d, len(track_ids)=%d — mismatch", resp.TrackCount, len(resp.TrackIDs))
|
|
}
|
|
}
|
|
|
|
func TestSystemRefresh_Discover_Returns200(t *testing.T) {
|
|
if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" {
|
|
t.Skip("MINSTREL_TEST_DATABASE_URL not set")
|
|
}
|
|
h, pool := testHandlers(t)
|
|
user := seedUser(t, pool, "sysdiscover", "pw", false)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/playlists/system/discover/refresh", nil)
|
|
req = withUser(req, user)
|
|
rec := httptest.NewRecorder()
|
|
newSystemPlaylistRouter(h).ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want 200; body=%s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp systemRefreshResp
|
|
if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil {
|
|
t.Fatalf("decode: %v", err)
|
|
}
|
|
if resp.TrackCount < 0 {
|
|
t.Errorf("track_count = %d, want >= 0", resp.TrackCount)
|
|
}
|
|
}
|
|
|
|
// A non-singleton (songs_like_artist) or unknown kind isn't
|
|
// addressable by the generic endpoints → 404, not a build.
|
|
func TestSystemRefresh_NonSingletonKind_Returns404(t *testing.T) {
|
|
if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" {
|
|
t.Skip("MINSTREL_TEST_DATABASE_URL not set")
|
|
}
|
|
h, pool := testHandlers(t)
|
|
user := seedUser(t, pool, "sysbadkind", "pw", false)
|
|
|
|
for _, kind := range []string{"songs_like_artist", "bogus"} {
|
|
req := httptest.NewRequest(http.MethodPost, "/api/playlists/system/"+kind+"/refresh", nil)
|
|
req = withUser(req, user)
|
|
rec := httptest.NewRecorder()
|
|
newSystemPlaylistRouter(h).ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusNotFound {
|
|
t.Errorf("kind=%s: status = %d, want 404", kind, rec.Code)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSystemRefresh_NoAuth_Returns401(t *testing.T) {
|
|
if os.Getenv("MINSTREL_TEST_DATABASE_URL") == "" {
|
|
t.Skip("MINSTREL_TEST_DATABASE_URL not set")
|
|
}
|
|
h, _ := testHandlers(t)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/api/playlists/system/for_you/refresh", nil)
|
|
rec := httptest.NewRecorder()
|
|
newSystemPlaylistRouter(h).ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusUnauthorized {
|
|
t.Errorf("status = %d, want 401", rec.Code)
|
|
}
|
|
}
|