desloppify: code health overhaul plus abuse hardening (140 green, strict 87.2)
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.
This commit is contained in:
78 files changed
+4908
-1430
No files matched your search
@@ -0,0 +1,77 @@
|
||||
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([]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user