import { describe, expect, it } from "vitest"; import { en } from "@/lib/i18n/en"; import { fr } from "@/lib/i18n/fr"; import { fmtDate, href, pickLocale } from "@/lib/i18n"; const keys = (o: Record, p = ""): string[] => Object.entries(o).flatMap(([k, v]) => (v && typeof v === "object" ? keys(v as Record, `${p}${k}.`) : [`${p}${k}`])); describe("i18n", () => { it("French covers every English key and vice versa", () => { expect(keys(fr).sort()).toEqual(keys(en).sort()); }); it("no empty strings", () => { for (const d of [en, fr]) for (const k of keys(d)) { const v = k.split(".").reduce((a: unknown, s) => (a as Record)[s], d); expect(String(v).length, k).toBeGreaterThan(0); } }); it("href keeps canonical EN and prefixes FR; API/admin untouched", () => { expect(href("en", "/papers")).toBe("/papers"); expect(href("fr", "/papers")).toBe("/fr/papers"); expect(href("fr", "/")).toBe("/fr"); expect(href("fr", "/api/docs")).toBe("/api/docs"); expect(href("fr", "/admin")).toBe("/admin"); }); it("date formatting honours precision and never invents a day", () => { expect(fmtDate("en", "2026-10-01", "month")).toBe("October 2026"); expect(fmtDate("fr", "2026-10-01", "month")).toBe("octobre 2026"); expect(fmtDate("en", "2026-10-01", "year")).toBe("2026"); expect(fmtDate("en", "2026-10-17", "day")).toBe("October 17, 2026"); expect(fmtDate("fr", "2026-10-17", "day")).toBe("17 octobre 2026"); expect(fmtDate("en", null)).toBe(""); }); it("locale picking is strict", () => { expect(pickLocale("fr")).toBe("fr"); expect(pickLocale("de")).toBe("en"); expect(pickLocale(null)).toBe("en"); }); });