feat(api): add /api/radio stub returning the seed track only
M6 stub. Validates seed_track param (400 on missing/blank/bad UUID), looks up the track (404 on miss), returns RadioResponse with a single TrackRef. M4 will replace the body with similarity-driven candidate pool + scoring; the request/response shape is final.
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
func newRadioRouter(h *handlers) chi.Router {
|
||||
r := chi.NewRouter()
|
||||
r.Get("/api/radio", h.handleRadio)
|
||||
return r
|
||||
}
|
||||
|
||||
func TestHandleRadio_Stub_ReturnsSeedOnly(t *testing.T) {
|
||||
h, pool := testHandlers(t)
|
||||
truncateLibrary(t, pool)
|
||||
artist := seedArtist(t, pool, "Beatles")
|
||||
album := seedAlbum(t, pool, artist.ID, "Abbey Road", 1969)
|
||||
track := seedTrack(t, pool, album.ID, artist.ID, "Something", 3, 183_000)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/radio?seed_track="+uuidToString(track.ID), nil)
|
||||
w := httptest.NewRecorder()
|
||||
newRadioRouter(h).ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d body=%s", w.Code, w.Body.String())
|
||||
}
|
||||
var got struct {
|
||||
Tracks []TrackRef `json:"tracks"`
|
||||
}
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
|
||||
t.Fatalf("decode: %v", err)
|
||||
}
|
||||
if len(got.Tracks) != 1 {
|
||||
t.Fatalf("len=%d, want 1", len(got.Tracks))
|
||||
}
|
||||
if got.Tracks[0].Title != "Something" {
|
||||
t.Errorf("title=%q", got.Tracks[0].Title)
|
||||
}
|
||||
if got.Tracks[0].AlbumTitle != "Abbey Road" || got.Tracks[0].ArtistName != "Beatles" {
|
||||
t.Errorf("ref = %+v", got.Tracks[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleRadio_NotFound(t *testing.T) {
|
||||
h, pool := testHandlers(t)
|
||||
truncateLibrary(t, pool)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/radio?seed_track=00000000-0000-0000-0000-000000000000", nil)
|
||||
w := httptest.NewRecorder()
|
||||
newRadioRouter(h).ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("status = %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleRadio_MissingSeed(t *testing.T) {
|
||||
h, _ := testHandlers(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/radio", nil)
|
||||
w := httptest.NewRecorder()
|
||||
newRadioRouter(h).ServeHTTP(w, req)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("status=%d, want 400", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleRadio_BlankSeed(t *testing.T) {
|
||||
h, _ := testHandlers(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/radio?seed_track=%20%20", nil)
|
||||
w := httptest.NewRecorder()
|
||||
newRadioRouter(h).ServeHTTP(w, req)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("status=%d, want 400", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleRadio_BadUUID(t *testing.T) {
|
||||
h, _ := testHandlers(t)
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/radio?seed_track=not-a-uuid", nil)
|
||||
w := httptest.NewRecorder()
|
||||
newRadioRouter(h).ServeHTTP(w, req)
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("status=%d, want 400", w.Code)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user