message-repository.test.ts
1 import assert from 'node:assert/strict' 2 import test from 'node:test' 3 import { runWithTempDataDir } from '@/lib/server/test-utils/run-with-temp-data-dir' 4 5 test('appendMessage notifies both generic and per-session message topics', () => { 6 const output = runWithTempDataDir<{ 7 genericTopics: string[] 8 sessionTopics: string[] 9 }>(` 10 const { WebSocket } = await import('ws') 11 const storageMod = await import('@/lib/server/storage') 12 const repoMod = await import('@/lib/server/messages/message-repository') 13 const storage = storageMod.default || storageMod 14 const repo = repoMod.default || repoMod 15 16 storage.saveSessions({ 17 'sess-notify': { 18 id: 'sess-notify', 19 name: 'Notify Session', 20 cwd: process.env.WORKSPACE_DIR, 21 user: 'tester', 22 provider: 'openai', 23 model: 'gpt-5', 24 claudeSessionId: null, 25 codexThreadId: null, 26 opencodeSessionId: null, 27 delegateResumeIds: { claudeCode: null, codex: null, opencode: null, gemini: null }, 28 messages: [], 29 createdAt: Date.now(), 30 lastActiveAt: Date.now(), 31 }, 32 }) 33 34 const genericPayloads = [] 35 const sessionPayloads = [] 36 globalThis.__swarmclaw_ws__ = { 37 wss: null, 38 clients: new Set([ 39 { 40 ws: { 41 readyState: WebSocket.OPEN, 42 send(payload) { genericPayloads.push(JSON.parse(payload)) }, 43 }, 44 topics: new Set(['messages']), 45 }, 46 { 47 ws: { 48 readyState: WebSocket.OPEN, 49 send(payload) { sessionPayloads.push(JSON.parse(payload)) }, 50 }, 51 topics: new Set(['messages:sess-notify']), 52 }, 53 ]), 54 } 55 56 repo.appendMessage('sess-notify', { 57 role: 'user', 58 text: 'hello', 59 time: 1, 60 }) 61 62 console.log(JSON.stringify({ 63 genericTopics: genericPayloads.map((payload) => payload.topic), 64 sessionTopics: sessionPayloads.map((payload) => payload.topic), 65 })) 66 `, { prefix: 'swarmclaw-message-repo-notify-' }) 67 68 assert.deepEqual(output.genericTopics, ['messages']) 69 assert.deepEqual(output.sessionTopics, ['messages:sess-notify']) 70 })