97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
/**
|
|
* PWA Install Prompt tests — Task 5.24.
|
|
*/
|
|
|
|
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
import { PWAInstallPrompt } from '@/components/PWAInstallPrompt';
|
|
import { getNotificationPermission, isPWAInstalled } from '@/utils/notifications';
|
|
|
|
// Mock i18n
|
|
vi.mock('react-i18next', () => ({
|
|
useTranslation: () => ({ t: (key: string) => key }),
|
|
}));
|
|
|
|
describe('PWAInstallPrompt', () => {
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('renders nothing when no beforeinstallprompt event fires', () => {
|
|
render(<PWAInstallPrompt />);
|
|
expect(screen.queryByTestId('pwa-install-prompt')).toBeNull();
|
|
});
|
|
|
|
it('shows install prompt when beforeinstallprompt fires', async () => {
|
|
render(<PWAInstallPrompt />);
|
|
|
|
const event = new Event('beforeinstallprompt');
|
|
Object.assign(event, {
|
|
prompt: vi.fn().mockResolvedValue(undefined),
|
|
userChoice: Promise.resolve({ outcome: 'accepted' }),
|
|
});
|
|
|
|
window.dispatchEvent(event);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId('pwa-install-prompt')).toBeInTheDocument();
|
|
});
|
|
expect(screen.getByTestId('pwa-install-btn')).toBeInTheDocument();
|
|
expect(screen.getByTestId('pwa-dismiss-btn')).toBeInTheDocument();
|
|
});
|
|
|
|
it('hides when dismiss button is clicked', async () => {
|
|
render(<PWAInstallPrompt />);
|
|
|
|
const event = new Event('beforeinstallprompt');
|
|
Object.assign(event, {
|
|
prompt: vi.fn().mockResolvedValue(undefined),
|
|
userChoice: Promise.resolve({ outcome: 'dismissed' }),
|
|
});
|
|
|
|
window.dispatchEvent(event);
|
|
|
|
await waitFor(() => {
|
|
expect(screen.getByTestId('pwa-install-prompt')).toBeInTheDocument();
|
|
});
|
|
|
|
fireEvent.click(screen.getByTestId('pwa-dismiss-btn'));
|
|
|
|
await waitFor(() => {
|
|
expect(screen.queryByTestId('pwa-install-prompt')).toBeNull();
|
|
});
|
|
|
|
// Should not show again after dismiss (localStorage)
|
|
expect(localStorage.getItem('leocrm_pwa_install_dismissed')).toBe('1');
|
|
});
|
|
|
|
it('does not show when already dismissed', () => {
|
|
localStorage.setItem('leocrm_pwa_install_dismissed', '1');
|
|
render(<PWAInstallPrompt />);
|
|
|
|
const event = new Event('beforeinstallprompt');
|
|
Object.assign(event, {
|
|
prompt: vi.fn(),
|
|
userChoice: Promise.resolve({ outcome: 'dismissed' }),
|
|
});
|
|
|
|
window.dispatchEvent(event);
|
|
|
|
expect(screen.queryByTestId('pwa-install-prompt')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('Notification helpers', () => {
|
|
it('getNotificationPermission returns unsupported when Notification API missing', () => {
|
|
const original = (window as any).Notification;
|
|
delete (window as any).Notification;
|
|
expect(getNotificationPermission()).toBe('unsupported');
|
|
(window as any).Notification = original;
|
|
});
|
|
|
|
it('isPWAInstalled returns false in browser mode', () => {
|
|
expect(isPWAInstalled()).toBe(false);
|
|
});
|
|
});
|