From 0a77999d7351d9aedaa10cb66a35443a22ef1f29 Mon Sep 17 00:00:00 2001 From: jw bot Date: Wed, 28 Jan 2026 05:30:08 -0800 Subject: [PATCH] test(core): mock fetch in OAuth transport fallback tests (#17059) Co-authored-by: Bryan Morgan --- integration-tests/hooks-system.test.ts | 18 ++++++++++++++---- packages/core/src/tools/mcp-client.test.ts | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/integration-tests/hooks-system.test.ts b/integration-tests/hooks-system.test.ts index 5526a4e758..9699916ade 100644 --- a/integration-tests/hooks-system.test.ts +++ b/integration-tests/hooks-system.test.ts @@ -484,9 +484,19 @@ console.log(JSON.stringify({ 'hooks-system.before-tool-selection.responses', ), }); - // Create inline hook command (works on both Unix and Windows) - const hookCommand = - "node -e \"console.log(JSON.stringify({hookSpecificOutput: {hookEventName: 'BeforeToolSelection', toolConfig: {mode: 'ANY', allowedFunctionNames: ['read_file', 'run_shell_command']}}}))\""; + + // Write hook script to file (inline node -e has quoting issues on Windows) + const hookScript = `console.log(JSON.stringify({ + hookSpecificOutput: { + hookEventName: 'BeforeToolSelection', + toolConfig: { + mode: 'ANY', + allowedFunctionNames: ['read_file', 'run_shell_command'] + } + } +}));`; + const scriptPath = join(rig.testDir!, 'before_tool_selection_hook.cjs'); + writeFileSync(scriptPath, hookScript); rig.setup('should modify tool selection with BeforeToolSelection hooks', { settings: { @@ -500,7 +510,7 @@ console.log(JSON.stringify({ hooks: [ { type: 'command', - command: hookCommand, + command: `node "${scriptPath.replace(/\\/g, '/')}"`, timeout: 5000, }, ], diff --git a/packages/core/src/tools/mcp-client.test.ts b/packages/core/src/tools/mcp-client.test.ts index 4a07b1aa4f..9799ab71ae 100644 --- a/packages/core/src/tools/mcp-client.test.ts +++ b/packages/core/src/tools/mcp-client.test.ts @@ -1998,6 +1998,19 @@ describe('connectToMcpServer - OAuth with transport fallback', () => { vi.spyOn(console, 'warn').mockImplementation(() => {}); vi.spyOn(console, 'error').mockImplementation(() => {}); + // Mock fetch to prevent real network calls during OAuth discovery fallback. + // When a 401 error lacks a www-authenticate header, the code attempts to + // fetch the header directly from the server, which would hang without this mock. + vi.stubGlobal( + 'fetch', + vi.fn().mockResolvedValue({ + status: 401, + headers: new Headers({ + 'www-authenticate': `Bearer realm="test", resource_metadata="http://test-server/.well-known/oauth-protected-resource"`, + }), + }), + ); + mockTokenStorage = { getCredentials: vi.fn().mockResolvedValue({ clientId: 'test-client' }), } as unknown as MCPOAuthTokenStorage; @@ -2019,6 +2032,7 @@ describe('connectToMcpServer - OAuth with transport fallback', () => { afterEach(() => { vi.clearAllMocks(); + vi.unstubAllGlobals(); }); it('should handle HTTP 404 → SSE 401 → OAuth → SSE+OAuth succeeds', async () => {