feat(ui): redesign grouped application shell
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
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: <span /> },
|
||||
{ to: "/jobs", label: "Jobs", icon: <span />, section: "Job search", children: [
|
||||
{ to: "/kanban", label: "Board", icon: <span /> },
|
||||
{ to: "/trash", label: "Trash", icon: <span /> },
|
||||
] },
|
||||
{ to: "/career", label: "Career profile", icon: <span />, section: "Career" },
|
||||
];
|
||||
|
||||
function Providers({ children }: { children: React.ReactNode }) {
|
||||
return <CssVarsProvider theme={getTheme("light") as any} defaultMode="light"><I18nProvider>{children}</I18nProvider></CssVarsProvider>;
|
||||
}
|
||||
|
||||
afterEach(() => localStorage.clear());
|
||||
|
||||
test("[P5-01 PRES-E07 E08] grouped navigation exposes the current child without marking the parent as the page", () => {
|
||||
render(<Providers><AppShell pageTitle="Board" breadcrumbs={[]} pathname="/kanban" nav={nav} navBottom={[]} onNavigate={jest.fn()} onToggleDrawer={jest.fn()} drawerOpen={false}><div>Board content</div></AppShell></Providers>);
|
||||
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(<Providers><AppShell pageTitle="Jobs" breadcrumbs={[]} pathname="/jobs" nav={nav} navBottom={[]} onNavigate={navigate} onToggleDrawer={jest.fn()} drawerOpen={false}><div>Jobs content</div></AppShell></Providers>);
|
||||
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 <AppShell pageTitle={path === "/career" ? "Career profile" : "Dashboard"} breadcrumbs={[]} pathname={path} nav={nav} navBottom={[]} onNavigate={setPath} onToggleDrawer={jest.fn()} drawerOpen={false}><div>Page content</div></AppShell>;
|
||||
}
|
||||
render(<Providers><Harness /></Providers>);
|
||||
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();
|
||||
});
|
||||
Reference in New Issue
Block a user