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"));
}));