Skip to content

Commit 5f455d1

Browse files
waleedlatif1claude
andcommitted
test(cloudtrail): cover comma-separated input splitting at the tool boundary
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LJV2dCcAYvf1JuxquCMZAd
1 parent f37cbeb commit 5f455d1

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* @vitest-environment node
3+
*
4+
* The CloudTrail block collects `trailNameList`, `resourceIdList`, and `queryParameters` as
5+
* comma-separated strings, while their contracts require arrays. `operation.input` is the seam
6+
* that converts them, and it runs before contract validation, so these fields must arrive at the
7+
* contract already split. Regressing this would 400 every request that uses them.
8+
*/
9+
import { describe, expect, it } from 'vitest'
10+
import { describeTrailsTool } from '@/tools/cloudtrail/describe_trails'
11+
import { listTagsTool } from '@/tools/cloudtrail/list_tags'
12+
import { startQueryTool } from '@/tools/cloudtrail/start_query'
13+
14+
const CONNECTION = {
15+
awsRegion: 'us-east-1',
16+
awsAccessKeyId: 'AKIAIOSFODNN7EXAMPLE',
17+
awsSecretAccessKey: 'secret',
18+
}
19+
20+
const TRAIL_ARN = 'arn:aws:cloudtrail:us-east-1:123456789012:trail/audit-trail'
21+
22+
describe('cloudtrail operation input', () => {
23+
it('splits comma-separated trail names for describe_trails', () => {
24+
const input = describeTrailsTool.operation.input({
25+
...CONNECTION,
26+
trailNameList: 'audit-trail, security-trail',
27+
})
28+
29+
expect(input.trailNameList).toEqual(['audit-trail', 'security-trail'])
30+
})
31+
32+
it('omits trailNameList entirely when it is blank', () => {
33+
const input = describeTrailsTool.operation.input({ ...CONNECTION, trailNameList: ' ' })
34+
35+
expect(input.trailNameList).toBeUndefined()
36+
})
37+
38+
it('splits comma-separated resource ARNs for list_tags', () => {
39+
const input = listTagsTool.operation.input({
40+
...CONNECTION,
41+
resourceIdList: `${TRAIL_ARN},${TRAIL_ARN}`,
42+
})
43+
44+
expect(input.resourceIdList).toEqual([TRAIL_ARN, TRAIL_ARN])
45+
})
46+
47+
it('splits comma-separated query template parameters for start_query', () => {
48+
const input = startQueryTool.operation.input({
49+
...CONNECTION,
50+
queryAlias: 'top-errors',
51+
queryParameters: 'us-east-1, 2026-01-01',
52+
})
53+
54+
expect(input.queryParameters).toEqual(['us-east-1', '2026-01-01'])
55+
})
56+
})

0 commit comments

Comments
 (0)