mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
* 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>
52 lines
2.1 KiB
TypeScript
52 lines
2.1 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import test from "node:test";
|
|
|
|
import en from "../../src/i18n/messages/en.json" with { type: "json" };
|
|
import vi from "../../src/i18n/messages/vi.json" with { type: "json" };
|
|
import { BUILTIN_BADGES } from "../../src/lib/gamification/badges";
|
|
|
|
const profileSource = readFileSync("src/app/(dashboard)/dashboard/profile/page.tsx", "utf8");
|
|
const tokensSource = readFileSync("src/app/(dashboard)/dashboard/tokens/page.tsx", "utf8");
|
|
const topListSource = readFileSync(
|
|
"src/app/(dashboard)/dashboard/costs/components/TopListCard.tsx",
|
|
"utf8"
|
|
);
|
|
const englishBadges = en.gamification.badges as Record<string, Record<string, string>>;
|
|
const vietnameseBadges = vi.gamification.badges as Record<string, Record<string, string>>;
|
|
|
|
test("every built-in badge has complete English and Vietnamese display copy", () => {
|
|
for (const badge of BUILTIN_BADGES) {
|
|
for (const field of ["name", "description", "criteria"] as const) {
|
|
const englishValue = englishBadges[badge.id]?.[field];
|
|
const vietnameseValue = vietnameseBadges[badge.id]?.[field];
|
|
assert.ok(englishValue?.trim(), `en missing gamification.badges.${badge.id}.${field}`);
|
|
assert.ok(vietnameseValue?.trim(), `vi missing gamification.badges.${badge.id}.${field}`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test("profile renders mapped icons and localized badge criteria", () => {
|
|
assert.match(profileSource, /function BadgeIcon/);
|
|
assert.match(profileSource, /translateBadge\(selectedBadge, "criteria"\)/);
|
|
assert.doesNotMatch(profileSource, /<p className="text-sm">\{selectedBadge\.criteria\}<\/p>/);
|
|
});
|
|
|
|
test("token page no longer contains known raw English controls", () => {
|
|
for (const rawText of [
|
|
"Send Tokens",
|
|
"Create Invite",
|
|
"Connect Server",
|
|
"No servers connected",
|
|
"Last sync:",
|
|
"Disconnect",
|
|
]) {
|
|
assert.equal(tokensSource.includes(`>${rawText}<`), false, `raw token copy: ${rawText}`);
|
|
}
|
|
});
|
|
|
|
test("cost list component receives its localized legacy-free label", () => {
|
|
assert.match(topListSource, /legacyFreeLabel: string;/);
|
|
assert.match(topListSource, /\{legacyFreeLabel\}/);
|
|
});
|