57 lines
2.9 KiB
TypeScript
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();
|
|
});
|
|
});
|