@camunda/e2e-test-suite 0.0.1242 → 0.0.1244

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.
Files changed (83) hide show
  1. package/dist/fixtures/api.d.ts +15 -0
  2. package/dist/fixtures/api.js +27 -0
  3. package/dist/pages/SM-8.10/ModelerCreatePage.js +5 -4
  4. package/dist/tests/api/v2/authorization/authorization-api-tests.spec.d.ts +1 -0
  5. package/dist/tests/api/v2/authorization/authorization-api-tests.spec.js +247 -0
  6. package/dist/tests/api/v2/authorization/authorization-enforcement-api-tests.spec.d.ts +18 -0
  7. package/dist/tests/api/v2/authorization/authorization-enforcement-api-tests.spec.js +208 -0
  8. package/dist/tests/api/v2/batch-operation/batch-operation-api-tests.spec.d.ts +1 -0
  9. package/dist/tests/api/v2/batch-operation/batch-operation-api-tests.spec.js +264 -0
  10. package/dist/tests/api/v2/cluster/cluster-api-tests.spec.d.ts +1 -0
  11. package/dist/tests/api/v2/cluster/cluster-api-tests.spec.js +86 -0
  12. package/dist/tests/api/v2/decision/decision-api-tests.spec.d.ts +1 -0
  13. package/dist/tests/api/v2/decision/decision-api-tests.spec.js +233 -0
  14. package/dist/tests/api/v2/deployment/deployment-api-tests.spec.d.ts +1 -0
  15. package/dist/tests/api/v2/deployment/deployment-api-tests.spec.js +147 -0
  16. package/dist/tests/api/v2/document/document-api-tests.spec.d.ts +9 -0
  17. package/dist/tests/api/v2/document/document-api-tests.spec.js +111 -0
  18. package/dist/tests/api/v2/element-instance/element-instance-api-tests.spec.d.ts +1 -0
  19. package/dist/tests/api/v2/element-instance/element-instance-api-tests.spec.js +127 -0
  20. package/dist/tests/api/v2/flows/end-to-end-flows.spec.d.ts +9 -0
  21. package/dist/tests/api/v2/flows/end-to-end-flows.spec.js +204 -0
  22. package/dist/tests/api/v2/form/form-api-tests.spec.d.ts +1 -0
  23. package/dist/tests/api/v2/form/form-api-tests.spec.js +88 -0
  24. package/dist/tests/api/v2/identity/group-api-tests.spec.d.ts +1 -0
  25. package/dist/tests/api/v2/identity/group-api-tests.spec.js +172 -0
  26. package/dist/tests/api/v2/identity/membership-api-tests.spec.d.ts +10 -0
  27. package/dist/tests/api/v2/identity/membership-api-tests.spec.js +164 -0
  28. package/dist/tests/api/v2/identity/role-api-tests.spec.d.ts +1 -0
  29. package/dist/tests/api/v2/identity/role-api-tests.spec.js +212 -0
  30. package/dist/tests/api/v2/identity/tenant-api-tests.spec.d.ts +1 -0
  31. package/dist/tests/api/v2/identity/tenant-api-tests.spec.js +319 -0
  32. package/dist/tests/api/v2/identity/user-api-tests.spec.d.ts +1 -0
  33. package/dist/tests/api/v2/identity/user-api-tests.spec.js +148 -0
  34. package/dist/tests/api/v2/job/job-api-tests.spec.d.ts +1 -0
  35. package/dist/tests/api/v2/job/job-api-tests.spec.js +260 -0
  36. package/dist/tests/api/v2/message/message-api-tests.spec.d.ts +1 -0
  37. package/dist/tests/api/v2/message/message-api-tests.spec.js +219 -0
  38. package/dist/tests/api/v2/process-definition/process-definition-api-tests.spec.d.ts +1 -0
  39. package/dist/tests/api/v2/process-definition/process-definition-api-tests.spec.js +118 -0
  40. package/dist/tests/api/v2/process-instance/process-instance-api-tests.spec.d.ts +1 -0
  41. package/dist/tests/api/v2/process-instance/process-instance-api-tests.spec.js +335 -0
  42. package/dist/tests/api/v2/runtime/batch-modification-api-tests.spec.d.ts +1 -0
  43. package/dist/tests/api/v2/runtime/batch-modification-api-tests.spec.js +123 -0
  44. package/dist/tests/api/v2/runtime/variable-incident-api-tests.spec.d.ts +1 -0
  45. package/dist/tests/api/v2/runtime/variable-incident-api-tests.spec.js +174 -0
  46. package/dist/tests/api/v2/system/clock-api-tests.spec.d.ts +19 -0
  47. package/dist/tests/api/v2/system/clock-api-tests.spec.js +62 -0
  48. package/dist/tests/api/v2/system/system-api-tests.spec.d.ts +1 -0
  49. package/dist/tests/api/v2/system/system-api-tests.spec.js +183 -0
  50. package/dist/tests/api/v2/user-task/user-task-api-tests.spec.d.ts +1 -0
  51. package/dist/tests/api/v2/user-task/user-task-api-tests.spec.js +258 -0
  52. package/dist/utils/api/assertions.d.ts +50 -0
  53. package/dist/utils/api/assertions.js +142 -0
  54. package/dist/utils/api/auth.d.ts +27 -0
  55. package/dist/utils/api/auth.js +137 -0
  56. package/dist/utils/api/beans.d.ts +46 -0
  57. package/dist/utils/api/beans.js +87 -0
  58. package/dist/utils/api/bpmn.d.ts +50 -0
  59. package/dist/utils/api/bpmn.js +217 -0
  60. package/dist/utils/api/capabilities.d.ts +90 -0
  61. package/dist/utils/api/capabilities.js +198 -0
  62. package/dist/utils/api/cleanup.d.ts +24 -0
  63. package/dist/utils/api/cleanup.js +120 -0
  64. package/dist/utils/api/config.d.ts +103 -0
  65. package/dist/utils/api/config.js +62 -0
  66. package/dist/utils/api/deployments.d.ts +45 -0
  67. package/dist/utils/api/deployments.js +120 -0
  68. package/dist/utils/api/eventually.d.ts +36 -0
  69. package/dist/utils/api/eventually.js +54 -0
  70. package/dist/utils/api/http.d.ts +56 -0
  71. package/dist/utils/api/http.js +244 -0
  72. package/dist/utils/api/identity.d.ts +29 -0
  73. package/dist/utils/api/identity.js +43 -0
  74. package/dist/utils/api/keys.d.ts +37 -0
  75. package/dist/utils/api/keys.js +40 -0
  76. package/dist/utils/api/paths.d.ts +25 -0
  77. package/dist/utils/api/paths.js +167 -0
  78. package/dist/utils/api/tenancy.d.ts +31 -0
  79. package/dist/utils/api/tenancy.js +65 -0
  80. package/package.json +1 -1
  81. package/playwright.config.ts +14 -2
  82. package/dist/resources/test-api-v2-complete.sh +0 -12246
  83. package/resources/test-api-v2-complete.sh +0 -12246
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const api_1 = require("../../../../fixtures/api");
4
+ const test_1 = require("@playwright/test");
5
+ const assertions_1 = require("../../../../utils/api/assertions");
6
+ const beans_1 = require("../../../../utils/api/beans");
7
+ const identity_1 = require("../../../../utils/api/identity");
8
+ const eventually_1 = require("../../../../utils/api/eventually");
9
+ const bpmn_1 = require("../../../../utils/api/bpmn");
10
+ const capabilities_1 = require("../../../../utils/api/capabilities");
11
+ async function createTenant(api, resources) {
12
+ const tenant = (0, beans_1.newTenant)();
13
+ await (0, assertions_1.assertCreated)(await api.post('/tenants', { body: tenant, tenant: 'none' }));
14
+ resources.track('tenant', tenant.tenantId);
15
+ return tenant;
16
+ }
17
+ api_1.test.describe('Tenants', () => {
18
+ (0, api_1.test)('creates a tenant', async ({ api, resources }) => {
19
+ const tenant = (0, beans_1.newTenant)();
20
+ const response = await api.post('/tenants', {
21
+ body: tenant,
22
+ tenant: 'none',
23
+ });
24
+ // The shell suite expected `200 201 403 404 405` — five statuses, three of
25
+ // which mean the request never took effect.
26
+ const created = (await (0, assertions_1.assertCreated)(response));
27
+ (0, assertions_1.assertRequiredFields)(created, beans_1.tenantRequiredFields);
28
+ (0, test_1.expect)(created.tenantId).toBe(tenant.tenantId);
29
+ resources.track('tenant', tenant.tenantId);
30
+ });
31
+ (0, api_1.test)('returns a created tenant by id', async ({ api, resources }) => {
32
+ const tenant = await createTenant(api, resources);
33
+ await (0, eventually_1.eventually)(async () => {
34
+ const response = await api.get('/tenants/{tenantId}', {
35
+ params: { tenantId: tenant.tenantId },
36
+ tenant: 'none',
37
+ });
38
+ const json = (await (0, assertions_1.assertOk)(response));
39
+ (0, test_1.expect)(json.tenantId).toBe(tenant.tenantId);
40
+ (0, test_1.expect)(json.name).toBe(tenant.name);
41
+ });
42
+ });
43
+ (0, api_1.test)('updates a tenant', async ({ api, resources }) => {
44
+ const tenant = await createTenant(api, resources);
45
+ const updatedName = `Updated ${tenant.name}`;
46
+ const response = await api.put('/tenants/{tenantId}', {
47
+ params: { tenantId: tenant.tenantId },
48
+ body: { name: updatedName, description: 'updated by the API suite' },
49
+ tenant: 'none',
50
+ });
51
+ await (0, assertions_1.assertStatusIn)(response, [200, 204], 'the update returns the tenant on 8.8+ and an empty body on earlier minors');
52
+ await (0, eventually_1.eventually)(async () => {
53
+ const lookup = await api.get('/tenants/{tenantId}', {
54
+ params: { tenantId: tenant.tenantId },
55
+ tenant: 'none',
56
+ });
57
+ const json = (await (0, assertions_1.assertOk)(lookup));
58
+ (0, test_1.expect)(json.name).toBe(updatedName);
59
+ });
60
+ });
61
+ (0, api_1.test)('finds a created tenant through search', async ({ api, resources }) => {
62
+ const tenant = await createTenant(api, resources);
63
+ await (0, eventually_1.eventually)(async () => {
64
+ const response = await api.post('/tenants/search', {
65
+ body: { filter: { tenantId: tenant.tenantId }, page: { limit: 10 } },
66
+ tenant: 'none',
67
+ });
68
+ await (0, assertions_1.assertPaginated)(response, { exactItems: 1 });
69
+ });
70
+ });
71
+ (0, api_1.test)('deletes a tenant', async ({ api, resources }) => {
72
+ const tenant = await createTenant(api, resources);
73
+ const response = await api.delete('/tenants/{tenantId}', {
74
+ params: { tenantId: tenant.tenantId },
75
+ tenant: 'none',
76
+ });
77
+ await (0, assertions_1.assertStatusIn)(response, [204], 'deletion is acknowledged');
78
+ resources.forget('tenant', tenant.tenantId);
79
+ await (0, eventually_1.eventually)(async () => {
80
+ const lookup = await api.get('/tenants/{tenantId}', {
81
+ params: { tenantId: tenant.tenantId },
82
+ tenant: 'none',
83
+ });
84
+ await (0, assertions_1.assertNotFound)(lookup);
85
+ });
86
+ });
87
+ (0, api_1.test)('rejects a tenant whose id already exists', async ({ api, resources }) => {
88
+ const tenant = await createTenant(api, resources);
89
+ const response = await api.post('/tenants', {
90
+ body: (0, beans_1.newTenant)({ tenantId: tenant.tenantId }),
91
+ tenant: 'none',
92
+ });
93
+ await (0, assertions_1.assertConflict)(response);
94
+ });
95
+ (0, api_1.test)('rejects an over-long tenant id', async ({ api }) => {
96
+ const response = await api.post('/tenants', {
97
+ body: (0, beans_1.newTenant)({ tenantId: 'a'.repeat(300) }),
98
+ tenant: 'none',
99
+ });
100
+ await (0, assertions_1.assertBadRequest)(response);
101
+ });
102
+ (0, api_1.test)('rejects a lookup for an absent tenant', async ({ api }) => {
103
+ const response = await api.get('/tenants/{tenantId}', {
104
+ params: { tenantId: (0, bpmn_1.uniqueId)('absent-tenant') },
105
+ tenant: 'none',
106
+ });
107
+ await (0, assertions_1.assertNotFound)(response);
108
+ });
109
+ (0, api_1.test)('rejects an unauthenticated tenant creation', async ({ api }) => {
110
+ api_1.test.skip(capabilities_1.unauthenticatedAccessAllowed !== false, capabilities_1.unauthenticatedAccessAllowed === false
111
+ ? ''
112
+ : capabilities_1.unauthenticatedAccessAllowed);
113
+ const response = await api.post('/tenants', {
114
+ body: (0, beans_1.newTenant)(),
115
+ tenant: 'none',
116
+ authorization: null,
117
+ });
118
+ await (0, assertions_1.assertUnauthorized)(response);
119
+ });
120
+ });
121
+ api_1.test.describe('Tenant membership', () => {
122
+ (0, api_1.test)('assigns and removes a user', async ({ api, resources }) => {
123
+ const tenant = await createTenant(api, resources);
124
+ const username = await (0, identity_1.provisionUsername)(api, resources);
125
+ const assign = await api.put('/tenants/{tenantId}/users/{username}', {
126
+ params: { tenantId: tenant.tenantId, username },
127
+ tenant: 'none',
128
+ });
129
+ await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
130
+ await (0, eventually_1.eventually)(async () => {
131
+ const response = await api.post('/tenants/{tenantId}/users/search', {
132
+ params: { tenantId: tenant.tenantId },
133
+ body: { page: { limit: 20 } },
134
+ tenant: 'none',
135
+ });
136
+ const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
137
+ const usernames = page.items.map((item) => item.username);
138
+ (0, test_1.expect)(usernames).toContain(username);
139
+ });
140
+ const remove = await api.delete('/tenants/{tenantId}/users/{username}', {
141
+ params: { tenantId: tenant.tenantId, username },
142
+ tenant: 'none',
143
+ });
144
+ await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
145
+ });
146
+ (0, api_1.test)('assigns and removes a group', async ({ api, resources }) => {
147
+ const tenant = await createTenant(api, resources);
148
+ const group = (0, beans_1.newGroup)();
149
+ await (0, assertions_1.assertCreated)(await api.post('/groups', { body: group, tenant: 'none' }));
150
+ resources.track('group', group.groupId);
151
+ const assign = await api.put('/tenants/{tenantId}/groups/{groupId}', {
152
+ params: { tenantId: tenant.tenantId, groupId: group.groupId },
153
+ tenant: 'none',
154
+ });
155
+ await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
156
+ await (0, eventually_1.eventually)(async () => {
157
+ const response = await api.post('/tenants/{tenantId}/groups/search', {
158
+ params: { tenantId: tenant.tenantId },
159
+ body: { page: { limit: 20 } },
160
+ tenant: 'none',
161
+ });
162
+ const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
163
+ const groupIds = page.items.map((item) => item.groupId);
164
+ (0, test_1.expect)(groupIds).toContain(group.groupId);
165
+ });
166
+ const remove = await api.delete('/tenants/{tenantId}/groups/{groupId}', {
167
+ params: { tenantId: tenant.tenantId, groupId: group.groupId },
168
+ tenant: 'none',
169
+ });
170
+ await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
171
+ });
172
+ (0, api_1.test)('assigns and removes a role', async ({ api, resources }) => {
173
+ const tenant = await createTenant(api, resources);
174
+ const role = (0, beans_1.newRole)();
175
+ await (0, assertions_1.assertCreated)(await api.post('/roles', { body: role, tenant: 'none' }));
176
+ resources.track('role', role.roleId);
177
+ const assign = await api.put('/tenants/{tenantId}/roles/{roleId}', {
178
+ params: { tenantId: tenant.tenantId, roleId: role.roleId },
179
+ tenant: 'none',
180
+ });
181
+ await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
182
+ await (0, eventually_1.eventually)(async () => {
183
+ const response = await api.post('/tenants/{tenantId}/roles/search', {
184
+ params: { tenantId: tenant.tenantId },
185
+ body: { page: { limit: 20 } },
186
+ tenant: 'none',
187
+ });
188
+ await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
189
+ });
190
+ const remove = await api.delete('/tenants/{tenantId}/roles/{roleId}', {
191
+ params: { tenantId: tenant.tenantId, roleId: role.roleId },
192
+ tenant: 'none',
193
+ });
194
+ await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
195
+ });
196
+ (0, api_1.test)('assigns and removes a mapping rule', async ({ api, resources }) => {
197
+ const tenant = await createTenant(api, resources);
198
+ const rule = (0, beans_1.newMappingRule)();
199
+ await (0, assertions_1.assertCreated)(await api.post('/mapping-rules', { body: rule, tenant: 'none' }));
200
+ resources.track('mappingRule', rule.mappingRuleId);
201
+ const assign = await api.put('/tenants/{tenantId}/mapping-rules/{mappingRuleId}', {
202
+ params: {
203
+ tenantId: tenant.tenantId,
204
+ mappingRuleId: rule.mappingRuleId,
205
+ },
206
+ tenant: 'none',
207
+ });
208
+ await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
209
+ await (0, eventually_1.eventually)(async () => {
210
+ const response = await api.post('/tenants/{tenantId}/mapping-rules/search', {
211
+ params: { tenantId: tenant.tenantId },
212
+ body: { page: { limit: 20 } },
213
+ tenant: 'none',
214
+ });
215
+ await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
216
+ });
217
+ const remove = await api.delete('/tenants/{tenantId}/mapping-rules/{mappingRuleId}', {
218
+ params: {
219
+ tenantId: tenant.tenantId,
220
+ mappingRuleId: rule.mappingRuleId,
221
+ },
222
+ tenant: 'none',
223
+ });
224
+ await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
225
+ });
226
+ (0, api_1.test)('rejects assigning a user to an absent tenant', async ({ api, resources, }) => {
227
+ const username = await (0, identity_1.provisionUsername)(api, resources);
228
+ const response = await api.put('/tenants/{tenantId}/users/{username}', {
229
+ params: {
230
+ tenantId: (0, bpmn_1.uniqueId)('absent-tenant'),
231
+ username,
232
+ },
233
+ tenant: 'none',
234
+ });
235
+ await (0, assertions_1.assertNotFound)(response);
236
+ });
237
+ (0, api_1.test)('rejects assigning an absent user to a tenant', async ({ api, resources, }) => {
238
+ const tenant = await createTenant(api, resources);
239
+ const response = await api.put('/tenants/{tenantId}/users/{username}', {
240
+ params: {
241
+ tenantId: tenant.tenantId,
242
+ username: (0, bpmn_1.uniqueId)('absent-user'),
243
+ },
244
+ tenant: 'none',
245
+ });
246
+ // The shell suite called this case "idempotent" and asserted
247
+ // `200 204 403 404` — i.e. it passed whether the API accepted or refused.
248
+ // The real answer depends on the cluster's identity mode; the expectation
249
+ // follows it and states why.
250
+ await (0, assertions_1.assertStatusIn)(response, [capabilities_1.absentUserMembership.status], capabilities_1.absentUserMembership.reason);
251
+ });
252
+ });
253
+ api_1.test.describe('Mapping rules', () => {
254
+ (0, api_1.test)('creates a mapping rule', async ({ api, resources }) => {
255
+ const rule = (0, beans_1.newMappingRule)();
256
+ const response = await api.post('/mapping-rules', {
257
+ body: rule,
258
+ tenant: 'none',
259
+ });
260
+ const created = (await (0, assertions_1.assertCreated)(response));
261
+ (0, assertions_1.assertRequiredFields)(created, ['mappingRuleId', 'claimName', 'claimValue']);
262
+ (0, test_1.expect)(created.mappingRuleId).toBe(rule.mappingRuleId);
263
+ resources.track('mappingRule', rule.mappingRuleId);
264
+ });
265
+ (0, api_1.test)('returns a created mapping rule by id', async ({ api, resources }) => {
266
+ const rule = (0, beans_1.newMappingRule)();
267
+ await (0, assertions_1.assertCreated)(await api.post('/mapping-rules', { body: rule, tenant: 'none' }));
268
+ resources.track('mappingRule', rule.mappingRuleId);
269
+ await (0, eventually_1.eventually)(async () => {
270
+ const response = await api.get('/mapping-rules/{mappingRuleId}', {
271
+ params: { mappingRuleId: rule.mappingRuleId },
272
+ tenant: 'none',
273
+ });
274
+ const json = (await (0, assertions_1.assertOk)(response));
275
+ (0, test_1.expect)(json.claimName).toBe(rule.claimName);
276
+ (0, test_1.expect)(json.claimValue).toBe(rule.claimValue);
277
+ });
278
+ });
279
+ (0, api_1.test)('updates a mapping rule', async ({ api, resources }) => {
280
+ const rule = (0, beans_1.newMappingRule)();
281
+ await (0, assertions_1.assertCreated)(await api.post('/mapping-rules', { body: rule, tenant: 'none' }));
282
+ resources.track('mappingRule', rule.mappingRuleId);
283
+ const response = await api.put('/mapping-rules/{mappingRuleId}', {
284
+ params: { mappingRuleId: rule.mappingRuleId },
285
+ body: {
286
+ claimName: rule.claimName,
287
+ claimValue: rule.claimValue,
288
+ name: `Updated ${rule.name}`,
289
+ },
290
+ tenant: 'none',
291
+ });
292
+ await (0, assertions_1.assertStatusIn)(response, [200, 204], 'the update returns the rule on 8.8+ and an empty body on earlier minors');
293
+ });
294
+ (0, api_1.test)('rejects a mapping rule whose id already exists', async ({ api, resources, }) => {
295
+ const rule = (0, beans_1.newMappingRule)();
296
+ await (0, assertions_1.assertCreated)(await api.post('/mapping-rules', { body: rule, tenant: 'none' }));
297
+ resources.track('mappingRule', rule.mappingRuleId);
298
+ const response = await api.post('/mapping-rules', {
299
+ body: (0, beans_1.newMappingRule)({ mappingRuleId: rule.mappingRuleId }),
300
+ tenant: 'none',
301
+ });
302
+ await (0, assertions_1.assertConflict)(response);
303
+ });
304
+ (0, api_1.test)('rejects updating an absent mapping rule', async ({ api }) => {
305
+ const response = await api.put('/mapping-rules/{mappingRuleId}', {
306
+ params: { mappingRuleId: (0, bpmn_1.uniqueId)('absent-rule') },
307
+ body: { claimName: 'c', claimValue: 'v', name: 'absent' },
308
+ tenant: 'none',
309
+ });
310
+ await (0, assertions_1.assertNotFound)(response);
311
+ });
312
+ (0, api_1.test)('rejects deleting an absent mapping rule', async ({ api }) => {
313
+ const response = await api.delete('/mapping-rules/{mappingRuleId}', {
314
+ params: { mappingRuleId: (0, bpmn_1.uniqueId)('absent-rule') },
315
+ tenant: 'none',
316
+ });
317
+ await (0, assertions_1.assertNotFound)(response);
318
+ });
319
+ });
@@ -0,0 +1,148 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const api_1 = require("../../../../fixtures/api");
4
+ const test_1 = require("@playwright/test");
5
+ const assertions_1 = require("../../../../utils/api/assertions");
6
+ const beans_1 = require("../../../../utils/api/beans");
7
+ const eventually_1 = require("../../../../utils/api/eventually");
8
+ const bpmn_1 = require("../../../../utils/api/bpmn");
9
+ const capabilities_1 = require("../../../../utils/api/capabilities");
10
+ async function createUser(api, resources, overrides = {}) {
11
+ const user = (0, beans_1.newUser)(overrides);
12
+ await (0, assertions_1.assertCreated)(await api.post('/users', { body: user, tenant: 'none' }));
13
+ resources.track('user', user.username);
14
+ return user;
15
+ }
16
+ api_1.test.describe('Users', () => {
17
+ // Every test below creates or reads a local user. On an OIDC cluster the
18
+ // whole /v2/users/** tree is turned off, so none of them has a subject.
19
+ // `system-api-tests.spec.ts` asserts that the tree really is closed there,
20
+ // so this gate cannot quietly drop coverage if the mode is misread.
21
+ api_1.test.skip(capabilities_1.usersApiUnavailable !== false, capabilities_1.usersApiUnavailable === false ? '' : capabilities_1.usersApiUnavailable);
22
+ (0, api_1.test)('creates a user', async ({ api, resources }) => {
23
+ const user = (0, beans_1.newUser)();
24
+ const response = await api.post('/users', { body: user, tenant: 'none' });
25
+ const created = (await (0, assertions_1.assertCreated)(response));
26
+ (0, assertions_1.assertRequiredFields)(created, beans_1.userRequiredFields);
27
+ (0, test_1.expect)(created.username).toBe(user.username);
28
+ (0, test_1.expect)(created.email).toBe(user.email);
29
+ // A password must never be echoed back by the API.
30
+ (0, test_1.expect)(created.password).toBeUndefined();
31
+ resources.track('user', user.username);
32
+ });
33
+ (0, api_1.test)('returns a created user by username', async ({ api, resources }) => {
34
+ const user = await createUser(api, resources);
35
+ await (0, eventually_1.eventually)(async () => {
36
+ const response = await api.get('/users/{username}', {
37
+ params: { username: user.username },
38
+ tenant: 'none',
39
+ });
40
+ const json = (await (0, assertions_1.assertOk)(response));
41
+ (0, test_1.expect)(json.username).toBe(user.username);
42
+ (0, test_1.expect)(json.email).toBe(user.email);
43
+ });
44
+ });
45
+ (0, api_1.test)('updates a user profile', async ({ api, resources }) => {
46
+ const user = await createUser(api, resources);
47
+ const updatedName = `Updated ${user.name}`;
48
+ const response = await api.put('/users/{username}', {
49
+ params: { username: user.username },
50
+ body: { name: updatedName, email: user.email },
51
+ tenant: 'none',
52
+ });
53
+ await (0, assertions_1.assertStatusIn)(response, [200, 204], 'the update returns the user on 8.8+ and an empty body on earlier minors');
54
+ await (0, eventually_1.eventually)(async () => {
55
+ const lookup = await api.get('/users/{username}', {
56
+ params: { username: user.username },
57
+ tenant: 'none',
58
+ });
59
+ const json = (await (0, assertions_1.assertOk)(lookup));
60
+ (0, test_1.expect)(json.name).toBe(updatedName);
61
+ });
62
+ });
63
+ (0, api_1.test)('finds a created user through search', async ({ api, resources }) => {
64
+ const user = await createUser(api, resources);
65
+ await (0, eventually_1.eventually)(async () => {
66
+ const response = await api.post('/users/search', {
67
+ body: { filter: { username: user.username }, page: { limit: 10 } },
68
+ tenant: 'none',
69
+ });
70
+ await (0, assertions_1.assertPaginated)(response, { exactItems: 1 });
71
+ });
72
+ });
73
+ (0, api_1.test)('deletes a user', async ({ api, resources }) => {
74
+ const user = await createUser(api, resources);
75
+ const response = await api.delete('/users/{username}', {
76
+ params: { username: user.username },
77
+ tenant: 'none',
78
+ });
79
+ await (0, assertions_1.assertStatusIn)(response, [204], 'deletion is acknowledged');
80
+ resources.forget('user', user.username);
81
+ await (0, eventually_1.eventually)(async () => {
82
+ const lookup = await api.get('/users/{username}', {
83
+ params: { username: user.username },
84
+ tenant: 'none',
85
+ });
86
+ await (0, assertions_1.assertNotFound)(lookup);
87
+ });
88
+ });
89
+ // There is no /users/{username}/roles|groups|tenants sub-search on any
90
+ // supported version — membership is only queryable from the owning side.
91
+ // The two tests that stood here asserted `exactItems: 0` against a 404 from
92
+ // an unrouted path, so neither could report anything. Role, group and
93
+ // tenant membership is asserted in role-api-tests, group-api-tests and
94
+ // tenant-api-tests, each through the endpoint that exists.
95
+ (0, api_1.test)('rejects a username that already exists', async ({ api, resources }) => {
96
+ const user = await createUser(api, resources);
97
+ const response = await api.post('/users', {
98
+ body: (0, beans_1.newUser)({ username: user.username }),
99
+ tenant: 'none',
100
+ });
101
+ await (0, assertions_1.assertConflict)(response);
102
+ });
103
+ (0, api_1.test)('rejects a malformed email address', async ({ api }) => {
104
+ const response = await api.post('/users', {
105
+ body: (0, beans_1.newUser)({ email: 'not-an-email' }),
106
+ tenant: 'none',
107
+ });
108
+ await (0, assertions_1.assertBadRequest)(response, /email/i);
109
+ });
110
+ (0, api_1.test)('rejects a user with no password', async ({ api }) => {
111
+ const user = (0, beans_1.newUser)();
112
+ delete user.password;
113
+ const response = await api.post('/users', { body: user, tenant: 'none' });
114
+ await (0, assertions_1.assertBadRequest)(response, /password/i);
115
+ });
116
+ (0, api_1.test)('rejects updating an absent user', async ({ api }) => {
117
+ const response = await api.put('/users/{username}', {
118
+ params: { username: (0, bpmn_1.uniqueId)('absent-user') },
119
+ body: { name: 'does not exist', email: 'nobody@example.com' },
120
+ tenant: 'none',
121
+ });
122
+ await (0, assertions_1.assertNotFound)(response);
123
+ });
124
+ (0, api_1.test)('rejects a lookup for an absent user', async ({ api }) => {
125
+ const response = await api.get('/users/{username}', {
126
+ params: { username: (0, bpmn_1.uniqueId)('absent-user') },
127
+ tenant: 'none',
128
+ });
129
+ await (0, assertions_1.assertNotFound)(response);
130
+ });
131
+ });
132
+ // Outside the capability gate above: the security filter chain answers before
133
+ // the OIDC endpoint filter does, so an unauthenticated call is rejected with
134
+ // 401 whether or not the cluster serves the Users API. That holds in both
135
+ // modes and is worth asserting in both.
136
+ api_1.test.describe('Users, unauthenticated', () => {
137
+ (0, api_1.test)('rejects an unauthenticated user creation', async ({ api }) => {
138
+ api_1.test.skip(capabilities_1.unauthenticatedAccessAllowed !== false, capabilities_1.unauthenticatedAccessAllowed === false
139
+ ? ''
140
+ : capabilities_1.unauthenticatedAccessAllowed);
141
+ const response = await api.post('/users', {
142
+ body: (0, beans_1.newUser)(),
143
+ tenant: 'none',
144
+ authorization: null,
145
+ });
146
+ await (0, assertions_1.assertUnauthorized)(response);
147
+ });
148
+ });
@@ -0,0 +1 @@
1
+ export {};