From 6e99bf7d0355ac68dbbf84476eb2f7a759d12050 Mon Sep 17 00:00:00 2001 From: Test Date: Sun, 1 Mar 2026 11:32:05 +0100 Subject: [PATCH] fix(test): mock WebSocket in executeToolViaWs test to avoid jsdom/undici unhandled rejection jsdom's WebSocket implementation internally throws InvalidArgumentError ('invalid onError method') via undici when a connection fails, causing Vitest to catch it as an unhandled rejection and fail the test suite. Replace the real WebSocket with a mock that fires onerror via setTimeout, properly exercising the error path without triggering the jsdom internals. --- src/utils/ai-agent.test.ts | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/utils/ai-agent.test.ts b/src/utils/ai-agent.test.ts index 5238abeb..406b2976 100644 --- a/src/utils/ai-agent.test.ts +++ b/src/utils/ai-agent.test.ts @@ -150,8 +150,32 @@ describe('runAgentLoop', () => { describe('executeToolViaWs', () => { it('resolves with error when WebSocket is unavailable', async () => { - // jsdom WebSocket will fail to connect - const result = await executeToolViaWs('read_note', { path: 'test.md' }) - expect(result.isError).toBe(true) + // Mock WebSocket to simulate a connection failure without triggering + // jsdom/undici unhandled rejections (jsdom's WebSocket internally throws + // InvalidArgumentError: invalid onError method on failed connections). + const OriginalWebSocket = globalThis.WebSocket + const mockWs = { + readyState: WebSocket.CONNECTING, + close: vi.fn(), + send: vi.fn(), + onopen: null as ((ev: Event) => void) | null, + onerror: null as ((ev: Event) => void) | null, + onmessage: null as ((ev: MessageEvent) => void) | null, + } + // @ts-expect-error - partial mock for test + globalThis.WebSocket = vi.fn(() => { + // Fire onerror asynchronously to simulate failed connection + setTimeout(() => { + if (mockWs.onerror) mockWs.onerror(new Event('error')) + }, 0) + return mockWs + }) + + try { + const result = await executeToolViaWs('read_note', { path: 'test.md' }) + expect(result.isError).toBe(true) + } finally { + globalThis.WebSocket = OriginalWebSocket + } }) })