Files
jobtrackingapp/job-tracker-ui/src/shell-readiness.test.tsx
T
2026-09-21 21:38:11 +02:00

73 lines
4.0 KiB
TypeScript

import React, { useState } from "react";
import "@testing-library/jest-dom";
import { act, fireEvent, render, screen, within } from "@testing-library/react";
import { CssVarsProvider } from "@mui/material/styles";
import AppShell from "./layout/AppShell";
import { getTheme } from "./theme";
import { I18nProvider } from "./i18n/I18nProvider";
import { translations } from "./i18n/translations";
import { ToastProvider, useToast } from "./toast";
jest.mock("@mui/material/useMediaQuery", () => ({ __esModule: true, default: () => true }));
for (const language of ["en", "nb"] as const) {
test(`[P5-00 PRES-E07 E08 A03] ${language} mobile names/current route ignore desktop collapse and retain metadata`, () => {
localStorage.setItem("uiLanguage", language);
localStorage.setItem("appShellDesktopSidebarCollapsed", "1");
const t = translations[language];
function Shell() {
const [open, setOpen] = useState(false);
return <AppShell pageTitle={t.settings} breadcrumbs={[]} pathname="/settings"
nav={[{ to: "/dashboard", label: t.dashboard, icon: <span /> }, { to: "/settings", label: t.settings, icon: <span /> }, { to: "/admin/users", label: "Hidden admin", icon: <span />, hidden: true }]}
navBottom={[]} drawerOpen={open} onToggleDrawer={setOpen} onNavigate={jest.fn()}
user={{ userName: "Åse" }} buildMetadata={{ version: "long-version-æøå", commitSha: "abc1234" }}>
<div>Existing page</div>
</AppShell>;
}
render(<CssVarsProvider theme={getTheme("light") as any}><I18nProvider><Shell /></I18nProvider></CssVarsProvider>);
expect(screen.queryByTestId("admin-version-badge")).not.toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: t.user }));
expect(screen.getByRole("menu")).toHaveTextContent("long-version-æøå");
expect(screen.getByRole("menu")).toHaveTextContent("abc1234");
fireEvent.keyDown(screen.getByRole("menu"), { key: "Escape" });
fireEvent.click(screen.getByRole("button", { name: t.openNavigation }));
const drawer = screen.getByRole("dialog", { name: t.navigation });
expect(within(drawer).getByRole("button", { name: t.dashboard })).toHaveTextContent(t.dashboard);
expect(within(drawer).getByRole("button", { name: t.settings })).toHaveAttribute("aria-current", "page");
expect(within(drawer).queryByText("Hidden admin")).not.toBeInTheDocument();
expect(localStorage.getItem("appShellDesktopSidebarCollapsed")).toBe("1");
});
}
function ToastTrigger({ action }: { action?: () => void }) {
const { toast } = useToast();
return <button onClick={() => toast("Downloaded æøå", "success", action ? { label: "Undo", onClick: action } : undefined)}>Notify</button>;
}
test("[P5-00 PRES-E08 S05] toast retains its full existing display duration and dismiss action", () => {
jest.useFakeTimers();
try {
render(<ToastProvider><ToastTrigger /></ToastProvider>);
fireEvent.click(screen.getByRole("button", { name: "Notify" }));
act(() => jest.advanceTimersByTime(3499));
expect(screen.getByRole("alert")).toHaveTextContent("Downloaded æøå");
act(() => jest.advanceTimersByTime(1));
// Flush the existing exit transition after React observes the timeout.
act(() => jest.advanceTimersByTime(300));
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
fireEvent.click(screen.getByRole("button", { name: "Notify" }));
fireEvent.click(within(screen.getByRole("alert")).getByRole("button"));
act(() => jest.advanceTimersByTime(300));
expect(screen.queryByRole("alert")).not.toBeInTheDocument();
} finally { jest.useRealTimers(); }
});
test("[P5-00 PRES-E08] toast action is explicit and executes once", () => {
const action = jest.fn();
render(<ToastProvider><ToastTrigger action={action} /></ToastProvider>);
fireEvent.click(screen.getByRole("button", { name: "Notify" }));
expect(action).not.toHaveBeenCalled();
fireEvent.click(screen.getByRole("button", { name: "Undo" }));
expect(action).toHaveBeenCalledTimes(1);
});