54 lines
2.0 KiB
JavaScript
54 lines
2.0 KiB
JavaScript
// Unit: PWA manifest validity (Session 27).
|
|
//
|
|
// The manifest IS the brand on a user's home screen. A malformed manifest
|
|
// silently breaks installability, so guard the required fields + that the
|
|
// icon files it references actually exist on disk.
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const WEB_PUBLIC = path.join(__dirname, '..', '..', 'web', 'public');
|
|
const MANIFEST_PATH = path.join(WEB_PUBLIC, 'manifest.json');
|
|
|
|
describe('PWA manifest', () => {
|
|
let manifest;
|
|
beforeAll(() => {
|
|
manifest = JSON.parse(fs.readFileSync(MANIFEST_PATH, 'utf8'));
|
|
});
|
|
|
|
test('is valid JSON with the required installability fields', () => {
|
|
expect(manifest.name).toBeTruthy();
|
|
expect(manifest.short_name).toBe('VYNDR');
|
|
expect(manifest.start_url).toBe('/dashboard');
|
|
expect(manifest.display).toBe('standalone');
|
|
expect(manifest.theme_color).toMatch(/^#[0-9A-Fa-f]{6}$/);
|
|
expect(manifest.background_color).toMatch(/^#[0-9A-Fa-f]{6}$/);
|
|
});
|
|
|
|
test('declares app categories', () => {
|
|
expect(Array.isArray(manifest.categories)).toBe(true);
|
|
expect(manifest.categories).toContain('sports');
|
|
});
|
|
|
|
test('every PNG icon it references exists on disk', () => {
|
|
const pngs = manifest.icons.filter((i) => i.type === 'image/png');
|
|
expect(pngs.length).toBeGreaterThan(0);
|
|
for (const icon of pngs) {
|
|
const file = path.join(WEB_PUBLIC, icon.src.replace(/^\//, ''));
|
|
expect(fs.existsSync(file)).toBe(true);
|
|
}
|
|
});
|
|
|
|
test('provides a maskable icon (Android adaptive)', () => {
|
|
const maskable = manifest.icons.find((i) => (i.purpose || '').includes('maskable'));
|
|
expect(maskable).toBeDefined();
|
|
});
|
|
|
|
test('theme + background match the brand dark base', () => {
|
|
// Brand bg-0 is #06060B — keep manifest in lockstep so the splash /
|
|
// status bar don't flash a mismatched color.
|
|
expect(manifest.theme_color.toLowerCase()).toBe('#06060b');
|
|
expect(manifest.background_color.toLowerCase()).toBe('#06060b');
|
|
});
|
|
});
|