43 lines
1.6 KiB
TypeScript
43 lines
1.6 KiB
TypeScript
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
||
|
|
|
||
|
|
import { registerServiceWorker } from '@/lib/serviceWorker';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* PWA (Фаза 5): сервис-воркер регистрируется только в production-сборке и
|
||
|
|
* только там, где браузер его поддерживает.
|
||
|
|
*/
|
||
|
|
|
||
|
|
afterEach(() => {
|
||
|
|
vi.unstubAllGlobals();
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('регистрация сервис-воркера', () => {
|
||
|
|
it('в тестовом окружении (не production) ничего не делает', () => {
|
||
|
|
const register = vi.fn().mockResolvedValue(undefined);
|
||
|
|
vi.stubGlobal('navigator', { serviceWorker: { register } });
|
||
|
|
|
||
|
|
expect(registerServiceWorker()).toBe(false);
|
||
|
|
expect(register).not.toHaveBeenCalled();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('манифест PWA', () => {
|
||
|
|
it('содержит обязательные поля и иконки нужных размеров', async () => {
|
||
|
|
const manifest = await import('../public/manifest.webmanifest?raw');
|
||
|
|
const parsed = JSON.parse(manifest.default) as {
|
||
|
|
name: string;
|
||
|
|
start_url: string;
|
||
|
|
display: string;
|
||
|
|
icons: { sizes: string; type: string; purpose?: string }[];
|
||
|
|
};
|
||
|
|
expect(parsed.name).toBe('glchat');
|
||
|
|
expect(parsed.start_url).toBe('/app');
|
||
|
|
expect(parsed.display).toBe('standalone');
|
||
|
|
const sizes = parsed.icons.map((icon) => icon.sizes);
|
||
|
|
expect(sizes).toContain('192x192');
|
||
|
|
expect(sizes).toContain('512x512');
|
||
|
|
expect(parsed.icons.every((icon) => icon.type === 'image/png')).toBe(true);
|
||
|
|
expect(parsed.icons.some((icon) => icon.purpose === 'maskable')).toBe(true);
|
||
|
|
});
|
||
|
|
});
|