/** * test/setup/local-storage.ts — in-memory Web Storage polyfill for the test env. * * jsdom 29 (the `@vitest-environment jsdom` files) exposes a `localStorage` * object whose Storage methods (getItem/setItem/clear/…) are `undefined` under * this vitest config — so any test that calls `localStorage.clear()` throws * "localStorage.clear is not a function". This registered setupFile installs a * spec-compliant in-memory Storage whenever the ambient one is missing or * non-functional, so frontend unit tests (quick-reply, push, projects-panel) * get real persistence semantics. It is a no-op if a working Storage already * exists, and harmless in the node environment (just adds an unused global). */ class MemoryStorage implements Storage { private store = new Map() get length(): number { return this.store.size } clear(): void { this.store.clear() } getItem(key: string): string | null { return this.store.has(key) ? (this.store.get(key) as string) : null } setItem(key: string, value: string): void { this.store.set(String(key), String(value)) } removeItem(key: string): void { this.store.delete(key) } key(index: number): string | null { return Array.from(this.store.keys())[index] ?? null } } /** True when `s` is a usable Storage (has a callable `clear`). */ function isUsableStorage(s: unknown): s is Storage { return s != null && typeof (s as Storage).clear === 'function' } /** Install an in-memory Storage on `target[name]` unless a working one exists. */ function ensureStorage(target: Record, name: string): void { if (isUsableStorage(target[name])) return Object.defineProperty(target, name, { value: new MemoryStorage(), configurable: true, writable: true, }) } const globalTarget = globalThis as unknown as Record ensureStorage(globalTarget, 'localStorage') ensureStorage(globalTarget, 'sessionStorage') // Mirror onto `window` (jsdom env) so `window.localStorage` resolves too. const win = (globalThis as { window?: Record }).window if (win) { ensureStorage(win, 'localStorage') ensureStorage(win, 'sessionStorage') }