import { afterEach, describe, expect, it } from 'vitest'; import type { DecryptedMessage } from '@chat-app/shared/chat'; import { __resetForTests, getCachedMessages, hasCachedMessages, setCachedMessages, } from './messageMemoryCache'; function msg(id: string): DecryptedMessage { return { id, conversationId: 'conv-1', senderId: 'sender-1', senderDeviceId: null, replyToId: null, editedAt: null, deletedAt: null, createdAt: '2026-05-17T00:00:00Z', plaintext: 'hi ' + id, }; } describe('messageMemoryCache', () => { afterEach(() => { __resetForTests(); }); it('returns empty array when nothing is cached', () => { expect(getCachedMessages('unknown')).toEqual([]); expect(hasCachedMessages('unknown')).toBe(false); }); it('stores and returns messages per conversation', () => { setCachedMessages('a', [msg('m1'), msg('m2')]); expect(getCachedMessages('a').map((m) => m.id)).toEqual(['m1', 'm2']); expect(hasCachedMessages('a')).toBe(true); }); it('isolates conversations', () => { setCachedMessages('a', [msg('m1')]); setCachedMessages('b', [msg('m9')]); expect(getCachedMessages('a').map((m) => m.id)).toEqual(['m1']); expect(getCachedMessages('b').map((m) => m.id)).toEqual(['m9']); }); it('overwrites prior cache when set again', () => { setCachedMessages('a', [msg('m1')]); setCachedMessages('a', [msg('m1'), msg('m2')]); expect(getCachedMessages('a').map((m) => m.id)).toEqual(['m1', 'm2']); }); it('treats an explicit empty list as "cached"', () => { // A conversation that genuinely has zero messages should still be // flagged as cached so the hook skips the loading spinner on re-entry. setCachedMessages('a', []); expect(hasCachedMessages('a')).toBe(true); expect(getCachedMessages('a')).toEqual([]); }); });