unreadCenter.test.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132
  1. // @vitest-environment node
  2. import { afterEach, expect, it, vi } from 'vitest'
  3. import { mkdtempSync,rmSync } from 'node:fs'
  4. import { tmpdir } from 'node:os'
  5. import { join } from 'node:path'
  6. import { WorkspaceStore } from '../../src/server/workspaceStore'
  7. import { ChatCacheStore,ChatCacheCoordinator } from '../../src/server/chatCache'
  8. import { unreadSnapshot,acknowledgeUnread } from '../../src/server/unreadCenter'
  9. const homes:string[]=[];const stores:Array<{close():void}>=[]
  10. afterEach(()=>{stores.reverse().forEach(s=>s.close());stores.length=0;homes.splice(0).forEach(h=>rmSync(h,{recursive:true,force:true}))})
  11. it('shares exact snapshots between devices, isolates owners/profiles, and excludes task duplication and process rows',()=>{
  12. const home=mkdtempSync(join(tmpdir(),'unread-integration-'));homes.push(home)
  13. const workspace=new WorkspaceStore(home),cache=new ChatCacheStore(home),coordinator=new ChatCacheCoordinator(cache,{request:vi.fn()} as any);stores.push(workspace,cache,coordinator)
  14. const a=workspace.createAgent('a',{name:'bot',profile:'p'}),b=workspace.createAgent('a',{name:'two',profile:'p'}),c=workspace.createGroup('a',{name:'group',memberIds:[a.id,b.id],administratorId:a.id}),task=workspace.tasks('a',c.id)[0]!
  15. workspace.saveMessage('a',{id:'bot-final',conversationId:c.id,conversationTaskId:task.id,seq:0,role:'assistant',status:'complete',content:'附件答复',reasoning:'',attachments:[],tools:[],createdAt:1})
  16. for(const profile of ['p','other']){
  17. cache.recordCommand('a',profile,'s','session.create',{})
  18. coordinator.observe('a',profile,'s',{type:'message.interim',payload:{text:'检查中'},delivery_id:'progress'})
  19. coordinator.observe('a',profile,'s',{type:'message.complete',payload:{text:'答复'},delivery_id:'final'})
  20. coordinator.observe('a',profile,'s',{type:'message.complete',payload:{text:'答复'},delivery_id:'final'})
  21. }
  22. const device1=unreadSnapshot(workspace,cache,'a'),device2=unreadSnapshot(workspace,cache,'a')
  23. expect(device1).toMatchObject({total:3,bot:1,chat:2});expect(device2).toEqual(device1)
  24. expect(unreadSnapshot(workspace,cache,'b').total).toBe(0)
  25. expect(unreadSnapshot(workspace,cache,'a',(_,p)=>p==='p').total).toBe(2)
  26. coordinator.observe('a','p','s',{type:'message.start',payload:{},delivery_id:'new-start'})
  27. coordinator.observe('a','p','s',{type:'message.complete',payload:{text:'随后新消息'},delivery_id:'new-final'})
  28. acknowledgeUnread(workspace,cache,'a',device1.conversations)
  29. acknowledgeUnread(workspace,cache,'a',device2.conversations)
  30. expect(unreadSnapshot(workspace,cache,'a')).toMatchObject({total:1,chat:1,bot:0})
  31. expect(workspace.require<any>('a','conversation-task',task.id).unreadCount).toBe(0)
  32. })