Files
OmniRoute/tests/unit/dashboard-shell-tabs.test.ts
nguyenha935 4012bac41d fix(i18n): preserve remaining Vietnamese localization (#7935)
* fix(i18n): preserve remaining Vietnamese localization

* chore(quality): rebaseline file-size cap for 9 dashboard components (i18n wiring)

Restoring the Vietnamese localization on 9 dashboard components (useTranslations
wiring + t()/tc() call-site swaps for previously hardcoded strings) grows each
file by a small, irreducible amount. Bumps the frozen file-size-baseline.json
caps to match, with a justification entry per the project's own ratchet policy.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* fix(i18n): wire weekday localization + add missing qwen CLI description

Two gaps left by this PR's own new contract tests, caught while
reconciling the branch against the release tip:

- CostOverviewTab.tsx added formatWeekdayLabel() but never called it;
  the Weekly Usage Pattern chart still showed raw English day
  abbreviations regardless of locale. Now maps weeklyPattern rows
  through it before handing them to WeeklyPatternCard.
- cliTools.toolDescriptions was missing an entry for "qwen" (a
  baseUrlSupport:"full" tool) in both en.json and vi.json, failing
  the PR's own cli-catalog-display-contract.test.ts.

Covered by the PR's existing tests/unit/dashboard-localization-contract.test.ts
and tests/unit/cli-catalog-display-contract.test.ts (both now pass).

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* i18n(vi): backfill the 4 proxySubscription keys #7299 added to en.json

#7299 (proxy subscriptions) merged while this branch was rebasing, adding
settings.proxySubscriptionsTab and settings.proxySubscription.error.{LOCAL_CORE_ENDPOINT_INVALID,
NEEDS_CORE_NOT_CONFIGURED,NO_USABLE_NODES} to en.json. This PR's own
i18n-vi-completeness contract asserts full en↔vi key parity, so the merge of the
current release tip surfaced them as missing. Adds the Vietnamese translations,
keeping the SS/VMess/Trojan/VLESS/SOCKS5 technical terms verbatim.

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

---------

Co-authored-by: nguyenha935 <208228297+nguyenha935@users.noreply.github.com>
Co-authored-by: Diego Rodrigues de Sa e Souza <diegosouza.pw@gmail.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: nguyenha935 <nguyenha935@users.noreply.github.com>
2026-07-21 13:41:02 -03:00

106 lines
4.5 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
function readSource(relativePath: string) {
return readFileSync(new URL("../../" + relativePath, import.meta.url), "utf8");
}
test("analytics page exposes the restored analytics tab shell", () => {
const source = readSource("src/app/(dashboard)/dashboard/analytics/page.tsx");
assert.ok(source.includes('role="tablist"'));
assert.ok(source.includes('aria-label={t("sectionsAria")}'));
for (const [labelKey, label] of [
["overview", "Overview"],
["evals", "Evals"],
["search", "Search"],
["utilization", "Utilization"],
["comboHealth", "Combo Health"],
["routeTrace", "Route Trace"],
]) {
assert.ok(source.includes('labelKey: "' + labelKey + '"'));
assert.ok(source.includes('label: "' + label + '"'));
}
for (const tabId of [
"overview",
"evals",
"search",
"utilization",
"combo-health",
"route-trace",
]) {
assert.ok(source.includes('id: "' + tabId + '"'));
}
});
test("endpoint page keeps APIs, MCP, and A2A as in-page tabs", () => {
const source = readSource("src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx");
assert.ok(source.includes('type EndpointTab = "apis" | "mcp" | "a2a" | "context-sources"'));
for (const labelKey of ["tabApis", "tabMcp", "tabA2a", "tabContextSources"]) {
assert.ok(source.includes('labelKey: "' + labelKey + '"'));
}
assert.ok(source.includes("label: t(tab.labelKey)"));
assert.ok(source.includes('aria-label={t("endpointSections")}'));
assert.ok(source.includes('useState<EndpointTab>("apis")'));
assert.ok(source.includes('activeEndpointTab === "mcp" ? <McpDashboardPage /> : null'));
assert.ok(source.includes('activeEndpointTab === "a2a" ? <A2ADashboardPage /> : null'));
assert.ok(source.includes('activeEndpointTab === "context-sources"'));
});
test("endpoint page exposes context-sources tab with Notion and Obsidian source cards", () => {
const source = readSource("src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx");
// Verify context-sources is part of the EndpointTab type contract
assert.ok(source.includes('type EndpointTab = "apis" | "mcp" | "a2a" | "context-sources"'));
// Verify context-sources tab label is in ENDPOINT_TABS
assert.ok(
source.includes('{ value: "context-sources", labelKey: "tabContextSources", icon: "database" }')
);
// Verify both source card components are imported
assert.ok(source.includes('import NotionSourceCard from "./components/NotionSourceCard"'));
assert.ok(source.includes('import ObsidianSourceCard from "./components/ObsidianSourceCard"'));
// Verify both components are rendered in the context-sources conditional block
assert.ok(source.includes('activeEndpointTab === "context-sources" ? ('));
assert.ok(source.includes("<NotionSourceCard />"));
assert.ok(source.includes("<ObsidianSourceCard />"));
});
test("settings root redirects to section pages instead of rendering a tab shell", () => {
const pageSource = readSource("src/app/(dashboard)/dashboard/settings/page.tsx");
assert.ok(pageSource.includes('import { redirect } from "next/navigation"'));
assert.ok(pageSource.includes('general: "/dashboard/settings/general"'));
assert.ok(pageSource.includes('resilience: "/dashboard/settings/resilience"'));
assert.ok(pageSource.includes("redirect(resolveSettingsRoute(tab))"));
});
test("provider limit status chips use English fallback labels", () => {
const source = readSource(
"src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx"
);
assert.ok(source.includes('critical: tr("statCritical", "Critical")'));
assert.ok(source.includes('alert: tr("statAlert", "Alert")'));
assert.ok(source.includes('ok: tr("statHealthy", "Healthy")'));
assert.doesNotMatch(source, /Crítico|Alerta|Saudável/);
});
test("provider limits collapsed rows show quota resets and progress bars inline", () => {
const source = readSource(
"src/app/(dashboard)/dashboard/usage/components/ProviderLimits/index.tsx"
);
assert.ok(source.includes("const renderInlineQuotaSummary = (quotas: any[]) =>"));
assert.ok(source.includes("const cd = formatCountdown(q.resetAt)"));
assert.ok(source.includes("`⏱ ${cd}`"));
assert.ok(source.includes("h-1 w-14 rounded-sm"));
assert.ok(source.includes("getQuotaBarWidthClass(pct)"));
assert.ok(source.includes("getQuotaToneClasses(pct)"));
assert.ok(source.includes("renderInlineQuotaSummary(quota.quotas)"));
});