@postman-cse/onboarding-bootstrap 0.9.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/contract-smoke.yml +155 -0
- package/.omc/sessions/b36ac16d-ce26-4e94-ae7e-dd817f2430a3.json +8 -0
- package/CLAUDE.md +57 -0
- package/README.md +133 -12
- package/action.yml +21 -18
- package/dist/cli.cjs +370 -518
- package/dist/index.cjs +364 -509
- package/package.json +3 -2
- package/src/cli.ts +6 -11
- package/src/contracts.ts +30 -24
- package/src/index.ts +302 -322
- package/src/lib/postman/internal-integration-adapter.ts +116 -30
- package/src/lib/postman/postman-assets-client.ts +27 -4
- package/tests/bootstrap-action.test.ts +647 -77
- package/tests/cli.test.ts +15 -6
- package/tests/contract.test.ts +28 -3
- package/tests/internal-integration-adapter.test.ts +69 -0
- package/tests/postman-assets-client.test.ts +153 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { stringify as stringifyYaml } from 'yaml';
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
4
|
|
|
3
5
|
import {
|
|
4
6
|
lintSpecViaCli,
|
|
@@ -58,21 +60,24 @@ function createCoreStub(values: Record<string, string> = {}) {
|
|
|
58
60
|
function createInputs(overrides: Partial<ResolvedInputs> = {}): ResolvedInputs {
|
|
59
61
|
return {
|
|
60
62
|
projectName: 'core-payments',
|
|
63
|
+
syncExamples: true,
|
|
64
|
+
collectionSyncMode: 'refresh',
|
|
65
|
+
specSyncMode: 'update',
|
|
66
|
+
releaseLabel: undefined,
|
|
61
67
|
domain: 'core-banking',
|
|
62
68
|
domainCode: 'AF',
|
|
63
69
|
requesterEmail: 'owner@example.com',
|
|
64
70
|
workspaceAdminUserIds: '101,102',
|
|
65
71
|
repoUrl: 'https://github.com/postman-cs/bootstrap-action-test',
|
|
66
72
|
specUrl: 'https://example.test/openapi.yaml',
|
|
67
|
-
environmentsJson: '["prod","stage"]',
|
|
68
|
-
systemEnvMapJson: '{"prod":"sys-prod","stage":"sys-stage"}',
|
|
69
73
|
governanceMappingJson: '{"core-banking":"Core Banking"}',
|
|
70
74
|
postmanApiKey: 'pmak-test',
|
|
71
75
|
postmanAccessToken: 'postman-access-token',
|
|
72
|
-
githubToken: 'github-token',
|
|
73
|
-
ghFallbackToken: 'github-fallback-token',
|
|
74
|
-
githubAuthMode: 'github_token_first',
|
|
75
76
|
integrationBackend: 'bifrost',
|
|
77
|
+
githubRefName: undefined,
|
|
78
|
+
githubHeadRef: undefined,
|
|
79
|
+
githubRef: undefined,
|
|
80
|
+
githubSha: undefined,
|
|
76
81
|
...overrides
|
|
77
82
|
};
|
|
78
83
|
}
|
|
@@ -95,14 +100,16 @@ function createIoStub(): IOLike {
|
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
describe('bootstrap action', () => {
|
|
103
|
+
afterEach(() => {
|
|
104
|
+
rmSync('.postman', { recursive: true, force: true });
|
|
105
|
+
});
|
|
106
|
+
|
|
98
107
|
it('marks secrets as early as input resolution', () => {
|
|
99
108
|
const { core, secrets } = createCoreStub({
|
|
100
109
|
'project-name': 'core-payments',
|
|
101
110
|
'spec-url': 'https://example.test/openapi.yaml',
|
|
102
111
|
'postman-api-key': 'pmak-test',
|
|
103
|
-
'postman-access-token': 'postman-access-token'
|
|
104
|
-
'github-token': 'github-token',
|
|
105
|
-
'gh-fallback-token': 'github-fallback-token'
|
|
112
|
+
'postman-access-token': 'postman-access-token'
|
|
106
113
|
});
|
|
107
114
|
|
|
108
115
|
const inputs = readActionInputs(core);
|
|
@@ -110,9 +117,7 @@ describe('bootstrap action', () => {
|
|
|
110
117
|
expect(inputs.postmanApiKey).toBe('pmak-test');
|
|
111
118
|
expect(secrets).toEqual([
|
|
112
119
|
'pmak-test',
|
|
113
|
-
'postman-access-token'
|
|
114
|
-
'github-token',
|
|
115
|
-
'github-fallback-token'
|
|
120
|
+
'postman-access-token'
|
|
116
121
|
]);
|
|
117
122
|
});
|
|
118
123
|
|
|
@@ -134,6 +139,7 @@ describe('bootstrap action', () => {
|
|
|
134
139
|
return 'col-contract';
|
|
135
140
|
}),
|
|
136
141
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
142
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
137
143
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
138
144
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
139
145
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -143,11 +149,9 @@ describe('bootstrap action', () => {
|
|
|
143
149
|
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
144
150
|
};
|
|
145
151
|
const internalIntegration = {
|
|
146
|
-
assignWorkspaceToGovernanceGroup: vi.fn().mockResolvedValue(undefined)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
setRepositoryVariable: vi.fn().mockResolvedValue(undefined),
|
|
150
|
-
getRepositoryVariable: vi.fn().mockResolvedValue('')
|
|
152
|
+
assignWorkspaceToGovernanceGroup: vi.fn().mockResolvedValue(undefined),
|
|
153
|
+
linkCollectionsToSpecification: vi.fn().mockResolvedValue(undefined),
|
|
154
|
+
syncCollection: vi.fn().mockResolvedValue(undefined)
|
|
151
155
|
};
|
|
152
156
|
const specFetcher = vi.fn<typeof fetch>().mockResolvedValue(
|
|
153
157
|
new Response('openapi: 3.1.0', {
|
|
@@ -158,7 +162,6 @@ describe('bootstrap action', () => {
|
|
|
158
162
|
const result = await runBootstrap(createInputs(), {
|
|
159
163
|
core,
|
|
160
164
|
exec: execStub,
|
|
161
|
-
github,
|
|
162
165
|
io: ioStub,
|
|
163
166
|
internalIntegration,
|
|
164
167
|
postman,
|
|
@@ -177,21 +180,28 @@ describe('bootstrap action', () => {
|
|
|
177
180
|
);
|
|
178
181
|
expect(postman.addAdminsToWorkspace).toHaveBeenCalledWith('ws-123', '101,102');
|
|
179
182
|
expect(order).toEqual(['[Baseline]', '[Smoke]', '[Contract]']);
|
|
180
|
-
expect(
|
|
181
|
-
'
|
|
182
|
-
|
|
183
|
+
expect(internalIntegration.linkCollectionsToSpecification).toHaveBeenCalledWith(
|
|
184
|
+
'spec-123',
|
|
185
|
+
[
|
|
186
|
+
{ collectionId: 'col-baseline', syncOptions: { syncExamples: true } },
|
|
187
|
+
{ collectionId: 'col-smoke', syncOptions: { syncExamples: true } },
|
|
188
|
+
{ collectionId: 'col-contract', syncOptions: { syncExamples: true } }
|
|
189
|
+
]
|
|
183
190
|
);
|
|
184
|
-
expect(
|
|
185
|
-
|
|
186
|
-
'
|
|
191
|
+
expect(internalIntegration.syncCollection).toHaveBeenNthCalledWith(
|
|
192
|
+
1,
|
|
193
|
+
'spec-123',
|
|
194
|
+
'col-baseline'
|
|
187
195
|
);
|
|
188
|
-
expect(
|
|
189
|
-
|
|
190
|
-
'
|
|
196
|
+
expect(internalIntegration.syncCollection).toHaveBeenNthCalledWith(
|
|
197
|
+
2,
|
|
198
|
+
'spec-123',
|
|
199
|
+
'col-smoke'
|
|
191
200
|
);
|
|
192
|
-
expect(
|
|
193
|
-
|
|
194
|
-
'
|
|
201
|
+
expect(internalIntegration.syncCollection).toHaveBeenNthCalledWith(
|
|
202
|
+
3,
|
|
203
|
+
'spec-123',
|
|
204
|
+
'col-contract'
|
|
195
205
|
);
|
|
196
206
|
expect(result).toMatchObject({
|
|
197
207
|
'workspace-id': 'ws-123',
|
|
@@ -238,6 +248,7 @@ describe('bootstrap action', () => {
|
|
|
238
248
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
239
249
|
generateCollection: vi.fn(),
|
|
240
250
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
251
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
241
252
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
242
253
|
injectTests: vi.fn(),
|
|
243
254
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -282,6 +293,7 @@ describe('bootstrap action', () => {
|
|
|
282
293
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
283
294
|
generateCollection: vi.fn(),
|
|
284
295
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
296
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
285
297
|
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.0.0\ninfo:\n title: old\n'),
|
|
286
298
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
287
299
|
injectTests: vi.fn(),
|
|
@@ -331,6 +343,7 @@ describe('bootstrap action', () => {
|
|
|
331
343
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
332
344
|
generateCollection: vi.fn(),
|
|
333
345
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
346
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
334
347
|
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0'),
|
|
335
348
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
336
349
|
injectTests: vi.fn(),
|
|
@@ -366,6 +379,7 @@ describe('bootstrap action', () => {
|
|
|
366
379
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
367
380
|
generateCollection: vi.fn(),
|
|
368
381
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
382
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
369
383
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
370
384
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
371
385
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -374,23 +388,18 @@ describe('bootstrap action', () => {
|
|
|
374
388
|
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
375
389
|
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
376
390
|
};
|
|
377
|
-
const github = {
|
|
378
|
-
setRepositoryVariable: vi.fn().mockResolvedValue(undefined),
|
|
379
|
-
getRepositoryVariable: vi.fn()
|
|
380
|
-
};
|
|
381
|
-
|
|
382
391
|
const result = await runBootstrap(
|
|
383
392
|
createInputs({
|
|
384
393
|
workspaceId: 'ws-existing',
|
|
385
394
|
specId: 'spec-existing',
|
|
386
395
|
baselineCollectionId: 'col-baseline-existing',
|
|
387
396
|
smokeCollectionId: 'col-smoke-existing',
|
|
388
|
-
contractCollectionId: 'col-contract-existing'
|
|
397
|
+
contractCollectionId: 'col-contract-existing',
|
|
398
|
+
collectionSyncMode: 'reuse'
|
|
389
399
|
}),
|
|
390
400
|
{
|
|
391
401
|
core,
|
|
392
402
|
exec: execStub,
|
|
393
|
-
github,
|
|
394
403
|
io: ioStub,
|
|
395
404
|
postman,
|
|
396
405
|
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
@@ -399,7 +408,6 @@ describe('bootstrap action', () => {
|
|
|
399
408
|
}
|
|
400
409
|
);
|
|
401
410
|
|
|
402
|
-
expect(github.getRepositoryVariable).not.toHaveBeenCalled();
|
|
403
411
|
expect(postman.createWorkspace).not.toHaveBeenCalled();
|
|
404
412
|
expect(postman.uploadSpec).not.toHaveBeenCalled();
|
|
405
413
|
expect(postman.generateCollection).not.toHaveBeenCalled();
|
|
@@ -424,7 +432,57 @@ describe('bootstrap action', () => {
|
|
|
424
432
|
expect(infos).toContain('Using existing contract collection: col-contract-existing');
|
|
425
433
|
});
|
|
426
434
|
|
|
427
|
-
it('
|
|
435
|
+
it('refresh mode regenerates collections even when ids already exist', async () => {
|
|
436
|
+
const { core } = createCoreStub();
|
|
437
|
+
const execStub = createExecStub();
|
|
438
|
+
const ioStub = createIoStub();
|
|
439
|
+
const generatedIds = ['col-baseline-refresh', 'col-smoke-refresh', 'col-contract-refresh'];
|
|
440
|
+
const postman = {
|
|
441
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
442
|
+
createWorkspace: vi.fn(),
|
|
443
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
444
|
+
generateCollection: vi
|
|
445
|
+
.fn()
|
|
446
|
+
.mockImplementation(async () => generatedIds.shift() || 'col-fallback'),
|
|
447
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
448
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
449
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
450
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
451
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
452
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
453
|
+
uploadSpec: vi.fn(),
|
|
454
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
455
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
456
|
+
};
|
|
457
|
+
const result = await runBootstrap(
|
|
458
|
+
createInputs({
|
|
459
|
+
workspaceId: 'ws-existing',
|
|
460
|
+
specId: 'spec-existing',
|
|
461
|
+
baselineCollectionId: 'col-baseline-existing',
|
|
462
|
+
smokeCollectionId: 'col-smoke-existing',
|
|
463
|
+
contractCollectionId: 'col-contract-existing',
|
|
464
|
+
collectionSyncMode: 'refresh',
|
|
465
|
+
}),
|
|
466
|
+
{
|
|
467
|
+
core,
|
|
468
|
+
exec: execStub,
|
|
469
|
+
io: ioStub,
|
|
470
|
+
postman,
|
|
471
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
472
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
473
|
+
)
|
|
474
|
+
}
|
|
475
|
+
);
|
|
476
|
+
|
|
477
|
+
expect(postman.generateCollection).toHaveBeenCalledTimes(3);
|
|
478
|
+
expect(result).toMatchObject({
|
|
479
|
+
'baseline-collection-id': 'col-baseline-refresh',
|
|
480
|
+
'smoke-collection-id': 'col-smoke-refresh',
|
|
481
|
+
'contract-collection-id': 'col-contract-refresh'
|
|
482
|
+
});
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
it('version mode reuses the current ref resources.yaml mappings instead of a release manifest', async () => {
|
|
428
486
|
const { core } = createCoreStub();
|
|
429
487
|
const execStub = createExecStub();
|
|
430
488
|
const ioStub = createIoStub();
|
|
@@ -434,6 +492,7 @@ describe('bootstrap action', () => {
|
|
|
434
492
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
435
493
|
generateCollection: vi.fn(),
|
|
436
494
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
495
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
437
496
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
438
497
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
439
498
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -442,24 +501,190 @@ describe('bootstrap action', () => {
|
|
|
442
501
|
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
443
502
|
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
444
503
|
};
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
504
|
+
mkdirSync('.postman', { recursive: true });
|
|
505
|
+
writeFileSync(
|
|
506
|
+
'.postman/resources.yaml',
|
|
507
|
+
stringifyYaml({
|
|
508
|
+
workspace: { id: 'ws-existing' },
|
|
509
|
+
cloudResources: {
|
|
510
|
+
specs: { '../index.yaml': 'spec-v111' },
|
|
511
|
+
collections: {
|
|
512
|
+
'../postman/collections/[Baseline] core-payments release-v1.1.1': 'col-baseline-v111',
|
|
513
|
+
'../postman/collections/[Smoke] core-payments release-v1.1.1': 'col-smoke-v111',
|
|
514
|
+
'../postman/collections/[Contract] core-payments release-v1.1.1': 'col-contract-v111'
|
|
515
|
+
}
|
|
516
|
+
}
|
|
456
517
|
})
|
|
518
|
+
);
|
|
519
|
+
const result = await runBootstrap(
|
|
520
|
+
createInputs({
|
|
521
|
+
workspaceId: 'ws-existing',
|
|
522
|
+
collectionSyncMode: 'version',
|
|
523
|
+
specSyncMode: 'version',
|
|
524
|
+
releaseLabel: 'release/v1.1.1',
|
|
525
|
+
githubRefName: 'release/v1.1.1',
|
|
526
|
+
githubSha: 'deadbeef'
|
|
527
|
+
}),
|
|
528
|
+
{
|
|
529
|
+
core,
|
|
530
|
+
exec: execStub,
|
|
531
|
+
io: ioStub,
|
|
532
|
+
postman,
|
|
533
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
534
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
535
|
+
)
|
|
536
|
+
}
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
expect(postman.updateSpec).toHaveBeenCalledWith(
|
|
540
|
+
'spec-v111',
|
|
541
|
+
'openapi: 3.1.0',
|
|
542
|
+
'ws-existing'
|
|
543
|
+
);
|
|
544
|
+
expect(postman.uploadSpec).not.toHaveBeenCalled();
|
|
545
|
+
expect(postman.generateCollection).not.toHaveBeenCalled();
|
|
546
|
+
expect(result['spec-id']).toBe('spec-v111');
|
|
547
|
+
expect(result['baseline-collection-id']).toBe('col-baseline-v111');
|
|
548
|
+
expect(result['smoke-collection-id']).toBe('col-smoke-v111');
|
|
549
|
+
expect(result['contract-collection-id']).toBe('col-contract-v111');
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
it('version mode does not persist asset identifiers to repository variables', async () => {
|
|
553
|
+
const { core } = createCoreStub();
|
|
554
|
+
const execStub = createExecStub();
|
|
555
|
+
const ioStub = createIoStub();
|
|
556
|
+
const postman = {
|
|
557
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
558
|
+
createWorkspace: vi.fn(),
|
|
559
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
560
|
+
generateCollection: vi
|
|
561
|
+
.fn()
|
|
562
|
+
.mockResolvedValueOnce('col-baseline-v111')
|
|
563
|
+
.mockResolvedValueOnce('col-smoke-v111')
|
|
564
|
+
.mockResolvedValueOnce('col-contract-v111'),
|
|
565
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
566
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
567
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
568
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
569
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
570
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
571
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-v111'),
|
|
572
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
573
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
457
574
|
};
|
|
575
|
+
await runBootstrap(
|
|
576
|
+
createInputs({
|
|
577
|
+
workspaceId: 'ws-existing',
|
|
578
|
+
collectionSyncMode: 'version',
|
|
579
|
+
specSyncMode: 'version',
|
|
580
|
+
releaseLabel: 'v1.1.1',
|
|
581
|
+
githubRefName: 'v1.1.1'
|
|
582
|
+
}),
|
|
583
|
+
{
|
|
584
|
+
core,
|
|
585
|
+
exec: execStub,
|
|
586
|
+
io: ioStub,
|
|
587
|
+
postman,
|
|
588
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
589
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
590
|
+
)
|
|
591
|
+
}
|
|
592
|
+
);
|
|
593
|
+
});
|
|
458
594
|
|
|
459
|
-
|
|
595
|
+
it("version mode doesn't fall back to singleton current spec uid", async () => {
|
|
596
|
+
const { core } = createCoreStub();
|
|
597
|
+
const execStub = createExecStub();
|
|
598
|
+
const ioStub = createIoStub();
|
|
599
|
+
const postman = {
|
|
600
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
601
|
+
createWorkspace: vi.fn(),
|
|
602
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
603
|
+
generateCollection: vi
|
|
604
|
+
.fn()
|
|
605
|
+
.mockResolvedValueOnce('col-baseline-v112')
|
|
606
|
+
.mockResolvedValueOnce('col-smoke-v112')
|
|
607
|
+
.mockResolvedValueOnce('col-contract-v112'),
|
|
608
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
609
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
610
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
611
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
612
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
613
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
614
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-v112'),
|
|
615
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
616
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
617
|
+
};
|
|
618
|
+
const result = await runBootstrap(
|
|
619
|
+
createInputs({
|
|
620
|
+
workspaceId: 'ws-existing',
|
|
621
|
+
collectionSyncMode: 'version',
|
|
622
|
+
specSyncMode: 'version',
|
|
623
|
+
releaseLabel: 'v1.1.2',
|
|
624
|
+
githubRefName: 'v1.1.2'
|
|
625
|
+
}),
|
|
626
|
+
{
|
|
627
|
+
core,
|
|
628
|
+
exec: execStub,
|
|
629
|
+
io: ioStub,
|
|
630
|
+
postman,
|
|
631
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
632
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
633
|
+
)
|
|
634
|
+
}
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
expect(postman.updateSpec).not.toHaveBeenCalledWith(
|
|
638
|
+
'spec-current',
|
|
639
|
+
'openapi: 3.1.0',
|
|
640
|
+
'ws-existing'
|
|
641
|
+
);
|
|
642
|
+
expect(postman.uploadSpec).toHaveBeenCalledWith(
|
|
643
|
+
'ws-existing',
|
|
644
|
+
'core-payments v1.1.2',
|
|
645
|
+
'openapi: 3.1.0'
|
|
646
|
+
);
|
|
647
|
+
expect(result['spec-id']).toBe('spec-v112');
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
it('reuses .postman/resources.yaml for reruns before creating new assets', async () => {
|
|
651
|
+
const { core } = createCoreStub();
|
|
652
|
+
const execStub = createExecStub();
|
|
653
|
+
const ioStub = createIoStub();
|
|
654
|
+
const postman = {
|
|
655
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
656
|
+
createWorkspace: vi.fn(),
|
|
657
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
658
|
+
generateCollection: vi.fn(),
|
|
659
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
660
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
661
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
662
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
663
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
664
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
665
|
+
uploadSpec: vi.fn(),
|
|
666
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
667
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
668
|
+
};
|
|
669
|
+
mkdirSync('.postman', { recursive: true });
|
|
670
|
+
writeFileSync(
|
|
671
|
+
'.postman/resources.yaml',
|
|
672
|
+
stringifyYaml({
|
|
673
|
+
workspace: { id: 'ws-from-file' },
|
|
674
|
+
cloudResources: {
|
|
675
|
+
specs: { '../index.yaml': 'spec-from-file' },
|
|
676
|
+
collections: {
|
|
677
|
+
'../postman/collections/[Baseline] core-payments': 'col-baseline-from-file',
|
|
678
|
+
'../postman/collections/[Smoke] core-payments': 'col-smoke-from-file',
|
|
679
|
+
'../postman/collections/[Contract] core-payments': 'col-contract-from-file'
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
})
|
|
683
|
+
);
|
|
684
|
+
|
|
685
|
+
const result = await runBootstrap(createInputs({ collectionSyncMode: 'reuse' }), {
|
|
460
686
|
core,
|
|
461
687
|
exec: execStub,
|
|
462
|
-
github,
|
|
463
688
|
io: ioStub,
|
|
464
689
|
postman,
|
|
465
690
|
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
@@ -470,19 +695,17 @@ describe('bootstrap action', () => {
|
|
|
470
695
|
expect(postman.createWorkspace).not.toHaveBeenCalled();
|
|
471
696
|
expect(postman.uploadSpec).not.toHaveBeenCalled();
|
|
472
697
|
expect(postman.generateCollection).not.toHaveBeenCalled();
|
|
473
|
-
expect(postman.updateSpec).toHaveBeenCalledWith('spec-from-
|
|
474
|
-
expect(github.getRepositoryVariable).toHaveBeenCalledWith('POSTMAN_CORE_PAYMENTS_WORKSPACE_ID');
|
|
475
|
-
expect(github.getRepositoryVariable).toHaveBeenCalledWith('POSTMAN_WORKSPACE_ID');
|
|
698
|
+
expect(postman.updateSpec).toHaveBeenCalledWith('spec-from-file', 'openapi: 3.1.0', 'ws-from-file');
|
|
476
699
|
expect(result).toMatchObject({
|
|
477
|
-
'workspace-id': 'ws-from-
|
|
478
|
-
'spec-id': 'spec-from-
|
|
479
|
-
'baseline-collection-id': 'col-baseline-from-
|
|
480
|
-
'smoke-collection-id': 'col-smoke-from-
|
|
481
|
-
'contract-collection-id': 'col-contract-from-
|
|
700
|
+
'workspace-id': 'ws-from-file',
|
|
701
|
+
'spec-id': 'spec-from-file',
|
|
702
|
+
'baseline-collection-id': 'col-baseline-from-file',
|
|
703
|
+
'smoke-collection-id': 'col-smoke-from-file',
|
|
704
|
+
'contract-collection-id': 'col-contract-from-file'
|
|
482
705
|
});
|
|
483
706
|
});
|
|
484
707
|
|
|
485
|
-
it('
|
|
708
|
+
it('ignores repository-variable asset state when .postman/resources.yaml is absent', async () => {
|
|
486
709
|
const previousRepository = process.env.GITHUB_REPOSITORY;
|
|
487
710
|
process.env.GITHUB_REPOSITORY = 'postman-cs/bootstrap-action-test';
|
|
488
711
|
|
|
@@ -502,6 +725,7 @@ describe('bootstrap action', () => {
|
|
|
502
725
|
return 'col-contract';
|
|
503
726
|
}),
|
|
504
727
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
728
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
505
729
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue('https://github.com/postman-cs/different-repo'),
|
|
506
730
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
507
731
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -510,20 +734,9 @@ describe('bootstrap action', () => {
|
|
|
510
734
|
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
511
735
|
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
512
736
|
};
|
|
513
|
-
const github = {
|
|
514
|
-
setRepositoryVariable: vi.fn().mockResolvedValue(undefined),
|
|
515
|
-
getRepositoryVariable: vi.fn(async (name: string) => {
|
|
516
|
-
const values: Record<string, string> = {
|
|
517
|
-
POSTMAN_WORKSPACE_ID: 'ws-from-vars'
|
|
518
|
-
};
|
|
519
|
-
return values[name] ?? '';
|
|
520
|
-
})
|
|
521
|
-
};
|
|
522
|
-
|
|
523
737
|
const result = await runBootstrap(createInputs(), {
|
|
524
738
|
core,
|
|
525
739
|
exec: execStub,
|
|
526
|
-
github,
|
|
527
740
|
io: ioStub,
|
|
528
741
|
postman,
|
|
529
742
|
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
@@ -531,10 +744,8 @@ describe('bootstrap action', () => {
|
|
|
531
744
|
)
|
|
532
745
|
});
|
|
533
746
|
|
|
534
|
-
expect(postman.getWorkspaceGitRepoUrl).toHaveBeenCalledWith('ws-from-vars', '12345', 'postman-access-token');
|
|
535
747
|
expect(postman.createWorkspace).toHaveBeenCalled();
|
|
536
748
|
expect(result['workspace-id']).toBe('ws-new');
|
|
537
|
-
expect(postman.updateSpec).not.toHaveBeenCalled();
|
|
538
749
|
} finally {
|
|
539
750
|
if (previousRepository === undefined) {
|
|
540
751
|
delete process.env.GITHUB_REPOSITORY;
|
|
@@ -545,7 +756,7 @@ describe('bootstrap action', () => {
|
|
|
545
756
|
});
|
|
546
757
|
|
|
547
758
|
it('skips governance assignment when postman-access-token is absent', async () => {
|
|
548
|
-
const { core } = createCoreStub();
|
|
759
|
+
const { core, warnings } = createCoreStub();
|
|
549
760
|
const execStub = createExecStub();
|
|
550
761
|
const ioStub = createIoStub();
|
|
551
762
|
const postman = {
|
|
@@ -554,6 +765,7 @@ describe('bootstrap action', () => {
|
|
|
554
765
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
555
766
|
generateCollection: vi.fn().mockResolvedValue('col-id'),
|
|
556
767
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
768
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
557
769
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
558
770
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
559
771
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -578,9 +790,67 @@ describe('bootstrap action', () => {
|
|
|
578
790
|
|
|
579
791
|
expect(result['workspace-id']).toBe('ws-123');
|
|
580
792
|
expect(postman.createWorkspace).toHaveBeenCalled();
|
|
793
|
+
expect(
|
|
794
|
+
warnings.some((warning) =>
|
|
795
|
+
warning.includes('Skipping cloud spec-to-collection linking and sync because postman-access-token is not configured')
|
|
796
|
+
)
|
|
797
|
+
).toBe(true);
|
|
798
|
+
});
|
|
799
|
+
|
|
800
|
+
it('passes syncExamples=false when configured', async () => {
|
|
801
|
+
const { core } = createCoreStub();
|
|
802
|
+
const execStub = createExecStub();
|
|
803
|
+
const ioStub = createIoStub();
|
|
804
|
+
const postman = {
|
|
805
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
806
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
807
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
808
|
+
generateCollection: vi
|
|
809
|
+
.fn()
|
|
810
|
+
.mockResolvedValueOnce('col-baseline')
|
|
811
|
+
.mockResolvedValueOnce('col-smoke')
|
|
812
|
+
.mockResolvedValueOnce('col-contract'),
|
|
813
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
814
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
815
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
816
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
817
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
818
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
819
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-123'),
|
|
820
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
821
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
822
|
+
};
|
|
823
|
+
const internalIntegration = {
|
|
824
|
+
assignWorkspaceToGovernanceGroup: vi.fn().mockResolvedValue(undefined),
|
|
825
|
+
linkCollectionsToSpecification: vi.fn().mockResolvedValue(undefined),
|
|
826
|
+
syncCollection: vi.fn().mockResolvedValue(undefined)
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
await runBootstrap(
|
|
830
|
+
createInputs({ syncExamples: false }),
|
|
831
|
+
{
|
|
832
|
+
core,
|
|
833
|
+
exec: execStub,
|
|
834
|
+
io: ioStub,
|
|
835
|
+
internalIntegration,
|
|
836
|
+
postman,
|
|
837
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
838
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
839
|
+
)
|
|
840
|
+
}
|
|
841
|
+
);
|
|
842
|
+
|
|
843
|
+
expect(internalIntegration.linkCollectionsToSpecification).toHaveBeenCalledWith(
|
|
844
|
+
'spec-123',
|
|
845
|
+
[
|
|
846
|
+
{ collectionId: 'col-baseline', syncOptions: { syncExamples: false } },
|
|
847
|
+
{ collectionId: 'col-smoke', syncOptions: { syncExamples: false } },
|
|
848
|
+
{ collectionId: 'col-contract', syncOptions: { syncExamples: false } }
|
|
849
|
+
]
|
|
850
|
+
);
|
|
581
851
|
});
|
|
582
852
|
|
|
583
|
-
it('
|
|
853
|
+
it('runs without any GitHub dependency', async () => {
|
|
584
854
|
const { core } = createCoreStub();
|
|
585
855
|
const execStub = createExecStub();
|
|
586
856
|
const ioStub = createIoStub();
|
|
@@ -590,6 +860,7 @@ describe('bootstrap action', () => {
|
|
|
590
860
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
591
861
|
generateCollection: vi.fn().mockResolvedValue('col-id'),
|
|
592
862
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
863
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
593
864
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
594
865
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
595
866
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -600,7 +871,7 @@ describe('bootstrap action', () => {
|
|
|
600
871
|
};
|
|
601
872
|
|
|
602
873
|
const result = await runBootstrap(
|
|
603
|
-
createInputs(
|
|
874
|
+
createInputs(),
|
|
604
875
|
{
|
|
605
876
|
core,
|
|
606
877
|
exec: execStub,
|
|
@@ -616,6 +887,117 @@ describe('bootstrap action', () => {
|
|
|
616
887
|
expect(result['spec-id']).toBe('spec-123');
|
|
617
888
|
});
|
|
618
889
|
|
|
890
|
+
it('version mode reuses current resources.yaml collections on the checked-out ref', async () => {
|
|
891
|
+
const { core, infos } = createCoreStub();
|
|
892
|
+
const execStub = createExecStub();
|
|
893
|
+
const ioStub = createIoStub();
|
|
894
|
+
const postman = {
|
|
895
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
896
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
897
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
898
|
+
generateCollection: vi
|
|
899
|
+
.fn()
|
|
900
|
+
.mockImplementation(async (_specId: string, _projectName: string, prefix: string) => {
|
|
901
|
+
if (prefix === '[Baseline]') return 'col-baseline-v2';
|
|
902
|
+
if (prefix === '[Smoke]') return 'col-smoke-v2';
|
|
903
|
+
return 'col-contract-v2';
|
|
904
|
+
}),
|
|
905
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
906
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
907
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
908
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
909
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
910
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
911
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-v2'),
|
|
912
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
913
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
914
|
+
};
|
|
915
|
+
const resources = {
|
|
916
|
+
workspace: { id: 'ws-current' },
|
|
917
|
+
cloudResources: {
|
|
918
|
+
collections: {
|
|
919
|
+
'../postman/collections/[Baseline] core-payments': 'col-baseline-current',
|
|
920
|
+
'../postman/collections/[Smoke] core-payments': 'col-smoke-current',
|
|
921
|
+
'../postman/collections/[Contract] core-payments': 'col-contract-current'
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
mkdirSync('.postman', { recursive: true });
|
|
926
|
+
writeFileSync('.postman/resources.yaml', stringifyYaml(resources));
|
|
927
|
+
|
|
928
|
+
const result = await runBootstrap(
|
|
929
|
+
createInputs({
|
|
930
|
+
collectionSyncMode: 'version',
|
|
931
|
+
specSyncMode: 'version',
|
|
932
|
+
releaseLabel: 'v2.0.0'
|
|
933
|
+
}),
|
|
934
|
+
{
|
|
935
|
+
core,
|
|
936
|
+
exec: execStub,
|
|
937
|
+
io: ioStub,
|
|
938
|
+
postman,
|
|
939
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
940
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
941
|
+
)
|
|
942
|
+
}
|
|
943
|
+
);
|
|
944
|
+
|
|
945
|
+
expect(postman.generateCollection).not.toHaveBeenCalled();
|
|
946
|
+
expect(result['baseline-collection-id']).toBe('col-baseline-current');
|
|
947
|
+
expect(result['smoke-collection-id']).toBe('col-smoke-current');
|
|
948
|
+
expect(result['contract-collection-id']).toBe('col-contract-current');
|
|
949
|
+
expect(infos).toContain('Resolved baseline-collection-id from .postman/resources.yaml');
|
|
950
|
+
expect(infos).toContain('Resolved smoke-collection-id from .postman/resources.yaml');
|
|
951
|
+
expect(infos).toContain('Resolved contract-collection-id from .postman/resources.yaml');
|
|
952
|
+
});
|
|
953
|
+
|
|
954
|
+
it('versioned runs do not emit releases-json or write releases.yaml', async () => {
|
|
955
|
+
const { core } = createCoreStub();
|
|
956
|
+
const execStub = createExecStub();
|
|
957
|
+
const ioStub = createIoStub();
|
|
958
|
+
const postman = {
|
|
959
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
960
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
961
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
962
|
+
generateCollection: vi
|
|
963
|
+
.fn()
|
|
964
|
+
.mockImplementation(async (_specId: string, _projectName: string, prefix: string) => {
|
|
965
|
+
if (prefix === '[Baseline]') return 'col-baseline-v2';
|
|
966
|
+
if (prefix === '[Smoke]') return 'col-smoke-v2';
|
|
967
|
+
return 'col-contract-v2';
|
|
968
|
+
}),
|
|
969
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
970
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
971
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
972
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
973
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
974
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
975
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-v2'),
|
|
976
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
977
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
const result = await runBootstrap(
|
|
981
|
+
createInputs({
|
|
982
|
+
collectionSyncMode: 'version',
|
|
983
|
+
specSyncMode: 'version',
|
|
984
|
+
releaseLabel: 'v2.0.0'
|
|
985
|
+
}),
|
|
986
|
+
{
|
|
987
|
+
core,
|
|
988
|
+
exec: execStub,
|
|
989
|
+
io: ioStub,
|
|
990
|
+
postman,
|
|
991
|
+
specFetcher: vi.fn<typeof fetch>().mockResolvedValue(
|
|
992
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
993
|
+
)
|
|
994
|
+
}
|
|
995
|
+
);
|
|
996
|
+
|
|
997
|
+
expect('releases-json' in result).toBe(false);
|
|
998
|
+
expect(existsSync('.postman/releases.yaml')).toBe(false);
|
|
999
|
+
});
|
|
1000
|
+
|
|
619
1001
|
it('emits warnings for lint violations but does not fail', async () => {
|
|
620
1002
|
const { core, warnings } = createCoreStub();
|
|
621
1003
|
const execStub = createExecStub(
|
|
@@ -632,6 +1014,7 @@ describe('bootstrap action', () => {
|
|
|
632
1014
|
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
633
1015
|
generateCollection: vi.fn().mockResolvedValue('col-id'),
|
|
634
1016
|
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
1017
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
635
1018
|
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
636
1019
|
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
637
1020
|
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
@@ -729,3 +1112,190 @@ describe('lintSpecViaCli', () => {
|
|
|
729
1112
|
});
|
|
730
1113
|
});
|
|
731
1114
|
});
|
|
1115
|
+
|
|
1116
|
+
it('fails with team list when org-mode detected and no workspace-team-id', async () => {
|
|
1117
|
+
const { core } = createCoreStub();
|
|
1118
|
+
const execStub = createExecStub();
|
|
1119
|
+
const ioStub = createIoStub();
|
|
1120
|
+
const postman = {
|
|
1121
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1122
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
1123
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
1124
|
+
generateCollection: vi.fn().mockResolvedValue('col-1'),
|
|
1125
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('13347347'),
|
|
1126
|
+
getTeams: vi.fn().mockResolvedValue([
|
|
1127
|
+
{ id: 132109, name: 'Field Services', handle: 'fs', organizationId: 13347347 },
|
|
1128
|
+
{ id: 132118, name: 'Customer Ed', handle: 'ce', organizationId: 13347347 }
|
|
1129
|
+
]),
|
|
1130
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
1131
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
1132
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1133
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
1134
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-123'),
|
|
1135
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
1136
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
1137
|
+
};
|
|
1138
|
+
const specFetcher = vi.fn<typeof fetch>().mockResolvedValue(
|
|
1139
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
1140
|
+
);
|
|
1141
|
+
|
|
1142
|
+
await expect(
|
|
1143
|
+
runBootstrap(createInputs(), {
|
|
1144
|
+
core,
|
|
1145
|
+
exec: execStub,
|
|
1146
|
+
io: ioStub,
|
|
1147
|
+
postman,
|
|
1148
|
+
specFetcher
|
|
1149
|
+
})
|
|
1150
|
+
).rejects.toThrow('Org-mode account detected');
|
|
1151
|
+
|
|
1152
|
+
expect(postman.createWorkspace).not.toHaveBeenCalled();
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
it('passes workspace-team-id to createWorkspace for org-mode accounts', async () => {
|
|
1156
|
+
const { core, outputs } = createCoreStub();
|
|
1157
|
+
const execStub = createExecStub();
|
|
1158
|
+
const ioStub = createIoStub();
|
|
1159
|
+
const postman = {
|
|
1160
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1161
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-org' }),
|
|
1162
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
1163
|
+
generateCollection: vi.fn().mockResolvedValue('col-1'),
|
|
1164
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('13347347'),
|
|
1165
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
1166
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
1167
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
1168
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1169
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
1170
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-123'),
|
|
1171
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
1172
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
1173
|
+
};
|
|
1174
|
+
const specFetcher = vi.fn<typeof fetch>().mockResolvedValue(
|
|
1175
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
1176
|
+
);
|
|
1177
|
+
|
|
1178
|
+
await runBootstrap(createInputs({ workspaceTeamId: '132319' }), {
|
|
1179
|
+
core,
|
|
1180
|
+
exec: execStub,
|
|
1181
|
+
io: ioStub,
|
|
1182
|
+
postman,
|
|
1183
|
+
specFetcher
|
|
1184
|
+
});
|
|
1185
|
+
|
|
1186
|
+
expect(postman.createWorkspace).toHaveBeenCalledWith(
|
|
1187
|
+
expect.any(String),
|
|
1188
|
+
expect.any(String),
|
|
1189
|
+
132319
|
|
1190
|
+
);
|
|
1191
|
+
expect(outputs['workspace-id']).toBe('ws-org');
|
|
1192
|
+
});
|
|
1193
|
+
|
|
1194
|
+
it('skips org-mode detection when workspace-id is already provided', async () => {
|
|
1195
|
+
const { core, outputs } = createCoreStub();
|
|
1196
|
+
const execStub = createExecStub();
|
|
1197
|
+
const ioStub = createIoStub();
|
|
1198
|
+
const postman = {
|
|
1199
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1200
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
1201
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
1202
|
+
generateCollection: vi.fn().mockResolvedValue('col-1'),
|
|
1203
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('13347347'),
|
|
1204
|
+
getTeams: vi.fn().mockResolvedValue([
|
|
1205
|
+
{ id: 132109, name: 'FS', handle: 'fs', organizationId: 13347347 },
|
|
1206
|
+
{ id: 132118, name: 'CE', handle: 'ce', organizationId: 13347347 }
|
|
1207
|
+
]),
|
|
1208
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
1209
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
1210
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1211
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
1212
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-123'),
|
|
1213
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
1214
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
1215
|
+
};
|
|
1216
|
+
const specFetcher = vi.fn<typeof fetch>().mockResolvedValue(
|
|
1217
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
1218
|
+
);
|
|
1219
|
+
|
|
1220
|
+
await runBootstrap(createInputs({ workspaceId: 'ws-existing' }), {
|
|
1221
|
+
core,
|
|
1222
|
+
exec: execStub,
|
|
1223
|
+
io: ioStub,
|
|
1224
|
+
postman,
|
|
1225
|
+
specFetcher
|
|
1226
|
+
});
|
|
1227
|
+
|
|
1228
|
+
expect(postman.createWorkspace).not.toHaveBeenCalled();
|
|
1229
|
+
expect(outputs['workspace-id']).toBe('ws-existing');
|
|
1230
|
+
});
|
|
1231
|
+
|
|
1232
|
+
it('warns and proceeds when getTeams fails', async () => {
|
|
1233
|
+
const { core } = createCoreStub();
|
|
1234
|
+
const warnings: string[] = [];
|
|
1235
|
+
core.warning = vi.fn((msg: string) => warnings.push(msg));
|
|
1236
|
+
const execStub = createExecStub();
|
|
1237
|
+
const ioStub = createIoStub();
|
|
1238
|
+
const postman = {
|
|
1239
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1240
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
1241
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
1242
|
+
generateCollection: vi.fn().mockResolvedValue('col-1'),
|
|
1243
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
1244
|
+
getTeams: vi.fn().mockRejectedValue(new Error('Network error')),
|
|
1245
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
1246
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
1247
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1248
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
1249
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-123'),
|
|
1250
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
1251
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
1252
|
+
};
|
|
1253
|
+
const specFetcher = vi.fn<typeof fetch>().mockResolvedValue(
|
|
1254
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
1255
|
+
);
|
|
1256
|
+
|
|
1257
|
+
await runBootstrap(createInputs(), {
|
|
1258
|
+
core,
|
|
1259
|
+
exec: execStub,
|
|
1260
|
+
io: ioStub,
|
|
1261
|
+
postman,
|
|
1262
|
+
specFetcher
|
|
1263
|
+
});
|
|
1264
|
+
|
|
1265
|
+
expect(warnings.some(w => w.includes('Could not check for org-mode'))).toBe(true);
|
|
1266
|
+
expect(postman.createWorkspace).toHaveBeenCalled();
|
|
1267
|
+
});
|
|
1268
|
+
|
|
1269
|
+
it('throws when workspace-team-id is non-numeric', async () => {
|
|
1270
|
+
const { core } = createCoreStub();
|
|
1271
|
+
const execStub = createExecStub();
|
|
1272
|
+
const ioStub = createIoStub();
|
|
1273
|
+
const postman = {
|
|
1274
|
+
addAdminsToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1275
|
+
createWorkspace: vi.fn().mockResolvedValue({ id: 'ws-123' }),
|
|
1276
|
+
findWorkspacesByName: vi.fn().mockResolvedValue([]),
|
|
1277
|
+
generateCollection: vi.fn().mockResolvedValue('col-1'),
|
|
1278
|
+
getAutoDerivedTeamId: vi.fn().mockResolvedValue('12345'),
|
|
1279
|
+
getTeams: vi.fn().mockResolvedValue([]),
|
|
1280
|
+
getWorkspaceGitRepoUrl: vi.fn().mockResolvedValue(null),
|
|
1281
|
+
injectTests: vi.fn().mockResolvedValue(undefined),
|
|
1282
|
+
inviteRequesterToWorkspace: vi.fn().mockResolvedValue(undefined),
|
|
1283
|
+
tagCollection: vi.fn().mockResolvedValue(undefined),
|
|
1284
|
+
uploadSpec: vi.fn().mockResolvedValue('spec-123'),
|
|
1285
|
+
updateSpec: vi.fn().mockResolvedValue(undefined),
|
|
1286
|
+
getSpecContent: vi.fn().mockResolvedValue('openapi: 3.1.0')
|
|
1287
|
+
};
|
|
1288
|
+
const specFetcher = vi.fn<typeof fetch>().mockResolvedValue(
|
|
1289
|
+
new Response('openapi: 3.1.0', { status: 200 })
|
|
1290
|
+
);
|
|
1291
|
+
|
|
1292
|
+
await expect(
|
|
1293
|
+
runBootstrap(createInputs({ workspaceTeamId: 'not-a-number' }), {
|
|
1294
|
+
core,
|
|
1295
|
+
exec: execStub,
|
|
1296
|
+
io: ioStub,
|
|
1297
|
+
postman,
|
|
1298
|
+
specFetcher
|
|
1299
|
+
})
|
|
1300
|
+
).rejects.toThrow('workspace-team-id must be a numeric sub-team ID');
|
|
1301
|
+
});
|