// @vitest-environment jsdom import * as React from "react" import { cleanup, fireEvent, render, screen } from "@testing-library/react" import { AppLayout, createLayoutConfig, defaultLayoutConfig, useLayoutConfig, } from "@workspace/layout" import { afterEach, describe, expect, it, vi } from "vitest" afterEach(cleanup) function LayoutControls() { const { layout, toggleAside, toggleSidebar } = useLayoutConfig() return (
{layout.sidebarOpen ? "sidebar-open" : "sidebar-closed"}| {layout.asideOpen ? "aside-open" : "aside-closed"}
) } function Header() { return Header component } function PreferencesProbe() { const { layout } = useLayoutConfig() return ( {String(layout.sidebarOpen)}|{String(layout.asideOpen)} ) } describe("layout config", () => { it("creates complete configurations from partial input", () => { expect(createLayoutConfig({ asideOpen: true })).toEqual({ ...defaultLayoutConfig, asideOpen: true, }) }) }) describe("AppLayout", () => { it("renders component and node slots in a generated grid", () => { render( Rail node} sidebar={Sidebar node} aside={Aside node} footer={Footer node} layout={{ asideOpen: true, footerStart: "sidebar", headerStart: "sidebar", }} > Content ) const root = document.querySelector('[data-slot="app-layout"]') expect(root?.style.gridTemplateAreas).toBe( '"rail header header header" "rail sidebar content aside" "rail footer footer aside"' ) expect(root?.dataset.headerStart).toBe("sidebar") expect(root?.dataset.footerStart).toBe("sidebar") expect(screen.getByText("Header component")).toBeTruthy() expect(screen.getByText("Rail node")).toBeTruthy() expect(screen.getByText("Sidebar node")).toBeTruthy() expect(screen.getByText("Aside node")).toBeTruthy() expect(screen.getByText("Footer node")).toBeTruthy() }) it("moves sidebar starts inward when the rail is absent", () => { render( Header} sidebar={Sidebar} aside={Aside} footer={Footer} layout={{ asideOpen: true, footerStart: "sidebar", headerStart: "sidebar", }} > Content ) const root = document.querySelector('[data-slot="app-layout"]') expect(root?.style.gridTemplateAreas).toBe( '"sidebar header header" "sidebar content aside" "sidebar footer aside"' ) expect(root?.dataset.headerStart).toBe("content") expect(root?.dataset.footerStart).toBe("content") }) it("applies visibility capabilities without changing stored preferences", () => { render( Sidebar} aside={Aside} layout={{ asideEnabled: false, asideOpen: true, sidebarCollapsible: false, sidebarOpen: false, }} > ) expect(screen.getByText("Sidebar")).toBeTruthy() expect(screen.queryByText("Aside")).toBeNull() expect(screen.getByLabelText("preferences").textContent).toBe("false|true") }) it("manages uncontrolled sidebar and aside state through the hook", () => { render( Sidebar} aside={Aside}> ) expect(screen.getByText("Sidebar")).toBeTruthy() expect(screen.queryByText("Aside")).toBeNull() fireEvent.click(screen.getByRole("button", { name: "Toggle sidebar" })) fireEvent.click(screen.getByRole("button", { name: "Toggle aside" })) expect(screen.queryByText("Sidebar")).toBeNull() expect(screen.getByText("Aside")).toBeTruthy() expect(screen.getByLabelText("layout-state").textContent).toBe( "sidebar-closed|aside-open" ) }) it("reports controlled changes without mutating controlled state", () => { const onLayoutChange = vi.fn() render( Aside} layout={{ asideOpen: false }} onLayoutChange={onLayoutChange} > ) fireEvent.click(screen.getByRole("button", { name: "Toggle aside" })) expect(onLayoutChange).toHaveBeenCalledWith({ ...defaultLayoutConfig, asideOpen: true, }) expect(screen.queryByText("Aside")).toBeNull() expect(screen.getByLabelText("layout-state").textContent).toContain( "aside-closed" ) }) })