Verified with the coordinated workspace changes by devkit full run 2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed). This shared UI pass does not mark the individual module reviews complete.
113 lines
5.0 KiB
JavaScript
Executable File
113 lines
5.0 KiB
JavaScript
Executable File
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { createRequire } from "node:module";
|
|
import test from "node:test";
|
|
import vm from "node:vm";
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const { transformSync } = require("esbuild");
|
|
const React = require("react");
|
|
const { renderToStaticMarkup } = require("react-dom/server");
|
|
const { MemoryRouter } = require("react-router");
|
|
|
|
function loadSource(path, bindings = {}) {
|
|
const context = vm.createContext({ module: { exports: {} }, require, ...bindings });
|
|
context.exports = context.module.exports;
|
|
vm.runInContext(transformSync(readFileSync(new URL(path, import.meta.url), "utf8"), {
|
|
loader: path.endsWith(".tsx") ? "tsx" : "ts", format: "cjs", jsx: "automatic"
|
|
}).code, context);
|
|
return { exports: context.module.exports, context };
|
|
}
|
|
|
|
const { generatedTranslations } = loadSource("../src/i18n/generatedTranslations.ts").exports;
|
|
const launch = loadSource("../src/platform/launchContext.ts").exports;
|
|
|
|
function harness(locale = "en") {
|
|
const navigation = [];
|
|
const translateText = (value) => {
|
|
if (typeof value === "string") return generatedTranslations[locale][value] ?? value;
|
|
let text = generatedTranslations[locale][value.key] ?? value.key;
|
|
for (const [key, replacement] of Object.entries(value.values)) {
|
|
text = text.replaceAll(`{${key}}`, replacement);
|
|
}
|
|
return text;
|
|
};
|
|
const loaded = loadSource("../src/layout/BreadcrumbBar.tsx", {
|
|
window: { history: { state: { idx: 7 } } },
|
|
require: (name) => {
|
|
if (name === "../i18n/LanguageContext") return {
|
|
usePlatformLanguage: () => ({ translateText }),
|
|
i18nMessage: (key, values) => ({ key, values })
|
|
};
|
|
if (name === "../components/UnsavedChangesGuard") return {
|
|
useGuardedNavigate: () => (...args) => navigation.push(args)
|
|
};
|
|
if (name === "../platform/launchContext") return launch;
|
|
return require(name);
|
|
}
|
|
});
|
|
const BreadcrumbBar = loaded.exports.default;
|
|
return {
|
|
...loaded, navigation, BreadcrumbBar,
|
|
links(pathname, search = "") {
|
|
const html = renderToStaticMarkup(React.createElement(
|
|
MemoryRouter, { initialEntries: [`${pathname}${search}`] },
|
|
React.createElement(BreadcrumbBar, { pathname })
|
|
));
|
|
return [...html.matchAll(/<a\b([^>]*)>(.*?)<\/a>/g)].map(([, attributes, label]) => ({
|
|
href: /href="([^"]*)"/.exec(attributes)?.[1], label: label.replaceAll("&", "&")
|
|
}));
|
|
}
|
|
};
|
|
}
|
|
|
|
test("module-global reports and operator queue have their own bilingual labels and exact links", () => {
|
|
for (const locale of ["en", "de"]) {
|
|
const h = harness(locale);
|
|
const root = generatedTranslations[locale]["i18n:govoplan-core.campaigns.01a23a28"];
|
|
for (const [route, key] of [
|
|
["reports", "i18n:govoplan-core.reports.88bc3fe3"],
|
|
["queue", "i18n:govoplan-core.operator_queue.72492fb5"]
|
|
]) {
|
|
for (const trailingSlash of ["", "/"]) {
|
|
assert.deepEqual(h.links(`/campaigns/${route}${trailingSlash}`, "?campaign=selected-campaign"), [
|
|
{ href: "/campaigns", label: root },
|
|
{ href: `/campaigns/${route}`, label: generatedTranslations[locale][key] }
|
|
]);
|
|
}
|
|
}
|
|
assert.equal(h.links("/operator")[0].label, generatedTranslations[locale]["i18n:govoplan-core.operator_queue.72492fb5"]);
|
|
}
|
|
});
|
|
|
|
test("campaign editor report aliases and attachment deep links retain their singular campaign context", () => {
|
|
const h = harness();
|
|
const campaignId = "8ef65230-94d1-49a5-93a9-c5ef7c87ad45";
|
|
for (const suffix of ["report", "reports", "attachments"]) {
|
|
const links = h.links(`/campaigns/${campaignId}/${suffix}`);
|
|
assert.deepEqual(links.map((item) => item.href), ["/campaigns", `/campaigns/${campaignId}`, `/campaigns/${campaignId}/${suffix}`]);
|
|
assert.equal(links[1].label, generatedTranslations.en["i18n:govoplan-core.campaign.69390e16"]);
|
|
assert.equal(links[2].label, generatedTranslations.en[suffix === "attachments"
|
|
? "i18n:govoplan-core.attachments.6771ade6" : "i18n:govoplan-core.report.ee45c303"]);
|
|
}
|
|
});
|
|
|
|
test("quick-access return preserves guarded history back or the exact origin deep link", () => {
|
|
const origin = launch.createQuickAccessLaunchContext({
|
|
pathname: "/cases/case-fixture", search: "?tab=work", hash: "#campaigns", historyIndex: 6,
|
|
auth: { user: { account_id: "account-fixture" }, tenant: { id: "tenant-fixture" } },
|
|
temporalContext: { validityMode: "current" }
|
|
});
|
|
const h = harness();
|
|
for (const historyIndex of [7, 20]) {
|
|
h.context.window.history.state.idx = historyIndex;
|
|
const tree = h.BreadcrumbBar({ pathname: "/campaigns/reports", locationState: launch.quickAccessLaunchState(origin) });
|
|
const button = React.Children.toArray(tree.props.children).find((item) => item.type === "button");
|
|
assert.ok(button, "the launch return action remains visible");
|
|
button.props.onClick();
|
|
}
|
|
assert.deepEqual(h.navigation[0], [-1]);
|
|
assert.equal(h.navigation[1][0], "/cases/case-fixture?tab=work#campaigns");
|
|
assert.equal(h.navigation[1][1].replace, true);
|
|
});
|