import React from 'react' import { render, fireEvent, screen } from '@testing-library/react' import '@testing-library/jest-dom' import { LateralModal } from './index' import * as slideHook from './useSlideTransition' // Mock styles so class names are predictable jest.mock('./styles.module.css', () => ({ modal: 'modal', 'modal--left': 'modal--left', 'modal--right': 'modal--right', 'modal--top': 'modal--top', 'modal--bottom': 'modal--bottom', 'modal--entering': 'modal--entering', 'modal--entered': 'modal--entered', 'modal--exiting': 'modal--exiting' })) // Mock the slide hook so tests can control mounted/stage jest.mock('./useSlideTransition', () => ({ useSlideTransition: jest.fn() })) // Mock Portal to simply render children jest.mock('../../organisms', () => ({ Portal: ({ children }: any) =>
{children}
})) // Mock Overline to expose onClick and props easily in tests jest.mock('../../atoms', () => ({ Overline: ({ show, bgColor, zIndex, onClick }: any) => (
) })) // Mock helper jest.mock('../../../helpers', () => ({ getGlobalStyle: (v: string) => `global:${v}` })) const mockUseSlide = slideHook.useSlideTransition as jest.MockedFunction< typeof slideHook.useSlideTransition > describe('LateralModal', () => { beforeEach(() => { jest.clearAllMocks() }) test('does not render when hook reports not mounted', () => { mockUseSlide.mockReturnValue({ mounted: false, stage: 'exiting' } as any) const { queryByRole } = render(Child) expect(queryByRole('dialog')).toBeNull() }) test('renders dialog with children and aria attributes when mounted', () => { mockUseSlide.mockReturnValue({ mounted: true, stage: 'entered' } as any) render(
Panel content
) const dialog = screen.getByRole('dialog') expect(dialog).toBeInTheDocument() expect(dialog).toHaveAttribute('aria-modal', 'true') expect(dialog).toHaveAttribute('aria-hidden', 'false') expect(dialog).toHaveAttribute('aria-label', 'My panel') expect(screen.getByText('Panel content')).toBeInTheDocument() }) test('applies direction and stage classes and transition duration style', () => { mockUseSlide.mockReturnValue({ mounted: true, stage: 'entering' } as any) const { container } = render( X ) const dialog = screen.getByRole('dialog') // class names come from mocked styles expect(dialog.className).toContain('modal') expect(dialog.className).toContain('modal--left') expect(dialog.className).toContain('modal--entering') // style transition includes the provided duration const style = dialog.getAttribute('style') || '' expect(style).toContain('transform 123ms') }) test('calls handleClose when Overline is clicked', () => { mockUseSlide.mockReturnValue({ mounted: true, stage: 'entered' } as any) const handleClose = jest.fn() render( Content ) const overline = screen.getByTestId('overline') fireEvent.click(overline) expect(handleClose).toHaveBeenCalled() }) test('invokes handleClose on Escape key', () => { mockUseSlide.mockReturnValue({ mounted: true, stage: 'entered' } as any) const handleClose = jest.fn() render( Content ) fireEvent.keyDown(window, { key: 'Escape' }) expect(handleClose).toHaveBeenCalled() }) test('does not call handleClose when clicking inside the modal (stops propagation)', () => { mockUseSlide.mockReturnValue({ mounted: true, stage: 'entered' } as any) const handleClose = jest.fn() render( ) const dialog = screen.getByRole('dialog') fireEvent.click(dialog) // should stop propagation; overline click not triggered expect(handleClose).not.toHaveBeenCalled() }) })