Skip to content

Commit 84801ab

Browse files
committed
Make e2e tests fail on network/auth errors
1 parent b2650b6 commit 84801ab

16 files changed

+15
-158
lines changed

.agents/__tests__/context-pruner.integration.test.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,6 @@ import {
1111
type JSONValue,
1212
} from '@codebuff/sdk'
1313

14-
const shouldSkip = (output: { type: string; message?: string; errorCode?: string }) => {
15-
if (output.type !== 'error') return false
16-
const msg = output.message?.toLowerCase() ?? ''
17-
return (
18-
output.errorCode === 'NETWORK_ERROR' ||
19-
msg.includes('network error') ||
20-
msg.includes('authentication') ||
21-
msg.includes('api key')
22-
)
23-
}
24-
2514
/**
2615
* Integration tests for the context-pruner agent.
2716
* These tests verify that context-pruner correctly prunes message history
@@ -157,7 +146,6 @@ Do not do anything else. Just spawn context-pruner and then report the result.`,
157146
if (run.output.type === 'error') {
158147
console.error('Test 1 Error:', JSON.stringify(run.output, null, 2))
159148
}
160-
if (shouldSkip(run.output)) return
161149
expect(run.output.type).not.toEqual('error')
162150

163151
// Get the final message history from session state
@@ -286,7 +274,6 @@ Do not do anything else. Just spawn context-pruner and then report the result.`,
286274
if (run.output.type === 'error') {
287275
console.error('Test 2 Error:', JSON.stringify(run.output, null, 2))
288276
}
289-
if (shouldSkip(run.output)) return
290277
expect(run.output.type).not.toEqual('error')
291278

292279
// Get final messages and verify tool pairs are intact

.agents/__tests__/file-explorer.integration.test.ts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,6 @@ import fileListerDefinition from '../file-explorer/file-lister'
77

88
import type { PrintModeEvent } from '@codebuff/common/types/print-mode'
99

10-
const shouldSkip = (output: { type: string; message?: string; errorCode?: string }) => {
11-
if (output.type !== 'error') return false
12-
const msg = output.message?.toLowerCase() ?? ''
13-
return (
14-
output.errorCode === 'NETWORK_ERROR' ||
15-
msg.includes('network error') ||
16-
msg.includes('authentication') ||
17-
msg.includes('api key')
18-
)
19-
}
20-
2110
/**
2211
* Integration tests for agents that use the read_subtree tool.
2312
* These tests verify that the SDK properly initializes the session state
@@ -124,7 +113,6 @@ export interface User {
124113
})
125114

126115
// The output should not be an error
127-
if (shouldSkip(run.output)) return
128116
expect(run.output.type).not.toEqual('error')
129117

130118
// Verify we got some output
@@ -189,7 +177,6 @@ export interface User {
189177
},
190178
})
191179

192-
if (shouldSkip(run.output)) return
193180
expect(run.output.type).not.toEqual('error')
194181

195182
const outputStr =
@@ -244,7 +231,6 @@ export interface User {
244231
handleEvent: () => {},
245232
})
246233

247-
if (shouldSkip(run.output)) return
248234
expect(run.output.type).not.toEqual('error')
249235

250236
const outputStr =

common/src/mcp/client.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/
66
import type { MCPConfig } from '../types/mcp'
77
import type { ToolResultOutput } from '../types/messages/content-part'
88
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'
9-
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'
9+
import type {
10+
BlobResourceContents,
11+
CallToolResult,
12+
TextResourceContents,
13+
} from '@modelcontextprotocol/sdk/types.js'
1014

1115
const runningClients: Record<string, Client> = {}
1216
const listToolsCache: Record<
@@ -104,6 +108,14 @@ export function listMCPTools(
104108
return listToolsCache[clientId]
105109
}
106110

111+
function getResourceData(
112+
resource: TextResourceContents | BlobResourceContents,
113+
): string {
114+
if ('text' in resource) return resource.text
115+
if ('blob' in resource) return resource.blob
116+
return ''
117+
}
118+
107119
export async function callMCPTool(
108120
clientId: string,
109121
...args: Parameters<typeof Client.prototype.callTool>
@@ -136,15 +148,9 @@ export async function callMCPTool(
136148
} satisfies ToolResultOutput
137149
}
138150
if (c.type === 'resource') {
139-
const resourceData =
140-
'text' in c.resource
141-
? c.resource.text
142-
: 'blob' in c.resource
143-
? c.resource.blob
144-
: undefined
145151
return {
146152
type: 'media',
147-
data: resourceData ?? '',
153+
data: getResourceData(c.resource),
148154
mediaType: c.resource.mimeType ?? 'text/plain',
149155
} satisfies ToolResultOutput
150156
}

sdk/e2e/custom-agents/api-integration-agent.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
EventCollector,
1313
getApiKey,
1414
skipIfNoApiKey,
15-
shouldSkipOutput,
1615
DEFAULT_TIMEOUT,
1716
} from '../utils'
1817

@@ -112,8 +111,6 @@ Summarize the response data clearly.`,
112111
handleEvent: collector.handleEvent,
113112
})
114113

115-
if (shouldSkipOutput(result.output)) return
116-
117114
expect(result.output.type).not.toBe('error')
118115

119116
const toolCalls = collector.getEventsByType('tool_call')
@@ -139,8 +136,6 @@ Summarize the response data clearly.`,
139136
handleEvent: collector.handleEvent,
140137
})
141138

142-
if (shouldSkipOutput(result.output)) return
143-
144139
// Should complete without crashing
145140
expect(collector.hasEventType('finish')).toBe(true)
146141
},

sdk/e2e/custom-agents/database-query-agent.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
EventCollector,
1313
getApiKey,
1414
skipIfNoApiKey,
15-
shouldSkipOutput,
1615
MOCK_DATABASE,
1716
DEFAULT_TIMEOUT,
1817
} from '../utils'
@@ -83,8 +82,6 @@ Always format query results in a readable way.`,
8382
handleEvent: collector.handleEvent,
8483
})
8584

86-
if (shouldSkipOutput(result.output)) return
87-
8885
expect(result.output.type).not.toBe('error')
8986

9087
const toolCalls = collector.getEventsByType('tool_call')
@@ -115,8 +112,6 @@ Always format query results in a readable way.`,
115112
handleEvent: collector.handleEvent,
116113
})
117114

118-
if (shouldSkipOutput(result.output)) return
119-
120115
expect(result.output.type).not.toBe('error')
121116
expect(collector.hasEventType('finish')).toBe(true)
122117
},

sdk/e2e/custom-agents/weather-agent.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
EventCollector,
1313
getApiKey,
1414
skipIfNoApiKey,
15-
shouldSkipOutput,
1615
MOCK_WEATHER_DATA,
1716
DEFAULT_TIMEOUT,
1817
} from '../utils'
@@ -75,8 +74,6 @@ Always report the temperature and conditions clearly.`,
7574
handleEvent: collector.handleEvent,
7675
})
7776

78-
if (shouldSkipOutput(result.output)) return
79-
8077
expect(result.output.type).not.toBe('error')
8178

8279
// Check that the tool was called
@@ -112,8 +109,6 @@ Always report the temperature and conditions clearly.`,
112109
handleEvent: collector.handleEvent,
113110
})
114111

115-
if (shouldSkipOutput(result.output)) return
116-
117112
expect(result.output.type).not.toBe('error')
118113
expect(collector.hasEventType('finish')).toBe(true)
119114
},

sdk/e2e/features/knowledge-files.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
EventCollector,
1212
getApiKey,
1313
skipIfNoApiKey,
14-
shouldSkipOutput,
1514
DEFAULT_AGENT,
1615
DEFAULT_TIMEOUT,
1716
} from '../utils'
@@ -40,8 +39,6 @@ describe('Features: Knowledge Files', () => {
4039
handleEvent: collector.handleEvent,
4140
})
4241

43-
if (shouldSkipOutput(result.output)) return
44-
4542
expect(result.output.type).not.toBe('error')
4643

4744
const responseText = collector.getFullText().toUpperCase()
@@ -72,8 +69,6 @@ describe('Features: Knowledge Files', () => {
7269
handleEvent: collector.handleEvent,
7370
})
7471

75-
if (shouldSkipOutput(result.output)) return
76-
7772
expect(result.output.type).not.toBe('error')
7873

7974
const responseText = collector.getFullText().toLowerCase()

sdk/e2e/features/max-agent-steps.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
EventCollector,
1212
getApiKey,
1313
skipIfNoApiKey,
14-
shouldSkipOutput,
1514
DEFAULT_AGENT,
1615
DEFAULT_TIMEOUT,
1716
} from '../utils'
@@ -38,8 +37,6 @@ describe('Features: Max Agent Steps', () => {
3837
handleEvent: collector.handleEvent,
3938
})
4039

41-
if (shouldSkipOutput(result.output)) return
42-
4340
expect(result.output.type).not.toBe('error')
4441
expect(collector.hasEventType('finish')).toBe(true)
4542
},
@@ -60,8 +57,6 @@ describe('Features: Max Agent Steps', () => {
6057
handleEvent: collector.handleEvent,
6158
})
6259

63-
if (shouldSkipOutput(result.output)) return
64-
6560
// Should still complete for simple prompts
6661
expect(collector.hasEventType('start')).toBe(true)
6762
},

sdk/e2e/features/project-files.e2e.test.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
EventCollector,
1212
getApiKey,
1313
skipIfNoApiKey,
14-
shouldSkipOutput,
1514
SAMPLE_PROJECT_FILES,
1615
DEFAULT_AGENT,
1716
DEFAULT_TIMEOUT,
@@ -39,8 +38,6 @@ describe('Features: Project Files', () => {
3938
handleEvent: collector.handleEvent,
4039
})
4140

42-
if (shouldSkipOutput(result.output)) return
43-
4441
expect(result.output.type).not.toBe('error')
4542

4643
const responseText = collector.getFullText().toLowerCase()
@@ -69,8 +66,6 @@ describe('Features: Project Files', () => {
6966
handleEvent: collector.handleEvent,
7067
})
7168

72-
if (shouldSkipOutput(result.output)) return
73-
7469
expect(result.output.type).not.toBe('error')
7570

7671
const responseText = collector.getFullText().toLowerCase()

sdk/e2e/integration/event-ordering.integration.test.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
EventCollector,
1313
getApiKey,
1414
skipIfNoApiKey,
15-
shouldSkipOutput,
1615
DEFAULT_AGENT,
1716
DEFAULT_TIMEOUT,
1817
} from '../utils'
@@ -38,8 +37,6 @@ describe('Integration: Event Ordering', () => {
3837
handleEvent: collector.handleEvent,
3938
})
4039

41-
if (shouldSkipOutput(result.output)) return
42-
4340
const startIndex = collector.events.findIndex((e) => e.type === 'start')
4441
expect(startIndex).toBe(0)
4542
},
@@ -59,8 +56,6 @@ describe('Integration: Event Ordering', () => {
5956
handleEvent: collector.handleEvent,
6057
})
6158

62-
if (shouldSkipOutput(result.output)) return
63-
6459
const finishIndex = collector.events.findIndex((e) => e.type === 'finish')
6560
const lastTextIndex = collector.events
6661
.map((e, i) => (e.type === 'text' ? i : -1))
@@ -89,8 +84,6 @@ describe('Integration: Event Ordering', () => {
8984
cwd: process.cwd(),
9085
})
9186

92-
if (shouldSkipOutput(result.output)) return
93-
9487
const toolCalls = collector.getEventsByType('tool_call')
9588
const toolResults = collector.getEventsByType('tool_result')
9689

@@ -121,8 +114,6 @@ describe('Integration: Event Ordering', () => {
121114
handleEvent: collector.handleEvent,
122115
})
123116

124-
if (shouldSkipOutput(result.output)) return
125-
126117
// Use collector's verifyEventOrder method
127118
const hasCorrectOrder = collector.verifyEventOrder(['start', 'finish'])
128119
expect(hasCorrectOrder).toBe(true)
@@ -143,8 +134,6 @@ describe('Integration: Event Ordering', () => {
143134
handleEvent: collector.handleEvent,
144135
})
145136

146-
if (shouldSkipOutput(result.output)) return
147-
148137
// Find the last finish event
149138
const finishEvents = collector.getEventsByType('finish')
150139
if (finishEvents.length > 0) {
@@ -173,16 +162,12 @@ describe('Integration: Event Ordering', () => {
173162
handleEvent: collector1.handleEvent,
174163
})
175164

176-
if (shouldSkipOutput(result1.output)) return
177-
178165
const result2 = await client.run({
179166
agent: DEFAULT_AGENT,
180167
prompt: 'Say "second"',
181168
handleEvent: collector2.handleEvent,
182169
})
183170

184-
if (shouldSkipOutput(result2.output)) return
185-
186171
// Both should have correct ordering
187172
expect(collector1.verifyEventOrder(['start', 'finish'])).toBe(true)
188173
expect(collector2.verifyEventOrder(['start', 'finish'])).toBe(true)

0 commit comments

Comments
 (0)