/** * Tests for the Modal component * @jest-environment jsdom */ import React from 'react'; import { render, screen, fireEvent } from '@testing-library/react'; import { Modal } from '@/components/ui/Modal'; describe('Modal', () => { const mockOnClose = jest.fn(); beforeEach(() => { jest.clearAllMocks(); }); it('should not render when isOpen is false', () => { const { container } = render(
Modal content
); expect(container.firstChild).toBeNull(); }); it('should render when isOpen is true', () => { render(
Modal content
); expect(screen.getByText('Modal content')).toBeInTheDocument(); }); it('should render title when provided', () => { render(
Content
); expect(screen.getByText('Test Title')).toBeInTheDocument(); }); it('should render close button by default', () => { render(
Content
); expect(screen.getByLabelText('Fermer')).toBeInTheDocument(); }); it('should not render close button when showCloseButton is false', () => { render(
Content
); expect(screen.queryByLabelText('Fermer')).not.toBeInTheDocument(); }); it('should call onClose when close button is clicked', () => { render(
Content
); fireEvent.click(screen.getByLabelText('Fermer')); expect(mockOnClose).toHaveBeenCalledTimes(1); }); it('should call onClose when backdrop is clicked', () => { render(
Content
); // The dialog role is on the backdrop element itself const backdrop = screen.getByRole('dialog'); fireEvent.click(backdrop); expect(mockOnClose).toHaveBeenCalledTimes(1); }); it('should not call onClose when modal content is clicked', () => { render(
Content
); fireEvent.click(screen.getByText('Content')); expect(mockOnClose).not.toHaveBeenCalled(); }); it('should call onClose when Escape key is pressed', () => { render(
Content
); fireEvent.keyDown(document, { key: 'Escape' }); expect(mockOnClose).toHaveBeenCalledTimes(1); }); it('should have dialog role', () => { render(
Content
); expect(screen.getByRole('dialog')).toBeInTheDocument(); }); it('should have aria-modal attribute', () => { render(
Content
); expect(screen.getByRole('dialog')).toHaveAttribute('aria-modal', 'true'); }); it('should apply sm size class', () => { const { container } = render(
Content
); expect(container.querySelector('.max-w-md')).toBeInTheDocument(); }); it('should apply md size class by default', () => { const { container } = render(
Content
); expect(container.querySelector('.max-w-lg')).toBeInTheDocument(); }); it('should apply lg size class', () => { const { container } = render(
Content
); expect(container.querySelector('.max-w-2xl')).toBeInTheDocument(); }); it('should apply xl size class', () => { const { container } = render(
Content
); expect(container.querySelector('.max-w-4xl')).toBeInTheDocument(); }); it('should set body overflow to hidden when open', () => { render(
Content
); expect(document.body.style.overflow).toBe('hidden'); }); it('should reset body overflow when closed', () => { const { rerender } = render(
Content
); rerender(
Content
); expect(document.body.style.overflow).toBe('unset'); }); it('should have aria-labelledby when title is provided', () => { render(
Content
); const dialog = screen.getByRole('dialog'); expect(dialog).toHaveAttribute('aria-labelledby', 'modal-title'); }); it('should not have aria-labelledby when title is not provided', () => { render(
Content
); const dialog = screen.getByRole('dialog'); expect(dialog).not.toHaveAttribute('aria-labelledby'); }); });