Every locale formatter takes the language as an argument. Under the React
Compiler a formatter that read the i18n singleton was memoized on its other
arguments, so a card kept "2 hr 4 min" after a switch to Hungarian; plexLang()
had the same flaw and left Plex queries in the old language. Components now
take the language from useTranslation, and the signature makes forgetting it
a type error.
- ratings, file sizes, stream stats: the language's decimal mark ("8,3")
- view and subscriber counts compact in the language ("1,2 E")
- seconds as the language's unit ("6 mp") in the sliders and the stats
- a person's birth and death dates as dates, not ISO strings
- A-Z lists by the shown name in the language's alphabet (compareText),
the tag catalog re-sorted by its translated names
- lint local/locale-format (was date-format) also refuses Intl.NumberFormat
outside lib/format.ts, localeCompare, and a component reading the language
off the i18n singleton
67 lines
2.5 KiB
TypeScript
67 lines
2.5 KiB
TypeScript
// @vitest-environment jsdom
|
|
//
|
|
// E30: a scheduler job's result in the reader's language, through the REAL catalog. The server's own
|
|
// one-liner was "recent={'channels_processed': 0, …}, deep={…}" — English keys and a Python repr.
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import i18n, { setLanguage } from "../i18n";
|
|
import { jobResultText, parseSummary } from "./jobResult";
|
|
|
|
afterEach(() => setLanguage("en"));
|
|
|
|
describe("a job's result", () => {
|
|
it("names each count, and a phase's own counts inside it", () => {
|
|
setLanguage("hu");
|
|
const t = i18n.getFixedT("hu");
|
|
expect(jobResultText(t, { new: 3, failed: 0 }, "hu")).toBe("új videó: 3 · sikertelen: 0");
|
|
expect(
|
|
jobResultText(
|
|
t,
|
|
{
|
|
recent: { channels_processed: 0, videos_added: 0, reason: "no service user" },
|
|
deep: { channels_processed: 2, videos_added: 5, reconciled_full: 1 },
|
|
},
|
|
"hu",
|
|
),
|
|
).toBe(
|
|
"friss (feldolgozott csatorna: 0 · hozzáadott videó: 0 · ok: nincs szolgáltatásfiók) · " +
|
|
"mély (feldolgozott csatorna: 2 · hozzáadott videó: 5 · teljesen egyeztetve: 1)",
|
|
);
|
|
});
|
|
|
|
it("names a skip reason; an upstream error stays its own text", () => {
|
|
const t = i18n.getFixedT("hu");
|
|
expect(jobResultText(t, { enriched: 0, skipped: "tmdb_api_key not set" }, "hu")).toBe(
|
|
"kiegészítve: 0 · kihagyva: nincs TMDB API-kulcs",
|
|
);
|
|
expect(jobResultText(t, { error: "Plex returned 500" }, "hu")).toBe("hiba: Plex returned 500");
|
|
});
|
|
|
|
it("shows a key or word it does not know as it is, readable", () => {
|
|
const t = i18n.getFixedT("hu");
|
|
expect(jobResultText(t, { brand_new_count: 3, skipped: "moon is full" }, "hu")).toBe(
|
|
"brand new count: 3 · kihagyva: moon is full",
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("an older notice's one-liner", () => {
|
|
it("reads back into a result when flat", () => {
|
|
expect(parseSummary("new=403, failed=396, fallback=375")).toEqual({
|
|
new: 403,
|
|
failed: 396,
|
|
fallback: 375,
|
|
});
|
|
expect(parseSummary("enriched=0, skipped=tmdb_api_key not set")).toEqual({
|
|
enriched: 0,
|
|
skipped: "tmdb_api_key not set",
|
|
});
|
|
});
|
|
|
|
it("does not when a phase is nested, or it is no summary at all", () => {
|
|
expect(parseSummary("recent={'channels_processed': 0}, deep={'videos_added': 1}")).toBeNull();
|
|
expect(parseSummary("sync paused")).toBeNull();
|
|
expect(parseSummary("42")).toBeNull();
|
|
expect(parseSummary(null)).toBeNull();
|
|
});
|
|
});
|