Task 5.24: PWA — vite-plugin-pwa with autoUpdate, manifest, workbox caching, PWAInstallPrompt component, notification helper, SVG icons, 6 tests
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* 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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user