import { test } from 'node:test'; import assert from 'node:assert/strict'; import { getCachedClientId, cacheClientId, invalidateCachedClient, parseOidcCallbackParams, } from './oidcState'; const installStorage = (): Map => { const store = new Map(); (globalThis as { localStorage?: unknown }).localStorage = { getItem: (k: string) => (store.has(k) ? store.get(k) : null), setItem: (k: string, v: string) => { store.set(k, String(v)); }, removeItem: (k: string) => { store.delete(k); }, }; return store; }; test('registration cache: get / put / invalidate, scoped by issuer + redirectUri', () => { installStorage(); assert.equal(getCachedClientId('iss', 'rd'), undefined); cacheClientId('iss', 'client-1', 'rd'); assert.equal(getCachedClientId('iss', 'rd'), 'client-1'); assert.equal(getCachedClientId('iss', 'other-redirect'), undefined); // redirect mismatch = miss assert.equal(getCachedClientId('iss2', 'rd'), undefined); // different issuer = miss invalidateCachedClient('iss'); assert.equal(getCachedClientId('iss', 'rd'), undefined); invalidateCachedClient('absent'); // no-op, no throw }); test('registration cache tolerates corrupt storage', () => { const store = installStorage(); store.set('cinny_oidc_dynamic_clients', '{ not json'); assert.equal(getCachedClientId('iss', 'rd'), undefined); cacheClientId('iss', 'c', 'rd'); assert.equal(getCachedClientId('iss', 'rd'), 'c'); }); test('parseOidcCallbackParams classifies success / error / invalid', () => { assert.deepEqual(parseOidcCallbackParams('?code=abc&state=xyz'), { kind: 'success', code: 'abc', state: 'xyz', }); assert.deepEqual(parseOidcCallbackParams('?error=access_denied&error_description=nope'), { kind: 'error', error: 'access_denied', errorDescription: 'nope', }); assert.deepEqual(parseOidcCallbackParams('?error=bad'), { kind: 'error', error: 'bad', errorDescription: undefined, }); assert.deepEqual(parseOidcCallbackParams('?code=only'), { kind: 'invalid' }); assert.deepEqual(parseOidcCallbackParams(''), { kind: 'invalid' }); });