import { test } from 'node:test'; import assert from 'node:assert/strict'; import { createStore } from 'jotai'; import { enableMapSet } from 'immer'; import type { Path } from 'react-router'; // `makeNavToActivePathAtom(userId)` is a factory: localStorage is read when the // returned atom is first created/accessed (not at module load), but we still // install the mock up front. The reducers `produce` over an immer-managed Map, // so immer's Map/Set plugin must be enabled. const NAV_TO_ACTIVE_PATH = 'navToActivePath'; const storeKeyFor = (userId: string): string => `${NAV_TO_ACTIVE_PATH}${userId}`; const installStorage = (): Map => { const map = new Map(); (globalThis as { localStorage?: unknown }).localStorage = { getItem: (k: string) => (map.has(k) ? map.get(k)! : null), setItem: (k: string, v: string) => { map.set(k, v); }, removeItem: (k: string) => { map.delete(k); }, }; return map; }; enableMapSet(); installStorage(); // eslint-disable-next-line import/first import { makeNavToActivePathAtom } from './navToActivePath'; const USER = '@user:server'; const path = (pathname: string): Path => ({ pathname, search: '', hash: '' }); test('starts as an empty Map', () => { installStorage(); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); const map = store.get(navAtom); assert.ok(map instanceof Map); assert.equal(map.size, 0); }); test('PUT stores a path under its navId', () => { installStorage(); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); store.set(navAtom, { type: 'PUT', navId: 'home', path: path('/home') }); assert.deepEqual(store.get(navAtom).get('home'), path('/home')); }); test('PUT overwrites the path for an existing navId', () => { installStorage(); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); store.set(navAtom, { type: 'PUT', navId: 'home', path: path('/old') }); store.set(navAtom, { type: 'PUT', navId: 'home', path: path('/new') }); const map = store.get(navAtom); assert.equal(map.size, 1); assert.deepEqual(map.get('home'), path('/new')); }); test('DELETE removes a navId', () => { installStorage(); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); store.set(navAtom, { type: 'PUT', navId: 'home', path: path('/home') }); store.set(navAtom, { type: 'PUT', navId: 'dms', path: path('/dms') }); store.set(navAtom, { type: 'DELETE', navId: 'home' }); const map = store.get(navAtom); assert.equal(map.has('home'), false); assert.deepEqual(map.get('dms'), path('/dms')); }); test('DELETE of an absent navId is a no-op', () => { installStorage(); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); store.set(navAtom, { type: 'PUT', navId: 'home', path: path('/home') }); store.set(navAtom, { type: 'DELETE', navId: 'ghost' }); assert.deepEqual([...store.get(navAtom).keys()], ['home']); }); test('persists to localStorage as an Object keyed per user', () => { const backing = installStorage(); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); store.set(navAtom, { type: 'PUT', navId: 'home', path: path('/home') }); const raw = backing.get(storeKeyFor(USER)); assert.ok(raw); const obj = JSON.parse(raw!) as Record; assert.deepEqual(obj, { home: path('/home') }); }); test('hydrates the Map from a stored Object', () => { const backing = installStorage(); backing.set(storeKeyFor(USER), JSON.stringify({ home: path('/home') })); const navAtom = makeNavToActivePathAtom(USER); const store = createStore(); assert.deepEqual(store.get(navAtom).get('home'), path('/home')); }); test('storage is scoped per userId', () => { const backing = installStorage(); const userA = '@a:s'; const userB = '@b:s'; const atomA = makeNavToActivePathAtom(userA); const atomB = makeNavToActivePathAtom(userB); const store = createStore(); store.set(atomA, { type: 'PUT', navId: 'home', path: path('/a-home') }); store.set(atomB, { type: 'PUT', navId: 'home', path: path('/b-home') }); assert.ok(backing.has(storeKeyFor(userA))); assert.ok(backing.has(storeKeyFor(userB))); assert.deepEqual(store.get(atomA).get('home'), path('/a-home')); assert.deepEqual(store.get(atomB).get('home'), path('/b-home')); });