@postman-cse/onboarding-bootstrap 0.9.1 → 0.10.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/tests/cli.test.ts CHANGED
@@ -14,6 +14,12 @@ describe('parseCliArgs', () => {
14
14
  'pmak-test',
15
15
  '--workspace-admin-user-ids',
16
16
  '101,102',
17
+ '--collection-sync-mode',
18
+ 'version',
19
+ '--spec-sync-mode',
20
+ 'version',
21
+ '--release-label',
22
+ 'v1.2.3',
17
23
  '--team-id',
18
24
  '12345',
19
25
  '--repo-url',
@@ -30,6 +36,9 @@ describe('parseCliArgs', () => {
30
36
  expect(config.inputEnv.INPUT_SPEC_URL).toBe('https://example.test/openapi.yaml');
31
37
  expect(config.inputEnv.INPUT_POSTMAN_API_KEY).toBe('pmak-test');
32
38
  expect(config.inputEnv.INPUT_WORKSPACE_ADMIN_USER_IDS).toBe('101,102');
39
+ expect(config.inputEnv.INPUT_COLLECTION_SYNC_MODE).toBe('version');
40
+ expect(config.inputEnv.INPUT_SPEC_SYNC_MODE).toBe('version');
41
+ expect(config.inputEnv.INPUT_RELEASE_LABEL).toBe('v1.2.3');
33
42
  expect(config.inputEnv.INPUT_TEAM_ID).toBe('12345');
34
43
  expect(config.inputEnv.INPUT_REPO_URL).toBe('https://github.com/postman-cs/postman-bootstrap-action');
35
44
  expect(config.resultJsonPath).toBe('tmp/result.json');
@@ -49,7 +58,7 @@ describe('toDotenv', () => {
49
58
  'contract-collection-id': 'col-contract',
50
59
  'collections-json': '{"baseline":"col-baseline"}',
51
60
  'lint-summary-json': '{"errors":0}'
52
- });
61
+ } as any);
53
62
 
54
63
  expect(dotenv).toContain('POSTMAN_BOOTSTRAP_WORKSPACE_ID="ws-123"');
55
64
  expect(dotenv).toContain('POSTMAN_BOOTSTRAP_SPEC_ID="spec-123"');
@@ -104,7 +113,7 @@ describe('runCli', () => {
104
113
  'contract-collection-id': 'col-contract',
105
114
  'collections-json': '{"baseline":"col-baseline","smoke":"col-smoke","contract":"col-contract"}',
106
115
  'lint-summary-json': '{"errors":0,"total":0,"violations":[],"warnings":0}'
107
- };
116
+ } as any;
108
117
  },
109
118
  writeStdout: (chunk) => {
110
119
  stdoutChunks.push(chunk);
@@ -124,21 +133,18 @@ describe('runCli', () => {
124
133
  });
125
134
 
126
135
  describe('createCliDependencies', () => {
127
- it('creates github and internal integration dependencies under token conditions', () => {
136
+ it('creates internal integration dependencies under token conditions', () => {
128
137
  const inputs = resolveInputs({
129
138
  INPUT_PROJECT_NAME: 'core-payments',
130
139
  INPUT_SPEC_URL: 'https://example.test/openapi.yaml',
131
140
  INPUT_POSTMAN_API_KEY: 'pmak-test',
132
141
  INPUT_POSTMAN_ACCESS_TOKEN: 'pat-test',
133
- INPUT_GITHUB_TOKEN: 'gh-token',
134
- INPUT_GH_FALLBACK_TOKEN: 'gh-fallback',
135
142
  INPUT_REPO_URL: 'https://github.com/postman-cs/postman-bootstrap-action',
136
143
  INPUT_TEAM_ID: '12345'
137
144
  });
138
145
 
139
146
  const dependencies = createCliDependencies(inputs);
140
147
 
141
- expect(dependencies.github).toBeDefined();
142
148
  expect(dependencies.internalIntegration).toBeDefined();
143
149
  });
144
150
  });
@@ -41,6 +41,26 @@ describe('open-alpha action contract', () => {
41
41
  expect(resolveInputs({}).integrationBackend).toBe('bifrost');
42
42
  });
43
43
 
44
+ it('defaults lifecycle controls in contract, manifest, and runtime', () => {
45
+ expect(openAlphaActionContract.inputs['collection-sync-mode'].default).toBe('refresh');
46
+ expect(openAlphaActionContract.inputs['collection-sync-mode'].allowedValues).toEqual([
47
+ 'reuse',
48
+ 'refresh',
49
+ 'version'
50
+ ]);
51
+ expect(actionManifest.inputs['collection-sync-mode'].default).toBe('refresh');
52
+ expect(resolveInputs({}).collectionSyncMode).toBe('refresh');
53
+
54
+ expect(openAlphaActionContract.inputs['spec-sync-mode'].default).toBe('update');
55
+ expect(openAlphaActionContract.inputs['spec-sync-mode'].allowedValues).toEqual([
56
+ 'update',
57
+ 'version'
58
+ ]);
59
+ expect(actionManifest.inputs['spec-sync-mode'].default).toBe('update');
60
+ expect(resolveInputs({}).specSyncMode).toBe('update');
61
+
62
+ });
63
+
44
64
  it('rejects unsupported integration backends during input resolution', () => {
45
65
  expect(() =>
46
66
  resolveInputs({
@@ -63,9 +83,6 @@ describe('open-alpha action contract', () => {
63
83
  expect(openAlphaActionContract.retainedBehavior).toContain(
64
84
  'governance group assignment'
65
85
  );
66
- expect(openAlphaActionContract.retainedBehavior).toContain(
67
- 'GitHub repository variable persistence for downstream sync steps'
68
- );
69
86
  expect(openAlphaActionContract.removedBehavior).toContain('step mode');
70
87
  expect(openAlphaActionContract.removedBehavior).toContain(
71
88
  'aws, docker, and infra workflow concerns'
@@ -112,4 +112,157 @@ describe('PostmanAssetsClient', () => {
112
112
 
113
113
  await expect(client.getSpecContent('spec-123')).resolves.toBeUndefined();
114
114
  });
115
+
116
+ it('creates a workspace with targetTeamId in the payload for org-mode', async () => {
117
+ const fetchImpl = vi
118
+ .fn<typeof fetch>()
119
+ .mockResolvedValueOnce(
120
+ jsonResponse({
121
+ workspace: {
122
+ id: 'ws-org-123'
123
+ }
124
+ })
125
+ )
126
+ .mockResolvedValueOnce(
127
+ jsonResponse({
128
+ workspace: {
129
+ id: 'ws-org-123',
130
+ visibility: 'team'
131
+ }
132
+ })
133
+ );
134
+
135
+ const client = new PostmanAssetsClient({
136
+ apiKey: 'pmak-test',
137
+ fetchImpl
138
+ });
139
+
140
+ await expect(client.createWorkspace('Org WS', 'desc', 132319)).resolves.toEqual({
141
+ id: 'ws-org-123'
142
+ });
143
+ expect(fetchImpl).toHaveBeenCalledTimes(2);
144
+ expect(fetchImpl).toHaveBeenNthCalledWith(
145
+ 1,
146
+ 'https://api.getpostman.com/workspaces',
147
+ expect.objectContaining({
148
+ method: 'POST',
149
+ body: JSON.stringify({
150
+ workspace: {
151
+ about: 'desc',
152
+ name: 'Org WS',
153
+ type: 'team',
154
+ teamId: 132319
155
+ }
156
+ })
157
+ })
158
+ );
159
+ });
160
+
161
+ it('creates a workspace without teamId when targetTeamId is not provided', async () => {
162
+ const fetchImpl = vi
163
+ .fn<typeof fetch>()
164
+ .mockResolvedValueOnce(
165
+ jsonResponse({
166
+ workspace: { id: 'ws-no-team' }
167
+ })
168
+ )
169
+ .mockResolvedValueOnce(
170
+ jsonResponse({
171
+ workspace: { id: 'ws-no-team', visibility: 'team' }
172
+ })
173
+ );
174
+
175
+ const client = new PostmanAssetsClient({
176
+ apiKey: 'pmak-test',
177
+ fetchImpl
178
+ });
179
+
180
+ await expect(client.createWorkspace('Regular WS', 'desc')).resolves.toEqual({
181
+ id: 'ws-no-team'
182
+ });
183
+ expect(fetchImpl).toHaveBeenNthCalledWith(
184
+ 1,
185
+ 'https://api.getpostman.com/workspaces',
186
+ expect.objectContaining({
187
+ body: JSON.stringify({
188
+ workspace: {
189
+ about: 'desc',
190
+ name: 'Regular WS',
191
+ type: 'team'
192
+ }
193
+ })
194
+ })
195
+ );
196
+ });
197
+
198
+ it('throws actionable error for org-mode workspace creation failure', async () => {
199
+ const errorBody = JSON.stringify({
200
+ error: {
201
+ name: 'invalidParamError',
202
+ message: 'Only personal workspaces (internal) can be created outside team'
203
+ }
204
+ });
205
+ const fetchImpl = vi.fn<typeof fetch>().mockImplementation(
206
+ async () => new Response(errorBody, { status: 400 })
207
+ );
208
+
209
+ const client = new PostmanAssetsClient({
210
+ apiKey: 'pmak-test',
211
+ fetchImpl
212
+ });
213
+
214
+ await expect(client.createWorkspace('Org WS', 'desc')).rejects.toThrow(
215
+ 'workspace-team-id'
216
+ );
217
+ });
218
+
219
+ it('returns parsed sub-teams from getTeams', async () => {
220
+ const fetchImpl = vi.fn<typeof fetch>().mockResolvedValueOnce(
221
+ jsonResponse({
222
+ data: [
223
+ { id: 132109, name: 'Field Services', handle: 'fs', organizationId: 13347347 },
224
+ { id: 132118, name: 'Customer Education', handle: 'ce', organizationId: 13347347 },
225
+ { id: 132272, name: 'RonCorp', handle: 'rc', organizationId: 13347347 }
226
+ ]
227
+ })
228
+ );
229
+
230
+ const client = new PostmanAssetsClient({
231
+ apiKey: 'pmak-test',
232
+ fetchImpl
233
+ });
234
+
235
+ const teams = await client.getTeams();
236
+ expect(teams).toEqual([
237
+ { id: 132109, name: 'Field Services', handle: 'fs', organizationId: 13347347 },
238
+ { id: 132118, name: 'Customer Education', handle: 'ce', organizationId: 13347347 },
239
+ { id: 132272, name: 'RonCorp', handle: 'rc', organizationId: 13347347 }
240
+ ]);
241
+ });
242
+
243
+ it('returns empty array from getTeams when no teams exist', async () => {
244
+ const fetchImpl = vi.fn<typeof fetch>().mockResolvedValueOnce(
245
+ jsonResponse({ data: [] })
246
+ );
247
+
248
+ const client = new PostmanAssetsClient({
249
+ apiKey: 'pmak-test',
250
+ fetchImpl
251
+ });
252
+
253
+ await expect(client.getTeams()).resolves.toEqual([]);
254
+ });
255
+
256
+ it('propagates errors from getTeams without swallowing', async () => {
257
+ const fetchImpl = vi.fn<typeof fetch>().mockResolvedValueOnce(
258
+ new Response('Forbidden', { status: 403 })
259
+ );
260
+
261
+ const client = new PostmanAssetsClient({
262
+ apiKey: 'pmak-test',
263
+ fetchImpl
264
+ });
265
+
266
+ await expect(client.getTeams()).rejects.toThrow();
267
+ });
115
268
  });