import assert from "node:assert/strict"; import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs"; import { createRequire } from "node:module"; import { tmpdir } from "node:os"; import { dirname, join, resolve } from "node:path"; import { test } from "node:test"; import { auditRepository } from "../tools/devkit/audit-display-labels.mjs"; const require = createRequire(resolve(import.meta.dirname, "../../govoplan-core/webui/package.json")); const ts = require("typescript"); function fixture(fn) { const root = mkdtempSync(join(tmpdir(), "govoplan-label-audit-")); const write = (relative, content) => { const target = join(root, relative); mkdirSync(dirname(target), { recursive: true }); writeFileSync(target, content); }; try { write("core/webui/src/i18n/generatedTranslations.ts", 'export const generatedTranslations = { en: { Shared: "Shared" }, de: { Shared: "Gemeinsam" } };'); return fn(root, write); } finally { rmSync(root, { recursive: true, force: true }); } } test("plain labels resolve owning registered catalogs, aliases, constants and Core defaults", () => fixture((root, write) => { write("module/webui/src/i18n/generatedTranslations.ts", 'const en = { Projects: "Projects" }; const de = { Projects: "Projekte" }; export const generatedTranslations = { en, de };'); write("module/webui/src/module.ts", 'import { generatedTranslations as words } from "./i18n/generatedTranslations"; export const exampleModule: PlatformWebModule = { translations: words };'); write("module/webui/src/Page.tsx", 'import { PageLayout as Layout, PageTitle } from "@govoplan/core-webui"; const title = "Projects"; export const page = <>Shared;'); const result = auditRepository(ts, join(root, "module"), join(root, "core")); assert.equal(result.registration, "registered"); assert.equal(result.labels.length, 2); assert.deepEqual(result.findings, []); })); test("a catalog file without module registration cannot mask untranslated titles", () => fixture((root, write) => { write("module/webui/src/i18n/generatedTranslations.ts", 'export const generatedTranslations = { en: { Projects: "Projects" }, de: { Projects: "Projekte" } };'); write("module/webui/src/module.ts", 'export const exampleModule = { id: "example" };'); write("module/webui/src/Page.tsx", 'import * as Core from "@govoplan/core-webui"; export const page = ;'); const result = auditRepository(ts, join(root, "module"), join(root, "core")); assert(result.findings.some((item) => item.code === "catalog-not-registered")); assert.deepEqual(result.labels[0].missing_locales, ["en", "de"]); })); test("only known static display slots fail; markers and runtime data remain separate", () => fixture((root, write) => { write("module/webui/src/Page.tsx", 'import { PageLayout } from "@govoplan/core-webui"; export const page = <>;'); const result = auditRepository(ts, join(root, "module"), join(root, "core")); assert.equal(result.findings.length, 1); assert.equal(result.findings[0].text, "Untranslated"); assert.equal(result.review.length, 1); assert.equal(result.review[0].code, "dynamic-display-slot"); })); test("dynamic translation registration is reported for review, not falsely missing", () => fixture((root, write) => { write("module/webui/src/module.ts", 'export const exampleModule: PlatformWebModule = { translations: configuredCatalog() };'); write("module/webui/src/Page.tsx", 'export const page = Example;'); const result = auditRepository(ts, join(root, "module"), join(root, "core")); assert.equal(result.registration, "dynamic"); assert.deepEqual(result.findings, []); assert(result.review.some((item) => item.code === "dynamic-catalog-review")); }));