// @vitest-environment jsdom // // A notice is said in the reader's language when it is shown, not in the one it was raised in. The // text used to be translated by the caller and kept so: after a language switch every toast and every // row of the notification center stayed in the old language, and so did the history after a reload. import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { act, cleanup, render, screen } from "@testing-library/react"; import i18n from "../../i18n"; import Toaster from "./Toaster"; import { clearAll, msg, notify, raw, sayNotif } from "../../lib/notifications"; beforeEach(async () => { await i18n.changeLanguage("en"); }); afterEach(async () => { cleanup(); act(() => clearAll()); await i18n.changeLanguage("en"); }); describe("a notice speaks the reader's language of the moment", () => { it("a toast raised in English reads Hungarian after the switch", async () => { render(); act(() => void notify({ level: "success", message: msg("common.copy.done") })); const en = i18n.getFixedT("en")("common.copy.done"); const hu = i18n.getFixedT("hu")("common.copy.done"); expect(en).not.toBe(hu); expect(screen.getByText(en)).toBeTruthy(); await act(async () => void (await i18n.changeLanguage("hu"))); expect(screen.getByText(hu)).toBeTruthy(); expect(screen.queryByText(en)).toBeNull(); }); it("its button is said again too, beside the text it acts on", async () => { render(); act( () => void notify({ message: msg("common.copy.done"), action: { label: msg("common.undo"), onClick: () => {} }, }), ); expect(screen.getByRole("button", { name: "Undo" })).toBeTruthy(); await act(async () => void (await i18n.changeLanguage("hu"))); expect(screen.getByRole("button", { name: "Visszavonás" })).toBeTruthy(); expect(screen.queryByRole("button", { name: "Undo" })).toBeNull(); }); it("a server refusal is said again in the language of the moment", async () => { render(); act( () => void notify({ level: "error", message: { detail: { code: "not_found", reason: "view" } }, }), ); expect(screen.getByText("This view doesn't exist any more")).toBeTruthy(); await act(async () => void (await i18n.changeLanguage("hu"))); expect(screen.getByText("Ez a nézet már nem létezik")).toBeTruthy(); }); it("a value inside the text is said again too, and a number is grouped the reader's way", async () => { const text = msg("settings.takeout.read", { name: raw("watch-history.json"), count: 12345, n: { number: 12345 }, }); const en = sayNotif(text); await i18n.changeLanguage("hu"); const hu = sayNotif(text); expect(en).toContain("12,345"); expect(hu).not.toContain("12,345"); expect(hu).toContain("watch-history.json"); expect(hu).not.toBe(en); }); }); describe("the history kept from before", () => { beforeEach(() => { localStorage.clear(); vi.resetModules(); }); it("shows a notice stored as text as it was stored", async () => { localStorage.setItem("siftlode.owner", "5"); localStorage.setItem( "siftlode.notifications", JSON.stringify([ { id: 1, level: "info", title: "Old title", message: "Old text", ts: 1, read: true }, ]), ); const notifications = await import("../../lib/notifications"); const { claimLocalData } = await import("../../lib/storage"); claimLocalData(5); const n = notifications.getNotifications()[0]!; expect(n.message).toEqual(raw("Old text")); expect(n.title).toEqual(raw("Old title")); expect(notifications.sayNotif(n.message)).toBe("Old text"); }); });