import { describe, expect, test } from "bun:test"; import { SteamGridDbProvider } from "../src/art/steamgriddb.js"; import { parseTitle } from "../src/domain/titles.js"; import { platformById } from "../src/domain/platforms.js"; const snes = platformById("snes")!; /** A fake SteamGridDB backend keyed by URL path fragments. */ const fakeFetch = (opts: { status?: number; games?: unknown[]; grids?: unknown[]; heroes?: unknown[]; logos?: unknown[]; }): typeof fetch => ((input: string | URL | Request) => { const url = typeof input === "string" ? input : input.toString(); const path = new URL(url).pathname; if (opts.status && opts.status !== 200) { return Promise.resolve(new Response("nope", { status: opts.status })); } let data: unknown[] = []; if (path.includes("/search/autocomplete/")) data = opts.games ?? []; else if (path.includes("/grids/game/")) data = opts.grids ?? []; else if (path.includes("/heroes/game/")) data = opts.heroes ?? []; else if (path.includes("/logos/game/")) data = opts.logos ?? []; return Promise.resolve(Response.json({ success: true, data })); }) as typeof fetch; describe("SteamGridDbProvider", () => { test("classifies grids into portrait + header and pulls hero + logo", async () => { const provider = new SteamGridDbProvider( "key", fakeFetch({ games: [{ id: 1, name: "Chrono Trigger" }], grids: [ { url: "http://p600.png", width: 600, height: 900 }, { url: "http://h460.png", width: 460, height: 215 }, ], heroes: [{ url: "http://hero.png", width: 1920, height: 620 }], logos: [{ url: "http://logo.png", width: 400, height: 200 }], }), ); const art = await provider.resolve( snes, parseTitle("Chrono Trigger (USA)"), ); expect(art).toEqual({ portrait: "http://p600.png", header: "http://h460.png", hero: "http://hero.png", logo: "http://logo.png", }); }); test("no game match → null", async () => { const provider = new SteamGridDbProvider("key", fakeFetch({ games: [] })); expect(await provider.resolve(snes, parseTitle("Nope"))).toBeNull(); }); test("a bad key (401) disables the provider and returns null", async () => { const provider = new SteamGridDbProvider("bad", fakeFetch({ status: 401 })); expect(await provider.resolve(snes, parseTitle("Anything"))).toBeNull(); }); test("the cache id is scoped to the key (so a key change re-resolves)", () => { const a = new SteamGridDbProvider("k1").id; const b = new SteamGridDbProvider("k2").id; expect(a).not.toBe(b); expect(a.startsWith("steamgriddb:")).toBe(true); }); });