monal-rebuild/test/chat-state.test.ts

53 lines
2.7 KiB
TypeScript

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(); }
});