683c11661b
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
121 lines
3.5 KiB
Go
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))
|
|
}
|
|
}
|