121 lines
3.2 KiB
TypeScript
121 lines
3.2 KiB
TypeScript
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);
|
|
});
|
|
});
|