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.
149 lines
4.2 KiB
TypeScript
149 lines
4.2 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import type { GamePricePoint } from "@/lib/game/game-profile-types";
|
|
import {
|
|
describeProfile,
|
|
discountPercent,
|
|
formatCount,
|
|
formatElapsed,
|
|
formatPrice,
|
|
formatReleaseDate,
|
|
localizeScore,
|
|
normalizeGameTitle,
|
|
resolveGameLocale,
|
|
selectGameView,
|
|
type ModalDict,
|
|
} from "@/lib/game/game-format";
|
|
|
|
const dict = {
|
|
reviewScores: {
|
|
overwhelminglyPositive: "Son Derece Olumlu",
|
|
positive: "Olumlu",
|
|
mixed: "Karışık",
|
|
},
|
|
} as unknown as ModalDict;
|
|
|
|
const point: GamePricePoint = {
|
|
price: 100,
|
|
regular: 200,
|
|
currency: "USD",
|
|
shop: "Steam",
|
|
url: "https://example.com",
|
|
};
|
|
|
|
describe("localizeScore", () => {
|
|
it("maps known Steam labels", () => {
|
|
expect(localizeScore("Overwhelmingly Positive", dict)).toBe("Son Derece Olumlu");
|
|
});
|
|
|
|
it("falls back to the raw label", () => {
|
|
expect(localizeScore("Unknown Label", dict)).toBe("Unknown Label");
|
|
});
|
|
});
|
|
|
|
describe("discountPercent", () => {
|
|
it("computes the discount", () => {
|
|
expect(discountPercent(point)).toBe(50);
|
|
});
|
|
|
|
it("returns null without a real discount", () => {
|
|
expect(discountPercent({ ...point, regular: 100 })).toBeNull();
|
|
expect(discountPercent({ ...point, regular: 0 })).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("formatCount", () => {
|
|
it("formats with unit", () => {
|
|
expect(formatCount(3, "en-US", "reviews")).toBe("3 reviews");
|
|
});
|
|
|
|
it("renders a dash for nullish values", () => {
|
|
expect(formatCount(null, "en-US", "reviews")).toBe("—");
|
|
expect(formatCount(undefined, "en-US", "reviews")).toBe("—");
|
|
});
|
|
});
|
|
|
|
describe("formatPrice", () => {
|
|
it("formats currency", () => {
|
|
expect(formatPrice(point, "en-US")).toContain("100");
|
|
});
|
|
});
|
|
|
|
describe("formatReleaseDate", () => {
|
|
it("localizes ISO dates", () => {
|
|
expect(formatReleaseDate("2024-01-15", "en-US")).toContain("2024");
|
|
});
|
|
|
|
it("passes through non-ISO values", () => {
|
|
expect(formatReleaseDate("soon", "en-US")).toBe("soon");
|
|
});
|
|
});
|
|
|
|
describe("normalizeGameTitle", () => {
|
|
it("lowercases and strips marks", () => {
|
|
expect(normalizeGameTitle("Elden Ring™")).toBe("elden ring");
|
|
});
|
|
|
|
it("collapses separators", () => {
|
|
expect(normalizeGameTitle("Half-Life 2: Episode One")).toBe("half life 2 episode one");
|
|
});
|
|
});
|
|
|
|
describe("resolveGameLocale", () => {
|
|
it("resolves supported locales", () => {
|
|
expect(resolveGameLocale("tr")).toEqual({
|
|
lang: "tr",
|
|
country: "TR",
|
|
localeTag: "tr-TR",
|
|
steamLang: "turkish",
|
|
});
|
|
expect(resolveGameLocale("de").country).toBe("DE");
|
|
});
|
|
|
|
it("falls back to English", () => {
|
|
expect(resolveGameLocale("fr").lang).toBe("en");
|
|
expect(resolveGameLocale("").localeTag).toBe("en-US");
|
|
});
|
|
});
|
|
|
|
describe("selectGameView", () => {
|
|
it("falls back without a profile", () => {
|
|
expect(selectGameView(null, "Name", "https://fallback")).toEqual({
|
|
gameUrl: "https://fallback",
|
|
name: "Name",
|
|
bestPrice: null,
|
|
historyLow: null,
|
|
isFree: false,
|
|
});
|
|
});
|
|
});
|
|
describe("formatElapsed", () => {
|
|
it("formats per-locale units from one table", () => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date("2024-01-15T12:00:00Z"));
|
|
try {
|
|
const start = new Date("2024-01-15T10:30:00Z").getTime();
|
|
expect(formatElapsed(start, "tr")).toBe("1s 30dk");
|
|
expect(formatElapsed(start, "de")).toBe("1 Std. 30 Min.");
|
|
expect(formatElapsed(start, "en")).toBe("1h 30m");
|
|
expect(formatElapsed(start, "fr")).toBe("1h 30m");
|
|
expect(formatElapsed(Date.now(), "tr")).toBe("<1dk");
|
|
} finally {
|
|
vi.useRealTimers();
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("describeProfile", () => {
|
|
it("handles a null profile", () => {
|
|
const summary = describeProfile(null);
|
|
expect(summary).toEqual({
|
|
dbRating: null,
|
|
itadReviews: [],
|
|
hasDetails: false,
|
|
hasReviews: false,
|
|
metascore: null,
|
|
opencritic: null,
|
|
});
|
|
});
|
|
});
|