Skip to content

Commit 4f464d7

Browse files
authored
test: collapse schema enumeration tests and remove duplicates (#1087)
* test: collapse schema enumeration tests and remove duplicate help text tests Collapse it.each per-value enumeration patterns into consolidated tests across 9 schema test files. Each enum value was tested individually (e.g., 4 separate 'accepts SEMANTIC', 'accepts SUMMARIZATION' tests) -- now represented by 1-2 tests with representative values. Remove deploy/dev --help unit tests (covered by integ-tests/help.test.ts) and 5 it.todo placeholders from credential-ops.test.ts. Schema tests: ~506 -> ~415. All cross-field validation, superRefine, boundary, and discriminated union tests preserved. * fix: address review comments — restore help tests and add .options assertions - Restore deploy --help and dev --help flag-level assertions (integ smoke test only checks exit code and "Usage:", not specific flags) - Restore --invoke negative regression guard in dev.test.ts - Replace representative-sample enum tests with .options assertions for AgentCoreRegionSchema and GatewayTargetTypeSchema (catches accidental removal of enum values)
1 parent e9066ce commit 4f464d7

12 files changed

Lines changed: 158 additions & 376 deletions

File tree

src/cli/commands/deploy/__tests__/deploy.test.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,14 @@ import { join } from 'node:path';
66
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
77

88
describe('deploy --help', () => {
9-
it('shows verbose option', async () => {
10-
const result = await runCLI(['deploy', '--help'], process.cwd());
11-
expect(result.exitCode).toBe(0);
12-
expect(result.stdout.includes('--verbose'), 'Should show --verbose option').toBeTruthy();
13-
expect(result.stdout.includes('resource-level'), 'Should describe resource-level events').toBeTruthy();
14-
});
15-
169
it('shows all deploy options', async () => {
1710
const result = await runCLI(['deploy', '--help'], process.cwd());
11+
expect(result.exitCode).toBe(0);
1812
expect(result.stdout.includes('--yes')).toBeTruthy();
1913
expect(result.stdout.includes('--verbose')).toBeTruthy();
2014
expect(result.stdout.includes('--json')).toBeTruthy();
2115
expect(result.stdout.includes('--dry-run')).toBeTruthy();
16+
expect(result.stdout.includes('resource-level'), 'Should describe resource-level events').toBeTruthy();
2217
});
2318
});
2419

src/cli/commands/dev/__tests__/dev.test.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,5 @@ describe('dev command', () => {
7474

7575
expect(result.exitCode).toBe(1);
7676
});
77-
78-
it('stream flag is documented in help', async () => {
79-
const result = await runCLI(['dev', '--help'], process.cwd());
80-
81-
expect(result.exitCode).toBe(0);
82-
expect(result.stdout.includes('--stream'), 'Should show --stream option').toBeTruthy();
83-
});
8477
});
8578
});

src/cli/operations/identity/__tests__/credential-ops.test.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -147,20 +147,3 @@ describe('resolveCredentialStrategy', () => {
147147
expect(result.isAgentScoped).toBe(true);
148148
});
149149
});
150-
151-
// TODO: OAuth credential creation needs to be added to CredentialPrimitive.
152-
// These tests were ported from main's create-identity.ts OAuth support.
153-
// Once CredentialPrimitive.addOAuth() is implemented, convert these to use primitive.addOAuth().
154-
describe('createCredential OAuth', () => {
155-
afterEach(() => vi.clearAllMocks());
156-
157-
it.todo('creates OAuth credential and writes to project');
158-
159-
it.todo('writes CLIENT_ID and CLIENT_SECRET to env');
160-
161-
it.todo('uppercases name in env var keys');
162-
163-
it.todo('throws when OAuth credential already exists');
164-
165-
it.todo('includes scopes when provided');
166-
});

src/schema/__tests__/constants.test.ts

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -39,72 +39,45 @@ describe('matchEnumValue', () => {
3939
});
4040

4141
describe('SDKFrameworkSchema', () => {
42-
it.each(['Strands', 'LangChain_LangGraph', 'GoogleADK', 'OpenAIAgents'])('accepts "%s"', framework => {
43-
expect(SDKFrameworkSchema.safeParse(framework).success).toBe(true);
44-
});
45-
46-
it('rejects invalid framework', () => {
42+
it('accepts valid frameworks and rejects invalid', () => {
43+
expect(SDKFrameworkSchema.safeParse('Strands').success).toBe(true);
44+
expect(SDKFrameworkSchema.safeParse('OpenAIAgents').success).toBe(true);
4745
expect(SDKFrameworkSchema.safeParse('AutoGen').success).toBe(false);
4846
expect(SDKFrameworkSchema.safeParse('strands').success).toBe(false); // case-sensitive
4947
});
5048
});
5149

5250
describe('ModelProviderSchema', () => {
53-
it.each(['Bedrock', 'Gemini', 'OpenAI', 'Anthropic'])('accepts "%s"', provider => {
54-
expect(ModelProviderSchema.safeParse(provider).success).toBe(true);
55-
});
56-
57-
it('rejects invalid provider', () => {
51+
it('accepts valid providers and rejects invalid', () => {
52+
expect(ModelProviderSchema.safeParse('Bedrock').success).toBe(true);
53+
expect(ModelProviderSchema.safeParse('Anthropic').success).toBe(true);
5854
expect(ModelProviderSchema.safeParse('Azure').success).toBe(false);
5955
});
6056
});
6157

62-
describe('PythonRuntimeSchema', () => {
63-
it.each(['PYTHON_3_10', 'PYTHON_3_11', 'PYTHON_3_12', 'PYTHON_3_13', 'PYTHON_3_14'])('accepts "%s"', version => {
64-
expect(PythonRuntimeSchema.safeParse(version).success).toBe(true);
58+
describe('RuntimeVersionSchemas', () => {
59+
it('accepts valid Python and Node versions', () => {
60+
expect(PythonRuntimeSchema.safeParse('PYTHON_3_10').success).toBe(true);
61+
expect(PythonRuntimeSchema.safeParse('PYTHON_3_14').success).toBe(true);
62+
expect(NodeRuntimeSchema.safeParse('NODE_18').success).toBe(true);
63+
expect(NodeRuntimeSchema.safeParse('NODE_22').success).toBe(true);
64+
expect(RuntimeVersionSchema.safeParse('PYTHON_3_12').success).toBe(true);
65+
expect(RuntimeVersionSchema.safeParse('NODE_20').success).toBe(true);
6566
});
6667

67-
it('rejects unsupported versions', () => {
68+
it('rejects invalid versions', () => {
6869
expect(PythonRuntimeSchema.safeParse('PYTHON_3_9').success).toBe(false);
6970
expect(PythonRuntimeSchema.safeParse('PYTHON_3_15').success).toBe(false);
70-
});
71-
});
72-
73-
describe('NodeRuntimeSchema', () => {
74-
it.each(['NODE_18', 'NODE_20', 'NODE_22'])('accepts "%s"', version => {
75-
expect(NodeRuntimeSchema.safeParse(version).success).toBe(true);
76-
});
77-
78-
it('rejects unsupported versions', () => {
7971
expect(NodeRuntimeSchema.safeParse('NODE_16').success).toBe(false);
8072
expect(NodeRuntimeSchema.safeParse('NODE_24').success).toBe(false);
81-
});
82-
});
83-
84-
describe('RuntimeVersionSchema', () => {
85-
it('accepts Python versions', () => {
86-
expect(RuntimeVersionSchema.safeParse('PYTHON_3_12').success).toBe(true);
87-
});
88-
89-
it('accepts Node versions', () => {
90-
expect(RuntimeVersionSchema.safeParse('NODE_20').success).toBe(true);
91-
});
92-
93-
it('rejects invalid versions', () => {
9473
expect(RuntimeVersionSchema.safeParse('RUBY_3_0').success).toBe(false);
9574
});
9675
});
9776

9877
describe('NetworkModeSchema', () => {
99-
it('accepts PUBLIC', () => {
78+
it('accepts valid modes and rejects invalid', () => {
10079
expect(NetworkModeSchema.safeParse('PUBLIC').success).toBe(true);
101-
});
102-
103-
it('accepts VPC', () => {
10480
expect(NetworkModeSchema.safeParse('VPC').success).toBe(true);
105-
});
106-
107-
it('rejects other modes', () => {
10881
expect(NetworkModeSchema.safeParse('PRIVATE').success).toBe(false);
10982
});
11083
});

src/schema/schemas/__tests__/agent-env.test.ts

Lines changed: 46 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -15,72 +15,41 @@ import {
1515
import { describe, expect, it } from 'vitest';
1616

1717
describe('AgentNameSchema', () => {
18-
it.each(['Agent1', 'myAgent', 'A', 'agent_with_underscores', 'a' + '0'.repeat(47)])(
19-
'accepts valid name "%s"',
20-
name => {
21-
expect(AgentNameSchema.safeParse(name).success).toBe(true);
22-
}
23-
);
24-
25-
it('rejects empty string', () => {
26-
expect(AgentNameSchema.safeParse('').success).toBe(false);
18+
it('accepts valid names', () => {
19+
expect(AgentNameSchema.safeParse('Agent1').success).toBe(true);
20+
expect(AgentNameSchema.safeParse('A').success).toBe(true);
21+
expect(AgentNameSchema.safeParse('agent_with_underscores').success).toBe(true);
2722
});
2823

29-
it('rejects name starting with digit', () => {
24+
it('rejects invalid names', () => {
25+
expect(AgentNameSchema.safeParse('').success).toBe(false);
3026
expect(AgentNameSchema.safeParse('1Agent').success).toBe(false);
31-
});
32-
33-
it('rejects name with hyphens', () => {
3427
expect(AgentNameSchema.safeParse('my-agent').success).toBe(false);
3528
});
3629

37-
it('rejects name exceeding 48 chars', () => {
38-
const name = 'A' + 'b'.repeat(48);
39-
expect(name).toHaveLength(49);
40-
expect(AgentNameSchema.safeParse(name).success).toBe(false);
41-
});
42-
43-
it('accepts 48-char name (max)', () => {
44-
const name = 'A' + 'b'.repeat(47);
45-
expect(name).toHaveLength(48);
46-
expect(AgentNameSchema.safeParse(name).success).toBe(true);
30+
it('enforces 48-char boundary', () => {
31+
expect(AgentNameSchema.safeParse('A' + 'b'.repeat(47)).success).toBe(true);
32+
expect(AgentNameSchema.safeParse('A' + 'b'.repeat(48)).success).toBe(false);
4733
});
4834
});
4935

5036
describe('EnvVarNameSchema', () => {
51-
it.each(['MY_VAR', '_private', 'UPPER123', 'a', '_'])('accepts valid env var name "%s"', name => {
52-
expect(EnvVarNameSchema.safeParse(name).success).toBe(true);
53-
});
54-
55-
it('rejects name starting with digit', () => {
37+
it('accepts valid env var names and rejects invalid', () => {
38+
expect(EnvVarNameSchema.safeParse('MY_VAR').success).toBe(true);
39+
expect(EnvVarNameSchema.safeParse('_private').success).toBe(true);
5640
expect(EnvVarNameSchema.safeParse('1VAR').success).toBe(false);
57-
});
58-
59-
it('rejects name with hyphens', () => {
6041
expect(EnvVarNameSchema.safeParse('MY-VAR').success).toBe(false);
61-
});
62-
63-
it('rejects empty string', () => {
6442
expect(EnvVarNameSchema.safeParse('').success).toBe(false);
6543
});
6644
});
6745

6846
describe('GatewayNameSchema', () => {
69-
it.each(['gateway1', 'my-gateway', 'MyGateway', 'a'])('accepts valid gateway name "%s"', name => {
70-
expect(GatewayNameSchema.safeParse(name).success).toBe(true);
71-
});
72-
73-
it('rejects empty string', () => {
47+
it('accepts valid names and rejects invalid', () => {
48+
expect(GatewayNameSchema.safeParse('gateway1').success).toBe(true);
49+
expect(GatewayNameSchema.safeParse('my-gateway').success).toBe(true);
7450
expect(GatewayNameSchema.safeParse('').success).toBe(false);
75-
});
76-
77-
it('rejects name with underscores', () => {
7851
expect(GatewayNameSchema.safeParse('my_gateway').success).toBe(false);
79-
});
80-
81-
it('rejects name exceeding 100 chars', () => {
82-
const name = 'a'.repeat(101);
83-
expect(GatewayNameSchema.safeParse(name).success).toBe(false);
52+
expect(GatewayNameSchema.safeParse('a'.repeat(101)).success).toBe(false);
8453
});
8554
});
8655

@@ -288,9 +257,10 @@ describe('AgentEnvSpecSchema', () => {
288257
});
289258

290259
describe('protocol', () => {
291-
it.each(['HTTP', 'MCP', 'A2A', 'AGUI'])('accepts valid protocol "%s"', mode => {
292-
const result = AgentEnvSpecSchema.safeParse({ ...validPythonAgent, protocol: mode });
293-
expect(result.success, `Should accept protocol ${mode}`).toBe(true);
260+
it('accepts valid protocols', () => {
261+
expect(AgentEnvSpecSchema.safeParse({ ...validPythonAgent, protocol: 'HTTP' }).success).toBe(true);
262+
expect(AgentEnvSpecSchema.safeParse({ ...validPythonAgent, protocol: 'MCP' }).success).toBe(true);
263+
expect(AgentEnvSpecSchema.safeParse({ ...validPythonAgent, protocol: 'A2A' }).success).toBe(true);
294264
});
295265

296266
it('accepts agent without protocol (backwards compat)', () => {
@@ -300,7 +270,6 @@ describe('AgentEnvSpecSchema', () => {
300270

301271
it('rejects invalid protocol', () => {
302272
expect(AgentEnvSpecSchema.safeParse({ ...validPythonAgent, protocol: 'GRPC' }).success).toBe(false);
303-
expect(AgentEnvSpecSchema.safeParse({ ...validPythonAgent, protocol: 'websocket' }).success).toBe(false);
304273
});
305274
});
306275
});
@@ -439,12 +408,12 @@ describe('AgentEnvSpecSchema - dockerfile', () => {
439408
}
440409
});
441410

442-
it.each(['Dockerfile', 'Dockerfile.dev', 'Dockerfile.gpu-v2', 'my.Dockerfile', 'dockerfile_test'])(
443-
'accepts valid dockerfile name "%s"',
444-
name => {
445-
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: name }).success).toBe(true);
446-
}
447-
);
411+
it('accepts valid dockerfile names', () => {
412+
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: 'Dockerfile' }).success).toBe(true);
413+
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: 'Dockerfile.gpu-v2' }).success).toBe(
414+
true
415+
);
416+
});
448417

449418
it('rejects dockerfile on CodeZip builds', () => {
450419
const result = AgentEnvSpecSchema.safeParse({ ...validCodeZipAgent, dockerfile: 'Dockerfile.custom' });
@@ -454,12 +423,12 @@ describe('AgentEnvSpecSchema - dockerfile', () => {
454423
}
455424
});
456425

457-
it.each(['../Dockerfile', '/etc/Dockerfile', 'path/to/Dockerfile', '.hidden'])(
458-
'rejects path traversal or path separator in dockerfile "%s"',
459-
name => {
460-
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: name }).success).toBe(false);
461-
}
462-
);
426+
it('rejects path traversal or path separator in dockerfile', () => {
427+
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: '../Dockerfile' }).success).toBe(false);
428+
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: 'path/to/Dockerfile' }).success).toBe(
429+
false
430+
);
431+
});
463432

464433
it('rejects empty string dockerfile', () => {
465434
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: '' }).success).toBe(false);
@@ -481,12 +450,12 @@ describe('AgentEnvSpecSchema - dockerfile', () => {
481450
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: maxName }).success).toBe(true);
482451
});
483452

484-
it.each(['\\\\server\\share', 'Dockerfile\\..\\secret', '..\\Dockerfile'])(
485-
'rejects backslash path traversal in dockerfile "%s"',
486-
name => {
487-
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: name }).success).toBe(false);
488-
}
489-
);
453+
it('rejects backslash path traversal in dockerfile', () => {
454+
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: '\\\\server\\share' }).success).toBe(
455+
false
456+
);
457+
expect(AgentEnvSpecSchema.safeParse({ ...validContainerAgent, dockerfile: '..\\Dockerfile' }).success).toBe(false);
458+
});
490459
});
491460

492461
describe('AgentEnvSpecSchema - lifecycleConfiguration', () => {
@@ -544,34 +513,21 @@ describe('AgentEnvSpecSchema - lifecycleConfiguration', () => {
544513
});
545514

546515
describe('RuntimeEndpointNameSchema', () => {
547-
it.each(['prod', 'staging', 'myEndpoint', 'v1', 'A', 'a' + '0'.repeat(47)])(
548-
'accepts valid endpoint name "%s"',
549-
name => {
550-
expect(RuntimeEndpointNameSchema.safeParse(name).success).toBe(true);
551-
}
552-
);
553-
554-
it('rejects empty string', () => {
555-
expect(RuntimeEndpointNameSchema.safeParse('').success).toBe(false);
516+
it('accepts valid names', () => {
517+
expect(RuntimeEndpointNameSchema.safeParse('prod').success).toBe(true);
518+
expect(RuntimeEndpointNameSchema.safeParse('myEndpoint').success).toBe(true);
556519
});
557520

558-
it('rejects name starting with digit', () => {
521+
it('rejects invalid names', () => {
522+
expect(RuntimeEndpointNameSchema.safeParse('').success).toBe(false);
559523
expect(RuntimeEndpointNameSchema.safeParse('1prod').success).toBe(false);
560-
});
561-
562-
it('rejects name with hyphens', () => {
563524
expect(RuntimeEndpointNameSchema.safeParse('my-endpoint').success).toBe(false);
564-
});
565-
566-
it('rejects name with special characters', () => {
567525
expect(RuntimeEndpointNameSchema.safeParse('prod!').success).toBe(false);
568-
expect(RuntimeEndpointNameSchema.safeParse('my@endpoint').success).toBe(false);
569526
});
570527

571-
it('rejects name exceeding 48 chars', () => {
572-
const name = 'A' + 'b'.repeat(48);
573-
expect(name).toHaveLength(49);
574-
expect(RuntimeEndpointNameSchema.safeParse(name).success).toBe(false);
528+
it('enforces 48-char boundary', () => {
529+
expect(RuntimeEndpointNameSchema.safeParse('A' + 'b'.repeat(47)).success).toBe(true);
530+
expect(RuntimeEndpointNameSchema.safeParse('A' + 'b'.repeat(48)).success).toBe(false);
575531
});
576532
});
577533

0 commit comments

Comments
 (0)