The 15 test files whose fake t returned the bare key (the 12 of the issue, plus the three category render tests added by #423) now mock react-i18next with i18nMock. Assertions naming a displayed text are rewritten in the marked form, t(key[options]), so a text that skipped t fails them. Components without such an assertion get one: PriceFetchControl, PriceFetchConsentToggle (rendered through the hook harness, its loading slot preset), CategoryDetailPanel, SourceList and SourceCard, and the region label of OnboardingChecklist. Each component was proved by a mutation removing one t call: every one turns at least one test red (exit 1). Refs #389 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
81 lines
3 KiB
TypeScript
81 lines
3 KiB
TypeScript
// SourceList and SourceCard — the getting-started target (#398). No jsdom:
|
|
// react-dom/server renders in vitest's node environment, and the markup says
|
|
// which card carries the highlight.
|
|
import { describe, it, expect, vi } from "vitest";
|
|
import { renderToStaticMarkup } from "react-dom/server";
|
|
|
|
vi.mock("react-i18next", async () => (await import("../../test/i18nMock")).i18nMock());
|
|
|
|
import SourceList from "./SourceList";
|
|
import { SOURCE_CARD_TARGET } from "./SourceCard";
|
|
import type { ScannedSource } from "../../shared/types";
|
|
|
|
const HIGHLIGHT = 'data-onboarding-highlight="true"';
|
|
|
|
const source = (name: string): ScannedSource => ({
|
|
folder_name: name,
|
|
folder_path: `/releves/${name}`,
|
|
files: [{ filename: "releve.csv", file_path: `/releves/${name}/releve.csv`, size_bytes: 10, modified_at: "" }],
|
|
});
|
|
|
|
const SOURCES = [source("Desjardins"), source("Tangerine"), source("RBC")];
|
|
|
|
const markup = (onboardingTarget?: boolean, sources: ScannedSource[] = SOURCES) =>
|
|
renderToStaticMarkup(
|
|
<SourceList
|
|
sources={sources}
|
|
configuredSourceNames={new Set()}
|
|
importedFileNames={new Map()}
|
|
onSelectSource={vi.fn()}
|
|
onboardingTarget={onboardingTarget}
|
|
/>,
|
|
);
|
|
|
|
/** The source cards, in order: each is a button. */
|
|
const cards = (html: string) => html.split("<button").slice(1);
|
|
|
|
describe("SourceList — getting-started target (#398)", () => {
|
|
it("highlights the first card of the list, and only it", () => {
|
|
const html = markup(true);
|
|
expect(html.split(HIGHLIGHT).length - 1).toBe(1);
|
|
const [first, ...others] = cards(html);
|
|
expect(first).toContain(HIGHLIGHT);
|
|
expect(first).toContain(`data-onboarding-target="${SOURCE_CARD_TARGET}"`);
|
|
expect(first).toContain("Desjardins");
|
|
expect(others).toHaveLength(2);
|
|
for (const card of others) expect(card).not.toContain("data-onboarding");
|
|
});
|
|
|
|
it("highlights the only card of a one-source list", () => {
|
|
expect(markup(true, [source("Desjardins")]).split(HIGHLIGHT).length - 1).toBe(1);
|
|
});
|
|
|
|
it("highlights nothing without the property", () => {
|
|
expect(markup()).not.toContain("data-onboarding");
|
|
expect(markup(false)).not.toContain("data-onboarding");
|
|
});
|
|
});
|
|
|
|
describe("SourceList and SourceCard — displayed texts (#389)", () => {
|
|
it("titles the list and counts each source's files through t", () => {
|
|
const html = markup();
|
|
expect(html).toContain(">t(import.sources.title)<");
|
|
expect(cards(html)[0]).toContain("t(import.sources.fileCount[count=1])");
|
|
});
|
|
|
|
it("marks the files not yet imported through t", () => {
|
|
const html = renderToStaticMarkup(
|
|
<SourceList
|
|
sources={[source("Desjardins")]}
|
|
configuredSourceNames={new Set()}
|
|
importedFileNames={new Map([["Desjardins", new Set<string>()]])}
|
|
onSelectSource={vi.fn()}
|
|
/>,
|
|
);
|
|
expect(html).toContain("t(import.sources.new)");
|
|
});
|
|
|
|
it("says the folder is empty through t", () => {
|
|
expect(markup(false, [])).toContain(">t(import.sources.empty)<");
|
|
});
|
|
});
|