import test from 'node:test'; import assert from 'node:assert/strict'; import { createVerifierSaltCache } from '../src/core/verifier-salt-cache.mjs'; test('verifier salt cache reuses a fresh salt without calling the verifier hot path', async () => { let nowMs = 1_000; let calls = 0; const cache = createVerifierSaltCache({ loadSalt: async () => { calls += 1; return '252812b3'; }, maxAgeMs: 500, now: () => nowMs, }); const refreshed = await cache.getFreshSalt(); nowMs += 100; const cached = await cache.getFreshSalt(); assert.equal(calls, 1); assert.equal(refreshed.source, 'refresh'); assert.equal(cached.source, 'cache'); assert.equal(cached.currentSaltHex, '252812b3'); assert.equal(cached.ageMs, 100); }); test('verifier salt cache refreshes a stale salt before returning it', async () => { let nowMs = 1_000; const salts = ['252812b3', '252812b4']; const cache = createVerifierSaltCache({ loadSalt: async () => salts.shift(), maxAgeMs: 500, now: () => nowMs, }); const first = await cache.getFreshSalt(); nowMs += 501; const second = await cache.getFreshSalt(); assert.equal(first.currentSaltHex, '252812b3'); assert.equal(second.currentSaltHex, '252812b4'); assert.equal(second.source, 'refresh'); assert.equal(second.ageMs, 0); }); test('verifier salt cache fails closed when stale salt refresh fails', async () => { let nowMs = 1_000; let fail = false; const cache = createVerifierSaltCache({ loadSalt: async () => { if (fail) throw new Error('rpc unavailable'); return '252812b3'; }, maxAgeMs: 500, now: () => nowMs, }); await cache.getFreshSalt(); nowMs += 501; fail = true; await assert.rejects( () => cache.getFreshSalt(), /rpc unavailable/, ); assert.equal(cache.getState().fresh, false); assert.equal(cache.getState().last_refresh_error.message, 'rpc unavailable'); }); test('verifier salt cache rejects malformed salts before signing can use them', async () => { const cache = createVerifierSaltCache({ loadSalt: async () => 'not-a-salt', }); await assert.rejects( () => cache.getFreshSalt(), /current_salt must be 4 bytes in hex/, ); assert.equal(cache.getState().has_cached_salt, false); });