diff --git a/src/components/balance/PriceFetchControl.test.tsx b/src/components/balance/PriceFetchControl.test.tsx index ad30af2..2090daf 100644 --- a/src/components/balance/PriceFetchControl.test.tsx +++ b/src/components/balance/PriceFetchControl.test.tsx @@ -27,19 +27,8 @@ vi.mock("../../services/userPreferenceService", () => ({ setPreference: vi.fn(), })); -// react-i18next: return the key as-is for tests -vi.mock("react-i18next", () => ({ - useTranslation: vi.fn(() => ({ - t: (key: string, opts?: Record) => { - // Include interpolation values in the returned string for assertions - if (opts) { - return `${key}(${JSON.stringify(opts)})`; - } - return key; - }, - i18n: { language: "fr" }, - })), -})); +// react-i18next: the shared marked `t` (#389), so a text that skipped `t` fails +vi.mock("react-i18next", async () => (await import("../../test/i18nMock")).i18nMock()); // lucide-react: return simple stubs vi.mock("lucide-react", () => ({ @@ -58,7 +47,8 @@ import { getPreference, setPreference, } from "../../services/userPreferenceService"; -import { +import { renderToStaticMarkup } from "react-dom/server"; +import PriceFetchControl, { __resetBestEffortDismissForTests, } from "./PriceFetchControl"; @@ -363,3 +353,31 @@ describe("PriceFetchControl — fetchPrice invocation args", () => { expect(mockSetPreference).not.toHaveBeenCalled(); }); }); + +// --------------------------------------------------------------------------- +// Test: what the control displays (#389) +// --------------------------------------------------------------------------- + +describe("PriceFetchControl — displayed texts", () => { + beforeEach(() => { + __resetBestEffortDismissForTests(); + vi.resetAllMocks(); + setPremium(true); + }); + + it("names the fetch button and the stock best-effort notice through t", () => { + const html = renderToStaticMarkup( + , + ); + expect(html).toContain('aria-label="t(balance.priceFetching.button)"'); + expect(html).toContain(">t(balance.priceFetching.button)<"); + expect(html).toContain(">t(balance.priceFetching.bestEffortNotice)<"); + expect(html).toContain('aria-label="t(common.close)"'); + }); +}); diff --git a/src/components/categories/AddKeywordDialog.render.test.tsx b/src/components/categories/AddKeywordDialog.render.test.tsx index 002351d..e09e897 100644 --- a/src/components/categories/AddKeywordDialog.render.test.tsx +++ b/src/components/categories/AddKeywordDialog.render.test.tsx @@ -4,13 +4,7 @@ import { describe, it, expect, vi } from "vitest"; import { renderToStaticMarkup } from "react-dom/server"; -vi.mock("react-i18next", () => ({ - useTranslation: () => ({ - t: (k: string, o?: Record) => - o ? `${k}[${Object.entries(o).map(([a, b]) => `${a}=${String(b)}`).join(",")}]` : k, - i18n: { language: "fr" }, - }), -})); +vi.mock("react-i18next", async () => (await import("../../test/i18nMock")).i18nMock()); vi.mock("./keywordCategory", () => ({ loadKeywordCategories: vi.fn(() => new Promise(() => undefined)), @@ -51,12 +45,12 @@ describe("AddKeywordDialog — category field (#423)", () => { it("starts empty, with the 'no category' placeholder, until the list is in", () => { const [input] = markup(7).match(/]*role="combobox"[^>]*>/g) ?? []; expect(input).toContain('value=""'); - expect(input).toContain('placeholder="transactions.table.noCategory"'); + expect(input).toContain('placeholder="t(transactions.table.noCategory)"'); }); it("keeps the apply button disabled before the list is in", () => { const html = markup(7); - const [apply] = html.match(/