feat(api): /api/discover/suggestions handler
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"git.fabledsword.com/bvandeusen/minstrel/internal/db/dbq"
|
||||
)
|
||||
|
||||
func newSuggestionsRouter(h *handlers) chi.Router {
|
||||
r := chi.NewRouter()
|
||||
r.Get("/api/discover/suggestions", h.handleListSuggestions)
|
||||
return r
|
||||
}
|
||||
|
||||
func doListSuggestions(h *handlers, user dbq.User, query string) *httptest.ResponseRecorder {
|
||||
url := "/api/discover/suggestions"
|
||||
if query != "" {
|
||||
url += "?" + query
|
||||
}
|
||||
req := httptest.NewRequest(http.MethodGet, url, nil)
|
||||
req = withUser(req, user)
|
||||
w := httptest.NewRecorder()
|
||||
newSuggestionsRouter(h).ServeHTTP(w, req)
|
||||
return w
|
||||
}
|
||||
|
||||
func TestSuggestions_HappyPath(t *testing.T) {
|
||||
h, pool := testHandlers(t)
|
||||
user := seedUser(t, pool, "alice", "pw", false)
|
||||
|
||||
q := dbq.New(pool)
|
||||
seed, err := q.UpsertArtist(context.Background(), dbq.UpsertArtistParams{
|
||||
Name: "Seed", SortName: "Seed",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("UpsertArtist: %v", err)
|
||||
}
|
||||
if _, err := pool.Exec(context.Background(),
|
||||
`INSERT INTO general_likes_artists (user_id, artist_id) VALUES ($1, $2)`,
|
||||
user.ID, seed.ID,
|
||||
); err != nil {
|
||||
t.Fatalf("like artist: %v", err)
|
||||
}
|
||||
if err := q.UpsertArtistSimilarityUnmatched(context.Background(), dbq.UpsertArtistSimilarityUnmatchedParams{
|
||||
SeedArtistID: seed.ID,
|
||||
CandidateMbid: "out-mbid",
|
||||
CandidateName: "Outsider",
|
||||
Score: 0.9,
|
||||
Source: "listenbrainz",
|
||||
}); err != nil {
|
||||
t.Fatalf("UpsertArtistSimilarityUnmatched: %v", err)
|
||||
}
|
||||
|
||||
w := doListSuggestions(h, user, "")
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200; body = %s", w.Code, w.Body.String())
|
||||
}
|
||||
var got []suggestionView
|
||||
if err := json.Unmarshal(w.Body.Bytes(), &got); err != nil {
|
||||
t.Fatalf("decode: %v", err)
|
||||
}
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("len = %d, want 1; body = %s", len(got), w.Body.String())
|
||||
}
|
||||
if got[0].MBID != "out-mbid" || got[0].Name != "Outsider" {
|
||||
t.Errorf("got = %+v", got[0])
|
||||
}
|
||||
if len(got[0].Attribution) != 1 || got[0].Attribution[0].Name != "Seed" {
|
||||
t.Errorf("attribution = %+v, want one entry named Seed", got[0].Attribution)
|
||||
}
|
||||
if !got[0].Attribution[0].IsLiked {
|
||||
t.Errorf("attribution.IsLiked = false, want true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSuggestions_EmptyForNewUser(t *testing.T) {
|
||||
h, pool := testHandlers(t)
|
||||
user := seedUser(t, pool, "newbie", "pw", false)
|
||||
|
||||
w := doListSuggestions(h, user, "")
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200; body = %s", w.Code, w.Body.String())
|
||||
}
|
||||
body := w.Body.String()
|
||||
if body != "[]" && body != "[]\n" {
|
||||
t.Errorf("body = %q, want []", body)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSuggestions_BadLimit(t *testing.T) {
|
||||
h, pool := testHandlers(t)
|
||||
user := seedUser(t, pool, "alice", "pw", false)
|
||||
|
||||
w := doListSuggestions(h, user, "limit=not-a-number")
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want 400; body = %s", w.Code, w.Body.String())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user