Files
Lyra/web/src/lib/musicbrainz.test.ts
T

51 lines
2.8 KiB
TypeScript

import { describe, it, expect, vi, afterEach } from "vitest";
import { searchArtists, browseReleaseGroups, searchReleaseGroup } from "./musicbrainz";
function jsonResponse(data: unknown) {
return Promise.resolve({ ok: true, status: 200, json: () => Promise.resolve(data) } as Response);
}
afterEach(() => vi.unstubAllGlobals());
describe("musicbrainz module", () => {
it("searchArtists maps hits and sends a User-Agent", async () => {
const fetchMock = vi.fn((_url: string, _init?: RequestInit) =>
jsonResponse({ artists: [{ id: "a1", name: "John Mayer", disambiguation: "US singer" }] }),
);
vi.stubGlobal("fetch", fetchMock);
const hits = await searchArtists("john ma");
expect(hits).toEqual([{ mbid: "a1", name: "John Mayer", disambiguation: "US singer" }]);
const [, init] = fetchMock.mock.calls[0];
expect((init as RequestInit).headers).toMatchObject({ "User-Agent": expect.stringContaining("Lyra") });
});
it("browseReleaseGroups paginates until release-group-count is reached", async () => {
const page1 = { "release-group-count": 2, "release-groups": [{ id: "rg1", title: "A", "primary-type": "Album", "secondary-types": [], "first-release-date": "2001" }] };
const page2 = { "release-group-count": 2, "release-groups": [{ id: "rg2", title: "B", "primary-type": "EP", "secondary-types": ["Live"], "first-release-date": "" }] };
const fetchMock = vi.fn().mockReturnValueOnce(jsonResponse(page1)).mockReturnValueOnce(jsonResponse(page2));
vi.stubGlobal("fetch", fetchMock);
const rels = await browseReleaseGroups("a1");
expect(fetchMock).toHaveBeenCalledTimes(2);
expect(rels).toEqual([
{ rgMbid: "rg1", title: "A", primaryType: "Album", secondaryTypes: [], firstReleaseDate: "2001" },
{ rgMbid: "rg2", title: "B", primaryType: "EP", secondaryTypes: ["Live"], firstReleaseDate: null },
]);
});
it("throws on a non-2xx MusicBrainz response", async () => {
vi.stubGlobal("fetch", vi.fn(() => Promise.resolve({ ok: false, status: 503 } as Response)));
await expect(searchArtists("x")).rejects.toThrow(/503/);
});
it("searchReleaseGroup returns the top match with artist credit or null", async () => {
vi.stubGlobal("fetch", vi.fn(() => jsonResponse({ "release-groups": [
{ id: "rg9", title: "Continuum", "primary-type": "Album", "secondary-types": [], "first-release-date": "2006-09-12", "artist-credit": [{ artist: { id: "a1", name: "John Mayer" } }] },
] })));
const m = await searchReleaseGroup("John Mayer", "Continuum");
expect(m).toEqual({ rgMbid: "rg9", title: "Continuum", primaryType: "Album", secondaryTypes: [], firstReleaseDate: "2006-09-12", artistMbid: "a1", artistName: "John Mayer" });
vi.stubGlobal("fetch", vi.fn(() => jsonResponse({ "release-groups": [] })));
expect(await searchReleaseGroup("Nobody", "Nothing")).toBeNull();
});
});