import { describe, it, expect, vi, beforeEach } from 'vitest'; // Mock BroadcastChannel before importing stores if (typeof global.BroadcastChannel === 'undefined') { (global as any).BroadcastChannel = class MockBroadcastChannel { postMessage = vi.fn(); close = vi.fn(); addEventListener = vi.fn(); removeEventListener = vi.fn(); onmessage = null; }; } import { useUIStore } from './ui'; // Mock window.matchMedia Object.defineProperty(window, 'matchMedia', { writable: true, value: vi.fn().mockImplementation((query) => ({ matches: false, media: query, onchange: null, addListener: vi.fn(), removeListener: vi.fn(), addEventListener: vi.fn(), removeEventListener: vi.fn(), dispatchEvent: vi.fn(), })), }); // Mock crypto.randomUUID Object.defineProperty(global, 'crypto', { value: { randomUUID: () => `test-uuid-${Math.random().toString(36).substring(7)}`, }, }); describe('UIStore', () => { beforeEach(() => { // Reset store state useUIStore.setState({ theme: 'system', language: 'en', sidebarOpen: true, notifications: [], }); vi.clearAllMocks(); }); describe('Initial State', () => { it('should have correct initial state', () => { const state = useUIStore.getState(); expect(state.theme).toBe('system'); expect(state.language).toBe('en'); expect(state.sidebarOpen).toBe(true); expect(state.notifications).toEqual([]); }); }); describe('setTheme', () => { it('should set theme to light', () => { useUIStore.getState().setTheme('light'); expect(useUIStore.getState().theme).toBe('light'); expect(document.documentElement.classList.contains('dark')).toBe(false); }); it('should set theme to dark', () => { useUIStore.getState().setTheme('dark'); expect(useUIStore.getState().theme).toBe('dark'); expect(document.documentElement.classList.contains('dark')).toBe(true); }); it('should set theme to system', () => { useUIStore.getState().setTheme('system'); expect(useUIStore.getState().theme).toBe('system'); }); }); describe('setLanguage', () => { it('should set language to en', () => { useUIStore.getState().setLanguage('en'); expect(useUIStore.getState().language).toBe('en'); }); it('should set language to fr', () => { useUIStore.getState().setLanguage('fr'); expect(useUIStore.getState().language).toBe('fr'); }); }); describe('setSidebarOpen', () => { it('should set sidebar open state', () => { useUIStore.getState().setSidebarOpen(false); expect(useUIStore.getState().sidebarOpen).toBe(false); useUIStore.getState().setSidebarOpen(true); expect(useUIStore.getState().sidebarOpen).toBe(true); }); }); describe('addNotification', () => { it('should add a notification', () => { useUIStore.getState().addNotification({ type: 'success', message: 'Test notification', }); const notifications = useUIStore.getState().notifications; expect(notifications).toHaveLength(1); expect(notifications[0].message).toBe('Test notification'); expect(notifications[0].type).toBe('success'); expect(notifications[0].id).toBeDefined(); expect(notifications[0].timestamp).toBeDefined(); }); it('should add multiple notifications', () => { useUIStore.getState().addNotification({ type: 'info', message: 'First notification', }); useUIStore.getState().addNotification({ type: 'warning', message: 'Second notification', }); const notifications = useUIStore.getState().notifications; expect(notifications).toHaveLength(2); expect(notifications[0].message).toBe('First notification'); expect(notifications[1].message).toBe('Second notification'); }); }); describe('removeNotification', () => { it('should remove a notification by id', () => { useUIStore.getState().addNotification({ type: 'success', message: 'Test notification', }); const notifications = useUIStore.getState().notifications; const notificationId = notifications[0].id; useUIStore.getState().removeNotification(notificationId); expect(useUIStore.getState().notifications).toHaveLength(0); }); it('should not remove notification with wrong id', () => { useUIStore.getState().addNotification({ type: 'success', message: 'Test notification', }); useUIStore.getState().removeNotification('wrong-id'); expect(useUIStore.getState().notifications).toHaveLength(1); }); }); describe('markNotificationAsRead', () => { it('should mark notification as read', () => { useUIStore.getState().addNotification({ type: 'info', message: 'Test notification', }); const notifications = useUIStore.getState().notifications; const notificationId = notifications[0].id; expect(notifications[0].read).toBeUndefined(); useUIStore.getState().markNotificationAsRead(notificationId); const updatedNotifications = useUIStore.getState().notifications; expect(updatedNotifications[0].read).toBe(true); }); it('should not mark other notifications as read', () => { useUIStore.getState().addNotification({ type: 'info', message: 'First notification', }); useUIStore.getState().addNotification({ type: 'warning', message: 'Second notification', }); const notifications = useUIStore.getState().notifications; const firstId = notifications[0].id; useUIStore.getState().markNotificationAsRead(firstId); const updatedNotifications = useUIStore.getState().notifications; expect(updatedNotifications[0].read).toBe(true); expect(updatedNotifications[1].read).toBeUndefined(); }); }); describe('clearNotifications', () => { it('should clear all notifications', () => { useUIStore.getState().addNotification({ type: 'info', message: 'First notification', }); useUIStore.getState().addNotification({ type: 'warning', message: 'Second notification', }); expect(useUIStore.getState().notifications).toHaveLength(2); useUIStore.getState().clearNotifications(); expect(useUIStore.getState().notifications).toHaveLength(0); }); }); });