import 'fake-indexeddb/auto'; import { test } from 'node:test'; import assert from 'node:assert/strict'; import { ChatDB } from '../src/store/db.ts'; test('drafts preserve multiline text per peer/account across close; a send clears only its revision', async () => { const account = 'draft-a@example.org'; let a = await ChatDB.open(account); const b = await ChatDB.open('draft-b@example.org'); try { await a.saveDraft('one@example.org','chat',{text:'first\nsecond',revision:'v1'}); await a.saveDraft('two@example.org','chat',{text:'other',revision:'v2'}); await b.saveDraft('one@example.org','chat',{text:'account B',revision:'v3'}); a.close(); a = await ChatDB.open(account); assert.equal((await a.getDraft('one@example.org'))?.text,'first\nsecond'); assert.equal((await a.getConversations()).find(c=>c.peer==='two@example.org')?.draft,'other'); await a.saveDraft('one@example.org','chat',{text:'typed during send',revision:'v4'}); assert.equal(await a.clearSentDraft('one@example.org','v1'),false); assert.equal((await a.getDraft('one@example.org'))?.text,'typed during send'); assert.equal(await a.clearSentDraft('one@example.org','v4'),true); assert.equal(await a.getDraft('one@example.org'),undefined); assert.equal((await b.getDraft('one@example.org'))?.text,'account B'); } finally { a.close(); b.close(); } await ChatDB.destroy(account); a = await ChatDB.open(account); assert.equal(await a.getDraft('two@example.org'),undefined); a.close(); }); test('a competing tab draft survives completion of an older send', async () => { const a = await ChatDB.open('draft-tabs@example.org'), b = await ChatDB.open('draft-tabs@example.org'); try { await a.saveDraft('peer','chat',{text:'send this',revision:'old'}); const edit = b.saveDraft('peer','chat',{text:'new from another tab',revision:'new'}); const clear = a.clearSentDraft('peer','old'); await edit; assert.equal(await clear,false); assert.equal((await a.getDraft('peer'))?.text,'new from another tab'); } finally { a.close(); b.close(); } }); test('reading anchors load the required local page, with missing/cross-peer fallbacks', async () => { const db = await ChatDB.open('anchor@example.org'); try { for (let ts=1;ts<=180;ts++) await db.putMessage({key:'peer|'+ts,peer:'peer',type:'chat',dir:'in',from:'peer',body:String(ts),ts},false); const anchor = {key:'peer|20',offset:-12,bottom:false}; await db.saveReadingAnchor('peer',anchor); assert.deepEqual(await db.getMeta('anchor:peer'),anchor); assert.ok((await db.messagesForAnchor('peer',61,anchor)).some(m=>m.key===anchor.key)); assert.equal((await db.messagesForAnchor('peer',61,{...anchor,key:'missing'})).length,61); assert.equal((await db.messagesForAnchor('elsewhere',61,anchor)).length,0); } finally { db.close(); } });