import { describe, it, expect, vi, beforeEach } from "vitest"; import { render, screen, fireEvent, within } from "@testing-library/react"; // usePathname is mockable per-test so we can exercise the auto-expand behaviour. let mockPathname = "/dashboard"; vi.mock("next/navigation", () => ({ usePathname: () => mockPathname })); import { Sidebar } from "@/components/layout/sidebar"; beforeEach(() => { mockPathname = "/dashboard"; }); function headerButton(label: string) { return screen.getByRole("button", { name: new RegExp(`^${label}`, "i") }); } describe("Sidebar collapsible sections", () => { it("renders section headings as toggle buttons, collapsed by default", () => { // ADMIN sees a Purchasing-less layout? No — render a MANAGER who has // Purchasing + Administration headed sections. render(); const purchasing = headerButton("Purchasing"); const administration = headerButton("Administration"); expect(purchasing).toHaveAttribute("aria-expanded", "false"); expect(administration).toHaveAttribute("aria-expanded", "false"); // Collapsed → section links are not in the DOM. expect(screen.queryByRole("link", { name: /Cost Centres/i })).not.toBeInTheDocument(); }); it("expands a section and reveals its links when its header is clicked", () => { render(); const purchasing = headerButton("Purchasing"); fireEvent.click(purchasing); expect(purchasing).toHaveAttribute("aria-expanded", "true"); expect(screen.getByRole("link", { name: /Cost Centres/i })).toBeInTheDocument(); }); it("collapses other sections when one is opened (single-open accordion)", () => { render(); const purchasing = headerButton("Purchasing"); const administration = headerButton("Administration"); fireEvent.click(purchasing); expect(purchasing).toHaveAttribute("aria-expanded", "true"); fireEvent.click(administration); expect(administration).toHaveAttribute("aria-expanded", "true"); // Opening Administration collapses Purchasing. expect(purchasing).toHaveAttribute("aria-expanded", "false"); }); it("toggles a section closed when its header is clicked again", () => { render(); const purchasing = headerButton("Purchasing"); fireEvent.click(purchasing); expect(purchasing).toHaveAttribute("aria-expanded", "true"); fireEvent.click(purchasing); expect(purchasing).toHaveAttribute("aria-expanded", "false"); }); it("auto-expands the section containing the active route on mount", () => { mockPathname = "/admin/vessels"; // Cost Centres lives under Administration (manager mgmt → Purchasing) render(); // /admin/vessels is in the Purchasing management block for a MANAGER. const purchasing = headerButton("Purchasing"); expect(purchasing).toHaveAttribute("aria-expanded", "true"); expect(screen.getByRole("link", { name: /Cost Centres/i })).toBeInTheDocument(); }); it("keeps the PPMS brand outside any collapsible section", () => { render(); // Brand text is always visible regardless of section state. expect(screen.getByText("PPMS")).toBeInTheDocument(); }); it("renders the always-visible main links outside the sections", () => { render(); expect(screen.getByRole("link", { name: /Dashboard/i })).toBeInTheDocument(); expect(screen.getByRole("link", { name: /My Profile/i })).toBeInTheDocument(); }); it("scopes revealed links to the opened section", () => { render(); const administration = headerButton("Administration"); fireEvent.click(administration); // Vendors appears under Administration for a manager. const adminVendors = screen.getByRole("link", { name: /Vendors/i }); expect(adminVendors).toBeInTheDocument(); expect(within(adminVendors).queryByText("Vendors")).toBeTruthy(); }); });