import React from "react"; import { describe, it, expect, vi, beforeEach } from "vitest"; import { screen, fireEvent, waitFor } from "@testing-library/react"; import "@testing-library/jest-dom/vitest"; import { renderWithProviders } from "../utils/test-utils"; import Create from "../../app/components/modals/Create"; import TextInput from "../../app/components/controls/TextInput"; type CreateProps = React.ComponentProps; describe("Create", () => { const defaultProps: CreateProps = { isOpen: true, onClose: vi.fn(), title: "Test Create Dialog", description: "Test description", }; beforeEach(() => { vi.clearAllMocks(); }); it("renders when isOpen is true", () => { renderWithProviders( Create dialog content, ); expect(screen.getByRole("dialog")).toBeInTheDocument(); expect(screen.getByText("Test Create Dialog")).toBeInTheDocument(); expect(screen.getByText("Create dialog content")).toBeInTheDocument(); }); it("does not render when isOpen is false", () => { renderWithProviders(); expect(screen.queryByRole("dialog")).not.toBeInTheDocument(); }); it("calls onClose when close button is clicked", () => { const onClose = vi.fn(); renderWithProviders(); const closeButton = screen.getByLabelText("Close dialog"); fireEvent.click(closeButton); expect(onClose).toHaveBeenCalledTimes(1); }); it("calls onClose when ESC key is pressed", () => { const onClose = vi.fn(); renderWithProviders(); fireEvent.keyDown(document, { key: "Escape" }); expect(onClose).toHaveBeenCalledTimes(1); }); it("calls onClose when overlay is clicked", () => { const onClose = vi.fn(); renderWithProviders(); const overlay = document.querySelector(".fixed.inset-0"); if (overlay) { fireEvent.click(overlay); expect(onClose).toHaveBeenCalledTimes(1); } }); it("uses blurred yellow backdrop when backdropVariant is blurredYellow", () => { renderWithProviders( Header} />, ); const overlay = document.querySelector(".backdrop-blur-md"); expect(overlay).toBeInTheDocument(); }); it("renders footer buttons when provided", () => { const onBack = vi.fn(); const onNext = vi.fn(); renderWithProviders( , ); expect(screen.getByText("Go Back")).toBeInTheDocument(); expect(screen.getByText("Continue")).toBeInTheDocument(); }); it("calls onBack when back button is clicked", () => { const onBack = vi.fn(); renderWithProviders( , ); const backButton = screen.getByText("Back"); fireEvent.click(backButton); expect(onBack).toHaveBeenCalledTimes(1); }); it("calls onNext when next button is clicked", () => { const onNext = vi.fn(); renderWithProviders( , ); const nextButton = screen.getByText("Next"); fireEvent.click(nextButton); expect(onNext).toHaveBeenCalledTimes(1); }); it("disables next button when nextButtonDisabled is true", () => { renderWithProviders( , ); const nextButton = screen.getByText("Next"); expect(nextButton).toBeDisabled(); }); it("renders stepper when currentStep and totalSteps are provided", () => { renderWithProviders( , ); // Find the stepper by its aria-label const stepper = screen.getByRole("progressbar", { name: "Step 2 of 5", }); expect(stepper).toBeInTheDocument(); expect(stepper).toHaveAttribute("aria-valuenow", "2"); expect(stepper).toHaveAttribute("aria-valuemax", "5"); }); it("renders custom header when headerContent is provided", () => { renderWithProviders( Custom header} />, ); expect(screen.getByText("Custom header")).toBeInTheDocument(); expect(screen.queryByText("Default Title")).not.toBeInTheDocument(); expect(screen.queryByText("Default description")).not.toBeInTheDocument(); }); it("renders custom footer content", () => { renderWithProviders( Custom Footer} />, ); expect(screen.getByText("Custom Footer")).toBeInTheDocument(); }); it("has proper ARIA attributes", () => { renderWithProviders( , ); const dialog = screen.getByRole("dialog"); expect(dialog).toHaveAttribute("aria-modal", "true"); expect(dialog).toHaveAttribute("aria-label", "Test create dialog"); }); it("locks body scroll when open", () => { renderWithProviders(); expect(document.body.style.overflow).toBe("hidden"); }); it("restores body scroll when closed", () => { const { rerender } = renderWithProviders(); expect(document.body.style.overflow).toBe("hidden"); rerender(); expect(document.body.style.overflow).toBe(""); }); it("traps focus within create dialog", async () => { renderWithProviders( , ); const closeButton = screen.getByLabelText("Close dialog"); screen.getByLabelText("Test Input"); // Verify input is rendered // Focus should start on first focusable element (close button) await waitFor(() => { expect(closeButton).toHaveFocus(); }); // Tab should move focus to next element fireEvent.keyDown(document, { key: "Tab" }); await waitFor(() => { // Should focus on the more options button or input const focusedElement = document.activeElement; expect(focusedElement).toBeInTheDocument(); }); }); });