Honest baseline after removing 45 gaming suppressions. Structural: lib/game plus root hooks extraction, CORS origin echo, DEV_ORIGINS layering. Fixes: error-cause binding, discord 5xx split, null-cache guard, co-located tests, rejecting-fetch coverage, naming and typing cleanup, socket controller, cache bound, cascade helpers, latch resets. Hardening: per-IP rate limit on API routes, deterministic-miss UX, retry cooldown plus cap. Suite 140 green, build plus lint clean.
78 lines
2.3 KiB
TypeScript
78 lines
2.3 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import { _resetDetectablesCache, getDetectables, steamIdFromEntry } from "@/lib/game/detectables";
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
vi.restoreAllMocks();
|
|
_resetDetectablesCache();
|
|
});
|
|
|
|
describe("steamIdFromEntry", () => {
|
|
it("extracts numeric Steam SKUs", () => {
|
|
expect(
|
|
steamIdFromEntry({
|
|
id: "game",
|
|
name: "Game",
|
|
third_party_skus: [{ distributor: "steam", id: "12345" }],
|
|
}),
|
|
).toBe("12345");
|
|
});
|
|
|
|
it("rejects non-numeric or non-Steam SKUs", () => {
|
|
expect(
|
|
steamIdFromEntry({
|
|
id: "game",
|
|
name: "Game",
|
|
third_party_skus: [{ distributor: "steam", id: "abc" }],
|
|
}),
|
|
).toBeNull();
|
|
expect(
|
|
steamIdFromEntry({
|
|
id: "game",
|
|
name: "Game",
|
|
third_party_skus: [{ distributor: "gog", id: "12345" }],
|
|
}),
|
|
).toBeNull();
|
|
});
|
|
|
|
it("handles missing entries", () => {
|
|
expect(steamIdFromEntry(undefined)).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("getDetectables", () => {
|
|
it("caches the snapshot within the TTL", async () => {
|
|
const fetchMock = vi.fn(
|
|
async () =>
|
|
({
|
|
ok: true,
|
|
json: async () => [{ id: "1", name: "Game" }],
|
|
}) as Response,
|
|
);
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
const first = await getDetectables();
|
|
const second = await getDetectables();
|
|
expect(first).toHaveLength(1);
|
|
expect(second).toBe(first);
|
|
expect(fetchMock).toHaveBeenCalledOnce();
|
|
});
|
|
|
|
it("falls back to empty when fetch rejects", async () => {
|
|
vi.stubGlobal(
|
|
"fetch",
|
|
vi.fn(async () => {
|
|
throw new Error("down");
|
|
}),
|
|
);
|
|
await expect(getDetectables()).resolves.toEqual([]);
|
|
});
|
|
|
|
it("falls back to empty on HTTP error", async () => {
|
|
vi.stubGlobal(
|
|
"fetch",
|
|
vi.fn(async () => ({ ok: false, status: 500 }) as Response),
|
|
);
|
|
await expect(getDetectables()).resolves.toEqual([]);
|
|
});
|
|
});
|