UNPKG

@etsoo/toolpad

Version:

Dashboard framework extention based on Toolpad Core

308 lines (307 loc) 14.5 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { describe, test, expect, vi } from "vitest"; import { render, within, screen } from "@testing-library/react"; import DashboardIcon from "@mui/icons-material/Dashboard"; import ShoppingCartIcon from "@mui/icons-material/ShoppingCart"; import BarChartIcon from "@mui/icons-material/BarChart"; import DescriptionIcon from "@mui/icons-material/Description"; import LayersIcon from "@mui/icons-material/Layers"; import userEvent from "@testing-library/user-event"; import "@testing-library/jest-dom/vitest"; import { DashboardLayout } from "./DashboardLayout"; import { AppProvider } from "../AppProvider/AppProviderComponent"; describe("DashboardLayout", () => { test("renders content correctly", async () => { render(_jsx(DashboardLayout, { children: "Hello world" })); expect(screen.getByText("Hello world")).toBeTruthy(); }); test("renders branding correctly in header", async () => { const BRANDING = { title: "My Company", logo: _jsx("img", { src: "https://placehold.co/600x400", alt: "Placeholder Logo" }) }; render(_jsx(AppProvider, { branding: BRANDING, children: _jsx(DashboardLayout, { children: "Hello world" }) })); const header = screen.getByRole("banner"); expect(within(header).getByText("My Company")).toBeTruthy(); expect(within(header).getByAltText("Placeholder Logo")).toBeTruthy(); }); test("can switch theme", async () => { const user = userEvent.setup(); render(_jsx(AppProvider, { children: _jsx(DashboardLayout, { showThemeSwitcher: true, children: "Hello world" }) })); const getBackgroundColorCSSVariable = () => getComputedStyle(document.documentElement).getPropertyValue("--mui-palette-common-background"); const header = screen.getByRole("banner"); const themeSwitcherButton = within(header).getByLabelText("Switch to dark mode"); expect(getBackgroundColorCSSVariable()).toBe("#fff"); await user.click(themeSwitcherButton); expect(getBackgroundColorCSSVariable()).toBe("#000"); await user.click(themeSwitcherButton); expect(getBackgroundColorCSSVariable()).toBe("#fff"); }); test("navigation works correctly", async () => { const NAVIGATION = [ { kind: "header", title: "Main items" }, { title: "Dashboard", segment: "dashboard", icon: _jsx(DashboardIcon, {}) }, { title: "Orders", segment: "orders", icon: _jsx(ShoppingCartIcon, {}) }, { kind: "divider" }, { kind: "header", title: "Analytics" }, { segment: "reports", title: "Reports", icon: _jsx(BarChartIcon, {}), children: [ { segment: "sales", title: "Sales", icon: _jsx(DescriptionIcon, {}) }, { segment: "traffic", title: "Traffic", icon: _jsx(DescriptionIcon, {}) } ] }, { segment: "integrations", title: "Integrations", icon: _jsx(LayersIcon, {}) } ]; const user = userEvent.setup(); render(_jsx(AppProvider, { navigation: NAVIGATION, children: _jsx(DashboardLayout, { children: "Hello world" }) })); const desktopNavigation = screen.getByRole("navigation", { name: "Desktop" }); // List subheaders are present expect(within(desktopNavigation).getByText("Main items")).toBeTruthy(); expect(within(desktopNavigation).getByText("Analytics")).toBeTruthy(); // List items and their links are present const dashboardLink = within(desktopNavigation).getByRole("link", { name: "Dashboard" }); const ordersLink = within(desktopNavigation).getByRole("link", { name: "Orders" }); expect(dashboardLink.getAttribute("href")).toBe("/dashboard"); expect(ordersLink.getAttribute("href")).toBe("/orders"); const reportsItem = within(desktopNavigation).getByText("Reports"); expect(reportsItem).toBeTruthy(); expect(within(desktopNavigation).getByText("Integrations")).toBeTruthy(); // Nested list items show when parent item is clicked expect(within(desktopNavigation).queryByText("Sales")).toBeNull(); expect(within(desktopNavigation).queryByText("Traffic")).toBeNull(); await user.click(reportsItem); expect(within(desktopNavigation).getByText("Sales")).toBeTruthy(); expect(within(desktopNavigation).getByText("Traffic")).toBeTruthy(); }); test("starts with parent items expanded if any of their children is the current page", () => { const NAVIGATION = [ { segment: "reports", title: "Reports", icon: _jsx(BarChartIcon, {}), children: [ { segment: "sales", title: "Sales", icon: _jsx(DescriptionIcon, {}) }, { segment: "traffic", title: "Traffic", icon: _jsx(DescriptionIcon, {}) }, { segment: "hidden", title: "Hidden", icon: _jsx(DescriptionIcon, {}), hidden: true } ] } ]; const mockRouter = { pathname: "/reports/sales", searchParams: new URLSearchParams(), navigate: vi.fn() }; render(_jsx(AppProvider, { navigation: NAVIGATION, router: mockRouter, children: _jsx(DashboardLayout, { children: "Hello world" }) })); const desktopNavigation = screen.getByRole("navigation", { name: "Desktop" }); expect(within(desktopNavigation).getByText("Sales")).toBeTruthy(); expect(within(desktopNavigation).getByText("Traffic")).toBeTruthy(); expect(within(desktopNavigation).queryByText("Hidden")).toBeNull(); }); test("shows correct selected page item", () => { const NAVIGATION = [ { title: "Dashboard", segment: "dashboard", icon: _jsx(DashboardIcon, {}) }, { title: "Orders", segment: "orders", icon: _jsx(ShoppingCartIcon, {}), children: [ { segment: "nested", title: "Nested", hidden: true } ] }, { segment: "dynamic", title: "Dynamic", icon: _jsx(BarChartIcon, {}), pattern: "dynamic/:dynamicId" }, { segment: "optional", title: "Optional", pattern: "optional{/:optionalId}?" }, { segment: "oneOrMore", title: "One or more", pattern: "oneormore{/:oneormoreId}+" }, { segment: "zeroOrMore", title: "Zero or more", pattern: "zeroormore{/:zeroormoreId}*" } ]; function AppWithPathname({ pathname }) { const mockRouter = { pathname, searchParams: new URLSearchParams(), navigate: vi.fn() }; return (_jsx(AppProvider, { navigation: NAVIGATION, router: mockRouter, children: _jsx(DashboardLayout, { children: "Hello world" }) })); } const { rerender } = render(_jsx(AppWithPathname, { pathname: "/dashboard" })); const desktopNavigation = screen.getByRole("navigation", { name: "Desktop" }); expect(within(desktopNavigation).getByRole("link", { name: "Dashboard" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/orders" })); expect(within(desktopNavigation).getByRole("link", { name: "Dashboard" })).not.toHaveClass("Mui-selected"); expect(within(desktopNavigation).getByRole("link", { name: "Orders" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/orders/nested" })); expect(within(desktopNavigation).getByRole("link", { name: "Orders" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/dynamic" })); expect(within(desktopNavigation).getByRole("link", { name: "Dynamic" })).not.toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/dynamic/123" })); expect(within(desktopNavigation).getByRole("link", { name: "Dynamic" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/dynamic/123/456" })); expect(within(desktopNavigation).getByRole("link", { name: "Dynamic" })).not.toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/optional" })); expect(within(desktopNavigation).getByRole("link", { name: "Optional" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/optional/123" })); expect(within(desktopNavigation).getByRole("link", { name: "Optional" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/optional/123/456" })); expect(within(desktopNavigation).getByRole("link", { name: "Optional" })).not.toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/oneormore" })); expect(within(desktopNavigation).getByRole("link", { name: "One or more" })).not.toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/oneormore/123" })); expect(within(desktopNavigation).getByRole("link", { name: "One or more" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/oneormore/123/456" })); expect(within(desktopNavigation).getByRole("link", { name: "One or more" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/zeroormore" })); expect(within(desktopNavigation).getByRole("link", { name: "Zero or more" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/zeroormore/123" })); expect(within(desktopNavigation).getByRole("link", { name: "Zero or more" })).toHaveClass("Mui-selected"); rerender(_jsx(AppWithPathname, { pathname: "/zeroormore/123/456" })); expect(within(desktopNavigation).getByRole("link", { name: "Zero or more" })).toHaveClass("Mui-selected"); }); test("renders navigation actions", async () => { const NAVIGATION = [ { title: "Item 1", segment: "item1", icon: _jsx(DescriptionIcon, {}), action: _jsx("div", { children: "Action 1" }) }, { title: "Item", segment: "item2", icon: _jsx(DescriptionIcon, {}), action: _jsx("div", { children: "Action 2" }) } ]; render(_jsx(AppProvider, { navigation: NAVIGATION, children: _jsx(DashboardLayout, { children: "Hello world" }) })); const desktopNavigation = screen.getByRole("navigation", { name: "Desktop" }); expect(within(desktopNavigation).getByText("Action 1")).toBeTruthy(); expect(within(desktopNavigation).getByText("Action 2")).toBeTruthy(); }); test("renders sidebar footer slot content", async () => { function SidebarFooter() { return _jsx("div", { children: "I am footer" }); } render(_jsx(AppProvider, { children: _jsx(DashboardLayout, { slots: { sidebarFooter: SidebarFooter }, children: "Hello world" }) })); const desktopNavigation = screen.getByRole("navigation", { name: "Desktop" }); expect(within(desktopNavigation).getByText("I am footer")).toBeTruthy(); }); test("renders without the navigation and toggle button", async () => { const NAVIGATION = [ { title: "Dashboard", segment: "dashboard", icon: _jsx(DashboardIcon, {}) }, { title: "Orders", segment: "orders", icon: _jsx(ShoppingCartIcon, {}) } ]; render(_jsx(AppProvider, { navigation: NAVIGATION, children: _jsx(DashboardLayout, { hideNavigation: true, children: "Hello world" }) })); const desktopNavigation = screen.queryByRole("navigation", { name: "Desktop" }); const navigationToggle = screen.queryByLabelText("Collapse menu"); // Expect that navigation and menu button are not rendered expect(desktopNavigation).toBeNull(); expect(navigationToggle).toBeNull(); // Ensure that main content is still rendered expect(screen.getByText("Hello world")).toBeTruthy(); }); test("renders without default collapsed navigation on desktop", async () => { const NAVIGATION = [ { title: "Dashboard", segment: "dashboard", icon: _jsx(DashboardIcon, {}) } ]; render(_jsx(AppProvider, { navigation: NAVIGATION, children: _jsx(DashboardLayout, { defaultSidebarCollapsed: true, children: "Hello world" }) })); // Expect that menu button has expand action expect(screen.getAllByLabelText("Expand menu")).toBeTruthy(); expect(screen.queryByLabelText("Collapse menu")).toBeNull(); // Ensure that main content is still rendered expect(screen.getByText("Hello world")).toBeTruthy(); }); });