/* eslint-disable @typescript-eslint/no-non-null-assertion */ import React from "react"; import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { describe, it, expect, vi, beforeEach } from "vitest"; import { WidgetPicker } from "../WidgetPicker"; import type { WidgetPlacement } from "@mosaic/shared"; describe("WidgetPicker", (): void => { const defaultProps = { open: true, onClose: vi.fn(), onAddWidget: vi.fn(), currentLayout: [] as WidgetPlacement[], }; beforeEach((): void => { vi.clearAllMocks(); }); it("should render nothing when closed", (): void => { const { container } = render(); expect(container.innerHTML).toBe(""); }); it("should render dialog when open", (): void => { render(); expect(screen.getByRole("dialog", { name: "Add Widget" })).toBeInTheDocument(); }); it("should display Add Widget heading", (): void => { render(); expect(screen.getByText("Add Widget")).toBeInTheDocument(); }); it("should render search input", (): void => { render(); expect(screen.getByPlaceholderText("Search widgets...")).toBeInTheDocument(); }); it("should display available widgets", (): void => { render(); // Widget registry has multiple widgets; at least one Add button should appear const addButtons = screen.getAllByText("Add"); expect(addButtons.length).toBeGreaterThan(0); }); it("should filter widgets by search text", async (): Promise => { const user = userEvent.setup(); render(); const searchInput = screen.getByPlaceholderText("Search widgets..."); // Type a search term that won't match any widget await user.type(searchInput, "zzz-nonexistent-widget-zzz"); expect(screen.getByText("No widgets found")).toBeInTheDocument(); }); it("should call onAddWidget when Add is clicked", async (): Promise => { const user = userEvent.setup(); const onAdd = vi.fn(); render(); const addButtons = screen.getAllByText("Add"); await user.click(addButtons[0]!); expect(onAdd).toHaveBeenCalledTimes(1); const placement = onAdd.mock.calls[0]![0] as WidgetPlacement; expect(placement).toHaveProperty("i"); expect(placement).toHaveProperty("x"); expect(placement).toHaveProperty("y"); expect(placement).toHaveProperty("w"); expect(placement).toHaveProperty("h"); }); it("should call onClose when close button is clicked", async (): Promise => { const user = userEvent.setup(); render(); await user.click(screen.getByLabelText("Close")); expect(defaultProps.onClose).toHaveBeenCalledTimes(1); }); it("should place new widgets after existing layout items", async (): Promise => { const user = userEvent.setup(); const onAdd = vi.fn(); const existingLayout: WidgetPlacement[] = [ { i: "test-1", x: 0, y: 0, w: 6, h: 3 }, { i: "test-2", x: 0, y: 3, w: 6, h: 2 }, ]; render(); const addButtons = screen.getAllByText("Add"); await user.click(addButtons[0]!); const placement = onAdd.mock.calls[0]![0] as WidgetPlacement; // Should be placed at y=5 (3+2) to avoid overlap expect(placement.y).toBe(5); }); });