Discover request surface — taste-aware, rotating, snoozable, tag-targeted (milestone #268) #116

Merged
bvandeusen merged 14 commits from dev into main 2026-08-03 08:38:25 -04:00
Showing only changes of commit cf0d37bf8e - Show all commits
@@ -399,23 +399,57 @@ func TestSuggestArtists_UntaggedCandidateSurvivesAlongsideTagged(t *testing.T) {
seedCandidateTag(t, pool, "match", "shoegaze", 1.0)
// "loud" is deliberately left with NO cached tags at all.
out, err := SuggestArtists(context.Background(), pool, user.ID, 30, 12, 1.0)
// Compared against the same request with the term disabled, rather than
// against a literal. The pool score is signal-weighted by the seed query
// (ln(1+signal) x similarity), so hardcoding a number here would assert
// against the seeding maths — a different layer — and break whenever that
// changes. The property under test is only that the blend leaves an
// untagged candidate alone.
blended, err := SuggestArtists(context.Background(), pool, user.ID, 30, 12, 1.0)
if err != nil {
t.Fatalf("SuggestArtists: %v", err)
t.Fatalf("SuggestArtists(blended): %v", err)
}
if len(out) != 2 {
t.Fatalf("len = %d, want 2 — the untagged candidate must still appear", len(out))
baseline, err := SuggestArtists(context.Background(), pool, user.ID, 30, 12, 0)
if err != nil {
t.Fatalf("SuggestArtists(baseline): %v", err)
}
var loud *ArtistSuggestion
for i := range out {
if out[i].MBID == "loud" {
loud = &out[i]
if len(blended) != 2 {
t.Fatalf("len = %d, want 2 — the untagged candidate must still appear", len(blended))
}
scoreOf := func(out []ArtistSuggestion, mbid string) (float64, bool) {
for _, s := range out {
if s.MBID == mbid {
return s.Score, true
}
}
if loud == nil {
t.Fatal("untagged candidate vanished from the deck")
return 0, false
}
if loud.Score != 0.9 {
t.Errorf("untagged score = %v, want 0.9 unchanged", loud.Score)
want, ok := scoreOf(baseline, "loud")
if !ok {
t.Fatal("untagged candidate missing from the baseline deck")
}
got, ok := scoreOf(blended, "loud")
if !ok {
t.Fatal("untagged candidate vanished once the tag term was enabled")
}
if got != want {
t.Errorf("untagged score = %v, want %v (identical to the term-disabled run)", got, want)
}
// Sanity: the tagged candidate DID move, so the comparison above is
// meaningful rather than both runs being trivially identical.
if tagged, _ := scoreOf(blended, "match"); tagged == mustScore(t, baseline, "match") {
t.Error("the tagged candidate's score did not change — the term did nothing")
}
}
func mustScore(t *testing.T, out []ArtistSuggestion, mbid string) float64 {
t.Helper()
for _, s := range out {
if s.MBID == mbid {
return s.Score
}
}
t.Fatalf("no candidate %q in %v", mbid, out)
return 0
}