import { test } from 'node:test'; import assert from 'node:assert/strict'; // The module evaluates atomWithStorage(..., { getOnInit: true }) which reads // localStorage at load time. node has none — install a no-op mock, then import // dynamically (a static import would hoist above the mock). (globalThis as { localStorage?: unknown }).localStorage = { getItem: () => null, setItem: () => undefined, removeItem: () => undefined, }; const { addTranslation, findTranslation, makeCacheKey } = await import('./translation'); const entry = (key: string, translated = `t-${key}`, fromLang = 'de') => ({ key, translated, fromLang, }); test('makeCacheKey: eventId + normalized target + content fingerprint', () => { // Same event + target + text is stable and prefixed by event:normalizedTarget. const k1 = makeCacheKey('$abc', 'en-US', 'hola'); const k2 = makeCacheKey('$abc', 'EN', 'hola'); assert.equal(k1, k2); assert.ok(k1.startsWith('$abc:en:')); // Different body (an edit) => different key, so a stale translation misses. assert.notEqual(makeCacheKey('$abc', 'en', 'hola'), makeCacheKey('$abc', 'en', 'adios')); // Missing text arg still yields a stable key. assert.ok(makeCacheKey('$abc', 'en').startsWith('$abc:en:')); }); test('addTranslation: prepends, newest first', () => { const out = addTranslation([entry('a'), entry('b')], entry('c')); assert.deepEqual( out.map((e) => e.key), ['c', 'a', 'b'], ); }); test('addTranslation: de-dupes by key, moving to front (and updates value)', () => { const out = addTranslation([entry('a', 'old'), entry('b')], entry('a', 'new')); assert.deepEqual( out.map((e) => e.key), ['a', 'b'], ); assert.equal(out[0].translated, 'new'); }); test('addTranslation: caps at max (newest kept)', () => { const out = addTranslation([entry('a'), entry('b'), entry('c')], entry('d'), 3); assert.deepEqual( out.map((e) => e.key), ['d', 'a', 'b'], ); }); test('addTranslation: ignores empty key or translated', () => { const start = [entry('a')]; assert.equal(addTranslation(start, entry('', 'x')), start); assert.equal(addTranslation(start, entry('b', '')), start); }); test('findTranslation: returns match or undefined', () => { const list = [entry('a'), entry('b')]; assert.equal(findTranslation(list, 'b')?.key, 'b'); assert.equal(findTranslation(list, 'z'), undefined); });