61 lines
2.7 KiB
TypeScript
61 lines
2.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { DEFAULT_UI_LANGUAGE, UI_LANGUAGES, resolveUiLanguage } from "@/lib/languages";
|
|
import { DEFAULT_SETTINGS, acceptRemote } from "@/store/settings";
|
|
|
|
/**
|
|
* The interface language decides what `<html lang>` claims, and a wrong claim
|
|
* is exactly what makes Chrome offer to translate a page that needs no
|
|
* translating — which is the offer that ends in a rewritten DOM and a crashed
|
|
* component tree. So the resolution is deliberately narrow.
|
|
*/
|
|
describe("resolveUiLanguage", () => {
|
|
it("is English when nothing has been chosen", () => {
|
|
// The absent case covers both a new account and every settings file
|
|
// written before this setting existed.
|
|
expect(resolveUiLanguage(undefined)).toBe("en");
|
|
expect(resolveUiLanguage(null)).toBe("en");
|
|
expect(resolveUiLanguage("")).toBe("en");
|
|
expect(DEFAULT_SETTINGS.uiLanguage).toBe(DEFAULT_UI_LANGUAGE);
|
|
});
|
|
|
|
it("refuses a language whose strings are not shipped", () => {
|
|
// The account travels between machines and can outlive a catalog. A
|
|
// page that says lang="fr" while rendering English is worse than one that
|
|
// admits to English: it stops the reader translating it themselves.
|
|
// Derived rather than named, so shipping another language does not turn
|
|
// this into a failing test that is really just out of date.
|
|
const unshipped = ["cy", "is", "mt", "eu"].find((tag) => !UI_LANGUAGES.some((l) => l.tag === tag))!;
|
|
expect(resolveUiLanguage(unshipped)).toBe("en");
|
|
expect(resolveUiLanguage("xx-XX")).toBe("en");
|
|
});
|
|
|
|
it("carries the Beta flag until a person has signed the language off", () => {
|
|
// Not a completeness measure. A catalog can be word-for-word finished
|
|
// and still read like a machine wrote it, which is what this marks.
|
|
// Every shipped language except English is unreviewed, and stays marked
|
|
// until a person says otherwise.
|
|
for (const l of UI_LANGUAGES) {
|
|
if (l.tag === "en") expect(l.beta).toBeUndefined();
|
|
else expect(l.beta).toBe(true);
|
|
}
|
|
});
|
|
|
|
it("honors one that is", () => {
|
|
for (const l of UI_LANGUAGES) expect(resolveUiLanguage(l.tag)).toBe(l.tag);
|
|
});
|
|
|
|
it("only offers languages that resolve to themselves", () => {
|
|
// Guards the ordering mistake: adding a picker entry before its catalog.
|
|
for (const l of UI_LANGUAGES) {
|
|
expect(resolveUiLanguage(l.tag)).toBe(l.tag);
|
|
expect(l.name.trim()).not.toBe("");
|
|
}
|
|
});
|
|
|
|
it("follows the account rather than the device", () => {
|
|
// Language is a preference about the person, not the screen: it is not in
|
|
// DEVICE_KEYS, so it rides in the settings file like the rest.
|
|
expect(acceptRemote({ uiLanguage: "en" })).toEqual({ uiLanguage: "en" });
|
|
});
|
|
});
|