import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import React from 'react'; import { describe, expect, it, vi } from 'vitest'; import { MdModal } from '../MdModal'; describe('MdModal', () => { describe('rendering', () => { it('renders when open is true', () => { render( Modal content , ); expect(screen.getByText('Test Modal')).toBeInTheDocument(); expect(screen.getByText('Modal content')).toBeInTheDocument(); }); it('does not render when open is false', () => { render( Modal content , ); expect(screen.queryByText('Test Modal')).not.toBeInTheDocument(); }); it('renders heading', () => { render( Content , ); expect(screen.getByText('My Heading')).toBeInTheDocument(); }); it('renders heading icon', () => { render( }> Content , ); expect(screen.getByTestId('heading-icon')).toBeInTheDocument(); }); it('renders children', () => { render(
Child content
, ); expect(screen.getByTestId('child-content')).toBeInTheDocument(); }); it('renders footer', () => { render( Save}> Content , ); expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument(); }); it('renders close button', () => { render( Content , ); // Close button is the dismiss button within the modal expect(screen.getByRole('button')).toBeInTheDocument(); }); }); describe('states', () => { it('applies error class when error is true', () => { const { baseElement } = render( Content , ); expect(baseElement.querySelector('.md-modal--error')).toBeInTheDocument(); }); }); describe('dividers', () => { it('renders header divider when headingDivider is true', () => { const { baseElement } = render( Content , ); expect(baseElement.querySelector('.md-modal__header-divider')).toBeInTheDocument(); }); it('renders footer divider when footerDivider is true', () => { const { baseElement } = render( OK} footerDivider> Content , ); expect(baseElement.querySelector('.md-modal__footer-divider')).toBeInTheDocument(); }); }); describe('interactions', () => { it('calls onClose when close button is clicked', async () => { const user = userEvent.setup(); const onClose = vi.fn(); render( Content , ); // Click the close button (the dismiss button) const closeButton = screen.getByRole('button'); await user.click(closeButton); expect(onClose).toHaveBeenCalled(); }); it('calls onClose when pressing Escape', async () => { const user = userEvent.setup(); const onClose = vi.fn(); render( Content , ); await user.keyboard('{Escape}'); expect(onClose).toHaveBeenCalled(); }); }); describe('props forwarding', () => { it('applies custom className', () => { const { baseElement } = render( Content , ); expect(baseElement.querySelector('.md-modal')).toHaveClass('custom-modal'); }); it('applies contentClassName to content div', () => { const { baseElement } = render( Content , ); expect(baseElement.querySelector('.md-modal__content')).toHaveClass('custom-content'); }); it('forwards data-* attributes', () => { render( Content , ); expect(screen.getByTestId('my-modal')).toBeInTheDocument(); }); }); describe('accessibility', () => { it('is a dialog role', () => { render( Content , ); expect(screen.getByRole('dialog')).toBeInTheDocument(); }); it('is modal by default', () => { render( Content , ); // ariakit Dialog uses modal prop which ensures proper modal behavior // The aria-modal attribute may not be explicitly set but modal behavior is enforced expect(screen.getByRole('dialog')).toBeInTheDocument(); }); }); });