@etsoo/toolpad
Version:
Dashboard framework extention based on Toolpad Core
308 lines (307 loc) • 14.5 kB
JavaScript
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();
});
});