import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { renderHook } from '@testing-library/react'; import { useReducedMotion } from '../../hooks/useReducedMotion'; type Listener = (e: { matches: boolean }) => void; function createMatchMediaMock(initialMatches: boolean) { const listeners = new Set(); const mql = { matches: initialMatches, media: '', addEventListener: vi.fn((_evt: string, cb: Listener) => { listeners.add(cb); }), removeEventListener: vi.fn((_evt: string, cb: Listener) => { listeners.delete(cb); }), addListener: vi.fn((cb: Listener) => listeners.add(cb)), removeListener: vi.fn((cb: Listener) => listeners.delete(cb)), dispatchEvent: vi.fn(), onchange: null, }; return { mql }; } describe('useReducedMotion', () => { let originalMatchMedia: typeof window.matchMedia | undefined; beforeEach(() => { originalMatchMedia = window.matchMedia; }); afterEach(() => { if (originalMatchMedia) { window.matchMedia = originalMatchMedia; } else { // @ts-expect-error cleanup delete window.matchMedia; } vi.restoreAllMocks(); }); it('returns false when matchMedia reports no match', () => { const { mql } = createMatchMediaMock(false); window.matchMedia = vi.fn().mockReturnValue(mql) as unknown as typeof window.matchMedia; const { result } = renderHook(() => useReducedMotion()); expect(result.current).toBe(false); }); it('returns true when matchMedia reports a match', () => { const { mql } = createMatchMediaMock(true); window.matchMedia = vi.fn().mockReturnValue(mql) as unknown as typeof window.matchMedia; const { result } = renderHook(() => useReducedMotion()); expect(result.current).toBe(true); }); });