import { currentThemePreference, persistTheme } from '@/lib/theme/client'; import { isThemePreference, resolveTheme, serverResolvedTheme } from '@/lib/theme/config'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; let storage: Map; beforeEach(() => { storage = new Map(); Object.defineProperty(window, 'localStorage', { configurable: true, value: { clear: () => storage.clear(), getItem: (key: string) => storage.get(key) ?? null, removeItem: (key: string) => storage.delete(key), setItem: (key: string, value: string) => storage.set(key, value), }, }); }); afterEach(() => { storage.clear(); document.cookie = 'hpc-theme=; Path=/; Max-Age=0'; document.cookie = 'rentaldrivego-theme=; Path=/; Max-Age=0'; vi.restoreAllMocks(); }); describe('theme foundations', () => { it('accepts only approved preferences', () => { expect(isThemePreference('light')).toBe(true); expect(isThemePreference('dark')).toBe(true); expect(isThemePreference('system')).toBe(true); expect(isThemePreference('sepia')).toBe(false); }); it('keeps preference and resolved theme separate', () => { expect(resolveTheme('system', true)).toBe('dark'); expect(resolveTheme('system', false)).toBe('light'); expect(resolveTheme('light', true)).toBe('light'); expect(serverResolvedTheme('system')).toBe('light'); }); it('defaults client theme preference to dark when no choice exists', () => { delete document.documentElement.dataset.themePreference; expect(currentThemePreference()).toBe('dark'); }); it('persists the shared dashboard theme when homepage theme changes', () => { vi.spyOn(window, 'matchMedia').mockReturnValue({ matches: false } as MediaQueryList); persistTheme('dark'); expect(window.localStorage.getItem('hpc.theme.preference')).toBe('dark'); expect(window.localStorage.getItem('rentaldrivego-theme')).toBe('dark'); expect(document.cookie).toContain('hpc-theme=dark'); expect(document.cookie).toContain('rentaldrivego-theme=dark'); }); it('stores the resolved shared theme for system preference', () => { vi.spyOn(window, 'matchMedia').mockReturnValue({ matches: false } as MediaQueryList); persistTheme('system'); expect(window.localStorage.getItem('hpc.theme.preference')).toBe('system'); expect(window.localStorage.getItem('rentaldrivego-theme')).toBe('light'); expect(document.cookie).toContain('hpc-theme=system'); expect(document.cookie).toContain('rentaldrivego-theme=light'); }); });