Files
govoplan-core/webui/tests/metric-card.test.tsx
T

64 lines
2.8 KiB
TypeScript

function assert(condition: unknown, message = "assertion failed"): void {
if (!condition) throw new Error(message);
}
import { renderToStaticMarkup } from "react-dom/server";
import MetricCard from "../src/components/MetricCard";
import { PlatformLanguageProvider } from "../src/i18n/LanguageContext";
const translatedMarkup = renderToStaticMarkup(
<PlatformLanguageProvider>
<MetricCard
label="i18n:govoplan-core.installed_modules.32b3e799"
value="i18n:govoplan-core.core_only.d46ce7d9"
detail="i18n:govoplan-core.install_the_campaign_module_to_show_campaign_act.3085f23e"
tone="info"
/>
</PlatformLanguageProvider>
);
assert(translatedMarkup.includes('class="metric-card metric-info '), "the visual tone is preserved");
assert(translatedMarkup.includes('class="metric-label">Installed modules</div>'), "the label is translated");
assert(translatedMarkup.includes('class="metric-value">Core only</div>'), "a string value is translated");
assert(!translatedMarkup.includes("i18n:govoplan-core."), "translation keys never leak into visible card text");
const numericMarkup = renderToStaticMarkup(<MetricCard label="Count" value={7} />);
assert(numericMarkup.includes('class="metric-value">7</div>'), "numeric values are preserved");
assert(!numericMarkup.includes("data-metric-drilldown"), "summary-only metrics remain non-interactive");
const linkedMarkup = renderToStaticMarkup(
<MetricCard
label="Recipients"
value={17}
drilldown={{ label: "Review recipients", href: "/campaigns/42/recipients" }}
/>
);
assert(linkedMarkup.includes('data-metric-drilldown="link"'), "link drill-downs have an explicit affordance");
assert(linkedMarkup.includes('href="/campaigns/42/recipients"'), "link drill-downs preserve their destination");
assert(linkedMarkup.includes("Review recipients"), "link drill-downs name the resulting detail");
const actionMarkup = renderToStaticMarkup(
<MetricCard
label="Failures"
value={2}
drilldown={{ label: "Show failures", onActivate: () => undefined }}
/>
);
assert(actionMarkup.includes('data-metric-drilldown="action"'), "in-page drill-downs render as buttons");
assert(actionMarkup.includes('type="button"'), "in-page drill-downs do not submit an enclosing form");
const disabledMarkup = renderToStaticMarkup(
<MetricCard
label="Suppressed"
value="—"
drilldown={{
label: "Show records",
onActivate: () => undefined,
disabledReason: "Individual records are privacy-suppressed"
}}
/>
);
assert(disabledMarkup.includes('class="disabled-action-tooltip"'), "disabled drill-downs retain the shared explanation trigger");
assert(disabledMarkup.includes('tabindex="0"'), "disabled drill-down explanations remain keyboard reachable");
assert(disabledMarkup.includes("disabled"), "blocked drill-down actions cannot run");