import 'fake-indexeddb/auto'; import { test } from 'node:test'; import assert from 'node:assert/strict'; import { ChatDB, type StoredMessage } from '../src/store/db.ts'; import { displayedCandidate, statusLabel } from '../src/store/displayed.ts'; const peer = 'peer@example.org'; const msg = (id: string, ts: number, extra: Partial = {}): StoredMessage => ({key:peer+'|'+id, peer, type:'chat', dir:'in', from:peer, body:id, ts, id, markable:true, ...extra}); test('visible readable markers advance past errors but never select an error or an unseen item', () => { const readable = msg('readable',1), failed = msg('failed',2,{encrypted:true,undecryptable:true}), later = msg('later',3); assert.equal(displayedCandidate(peer, [failed]), undefined); assert.equal(displayedCandidate(peer, [readable,failed]), readable); assert.equal(displayedCandidate(peer, [failed,later]), later); assert.equal(displayedCandidate(peer, [msg('out',4,{dir:'out'}), msg('room',5,{type:'groupchat'})]), undefined); assert.equal(statusLabel('read'), 'Displayed'); }); test('local attention, own cumulative sync and remote cumulative monotonic state retain errors', async () => { const db = await ChatDB.open('display-test@example.org'); const error = msg('error',2,{body:'Could not decrypt this message.',encrypted:true,undecryptable:true}); try { await db.putMessage(msg('first',1)); await db.putMessage(error); await db.markRead(peer); assert.equal((await db.getConversations())[0].unread,0); assert.equal((await db.messagesByKeys([error.key]))[0].undecryptable,true); const later = msg('later',3); await db.putMessage(later); await db.markReadUpTo(peer,error.key); // older own-device marker cannot regress local attention assert.equal((await db.getConversations())[0].unread,1); await db.markReadUpTo(peer,later.key); assert.equal((await db.getConversations())[0].unread,0); const out1 = msg('out1',4,{dir:'out',status:'delivered'}), out2 = msg('out2',5,{dir:'out',status:'sent'}); await db.putMessage(out1); await db.putMessage(out2); await db.remoteDisplayed(out2.key); await db.setStatus(out2.key,'delivered'); await db.remoteDisplayed(out1.key); assert.deepEqual((await db.messagesByKeys([out1.key,out2.key])).map(m=>m.status),['read','read']); assert.deepEqual((await db.messagesByKeys([error.key]))[0],error); await db.remoteDisplayed('unknown'); } finally {db.close();} });