51 lines
1.8 KiB
TypeScript
51 lines
1.8 KiB
TypeScript
import { afterEach, describe, expect, it } from "vitest";
|
|
import { i18n } from "@/lib/i18n";
|
|
import {
|
|
pluginTranslationNamespace,
|
|
registerPluginTranslations,
|
|
unregisterPluginTranslations,
|
|
} from "./plugin-translations";
|
|
|
|
const PLUGIN_ID = "translation-test";
|
|
|
|
afterEach(() => unregisterPluginTranslations(PLUGIN_ID));
|
|
|
|
describe("plugin translations", () => {
|
|
it("isolates catalogs by plugin and removes them on revocation", () => {
|
|
const namespace = pluginTranslationNamespace(PLUGIN_ID);
|
|
registerPluginTranslations(PLUGIN_ID, { en: { greeting: "Hello {{name}}" } });
|
|
|
|
expect(i18n.t(`${namespace}:greeting`, { name: "Ada" })).toBe("Hello Ada");
|
|
unregisterPluginTranslations(PLUGIN_ID);
|
|
expect(i18n.hasResourceBundle("en", namespace)).toBe(false);
|
|
});
|
|
|
|
it("rejects unsupported locales and unsafe keys", () => {
|
|
expect(() =>
|
|
registerPluginTranslations(PLUGIN_ID, {
|
|
en: { greeting: "Hello" },
|
|
fr: { greeting: "Bonjour" },
|
|
}),
|
|
).toThrow("unsupported translation locale");
|
|
expect(() =>
|
|
registerPluginTranslations(PLUGIN_ID, { en: { "__proto__.polluted": "unsafe" } }),
|
|
).toThrow("invalid translation message");
|
|
});
|
|
|
|
it("requires an English fallback catalog", () => {
|
|
expect(() => registerPluginTranslations(PLUGIN_ID, { "pt-pt": { greeting: "Olá" } })).toThrow(
|
|
"English fallback",
|
|
);
|
|
});
|
|
|
|
it("keeps the active catalog when a replacement is invalid", () => {
|
|
const namespace = pluginTranslationNamespace(PLUGIN_ID);
|
|
registerPluginTranslations(PLUGIN_ID, { en: { greeting: "Hello" } });
|
|
|
|
expect(() => registerPluginTranslations(PLUGIN_ID, { en: { "unsafe.key": "broken" } })).toThrow(
|
|
"invalid translation message",
|
|
);
|
|
expect(i18n.t(`${namespace}:greeting`)).toBe("Hello");
|
|
});
|
|
});
|