49 lines
3.0 KiB
JavaScript
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),'');
|
|
});
|