import { describe, it, expect, vi, beforeEach } from 'vitest'; import { render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import HomePage from '../routes/+page.svelte'; import { pushNotificationManager } from '$lib/client/PushNotificationManager'; // Mock $app/environment vi.mock('$app/environment', () => ({ browser: true })); // Mock fetch for queue API calls globalThis.fetch = vi.fn(() => Promise.resolve({ ok: true, json: () => Promise.resolve({ items: [], stats: { total: 0, pending: 0, in_progress: 0, completed: 0, error: 0 } }) } as Response) ); // Mock EventSource for SSE globalThis.EventSource = vi.fn(() => ({ addEventListener: vi.fn(), removeEventListener: vi.fn(), close: vi.fn(), onerror: null, onmessage: null, onopen: null, readyState: 0, url: '', withCredentials: false, CONNECTING: 0, OPEN: 1, CLOSED: 2, dispatchEvent: vi.fn() })) as any; vi.mock('$lib/client/PushNotificationManager', () => ({ pushNotificationManager: { getState: vi.fn(), subscribe: vi.fn(), onStateChange: vi.fn(() => () => {}) } })); describe('Automatic Notification Subscription', () => { beforeEach(() => { vi.clearAllMocks(); vi.mocked(pushNotificationManager.getState).mockReturnValue({ supported: true, permission: 'default', subscribed: false, loading: false, error: null }); }); it('should auto-subscribe on first user click when supported and not subscribed', async () => { render(HomePage); // Wait for component to mount and set up event listeners await new Promise(resolve => setTimeout(resolve, 100)); // Simulate user click anywhere on page document.body.click(); // Wait for event handlers to process await new Promise(resolve => setTimeout(resolve, 50)); expect(pushNotificationManager.subscribe).toHaveBeenCalledTimes(1); }); it('should not auto-subscribe if permission denied', async () => { vi.mocked(pushNotificationManager.getState).mockReturnValue({ supported: true, permission: 'denied', subscribed: false, loading: false, error: null }); render(HomePage); await new Promise(resolve => setTimeout(resolve, 100)); document.body.click(); await new Promise(resolve => setTimeout(resolve, 50)); expect(pushNotificationManager.subscribe).not.toHaveBeenCalled(); }); it('should not auto-subscribe if already subscribed', async () => { vi.mocked(pushNotificationManager.getState).mockReturnValue({ supported: true, permission: 'granted', subscribed: true, loading: false, error: null }); render(HomePage); await new Promise(resolve => setTimeout(resolve, 100)); document.body.click(); await new Promise(resolve => setTimeout(resolve, 50)); expect(pushNotificationManager.subscribe).not.toHaveBeenCalled(); }); it('should only attempt subscription once', async () => { render(HomePage); await new Promise(resolve => setTimeout(resolve, 100)); document.body.click(); document.body.click(); document.body.click(); await new Promise(resolve => setTimeout(resolve, 50)); expect(pushNotificationManager.subscribe).toHaveBeenCalledTimes(1); }); });