From 9a64e0e17d177b1fdf6dd72b91c0577a8f6505a6 Mon Sep 17 00:00:00 2001 From: Alex Jordan <60003097+alex-jordan547@users.noreply.github.com> Date: Sun, 2 Aug 2026 21:28:08 +0200 Subject: [PATCH] test(i18n): cover hardcoded UI regressions --- .../i18n-hardcoded-ui-regressions.test.ts | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 tests/unit/i18n-hardcoded-ui-regressions.test.ts diff --git a/tests/unit/i18n-hardcoded-ui-regressions.test.ts b/tests/unit/i18n-hardcoded-ui-regressions.test.ts new file mode 100644 index 0000000000..0f1b46d4da --- /dev/null +++ b/tests/unit/i18n-hardcoded-ui-regressions.test.ts @@ -0,0 +1,81 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import { test } from "node:test"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); + +function readRepoFile(relativePath: string): string { + return readFileSync(path.join(repoRoot, relativePath), "utf8"); +} + +function readMessages(locale: string): Record { + return JSON.parse(readRepoFile(`src/i18n/messages/${locale}.json`)) as Record; +} + +function getMessage(messages: Record, dottedKey: string): unknown { + return dottedKey.split(".").reduce((value, segment) => { + if (!value || typeof value !== "object" || Array.isArray(value)) return undefined; + return (value as Record)[segment]; + }, messages); +} + +const residualKeys = [ + "analytics.autoRoutingNoDataAvailable", + "analytics.defaultVariantLabel", + "stats.accountLabel", + "stats.noAccountUsage", + "requestLogger.detail.correlationIdValue", + "requestLogger.detail.detailedPayloadInfo", + "settings.oneproxyDescription", + "settings.oneproxyClearAllConfirm", + "settings.oneproxyGoogle", + "settings.memorySkillsSkillsmpDescription", + "settings.memorySkillsActiveProviderDescription", + "settings.routingCcBridgeCatalogName", + "settings.routingUnknownOpKind", + "settings.routingInvalidJson", + "settings.routingJsonEditorLabel", + "settings.routingTransformsFootnote", +]; + +test("hardcoded UI residual keys exist in required catalogs", () => { + for (const locale of ["en", "fr", "vi", "pt-BR"]) { + const messages = readMessages(locale); + for (const key of residualKeys) { + assert.equal(typeof getMessage(messages, key), "string", `${locale}.${key} must exist`); + } + } +}); + +test("French and Vietnamese residual translations are complete", () => { + for (const locale of ["fr", "vi"]) { + const messages = readMessages(locale); + for (const key of residualKeys) { + const value = getMessage(messages, key) as string; + assert.ok(!value.startsWith("__MISSING__:"), `${locale}.${key} must be translated`); + } + } +}); + +test("Oneproxy and SkillsMP messages preserve their runtime values", () => { + const messages = readMessages("en"); + assert.equal( + getMessage(messages, "settings.oneproxySyncSuccess"), + "Synced {total} proxies ({added} new, {updated} updated)" + ); + assert.equal(getMessage(messages, "settings.oneproxySyncFailed"), "Sync failed: {error}"); + assert.match(getMessage(messages, "settings.skillsmpApiKeyHintAfter") as string, /\{limit\}/); +}); + +test("request log dates follow the active locale without duplicating rotated account IDs", () => { + const source = readRepoFile("src/shared/components/RequestLoggerDetail.tsx"); + assert.match(source, /const locale = useLocale\(\)/); + assert.doesNotMatch(source, /toLocaleDateString\("pt-BR"\)/); + assert.doesNotMatch(source, /toLocaleTimeString\("en-US"/); + assert.doesNotMatch( + source, + /\}\)\}\s*\{formatConnectionId\(codexAccountRotation\.finalConnectionId\)\}/ + ); +});