Files
2026-04-21 08:29:28 -04:00

121 lines
3.5 KiB
Go

package api
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
)
func TestHandleSearch_ThreeFacets(t *testing.T) {
h, pool := testHandlers(t)
truncateLibrary(t, pool)
artist := seedArtist(t, pool, "Beatles")
album := seedAlbum(t, pool, artist.ID, "Beatles Greatest", 1982)
seedTrack(t, pool, album.ID, artist.ID, "Beatles Jam", 1, 60_000)
req := httptest.NewRequest(http.MethodGet, "/api/search?q=beatles", nil)
w := httptest.NewRecorder()
newLibraryRouter(h).ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status = %d body = %s", w.Code, w.Body.String())
}
var got SearchResponse
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
t.Fatalf("decode: %v", err)
}
if got.Artists.Total != 1 || len(got.Artists.Items) != 1 {
t.Errorf("artists = %+v", got.Artists)
}
if got.Albums.Total != 1 || len(got.Albums.Items) != 1 {
t.Errorf("albums = %+v", got.Albums)
}
if got.Tracks.Total != 1 || len(got.Tracks.Items) != 1 {
t.Errorf("tracks = %+v", got.Tracks)
}
if got.Artists.Items[0].Name != "Beatles" {
t.Errorf("artist name = %q", got.Artists.Items[0].Name)
}
if got.Albums.Items[0].ArtistName != "Beatles" {
t.Errorf("album.artist_name = %q", got.Albums.Items[0].ArtistName)
}
if got.Tracks.Items[0].AlbumTitle != "Beatles Greatest" {
t.Errorf("track.album_title = %q", got.Tracks.Items[0].AlbumTitle)
}
}
func TestHandleSearch_NoMatches(t *testing.T) {
h, pool := testHandlers(t)
truncateLibrary(t, pool)
seedArtist(t, pool, "Beatles")
req := httptest.NewRequest(http.MethodGet, "/api/search?q=nothinghere", nil)
w := httptest.NewRecorder()
newLibraryRouter(h).ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status = %d", w.Code)
}
var got SearchResponse
_ = json.Unmarshal(w.Body.Bytes(), &got)
if got.Artists.Total != 0 || got.Albums.Total != 0 || got.Tracks.Total != 0 {
t.Errorf("totals = %+v", got)
}
// All three item slices must JSON-encode as [] not null.
if got.Artists.Items == nil || got.Albums.Items == nil || got.Tracks.Items == nil {
t.Errorf("nil item slice: %+v", got)
}
}
func TestHandleSearch_EmptyQuery(t *testing.T) {
h, _ := testHandlers(t)
req := httptest.NewRequest(http.MethodGet, "/api/search", nil)
w := httptest.NewRecorder()
newLibraryRouter(h).ServeHTTP(w, req)
if w.Code != http.StatusBadRequest {
t.Errorf("status = %d, want 400", w.Code)
}
}
func TestHandleSearch_BlankQuery(t *testing.T) {
h, _ := testHandlers(t)
req := httptest.NewRequest(http.MethodGet, "/api/search?q=%20%20", nil)
w := httptest.NewRecorder()
newLibraryRouter(h).ServeHTTP(w, req)
if w.Code != http.StatusBadRequest {
t.Errorf("status = %d, want 400", w.Code)
}
}
func TestHandleSearch_PagingAppliedPerFacet(t *testing.T) {
h, pool := testHandlers(t)
truncateLibrary(t, pool)
// Create three matching artists so paging shows.
a1 := seedArtist(t, pool, "Match One")
a2 := seedArtist(t, pool, "Match Two")
a3 := seedArtist(t, pool, "Match Three")
_ = a1
_ = a2
_ = a3
req := httptest.NewRequest(http.MethodGet, "/api/search?q=Match&limit=2&offset=1", nil)
w := httptest.NewRecorder()
newLibraryRouter(h).ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("status = %d", w.Code)
}
var got SearchResponse
_ = json.Unmarshal(w.Body.Bytes(), &got)
if got.Artists.Total != 3 {
t.Errorf("total = %d, want 3", got.Artists.Total)
}
if got.Artists.Limit != 2 || got.Artists.Offset != 1 {
t.Errorf("page = limit=%d offset=%d", got.Artists.Limit, got.Artists.Offset)
}
if len(got.Artists.Items) != 2 {
t.Errorf("items len = %d, want 2", len(got.Artists.Items))
}
}