import { describe, it, expect, beforeEach } from 'vitest'; import { clearOfflinePref, offlinePreloadEligible } from './offline'; // A minimal in-memory localStorage for the cleanup test (node has none). beforeEach(() => { const store = new Map(); (globalThis as unknown as { localStorage: Storage }).localStorage = { getItem: (k: string) => store.get(k) ?? null, setItem: (k: string, v: string) => void store.set(k, v), removeItem: (k: string) => void store.delete(k), clear: () => store.clear(), key: () => null, length: 0, } as Storage; }); describe('offline helpers', () => { it('offlinePreloadEligible requires a standalone PWA with email, online, outside mini-apps', () => { const base = { hasEmail: true, standalone: true, inTelegram: false, inVK: false, online: true }; expect(offlinePreloadEligible(base)).toBe(true); expect(offlinePreloadEligible({ ...base, hasEmail: false })).toBe(false); expect(offlinePreloadEligible({ ...base, standalone: false })).toBe(false); expect(offlinePreloadEligible({ ...base, inTelegram: true })).toBe(false); expect(offlinePreloadEligible({ ...base, inVK: true })).toBe(false); expect(offlinePreloadEligible({ ...base, online: false })).toBe(false); }); it('clearOfflinePref removes the retired deliberate-offline key (best-effort, idempotent)', () => { localStorage.setItem('scrabble.offlineMode', '1'); clearOfflinePref(); expect(localStorage.getItem('scrabble.offlineMode')).toBeNull(); // Idempotent: a second call on an already-clear key is a no-op, not an error. expect(() => clearOfflinePref()).not.toThrow(); }); });