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

63 lines
3.3 KiB
TypeScript

import React from "react";
import "@testing-library/jest-dom";
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { ConfirmProvider, useConfirm } from "./confirm";
import { PromptProvider, usePrompt } from "./prompt";
import { I18nProvider } from "./i18n/I18nProvider";
import { translations } from "./i18n/translations";
test.each(["en", "nb"] as const)("[PRES-E08 PRES-S05] %s confirmation traps/returns focus and preserves cancel/Escape/accept results", async language => {
localStorage.setItem("uiLanguage", language);
const t = translations[language];
const result = jest.fn();
function Caller() {
const { confirm } = useConfirm();
return <button onClick={async () => result(await confirm({ message: "Remove this item?", destructive: true }))}>Open</button>;
}
render(<I18nProvider><ConfirmProvider><Caller /></ConfirmProvider></I18nProvider>);
const trigger = screen.getByRole("button", { name: "Open" });
for (const action of ["escape", "cancel", "confirm"] as const) {
userEvent.click(trigger);
const dialog = await screen.findByRole("dialog", { name: t.confirmAction });
expect(dialog).toHaveAccessibleDescription("Remove this item?");
expect(screen.getByRole("button", { name: t.cancel })).toHaveFocus();
if (action === "escape") fireEvent.keyDown(dialog, { key: "Escape" });
else userEvent.click(screen.getByRole("button", { name: action === "cancel" ? t.cancel : t.confirm }));
await waitFor(() => expect(result).toHaveBeenLastCalledWith(action === "confirm"));
await waitFor(() => expect(screen.queryByRole("dialog")).not.toBeInTheDocument());
expect(trigger).toHaveFocus();
}
expect(result).toHaveBeenCalledTimes(3);
localStorage.clear();
});
test.each(["en", "nb"] as const)("[PRES-E08 PRES-W08] %s prompt preserves helper link, exact text, cancellation and reopen defaults", async language => {
localStorage.setItem("uiLanguage", language);
const t = translations[language];
const result = jest.fn();
function Caller() {
const { prompt } = usePrompt();
return <button onClick={async () => result(await prompt({ message: "Name æøå", defaultValue: "CV.pdf" }))}>Open</button>;
}
render(<I18nProvider><PromptProvider><Caller /></PromptProvider></I18nProvider>);
const trigger = screen.getByRole("button", { name: "Open" });
for (const action of ["escape", "cancel", "save"] as const) {
userEvent.click(trigger);
const input = await screen.findByRole("textbox", { name: "Name æøå" });
expect(input).toHaveFocus();
expect(input).toHaveValue("CV.pdf");
expect(input).toHaveAccessibleDescription("6/180");
expect(input).toHaveAttribute("maxlength", "180");
fireEvent.change(input, { target: { value: "Ny CV æøå.pdf" } });
expect(input).toHaveAccessibleDescription("13/180");
if (action === "escape") fireEvent.keyDown(input, { key: "Escape" });
else userEvent.click(screen.getByRole("button", { name: action === "cancel" ? t.cancel : t.save }));
await waitFor(() => expect(result).toHaveBeenLastCalledWith(action === "save" ? "Ny CV æøå.pdf" : null));
await waitFor(() => expect(screen.queryByRole("dialog")).not.toBeInTheDocument());
expect(trigger).toHaveFocus();
}
expect(result).toHaveBeenCalledTimes(3);
localStorage.clear();
});