Skip to content

Commit fab00e3

Browse files
committed
fix tests
1 parent cc8e281 commit fab00e3

15 files changed

Lines changed: 98 additions & 164 deletions

File tree

apps/sim/app/api/a2a/serve/[agentId]/route.ts

Lines changed: 14 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ import {
1515
} from '@/lib/a2a/utils'
1616
import {
1717
type A2AJsonRpcId,
18+
type A2AMessageSendParams,
19+
type A2APushNotificationSetParams,
20+
type A2ATaskIdParams,
1821
a2aJsonRpcRequestSchema,
1922
a2aMessageSendParamsSchema,
2023
a2aPushNotificationSetParamsSchema,
@@ -41,9 +44,6 @@ import {
4144
extractAgentContent,
4245
formatTaskResponse,
4346
generateTaskId,
44-
type MessageSendParams,
45-
type PushNotificationSetParams,
46-
type TaskIdParams,
4747
} from '@/app/api/a2a/serve/[agentId]/utils'
4848
import { getBrandConfig } from '@/ee/whitelabeling'
4949

@@ -329,7 +329,7 @@ export const POST = withRouteHandler(
329329
return handleMessageSend(
330330
id,
331331
agent,
332-
paramsValidation.data as MessageSendParams,
332+
paramsValidation.data,
333333
apiKey,
334334
executionUserId,
335335
callerFingerprint
@@ -349,7 +349,7 @@ export const POST = withRouteHandler(
349349
request,
350350
id,
351351
agent,
352-
paramsValidation.data as MessageSendParams,
352+
paramsValidation.data,
353353
apiKey,
354354
executionUserId,
355355
callerFingerprint
@@ -405,12 +405,7 @@ export const POST = withRouteHandler(
405405
)
406406
}
407407

408-
return handlePushNotificationSet(
409-
id,
410-
agent.id,
411-
paramsValidation.data as PushNotificationSetParams,
412-
callerFingerprint
413-
)
408+
return handlePushNotificationSet(id, agent.id, paramsValidation.data, callerFingerprint)
414409
}
415410

416411
case A2A_METHODS.PUSH_NOTIFICATION_GET: {
@@ -481,20 +476,11 @@ async function handleMessageSend(
481476
workflowId: string
482477
workspaceId: string
483478
},
484-
rawParams: unknown,
479+
params: A2AMessageSendParams,
485480
apiKey?: string | null,
486481
executionUserId?: string,
487482
callerFingerprint?: string
488483
): Promise<NextResponse> {
489-
const paramsResult = a2aMessageSendParamsSchema.safeParse(rawParams)
490-
if (!paramsResult.success) {
491-
return NextResponse.json(
492-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Message is required'),
493-
{ status: 400 }
494-
)
495-
}
496-
const params = paramsResult.data as MessageSendParams
497-
498484
const message = params.message
499485
const taskId = message.taskId || generateTaskId()
500486
const contextId = message.contextId || generateId()
@@ -712,20 +698,11 @@ async function handleMessageStream(
712698
workflowId: string
713699
workspaceId: string
714700
},
715-
rawParams: unknown,
701+
params: A2AMessageSendParams,
716702
apiKey?: string | null,
717703
executionUserId?: string,
718704
callerFingerprint?: string
719705
): Promise<NextResponse> {
720-
const paramsResult = a2aMessageSendParamsSchema.safeParse(rawParams)
721-
if (!paramsResult.success) {
722-
return NextResponse.json(
723-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Message is required'),
724-
{ status: 400 }
725-
)
726-
}
727-
const params = paramsResult.data as MessageSendParams
728-
729706
const message = params.message
730707
const contextId = message.contextId || generateId()
731708
const taskId = message.taskId || generateTaskId()
@@ -1145,18 +1122,9 @@ async function handleMessageStream(
11451122
async function handleTaskGet(
11461123
id: A2AJsonRpcId,
11471124
agentId: string,
1148-
rawParams: unknown,
1125+
params: A2ATaskIdParams,
11491126
callerFingerprint?: string
11501127
): Promise<NextResponse> {
1151-
const paramsResult = a2aTaskIdParamsSchema.safeParse(rawParams)
1152-
if (!paramsResult.success) {
1153-
return NextResponse.json(
1154-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Task ID is required'),
1155-
{ status: 400 }
1156-
)
1157-
}
1158-
const params = paramsResult.data as TaskIdParams
1159-
11601128
const historyLength =
11611129
params.historyLength !== undefined && params.historyLength >= 0
11621130
? params.historyLength
@@ -1189,18 +1157,9 @@ async function handleTaskGet(
11891157
async function handleTaskCancel(
11901158
id: A2AJsonRpcId,
11911159
agentId: string,
1192-
rawParams: unknown,
1160+
params: A2ATaskIdParams,
11931161
callerFingerprint?: string
11941162
): Promise<NextResponse> {
1195-
const paramsResult = a2aTaskIdParamsSchema.safeParse(rawParams)
1196-
if (!paramsResult.success) {
1197-
return NextResponse.json(
1198-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Task ID is required'),
1199-
{ status: 400 }
1200-
)
1201-
}
1202-
const params = paramsResult.data as TaskIdParams
1203-
12041163
const task = await getTaskForAgent(params.id, agentId, callerFingerprint)
12051164

12061165
if (!task) {
@@ -1266,18 +1225,9 @@ async function handleTaskResubscribe(
12661225
request: NextRequest,
12671226
id: A2AJsonRpcId,
12681227
agentId: string,
1269-
rawParams: unknown,
1228+
params: A2ATaskIdParams,
12701229
callerFingerprint?: string
12711230
): Promise<NextResponse> {
1272-
const paramsResult = a2aTaskIdParamsSchema.safeParse(rawParams)
1273-
if (!paramsResult.success) {
1274-
return NextResponse.json(
1275-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Task ID is required'),
1276-
{ status: 400 }
1277-
)
1278-
}
1279-
const params = paramsResult.data as TaskIdParams
1280-
12811231
const task = await getTaskForAgent(params.id, agentId, callerFingerprint)
12821232

12831233
if (!task) {
@@ -1476,26 +1426,9 @@ async function handleTaskResubscribe(
14761426
async function handlePushNotificationSet(
14771427
id: A2AJsonRpcId,
14781428
agentId: string,
1479-
rawParams: unknown,
1429+
params: A2APushNotificationSetParams,
14801430
callerFingerprint?: string
14811431
): Promise<NextResponse> {
1482-
const idResult = a2aTaskIdParamsSchema.safeParse(rawParams)
1483-
if (!idResult.success) {
1484-
return NextResponse.json(
1485-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Task ID is required'),
1486-
{ status: 400 }
1487-
)
1488-
}
1489-
1490-
const paramsResult = a2aPushNotificationSetParamsSchema.safeParse(rawParams)
1491-
if (!paramsResult.success) {
1492-
return NextResponse.json(
1493-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Push notification URL is required'),
1494-
{ status: 400 }
1495-
)
1496-
}
1497-
const params = paramsResult.data as PushNotificationSetParams
1498-
14991432
const urlValidation = await validateUrlWithDNS(
15001433
params.pushNotificationConfig.url,
15011434
'Push notification URL'
@@ -1559,18 +1492,9 @@ async function handlePushNotificationSet(
15591492
async function handlePushNotificationGet(
15601493
id: A2AJsonRpcId,
15611494
agentId: string,
1562-
rawParams: unknown,
1495+
params: A2ATaskIdParams,
15631496
callerFingerprint?: string
15641497
): Promise<NextResponse> {
1565-
const paramsResult = a2aTaskIdParamsSchema.safeParse(rawParams)
1566-
if (!paramsResult.success) {
1567-
return NextResponse.json(
1568-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Task ID is required'),
1569-
{ status: 400 }
1570-
)
1571-
}
1572-
const params = paramsResult.data as TaskIdParams
1573-
15741498
const task = await getTaskForAgent(params.id, agentId, callerFingerprint)
15751499

15761500
if (!task) {
@@ -1606,18 +1530,9 @@ async function handlePushNotificationGet(
16061530
async function handlePushNotificationDelete(
16071531
id: A2AJsonRpcId,
16081532
agentId: string,
1609-
rawParams: unknown,
1533+
params: A2ATaskIdParams,
16101534
callerFingerprint?: string
16111535
): Promise<NextResponse> {
1612-
const paramsResult = a2aTaskIdParamsSchema.safeParse(rawParams)
1613-
if (!paramsResult.success) {
1614-
return NextResponse.json(
1615-
createError(id, A2A_ERROR_CODES.INVALID_PARAMS, 'Task ID is required'),
1616-
{ status: 400 }
1617-
)
1618-
}
1619-
const params = paramsResult.data as TaskIdParams
1620-
16211536
const task = await getTaskForAgent(params.id, agentId, callerFingerprint)
16221537

16231538
if (!task) {

apps/sim/app/api/chat/[identifier]/otp/route.test.ts

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,18 +167,33 @@ vi.mock('zod', () => {
167167
this.errors = issues
168168
}
169169
}
170-
const mockStringReturnValue = {
171-
email: vi.fn().mockReturnThis(),
172-
length: vi.fn().mockReturnThis(),
173-
}
174-
return {
175-
z: {
176-
object: vi.fn().mockReturnValue({
177-
parse: mockZodParse,
178-
}),
179-
string: vi.fn().mockReturnValue(mockStringReturnValue),
180-
ZodError,
170+
const chainable: Record<string, unknown> = {}
171+
const proxy: Record<string, unknown> = new Proxy(chainable, {
172+
get(target, prop) {
173+
if (prop === 'parse') return mockZodParse
174+
if (prop === 'safeParse') {
175+
return (data: unknown) => ({ success: true, data })
176+
}
177+
if (prop === 'then') return undefined
178+
if (typeof prop === 'symbol') return Reflect.get(target, prop)
179+
if (!(prop in target)) {
180+
target[prop as string] = vi.fn().mockReturnValue(proxy)
181+
}
182+
return target[prop as string]
181183
},
184+
})
185+
const makeChain = vi.fn(() => proxy)
186+
return {
187+
z: new Proxy(
188+
{ ZodError },
189+
{
190+
get(target, prop) {
191+
if (prop === 'ZodError') return ZodError
192+
if (typeof prop === 'symbol') return Reflect.get(target, prop)
193+
return makeChain
194+
},
195+
}
196+
),
182197
}
183198
})
184199

apps/sim/app/api/chat/route.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
6363
allowedEmails = [],
6464
outputConfigs = [],
6565
} = validatedData
66-
const deployOutputConfigs = outputConfigs.filter(
67-
(config): config is { blockId: string; path: string } => typeof config.path === 'string'
68-
)
6966

7067
// Perform additional validation specific to auth types
7168
if (authType === 'password' && !password) {
@@ -113,7 +110,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
113110
authType,
114111
password,
115112
allowedEmails,
116-
outputConfigs: deployOutputConfigs,
113+
outputConfigs,
117114
workspaceId: workflowRecord.workspaceId,
118115
})
119116

apps/sim/app/api/copilot/api-keys/route.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ const { mockFetch } = vi.hoisted(() => ({
1414
vi.mock('@/lib/copilot/constants', () => ({
1515
SIM_AGENT_API_URL_DEFAULT: 'https://agent.sim.example.com',
1616
SIM_AGENT_API_URL: 'https://agent.sim.example.com',
17+
COPILOT_MODES: ['ask', 'build', 'plan'] as const,
18+
COPILOT_REQUEST_MODES: ['ask', 'build', 'plan', 'agent'] as const,
1719
}))
1820

1921
vi.mock('@/lib/core/config/env', () => createEnvMock({ COPILOT_API_KEY: 'test-api-key' }))

apps/sim/app/api/copilot/chat/delete/route.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,19 @@ describe('Copilot Chat Delete API Route', () => {
7777
expect(dbChainMockFns.where).toHaveBeenCalled()
7878
})
7979

80-
it('should return 500 for invalid request body - missing chatId', async () => {
80+
it('should return 400 for invalid request body - missing chatId', async () => {
8181
authMockFns.mockGetSession.mockResolvedValue({ user: { id: 'user-123' } })
8282

8383
const req = createMockRequest('DELETE', {})
8484

8585
const response = await DELETE(req)
8686

87-
expect(response.status).toBe(500)
87+
expect(response.status).toBe(400)
8888
const responseData = await response.json()
89-
expect(responseData.error).toBe('Failed to delete chat')
89+
expect(responseData.error).toBe('Validation error')
9090
})
9191

92-
it('should return 500 for invalid request body - chatId is not a string', async () => {
92+
it('should return 400 for invalid request body - chatId is not a string', async () => {
9393
authMockFns.mockGetSession.mockResolvedValue({ user: { id: 'user-123' } })
9494

9595
const req = createMockRequest('DELETE', {
@@ -98,9 +98,9 @@ describe('Copilot Chat Delete API Route', () => {
9898

9999
const response = await DELETE(req)
100100

101-
expect(response.status).toBe(500)
101+
expect(response.status).toBe(400)
102102
const responseData = await response.json()
103-
expect(responseData.error).toBe('Failed to delete chat')
103+
expect(responseData.error).toBe('Validation error')
104104
})
105105

106106
it('should handle database errors gracefully', async () => {

apps/sim/app/api/copilot/chat/update-messages/route.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,9 @@ describe('Copilot Chat Update Messages API Route', () => {
9898

9999
const response = await POST(req)
100100

101-
expect(response.status).toBe(500)
101+
expect(response.status).toBe(400)
102102
const responseData = await response.json()
103-
expect(responseData.error).toBe('Failed to update chat messages')
103+
expect(responseData.error).toBe('Validation error')
104104
})
105105

106106
it('should return 400 for invalid request body - missing messages', async () => {
@@ -112,9 +112,9 @@ describe('Copilot Chat Update Messages API Route', () => {
112112

113113
const response = await POST(req)
114114

115-
expect(response.status).toBe(500)
115+
expect(response.status).toBe(400)
116116
const responseData = await response.json()
117-
expect(responseData.error).toBe('Failed to update chat messages')
117+
expect(responseData.error).toBe('Validation error')
118118
})
119119

120120
it('should return 400 for invalid message structure - missing required fields', async () => {
@@ -131,9 +131,9 @@ describe('Copilot Chat Update Messages API Route', () => {
131131

132132
const response = await POST(req)
133133

134-
expect(response.status).toBe(500)
134+
expect(response.status).toBe(400)
135135
const responseData = await response.json()
136-
expect(responseData.error).toBe('Failed to update chat messages')
136+
expect(responseData.error).toBe('Validation error')
137137
})
138138

139139
it('should return 400 for invalid message role', async () => {
@@ -153,9 +153,9 @@ describe('Copilot Chat Update Messages API Route', () => {
153153

154154
const response = await POST(req)
155155

156-
expect(response.status).toBe(500)
156+
expect(response.status).toBe(400)
157157
const responseData = await response.json()
158-
expect(responseData.error).toBe('Failed to update chat messages')
158+
expect(responseData.error).toBe('Validation error')
159159
})
160160

161161
it('should return 404 when chat is not found', async () => {

apps/sim/app/api/copilot/stats/route.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ vi.mock('@/lib/copilot/request/http', () => copilotHttpMock)
1616
vi.mock('@/lib/copilot/constants', () => ({
1717
SIM_AGENT_API_URL_DEFAULT: 'https://agent.sim.example.com',
1818
SIM_AGENT_API_URL: 'https://agent.sim.example.com',
19+
COPILOT_MODES: ['ask', 'build', 'plan'] as const,
20+
COPILOT_REQUEST_MODES: ['ask', 'build', 'plan', 'agent'] as const,
1921
}))
2022

2123
vi.mock('@/lib/core/config/env', () => createEnvMock({ COPILOT_API_KEY: 'test-api-key' }))

0 commit comments

Comments
 (0)