import React, { useState } from "react";
import "@testing-library/jest-dom";
import { fireEvent, render, screen, within } from "@testing-library/react";
import { CssVarsProvider } from "@mui/material/styles";
import { I18nProvider } from "./i18n/I18nProvider";
import AppShell, { type NavItem } from "./layout/AppShell";
import { getTheme } from "./theme";
jest.mock("@mui/material/useMediaQuery", () => ({ __esModule: true, default: () => false }));
const nav: NavItem[] = [
{ to: "/dashboard", label: "Dashboard", icon: },
{ to: "/jobs", label: "Jobs", icon: , section: "Job search", children: [
{ to: "/kanban", label: "Board", icon: },
{ to: "/trash", label: "Trash", icon: },
] },
{ to: "/career", label: "Career profile", icon: , section: "Career" },
];
function Providers({ children }: { children: React.ReactNode }) {
return {children};
}
afterEach(() => localStorage.clear());
test("[P5-01 PRES-E07 E08] grouped navigation exposes the current child without marking the parent as the page", () => {
render(Board content
);
expect(screen.getByRole("navigation", { name: "Navigation" })).toBeInTheDocument();
expect(screen.getByRole("button", { name: "Board" })).toHaveAttribute("aria-current", "page");
expect(screen.getByRole("button", { name: "Jobs" })).toHaveAttribute("aria-current", "location");
expect(screen.getAllByText("Job search").length).toBeGreaterThan(0);
expect(screen.getAllByText("Career").length).toBeGreaterThan(0);
});
test("[P5-01 PRES-E07 E08] collapsed secondary destinations remain keyboard-operable", () => {
localStorage.setItem("appShellDesktopSidebarCollapsed", "1");
const navigate = jest.fn();
render(Jobs content
);
const jobs = screen.getByRole("button", { name: "Jobs" });
expect(jobs).toHaveAttribute("aria-haspopup", "menu");
fireEvent.keyDown(jobs, { key: "Enter" });
fireEvent.click(jobs);
const menu = screen.getByRole("menu");
fireEvent.click(within(menu).getByRole("menuitem", { name: "Trash" }));
expect(navigate).toHaveBeenCalledWith("/trash");
});
test("[P5-01 PRES-E08] successful shell navigation focuses the new route heading and exposes a skip link", () => {
function Harness() {
const [path, setPath] = useState("/dashboard");
return Page content
;
}
render();
expect(screen.getByRole("link", { name: "Skip to main content" })).toHaveAttribute("href", "#app-main-content");
fireEvent.click(screen.getByRole("button", { name: "Career profile" }));
expect(screen.getByRole("heading", { level: 1, name: "Career profile" })).toHaveFocus();
});