171 lines
5.7 KiB
JavaScript
171 lines
5.7 KiB
JavaScript
import { join } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import { readJsonFile } from "./helpers/readJsonFile";
|
|
import { readI18nRuntimeMessages } from "./helpers/readI18nRuntimeMessages";
|
|
|
|
const root = process.cwd();
|
|
const activeLocales = ["da", "en", "sv", "de", "no"];
|
|
const channelKeys = ["stable", "canary", "internal"];
|
|
const requiredReleaseAvailabilityLabels = {
|
|
channel_unavailable: [
|
|
"release_bundle",
|
|
"frontend_version",
|
|
"api_version",
|
|
"frontend_base_url",
|
|
"api_base_url",
|
|
"frontend_entry",
|
|
"release_runtime",
|
|
],
|
|
channel_selector: [
|
|
"release_bundle",
|
|
"frontend_version",
|
|
"api_version",
|
|
"frontend_base_url",
|
|
"api_base_url",
|
|
"frontend_entry",
|
|
"release_runtime",
|
|
"bundle",
|
|
"frontend",
|
|
"api",
|
|
"use_local_frontend",
|
|
],
|
|
};
|
|
const expectedNewReleaseLabels = {
|
|
da: {
|
|
frontend_base_url: "Frontend-URL",
|
|
api_base_url: "API-URL",
|
|
frontend_entry: "Frontend-entry",
|
|
release_runtime: "Release-runtime",
|
|
use_local_frontend: "Brug lokal frontend",
|
|
},
|
|
en: {
|
|
frontend_base_url: "Frontend URL",
|
|
api_base_url: "API URL",
|
|
frontend_entry: "Frontend entry",
|
|
release_runtime: "Release runtime",
|
|
use_local_frontend: "Use local frontend",
|
|
},
|
|
sv: {
|
|
frontend_base_url: "Frontend-URL",
|
|
api_base_url: "API-URL",
|
|
frontend_entry: "Frontend-entry",
|
|
release_runtime: "Release-runtime",
|
|
use_local_frontend: "Använd lokal frontend",
|
|
},
|
|
de: {
|
|
frontend_base_url: "Frontend-URL",
|
|
api_base_url: "API-URL",
|
|
frontend_entry: "Frontend-Einstiegspunkt",
|
|
release_runtime: "Release-Laufzeit",
|
|
use_local_frontend: "Lokales Frontend verwenden",
|
|
},
|
|
no: {
|
|
frontend_base_url: "Frontend-URL",
|
|
api_base_url: "API-URL",
|
|
frontend_entry: "Frontend-entry",
|
|
release_runtime: "Release-runtime",
|
|
use_local_frontend: "Bruk lokal frontend",
|
|
},
|
|
};
|
|
const sharedReleaseDetailLabels = {
|
|
bundle: "Bundle",
|
|
frontend: "Frontend",
|
|
api: "API",
|
|
};
|
|
|
|
const suspiciousTranslationArtifact =
|
|
/(?:\p{L}\?\p{L}|(?:^|[\s([{])\?\p{L}|\p{L}\?@:\{|\u00c3|\u00c2|\ufffd|\u00ef\u00bf\u00bd)/u;
|
|
|
|
const flattenStrings = (value, prefix = "") => {
|
|
if (typeof value === "string") {
|
|
return [{ key: prefix, value }];
|
|
}
|
|
|
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
return [];
|
|
}
|
|
|
|
return Object.entries(value).flatMap(([key, nestedValue]) =>
|
|
flattenStrings(nestedValue, prefix ? `${prefix}.${key}` : key)
|
|
);
|
|
};
|
|
|
|
const optionalCatalog = (name, catalog) => (catalog ? [[name, catalog]] : []);
|
|
|
|
const loadReleaseManagerCatalogs = () =>
|
|
activeLocales.flatMap((locale) => {
|
|
const source = readJsonFile(join(root, `src/i18n/source/${locale}/phrases/compat/configuration/index.json`)).compat
|
|
.configuration.release_manager;
|
|
const localeV2 = readJsonFile(join(root, `src/i18n/generated/${locale}-v2.json`));
|
|
const generatedV2 = localeV2.templates.generated.compat.configuration.release_manager;
|
|
const runtimeV2 = readI18nRuntimeMessages(locale).configuration.release_manager;
|
|
|
|
return [
|
|
...optionalCatalog(`${locale} source`, source),
|
|
[`${locale} generated v2`, generatedV2],
|
|
[`${locale} runtime v2`, runtimeV2],
|
|
];
|
|
});
|
|
|
|
describe("release manager i18n", () => {
|
|
it("does not contain replacement-character translation artifacts", () => {
|
|
const failures = [];
|
|
|
|
for (const [name, releaseManager] of loadReleaseManagerCatalogs()) {
|
|
for (const { key, value } of flattenStrings(releaseManager)) {
|
|
if (suspiciousTranslationArtifact.test(value)) {
|
|
failures.push(`${name}: ${key} = ${value}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
expect(failures).toEqual([]);
|
|
});
|
|
|
|
it("defines localized names and descriptions for built-in release channels", () => {
|
|
for (const [name, releaseManager] of loadReleaseManagerCatalogs()) {
|
|
expect(Object.keys(releaseManager.channel_names ?? {}), `${name} channel_names`).toEqual(channelKeys);
|
|
expect(Object.keys(releaseManager.channel_descriptions ?? {}), `${name} channel_descriptions`).toEqual(
|
|
channelKeys
|
|
);
|
|
|
|
for (const key of channelKeys) {
|
|
expect(releaseManager.channel_names[key], `${name} channel_names.${key}`).toEqual(expect.any(String));
|
|
expect(releaseManager.channel_descriptions[key], `${name} channel_descriptions.${key}`).toEqual(
|
|
expect.any(String)
|
|
);
|
|
}
|
|
}
|
|
});
|
|
|
|
it("defines release channel readiness labels for all runtime catalogs", () => {
|
|
for (const [name, releaseManager] of loadReleaseManagerCatalogs()) {
|
|
const locale = name.split(" ")[0];
|
|
|
|
for (const [group, keys] of Object.entries(requiredReleaseAvailabilityLabels)) {
|
|
for (const key of keys) {
|
|
const value = releaseManager[group]?.[key];
|
|
expect(value, `${name} ${group}.${key}`).toEqual(expect.any(String));
|
|
expect(value, `${name} ${group}.${key}`).not.toBe("");
|
|
expect(value, `${name} ${group}.${key}`).not.toBe(key);
|
|
|
|
const expectedLabel = expectedNewReleaseLabels[locale]?.[key] ?? sharedReleaseDetailLabels[key] ?? null;
|
|
if (expectedLabel && !value.startsWith("@:")) {
|
|
expect(value, `${name} ${group}.${key}`).toBe(expectedLabel);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
it("uses Danish copy for the internal channel guard", () => {
|
|
const danishReleaseManager = readI18nRuntimeMessages("da").configuration.release_manager;
|
|
|
|
expect(danishReleaseManager.channel_names.internal).toBe("Intern");
|
|
expect(danishReleaseManager.channel_descriptions.internal).toContain("Intern kanal");
|
|
expect(danishReleaseManager.channel_descriptions.internal).not.toBe(
|
|
"Internal staff and superuser validation channel."
|
|
);
|
|
});
|
|
});
|