import { cleanup, fireEvent, render, screen, waitFor } from '@testing-library/react' import { useState } from 'react' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import Modal from '@/components/modals/Modal' function mockMatchMedia(matches: boolean) { Object.defineProperty(window, 'matchMedia', { writable: true, configurable: true, value: vi.fn().mockImplementation((query: string) => ({ matches: matches && query === '(max-width: 768px)', media: query, onchange: null, addListener: () => {}, removeListener: () => {}, addEventListener: () => {}, removeEventListener: () => {}, dispatchEvent: () => false, })), }) } afterEach(cleanup) beforeEach(() => { mockMatchMedia(false) }) function ModalHarness() { const [isOpen, setIsOpen] = useState(false) return ( <> ) } describe('Modal', () => { it('contains focus, closes with Escape, and restores focus to its trigger', async () => { render() const trigger = screen.getByRole('button', { name: 'باز کردن' }) trigger.focus() fireEvent.click(trigger) const dialog = await screen.findByRole('dialog', { name: 'ویرایش' }) await waitFor(() => expect(dialog).toContainElement(document.activeElement as HTMLElement)) trigger.focus() await waitFor(() => expect(dialog).toContainElement(document.activeElement as HTMLElement)) fireEvent.keyDown(document.activeElement as HTMLElement, { key: 'Escape' }) await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument()) await waitFor(() => expect(trigger).toHaveFocus()) }) it('opens as a bottom sheet on mobile by default', async () => { mockMatchMedia(true) render() fireEvent.click(screen.getByRole('button', { name: 'باز کردن' })) const dialog = await screen.findByRole('dialog', { name: 'ویرایش' }) expect(dialog.className).toContain('mt-auto') expect(dialog.className).toContain('rounded-b-none') expect(dialog.className).toContain('max-h-full') expect(dialog.className).not.toContain('--keyboard-inset') }) })