import { describe, it, expect } from 'vitest'; import { MessageSocket } from './message-socket'; import type { SocketLike } from './types'; class FakeSocket implements SocketLike { handlers = new Map void>>(); acks: Array<{ event: string; payload: unknown }> = []; ackReturn: unknown = { threadId: 't1', status: 'OPEN', history: [] }; on(event: string, handler: (...a: unknown[]) => void): unknown { const list = this.handlers.get(event) ?? []; list.push(handler); this.handlers.set(event, list); return this; } off(event: string, handler: (...a: unknown[]) => void): unknown { this.handlers.set(event, (this.handlers.get(event) ?? []).filter((h) => h !== handler)); return this; } emit(_event: string, ..._args: unknown[]): unknown { return this; } async emitWithAck(event: string, ...args: unknown[]): Promise { this.acks.push({ event, payload: args[0] }); return this.ackReturn; } connect(): unknown { return this; } disconnect(): unknown { return this; } trigger(event: string, ...args: unknown[]): void { (this.handlers.get(event) ?? []).forEach((h) => h(...args)); } listenerCount(event: string): number { return (this.handlers.get(event) ?? []).length; } } const cfg = { serviceUrl: 'http://localhost:3200', token: 'tok' }; describe('MessageSocket facade', () => { it('on() registers a handler and the returned fn unsubscribes', () => { const fake = new FakeSocket(); const ms = new MessageSocket(cfg, fake); const off = ms.on('message', () => {}); expect(fake.listenerCount('message')).toBe(1); off(); expect(fake.listenerCount('message')).toBe(0); }); it('sendMessage invokes emitWithAck("send_message", payload)', async () => { const fake = new FakeSocket(); fake.ackReturn = { id: 'm1', threadId: 't1', content: 'hello' }; const ms = new MessageSocket(cfg, fake); await ms.sendMessage('t1', 'hello', { contentRef: 'sas://x' }); const call = fake.acks.find((a) => a.event === 'send_message'); expect(call?.payload).toMatchObject({ threadId: 't1', content: 'hello', contentRef: 'sas://x' }); }); it('openThread returns the ack and tracks the thread', async () => { const fake = new FakeSocket(); fake.ackReturn = { threadId: 't9', status: 'OPEN', history: [] }; const ms = new MessageSocket(cfg, fake); const r = await ms.openThread(); expect(r.threadId).toBe('t9'); }); });