Files
EJClaw/src/web-dashboard-room-envelope.test.ts
Eyejoker 8bb77ffaa3 Fix structured IPC envelope leakage
Normalize EJClaw structured send_message envelopes, preserve attachments, unwrap stored room payloads, and add regression tests.
2026-04-28 01:35:26 +09:00

78 lines
2.1 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import type { NewMessage } from './types.js';
import { buildWebDashboardRoomActivity } from './web-dashboard-data.js';
describe('web dashboard room envelope rendering', () => {
it('unwraps EJClaw structured envelopes in room messages', () => {
const envelope = JSON.stringify({
ejclaw: {
visibility: 'public',
text: 'PR #52 모바일/룸 parity 검증 스크린샷입니다.',
verdict: 'done',
attachments: [
{
path: '/tmp/ejclaw-room-mobile-list-390.png',
name: 'room.png',
mime: 'image/png',
},
],
},
});
const htmlEscapedEnvelope = envelope.replace(/"/g, '"');
const messages: NewMessage[] = [
makeMessage('msg-json', envelope, 'owner'),
makeMessage('msg-html-json', htmlEscapedEnvelope, 'reviewer'),
makeMessage(
'msg-silent',
'{"ejclaw":{"visibility":"silent","verdict":"silent"}}',
'arbiter',
),
];
const activity = buildWebDashboardRoomActivity({
serviceId: 'codex-main',
entry: {
jid: 'dc:ops',
name: '#ops',
folder: 'ops',
agentType: 'codex',
status: 'processing',
elapsedMs: 15_000,
pendingMessages: true,
pendingTasks: 1,
},
pairedTask: null,
turns: [],
attempts: [],
outputs: [],
messages,
});
expect(activity.messages).toHaveLength(2);
expect(activity.messages.map((message) => message.content)).toEqual([
'PR #52 모바일/룸 parity 검증 스크린샷입니다.',
'PR #52 모바일/룸 parity 검증 스크린샷입니다.',
]);
expect(JSON.stringify(activity.messages)).not.toContain('"ejclaw"');
});
});
function makeMessage(
id: string,
content: string,
senderName: string,
): NewMessage {
return {
id,
chat_jid: 'dc:ops',
sender: senderName,
sender_name: senderName,
content,
timestamp: '2026-04-26T05:29:00.000Z',
is_from_me: false,
is_bot_message: true,
message_source_kind: 'bot',
};
}