import { act, renderHook } from '@testing-library/react' import { afterEach, expect, it, vi } from 'vitest' import { useTheme } from '../../src/hooks/useTheme' import { useSettingsStore } from '../../src/stores/settingsStore' import { darkColors, lightColors } from '../../src/themes/app-theme' afterEach(() => vi.unstubAllGlobals()) it('keeps the returned theme, surfaces and borders synchronized with system changes', () => { let matches = false const listeners = new Set<() => void>() vi.stubGlobal('matchMedia', () => ({ get matches() { return matches }, addEventListener: (_event: string, listener: () => void) => listeners.add(listener), removeEventListener: (_event: string, listener: () => void) => listeners.delete(listener), })) const original = useSettingsStore.getState().settings useSettingsStore.setState({ settings: { ...original, theme: 'system' } }) const { result, unmount } = renderHook(() => useTheme()) expect(result.current.effective).toBe('light') expect(document.documentElement.style.getPropertyValue('--hairline')).toBe(lightColors.hairline) act(() => { matches = true listeners.forEach((listener) => listener()) }) expect(result.current.effective).toBe('dark') expect(document.documentElement.dataset.theme).toBe('dark') expect(document.documentElement.style.getPropertyValue('--hairline')).toBe(darkColors.hairline) act(() => useSettingsStore.setState({ settings: { ...original, theme: 'light' } })) expect(result.current.effective).toBe('light') unmount() expect(listeners.size).toBe(0) useSettingsStore.setState({ settings: original }) })