import { readFileSync } from "node:fs"; import { join } from "node:path"; import { describe, expect, it } from "vitest"; const root = process.cwd(); const locales = { da: JSON.parse(readFileSync(join(root, "src/i18n/locales/da.json"), "utf8")), en: JSON.parse(readFileSync(join(root, "src/i18n/locales/en.json"), "utf8")), sv: JSON.parse(readFileSync(join(root, "src/i18n/locales/sv.json"), "utf8")), de: JSON.parse(readFileSync(join(root, "src/i18n/locales/de.json"), "utf8")), no: JSON.parse(readFileSync(join(root, "src/i18n/locales/no.json"), "utf8")), }; const flattenKeys = (value, prefix = "") => { if (value === null || typeof value !== "object" || Array.isArray(value)) { return [prefix]; } const keys = []; for (const [key, nestedValue] of Object.entries(value)) { const nestedPrefix = prefix ? `${prefix}.${key}` : key; keys.push(...flattenKeys(nestedValue, nestedPrefix)); } return keys; }; describe("invoice distribution i18n coverage", () => { it("defines distribution namespace in every locale", () => { for (const [locale, data] of Object.entries(locales)) { expect(data.superuser_invoice_distribution, `missing namespace in ${locale}`).toBeTruthy(); } }); it("keeps the same translation key set across locales", () => { const baselineKeys = flattenKeys(locales.en.superuser_invoice_distribution).sort(); for (const [locale, data] of Object.entries(locales)) { const localeKeys = flattenKeys(data.superuser_invoice_distribution).sort(); expect(localeKeys, `mismatched key set in ${locale}`).toEqual(baselineKeys); } }); it("includes required distribution keys used by views", () => { const requiredKeys = [ "tab_label", "overview.title", "overview.subtitle", "monthly_page.title", "monthly_page.toolbar_month", "actions.reload", "actions.open_month", "actions.try_again", "actions.reset_filters", "tabs.overview", "tabs.departments", "tabs.customers", "tabs.compare", "compare.mode", "compare.modes.invoice_total", "compare.modes.line_by_line", "compare.run", "compare.run_short", "compare.progress", "compare.warning_details", "compare.status_label", "compare.status.ok", "compare.status.mismatch", "errors.overview_load_failed", "errors.month_load_failed", "errors.compare_failed", "warnings.legacy_distribution_fallback", "warnings.legacy_distribution_month", "warnings.legacy_compare_fallback", "sections.trend", "metrics.customer_prices", "table.customer_prices", "table.source_mix", "aria.month_table_caption", "aria.compare_table_caption", ]; const availableKeys = new Set(flattenKeys(locales.en.superuser_invoice_distribution)); requiredKeys.forEach((key) => { expect(availableKeys.has(key)).toBe(true); }); }); });