Files
baiyue-logistics-chat/tests/frontend/drafts.test.cjs
T

49 lines
3.0 KiB
JavaScript

const test=require('node:test');
const assert=require('node:assert/strict');
const fs=require('node:fs');
const vm=require('node:vm');
const path=require('node:path');
const context=vm.createContext({});
vm.runInContext(fs.readFileSync(path.join(__dirname,'../../static/js/drafts.js'),'utf8'),context);
function storage(){
const data=new Map();
return {data,get length(){return data.size;},key:index=>Array.from(data.keys())[index] ?? null,
getItem:key=>data.get(key) ?? null,setItem:(key,value)=>data.set(key,value),removeItem:key=>data.delete(key)};
}
function drafts(scope='1'.repeat(64),local=storage(),tab=storage()){
return context.ChatDrafts.create({scope,storage:()=>local,tabStorage:()=>tab});
}
test('conversation drafts and active tab restore independently of another visitor or tab',()=>{
const local=storage(),tab=storage(),a=drafts(undefined,local,tab);
a.write(9,'A');a.write(10,'B');a.write(null,'NEW');a.active(9);
const restored=drafts(undefined,local,tab);
assert.equal(restored.read(9),'A');assert.equal(restored.read(10),'B');assert.equal(restored.read(null),'NEW');
assert.equal(restored.active(),'9');
const otherTab=drafts(undefined,local);otherTab.write(10,'B updated');
assert.equal(otherTab.active(),'new');assert.equal(restored.read(10),'B updated');assert.equal(restored.read(9),'A');
otherTab.remove(10);assert.equal(restored.read(10),'');
assert.equal(drafts('2'.repeat(64),local,tab).read(9),'');
});
test('malformed records and invalid identifiers cannot become restored drafts',()=>{
const local=storage(),a=drafts(undefined,local),key='baiyue-draft-v1:'+'1'.repeat(64)+':9';
for(const value of ['null','{"version":2,"text":"old"}','{"version":1,"text":45}']){
local.setItem(key,value);assert.equal(a.read(9),'');
}
assert.equal(a.write('../9','invalid'),false);assert.equal(a.read('../9'),'');
});
test('removing and clearing a visitor never clears another visitor or unrelated preferences',()=>{
const local=storage(),a=drafts(undefined,local),b=drafts('2'.repeat(64),local);
local.setItem('theme','dark');a.write(9,'A');a.write(10,'B');b.write(9,'PRIVATE');
a.remove(9);assert.equal(a.read(9),'');assert.equal(a.read(10),'B');
a.clear();assert.equal(a.read(10),'');assert.equal(b.read(9),'PRIVATE');assert.equal(local.getItem('theme'),'dark');
});
test('blocked storage and quota errors retain the latest in-memory draft without a shared bucket',()=>{
const broken={getItem(){throw Error();},setItem(){throw Error();},removeItem(){throw Error();}};
const a=drafts(undefined,broken,broken);
assert.equal(a.write(9,'latest'),false);assert.equal(a.read(9),'latest');a.active(9);assert.equal(a.active(),'9');
const local=storage(),b=drafts(undefined,local);b.write(9,'old');
local.setItem=()=>{throw Error('quota');};assert.equal(b.write(9,'new'),false);assert.equal(b.read(9),'new');
const anonymous=drafts(null,local);anonymous.write(9,'memory only');assert.equal(anonymous.read(9),'memory only');
assert.equal(drafts(null,local).read(9),'');
});