import { render, screen, waitFor } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import userEvent from '@testing-library/user-event'; import '@testing-library/jest-dom/vitest'; import { Dialog, DialogBody, DialogFooter, DialogHeader } from './dialog'; describe('Dialog Component', () => { const mockOnClose = vi.fn(); beforeEach(() => { vi.clearAllMocks(); document.body.style.overflow = ''; }); it('renders nothing when open is false', () => { render(
Dialog content
, ); expect(screen.queryByText('Dialog content')).not.toBeInTheDocument(); }); it('renders dialog when open is true', () => { render(
Dialog content
, ); expect(screen.getByText('Dialog content')).toBeInTheDocument(); expect(screen.getByText('Test Dialog')).toBeInTheDocument(); }); it('displays title when provided', () => { render(
Dialog content
, ); expect(screen.getByText('Test Dialog')).toBeInTheDocument(); }); it('renders DialogHeader correctly', () => { render(
Dialog content
, ); const header = screen.getByText('Test Dialog').closest('.border-b'); expect(header).toBeInTheDocument(); }); it('renders DialogBody correctly', () => { render(
Dialog content
, ); expect(screen.getByText('Dialog content')).toBeInTheDocument(); }); it('renders custom footer when provided', () => { render( Custom Footer} >
Dialog content
, ); expect(screen.getByText('Custom Footer')).toBeInTheDocument(); }); it('shows default footer with confirm and cancel buttons for confirm variant', () => { const mockOnConfirm = vi.fn(); render(
Are you sure?
, ); expect(screen.getByText('Confirm')).toBeInTheDocument(); expect(screen.getByText('Cancel')).toBeInTheDocument(); }); it('calls onConfirm when confirm button is clicked', async () => { const user = userEvent.setup(); const mockOnConfirm = vi.fn(); render(
Are you sure?
, ); const confirmButton = screen.getByText('Confirm'); await user.click(confirmButton); expect(mockOnConfirm).toHaveBeenCalledTimes(1); expect(mockOnClose).toHaveBeenCalledTimes(1); }); it('calls onCancel when cancel button is clicked', async () => { const user = userEvent.setup(); const mockOnCancel = vi.fn(); render(
Are you sure?
, ); const cancelButton = screen.getByText('Cancel'); await user.click(cancelButton); expect(mockOnCancel).toHaveBeenCalledTimes(1); expect(mockOnClose).toHaveBeenCalledTimes(1); }); it('shows alert icon for alert variant', () => { render(
Alert message
, ); const icon = screen .getByText('Alert Dialog') .closest('.border-b') ?.querySelector('svg'); expect(icon).toBeInTheDocument(); }); it('shows info icon for info variant', () => { render(
Info message
, ); const icon = screen .getByText('Info Dialog') .closest('.border-b') ?.querySelector('svg'); expect(icon).toBeInTheDocument(); }); it('applies destructive variant to confirm button for alert', () => { const mockOnConfirm = vi.fn(); render(
Alert message
, ); const confirmButton = screen.getByText('Confirm'); const buttonElement = confirmButton.closest('button'); // Design: destructive variant uses text-destructive / bg-destructive expect(buttonElement?.className).toMatch(/text-destructive|bg-destructive/); }); it('uses custom confirm and cancel labels', () => { const mockOnConfirm = vi.fn(); render(
Are you sure?
, ); expect(screen.getByText('Yes')).toBeInTheDocument(); expect(screen.getByText('No')).toBeInTheDocument(); }); it('hides cancel button when showCancel is false', () => { const mockOnConfirm = vi.fn(); render(
Are you sure?
, ); expect(screen.queryByText('Cancel')).not.toBeInTheDocument(); expect(screen.getByText('Confirm')).toBeInTheDocument(); }); it('does not show footer for default variant without footer or actions', () => { render(
Dialog content
, ); const footer = document.querySelector('.border-t'); expect(footer).not.toBeInTheDocument(); }); it('handles async onConfirm', async () => { const user = userEvent.setup(); const mockOnConfirm = vi.fn().mockResolvedValue(undefined); render(
Are you sure?
, ); const confirmButton = screen.getByText('Confirm'); await user.click(confirmButton); await waitFor(() => { expect(mockOnConfirm).toHaveBeenCalledTimes(1); }); await waitFor(() => { expect(mockOnClose).toHaveBeenCalledTimes(1); }); }); describe('DialogHeader', () => { it('renders DialogHeader correctly', () => { render(
Header content
Body content
, ); expect(screen.getByText('Header content')).toBeInTheDocument(); }); }); describe('DialogBody', () => { it('renders DialogBody correctly', () => { render(
Body content
, ); expect(screen.getByText('Body content')).toBeInTheDocument(); }); }); describe('DialogFooter', () => { it('renders DialogFooter correctly', () => { render(
Body content
, ); expect(screen.getByText('Footer button')).toBeInTheDocument(); }); }); });