fix(web): resolve album names to the studio Album, not a same-title Single

searchReleaseGroup took the first MusicBrainz hit, so a title MB ranks with the
single first (e.g. "Thriller" ties single+album at score 100) resolved to the
single — the Last.fm album modal and the Want flow then showed a 1-track single.
Prefer a clean Album > EP > Single > album-with-secondary, keeping MB order as the
in-tier tiebreak; single-only titles still resolve.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jonathan
2026-07-13 21:06:15 +02:00
parent 146bf32f23
commit 13126addbc
2 changed files with 38 additions and 1 deletions
+20
View File
@@ -48,6 +48,26 @@ describe("musicbrainz module", () => {
expect(await searchReleaseGroup("Nobody", "Nothing")).toBeNull();
});
it("prefers a clean studio Album over a same-title Single/comp that MB ranks first", async () => {
// MB ties the "Thriller" single with the album at the same score and lists the single
// first; we must resolve to the studio album, not the single.
vi.stubGlobal("fetch", vi.fn(() => jsonResponse({ "release-groups": [
{ id: "single", title: "Thriller", "primary-type": "Single", "secondary-types": [], "first-release-date": "1983", "artist-credit": [{ artist: { id: "mj", name: "Michael Jackson" } }] },
{ id: "comp", title: "Thriller", "primary-type": "Album", "secondary-types": ["Compilation"], "first-release-date": "2015", "artist-credit": [{ artist: { id: "mj", name: "Michael Jackson" } }] },
{ id: "album", title: "Thriller", "primary-type": "Album", "secondary-types": [], "first-release-date": "1982", "artist-credit": [{ artist: { id: "mj", name: "Michael Jackson" } }] },
] })));
const m = await searchReleaseGroup("Michael Jackson", "Thriller");
expect(m?.rgMbid).toBe("album");
expect(m?.primaryType).toBe("Album");
});
it("falls back to a Single when no album-type release group matches", async () => {
vi.stubGlobal("fetch", vi.fn(() => jsonResponse({ "release-groups": [
{ id: "single-only", title: "Standalone", "primary-type": "Single", "secondary-types": [], "first-release-date": "2020", "artist-credit": [{ artist: { id: "a1", name: "Artist" } }] },
] })));
expect((await searchReleaseGroup("Artist", "Standalone"))?.rgMbid).toBe("single-only");
});
it("escapes quotes in the release-group query", async () => {
const fetchMock = vi.fn((_url: string, _init?: RequestInit) => jsonResponse({ "release-groups": [] }));
vi.stubGlobal("fetch", fetchMock);