/** * WidgetGrid Component Tests * Following TDD - write tests first! */ import { describe, it, expect, vi, beforeAll } from "vitest"; import { render, screen } from "@testing-library/react"; import { WidgetGrid } from "../WidgetGrid"; import type { WidgetPlacement } from "@mosaic/shared"; // ResizeObserver is not available in jsdom beforeAll((): void => { global.ResizeObserver = vi.fn().mockImplementation(() => ({ observe: vi.fn(), unobserve: vi.fn(), disconnect: vi.fn(), })); }); // Mock react-grid-layout vi.mock("react-grid-layout", () => ({ default: ({ children }: { children: React.ReactNode }): React.JSX.Element => (
{children}
), Responsive: ({ children }: { children: React.ReactNode }): React.JSX.Element => (
{children}
), })); describe("WidgetGrid", (): void => { const mockLayout: WidgetPlacement[] = [ { i: "tasks-1", x: 0, y: 0, w: 2, h: 2 }, { i: "calendar-1", x: 2, y: 0, w: 2, h: 2 }, ]; const mockOnLayoutChange = vi.fn(); it("should render grid layout", (): void => { render(); expect(screen.getByTestId("grid-layout")).toBeInTheDocument(); }); it("should render widgets from layout", (): void => { render(); // Should render correct number of widgets const widgets = screen.getAllByTestId(/widget-/); expect(widgets).toHaveLength(mockLayout.length); }); it("should call onLayoutChange when layout changes", (): void => { const { rerender } = render( ); const newLayout: WidgetPlacement[] = [ { i: "tasks-1", x: 1, y: 0, w: 2, h: 2 }, { i: "calendar-1", x: 2, y: 0, w: 2, h: 2 }, ]; rerender(); // Layout change handler should be set up (actual calls handled by react-grid-layout) expect(mockOnLayoutChange).toBeDefined(); }); it("should support edit mode", (): void => { render(); // In edit mode, widgets should have edit controls expect(screen.getByTestId("grid-layout")).toBeInTheDocument(); }); it("should support read-only mode", (): void => { render( ); expect(screen.getByTestId("grid-layout")).toBeInTheDocument(); }); it("should render empty state when no widgets", (): void => { render(); expect(screen.getByText(/no widgets/i)).toBeInTheDocument(); }); it("should handle widget removal", (): void => { const mockOnRemoveWidget = vi.fn(); render( ); // Widget removal should be supported expect(mockOnRemoveWidget).toBeDefined(); }); it("should apply custom className", (): void => { const { container } = render( ); expect(container.querySelector(".custom-grid")).toBeInTheDocument(); }); });