/** * Setup file for unit tests * * This file runs before all unit tests to set up global mocks * that are needed before any module imports. * * IMPORTANT: This runs in Node environment BEFORE jsdom is initialized * for test files that use @vitest-environment jsdom. */ import { vi } from 'vitest'; // Create a storage map that persists through the test session // This is used for the localStorage mock // We make it global so tests can clear it (globalThis as any).__testStorageMap = new Map(); // Mock ResizeObserver for tests that import modules using responsiveManager // This must be done at setup time because the responsiveManager singleton // is instantiated when the module is first imported globalThis.ResizeObserver = class { observe() {} unobserve() {} disconnect() {} } as any; // Mock MediaQueryListEvent for tests that need to simulate system theme changes // @ts-expect-error - Mocking a DOM API globalThis.MediaQueryListEvent = class MediaQueryListEvent extends Event { matches: boolean; media: string; constructor(type: string, eventInitDict: { matches: boolean; media: string }) { super(type); this.matches = eventInitDict.matches; this.media = eventInitDict.media; } }; // Mock window.matchMedia for tests that import modules using media queries // Some modules (like createPerspectiveManager) use matchMedia during import Object.defineProperty(globalThis, 'matchMedia', { writable: true, value: vi.fn().mockImplementation((query: string) => ({ matches: false, media: query, onchange: null, addListener: vi.fn(), removeListener: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn(), })), }); // Mock localStorage for tests that use it during module import // Some modules (like ThemeManager via createPersistentStore) access localStorage during initialization // This MUST be a fully functional mock since it's used during module load const getStorageMap = () => (globalThis as any).__testStorageMap; Object.defineProperty(globalThis, 'localStorage', { writable: true, value: { get length() { return getStorageMap().size; }, clear() { getStorageMap().clear(); }, getItem(key: string) { return getStorageMap().get(key) ?? null; }, setItem(key: string, value: string) { getStorageMap().set(key, value); }, removeItem(key: string) { getStorageMap().delete(key); }, key(index: number) { return Array.from(getStorageMap().keys())[index] ?? null; }, }, });