Files
jobtrackingapp/job-tracker-ui/src/loaded-theme-states.test.tsx
T
2026-09-11 19:31:32 +02:00

57 lines
2.9 KiB
TypeScript

import React from "react";
import "@testing-library/jest-dom";
import { act, fireEvent, render, screen } from "@testing-library/react";
import { MemoryRouter } from "react-router-dom";
import { api } from "./api";
import CompaniesTable from "./components/CompaniesTable";
import { I18nProvider } from "./i18n/I18nProvider";
import JobTrackerThemeProvider from "./ThemeProvider";
import { ToastProvider } from "./toast";
jest.mock("./api", () => ({
api: { get: jest.fn(), put: jest.fn() },
getApiErrorMessage: (_error: unknown, fallback: string) => fallback,
}));
describe.each(["light", "dark"] as const)("%s loaded company workflow", mode => {
beforeEach(() => { localStorage.clear(); localStorage.setItem("uiLanguage", "en"); jest.clearAllMocks(); });
test.each(["populated", "empty", "error"])("loading → %s remains understandable and usable", async outcome => {
let finish!: (value: unknown) => void;
let fail!: (error: unknown) => void;
(api.get as jest.Mock).mockReturnValue(new Promise((resolve, reject) => { finish = resolve; fail = reject; }));
render(<JobTrackerThemeProvider preference={mode} systemPrefersDark={false}>
<I18nProvider><ToastProvider><MemoryRouter><CompaniesTable /></MemoryRouter></ToastProvider></I18nProvider>
</JobTrackerThemeProvider>);
expect(screen.getByRole("status")).toHaveAttribute("aria-live", "polite");
expect(screen.getByRole("progressbar")).toHaveAccessibleName();
expect(screen.queryByRole("table")).not.toBeInTheDocument();
const company = { id: 3, name: "Nordlys æøå AS" };
await act(async () => {
if (outcome === "error") fail({ response: { status: 503 } });
else finish({ data: outcome === "empty" ? [] : [company] });
});
const status = screen.getByRole("status");
expect(status).toHaveTextContent(outcome === "error" ? "" : "Content loaded.");
if (outcome === "error") {
const error = screen.getByRole("alert");
expect(error).not.toBeEmptyDOMElement();
expect(screen.queryByRole("table")).not.toBeInTheDocument();
(api.get as jest.Mock).mockResolvedValue({ data: [company] });
fireEvent.click(screen.getByRole("button", { name: "Retry" }));
expect(await screen.findByText(company.name)).toBeVisible();
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
}
expect(screen.getByRole("table")).toBeVisible();
if (outcome !== "empty") {
fireEvent.click(screen.getByRole("button", { name: `Edit: ${company.name}` }));
expect(screen.getByRole("dialog")).toHaveAccessibleName();
// Reading/editing a loaded form must not repeat the loading announcement or save.
expect(screen.getByRole("status", { hidden: true })).toBe(status);
expect(status).toHaveTextContent("Content loaded.");
} else {
expect(screen.getByRole("table")).toHaveTextContent("No companies");
}
expect(api.put).not.toHaveBeenCalled();
});
});