@camunda/e2e-test-suite 0.0.1241 → 0.0.1243
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/dist/fixtures/api.d.ts +15 -0
- package/dist/fixtures/api.js +27 -0
- package/dist/pages/SM-8.10/NavigationPage.d.ts +3 -2
- package/dist/pages/SM-8.10/NavigationPage.js +24 -34
- package/dist/pages/SM-8.10/ProcessApplicationPage.js +7 -0
- package/dist/tests/api/v2/authorization/authorization-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/authorization/authorization-api-tests.spec.js +247 -0
- package/dist/tests/api/v2/authorization/authorization-enforcement-api-tests.spec.d.ts +18 -0
- package/dist/tests/api/v2/authorization/authorization-enforcement-api-tests.spec.js +208 -0
- package/dist/tests/api/v2/batch-operation/batch-operation-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/batch-operation/batch-operation-api-tests.spec.js +264 -0
- package/dist/tests/api/v2/cluster/cluster-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/cluster/cluster-api-tests.spec.js +86 -0
- package/dist/tests/api/v2/decision/decision-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/decision/decision-api-tests.spec.js +233 -0
- package/dist/tests/api/v2/deployment/deployment-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/deployment/deployment-api-tests.spec.js +147 -0
- package/dist/tests/api/v2/document/document-api-tests.spec.d.ts +9 -0
- package/dist/tests/api/v2/document/document-api-tests.spec.js +111 -0
- package/dist/tests/api/v2/element-instance/element-instance-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/element-instance/element-instance-api-tests.spec.js +127 -0
- package/dist/tests/api/v2/flows/end-to-end-flows.spec.d.ts +9 -0
- package/dist/tests/api/v2/flows/end-to-end-flows.spec.js +204 -0
- package/dist/tests/api/v2/form/form-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/form/form-api-tests.spec.js +88 -0
- package/dist/tests/api/v2/identity/group-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/identity/group-api-tests.spec.js +172 -0
- package/dist/tests/api/v2/identity/membership-api-tests.spec.d.ts +10 -0
- package/dist/tests/api/v2/identity/membership-api-tests.spec.js +164 -0
- package/dist/tests/api/v2/identity/role-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/identity/role-api-tests.spec.js +212 -0
- package/dist/tests/api/v2/identity/tenant-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/identity/tenant-api-tests.spec.js +319 -0
- package/dist/tests/api/v2/identity/user-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/identity/user-api-tests.spec.js +148 -0
- package/dist/tests/api/v2/job/job-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/job/job-api-tests.spec.js +260 -0
- package/dist/tests/api/v2/message/message-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/message/message-api-tests.spec.js +219 -0
- package/dist/tests/api/v2/process-definition/process-definition-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/process-definition/process-definition-api-tests.spec.js +118 -0
- package/dist/tests/api/v2/process-instance/process-instance-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/process-instance/process-instance-api-tests.spec.js +335 -0
- package/dist/tests/api/v2/runtime/batch-modification-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/runtime/batch-modification-api-tests.spec.js +123 -0
- package/dist/tests/api/v2/runtime/variable-incident-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/runtime/variable-incident-api-tests.spec.js +174 -0
- package/dist/tests/api/v2/system/clock-api-tests.spec.d.ts +19 -0
- package/dist/tests/api/v2/system/clock-api-tests.spec.js +62 -0
- package/dist/tests/api/v2/system/system-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/system/system-api-tests.spec.js +183 -0
- package/dist/tests/api/v2/user-task/user-task-api-tests.spec.d.ts +1 -0
- package/dist/tests/api/v2/user-task/user-task-api-tests.spec.js +258 -0
- package/dist/utils/api/assertions.d.ts +50 -0
- package/dist/utils/api/assertions.js +142 -0
- package/dist/utils/api/auth.d.ts +27 -0
- package/dist/utils/api/auth.js +137 -0
- package/dist/utils/api/beans.d.ts +46 -0
- package/dist/utils/api/beans.js +87 -0
- package/dist/utils/api/bpmn.d.ts +50 -0
- package/dist/utils/api/bpmn.js +217 -0
- package/dist/utils/api/capabilities.d.ts +90 -0
- package/dist/utils/api/capabilities.js +198 -0
- package/dist/utils/api/cleanup.d.ts +24 -0
- package/dist/utils/api/cleanup.js +120 -0
- package/dist/utils/api/config.d.ts +103 -0
- package/dist/utils/api/config.js +62 -0
- package/dist/utils/api/deployments.d.ts +45 -0
- package/dist/utils/api/deployments.js +120 -0
- package/dist/utils/api/eventually.d.ts +36 -0
- package/dist/utils/api/eventually.js +54 -0
- package/dist/utils/api/http.d.ts +56 -0
- package/dist/utils/api/http.js +244 -0
- package/dist/utils/api/identity.d.ts +29 -0
- package/dist/utils/api/identity.js +43 -0
- package/dist/utils/api/keys.d.ts +37 -0
- package/dist/utils/api/keys.js +40 -0
- package/dist/utils/api/paths.d.ts +25 -0
- package/dist/utils/api/paths.js +167 -0
- package/dist/utils/api/tenancy.d.ts +31 -0
- package/dist/utils/api/tenancy.js +65 -0
- package/package.json +1 -1
- package/playwright.config.ts +14 -2
- package/dist/resources/test-api-v2-complete.sh +0 -12246
- package/resources/test-api-v2-complete.sh +0 -12246
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Multi-step flows spanning several endpoints.
|
|
4
|
+
*
|
|
5
|
+
* These correspond to the shell suite's "Integration Test 1-4" (lines
|
|
6
|
+
* 8386-9353), which tracked their own `INTEGRATION_TEST_N_PASSED` booleans and
|
|
7
|
+
* incremented TESTS_PASSED by hand — 50 increment sites against 27 failure
|
|
8
|
+
* sites, so a step could report success with no path that reported failure.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const api_1 = require("../../../../fixtures/api");
|
|
12
|
+
const test_1 = require("@playwright/test");
|
|
13
|
+
const assertions_1 = require("../../../../utils/api/assertions");
|
|
14
|
+
const deployments_1 = require("../../../../utils/api/deployments");
|
|
15
|
+
const beans_1 = require("../../../../utils/api/beans");
|
|
16
|
+
const bpmn_1 = require("../../../../utils/api/bpmn");
|
|
17
|
+
const eventually_1 = require("../../../../utils/api/eventually");
|
|
18
|
+
const identity_1 = require("../../../../utils/api/identity");
|
|
19
|
+
api_1.test.describe('End-to-end flows', () => {
|
|
20
|
+
(0, api_1.test)('deploy, start, publish a message, and see the instance complete', async ({ api, resources, }) => {
|
|
21
|
+
const processId = (0, bpmn_1.uniqueId)('flow-message');
|
|
22
|
+
const messageName = (0, bpmn_1.uniqueId)('flow-message-name');
|
|
23
|
+
const correlationKey = (0, bpmn_1.uniqueId)('flow-correlation');
|
|
24
|
+
await api_1.test.step('deploy a process waiting on a message', async () => {
|
|
25
|
+
await (0, deployments_1.deployProcess)(api, resources, processId, (0, bpmn_1.linearProcess)(processId, bpmn_1.element.messageCatch(messageName)));
|
|
26
|
+
});
|
|
27
|
+
const processInstanceKey = await api_1.test.step('start an instance', async () => {
|
|
28
|
+
const response = await api.post('/process-instances', {
|
|
29
|
+
body: {
|
|
30
|
+
processDefinitionId: processId,
|
|
31
|
+
variables: { msgCorrelationKey: correlationKey },
|
|
32
|
+
},
|
|
33
|
+
tenant: 'root',
|
|
34
|
+
});
|
|
35
|
+
await (0, assertions_1.assertStatusIn)(response, [200], 'instance creation is synchronous');
|
|
36
|
+
const json = (await response.json());
|
|
37
|
+
return String(json.processInstanceKey);
|
|
38
|
+
});
|
|
39
|
+
await api_1.test.step('wait for the message subscription to open', async () => {
|
|
40
|
+
await (0, eventually_1.eventually)(async () => {
|
|
41
|
+
const response = await api.post('/message-subscriptions/search', {
|
|
42
|
+
body: { filter: { processInstanceKey }, page: { limit: 10 } },
|
|
43
|
+
});
|
|
44
|
+
await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
await api_1.test.step('publish the message', async () => {
|
|
48
|
+
const response = await api.post('/messages/publication', {
|
|
49
|
+
body: {
|
|
50
|
+
name: messageName,
|
|
51
|
+
correlationKey,
|
|
52
|
+
timeToLive: 30000,
|
|
53
|
+
variables: { published: true },
|
|
54
|
+
},
|
|
55
|
+
tenant: 'root',
|
|
56
|
+
});
|
|
57
|
+
await (0, assertions_1.assertOk)(response);
|
|
58
|
+
});
|
|
59
|
+
await api_1.test.step('the instance completes', async () => {
|
|
60
|
+
await (0, eventually_1.eventually)(async () => {
|
|
61
|
+
const response = await api.post('/process-instances/search', {
|
|
62
|
+
body: { filter: { processInstanceKey } },
|
|
63
|
+
});
|
|
64
|
+
const page = await (0, assertions_1.assertPaginated)(response, { exactItems: 1 });
|
|
65
|
+
(0, test_1.expect)(page.items[0].state).toBe('COMPLETED');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
(0, api_1.test)('start with variables, read them back, then modify them', async ({ api, resources, }) => {
|
|
70
|
+
const processId = (0, bpmn_1.uniqueId)('flow-variables');
|
|
71
|
+
await (0, deployments_1.deployProcess)(api, resources, processId, (0, bpmn_1.linearProcess)(processId, bpmn_1.element.serviceTask((0, bpmn_1.uniqueId)('job'))));
|
|
72
|
+
const processInstanceKey = await api_1.test.step('start with variables', async () => {
|
|
73
|
+
const response = await api.post('/process-instances', {
|
|
74
|
+
body: {
|
|
75
|
+
processDefinitionId: processId,
|
|
76
|
+
variables: { stage: 'initial', count: 1 },
|
|
77
|
+
},
|
|
78
|
+
tenant: 'root',
|
|
79
|
+
});
|
|
80
|
+
await (0, assertions_1.assertStatusIn)(response, [200], 'instance creation is synchronous');
|
|
81
|
+
const json = (await response.json());
|
|
82
|
+
return String(json.processInstanceKey);
|
|
83
|
+
});
|
|
84
|
+
resources.track('processInstance', processInstanceKey);
|
|
85
|
+
await api_1.test.step('the start variables are readable', async () => {
|
|
86
|
+
await (0, eventually_1.eventually)(async () => {
|
|
87
|
+
const response = await api.post('/variables/search', {
|
|
88
|
+
body: {
|
|
89
|
+
filter: { processInstanceKey, name: 'stage' },
|
|
90
|
+
page: { limit: 10 },
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
const page = await (0, assertions_1.assertPaginated)(response, { exactItems: 1 });
|
|
94
|
+
(0, test_1.expect)(page.items[0].value).toBe('"initial"');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
await api_1.test.step('modification replaces a variable', async () => {
|
|
98
|
+
const response = await api.post('/process-instances/{processInstanceKey}/modification', {
|
|
99
|
+
params: { processInstanceKey },
|
|
100
|
+
body: {
|
|
101
|
+
activateInstructions: [
|
|
102
|
+
{
|
|
103
|
+
elementId: 'task',
|
|
104
|
+
variableInstructions: [{ variables: { stage: 'modified' } }],
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
},
|
|
108
|
+
tenant: 'none',
|
|
109
|
+
});
|
|
110
|
+
await (0, assertions_1.assertStatusIn)(response, [204], 'modification is acknowledged');
|
|
111
|
+
});
|
|
112
|
+
await api_1.test.step('the new value is readable', async () => {
|
|
113
|
+
await (0, eventually_1.eventually)(async () => {
|
|
114
|
+
const response = await api.post('/variables/search', {
|
|
115
|
+
body: {
|
|
116
|
+
filter: { processInstanceKey, name: 'stage' },
|
|
117
|
+
page: { limit: 10 },
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
121
|
+
const values = page.items.map((item) => item.value);
|
|
122
|
+
(0, test_1.expect)(values).toContain('"modified"');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
(0, api_1.test)('deploy, run a job worker cycle, and complete the instance', async ({ api, resources, }) => {
|
|
127
|
+
const processId = (0, bpmn_1.uniqueId)('flow-job');
|
|
128
|
+
const jobType = (0, bpmn_1.uniqueId)('flow-job-type');
|
|
129
|
+
await (0, deployments_1.deployProcess)(api, resources, processId, (0, bpmn_1.linearProcess)(processId, bpmn_1.element.serviceTask(jobType)));
|
|
130
|
+
const processInstanceKey = await api_1.test.step('start an instance', async () => {
|
|
131
|
+
const response = await api.post('/process-instances', {
|
|
132
|
+
body: { processDefinitionId: processId },
|
|
133
|
+
tenant: 'root',
|
|
134
|
+
});
|
|
135
|
+
await (0, assertions_1.assertStatusIn)(response, [200], 'instance creation is synchronous');
|
|
136
|
+
const json = (await response.json());
|
|
137
|
+
return String(json.processInstanceKey);
|
|
138
|
+
});
|
|
139
|
+
const jobKey = await api_1.test.step('activate the job', async () => {
|
|
140
|
+
const jobs = await (0, eventually_1.eventuallyGet)(async () => {
|
|
141
|
+
const response = await api.post('/jobs/activation', {
|
|
142
|
+
body: {
|
|
143
|
+
type: jobType,
|
|
144
|
+
worker: 'api-v2-flow',
|
|
145
|
+
maxJobsToActivate: 1,
|
|
146
|
+
timeout: 60000,
|
|
147
|
+
},
|
|
148
|
+
tenant: 'tenantIds',
|
|
149
|
+
});
|
|
150
|
+
const json = (await response.json());
|
|
151
|
+
return json.jobs ?? [];
|
|
152
|
+
}, (found) => found.length > 0, { description: `job of type ${jobType}` });
|
|
153
|
+
(0, test_1.expect)(String(jobs[0].processInstanceKey)).toBe(processInstanceKey);
|
|
154
|
+
return String(jobs[0].jobKey);
|
|
155
|
+
});
|
|
156
|
+
await api_1.test.step('complete the job', async () => {
|
|
157
|
+
const response = await api.post('/jobs/{jobKey}/completion', {
|
|
158
|
+
params: { jobKey },
|
|
159
|
+
body: { variables: { handled: true } },
|
|
160
|
+
tenant: 'none',
|
|
161
|
+
});
|
|
162
|
+
await (0, assertions_1.assertStatusIn)(response, [204], 'completion is acknowledged');
|
|
163
|
+
});
|
|
164
|
+
await api_1.test.step('the instance completes', async () => {
|
|
165
|
+
await (0, eventually_1.eventually)(async () => {
|
|
166
|
+
const response = await api.post('/process-instances/search', {
|
|
167
|
+
body: { filter: { processInstanceKey } },
|
|
168
|
+
});
|
|
169
|
+
const page = await (0, assertions_1.assertPaginated)(response, { exactItems: 1 });
|
|
170
|
+
(0, test_1.expect)(page.items[0].state).toBe('COMPLETED');
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
(0, api_1.test)('grant a tenant to a user and see it listed', async ({ api, resources, }) => {
|
|
175
|
+
const tenant = (0, beans_1.newTenant)();
|
|
176
|
+
let username = '';
|
|
177
|
+
await api_1.test.step('create the tenant and the user', async () => {
|
|
178
|
+
await (0, assertions_1.assertCreated)(await api.post('/tenants', { body: tenant, tenant: 'none' }));
|
|
179
|
+
resources.track('tenant', tenant.tenantId);
|
|
180
|
+
username = await (0, identity_1.provisionUsername)(api, resources);
|
|
181
|
+
});
|
|
182
|
+
await api_1.test.step('assign the user to the tenant', async () => {
|
|
183
|
+
const response = await api.put('/tenants/{tenantId}/users/{username}', {
|
|
184
|
+
params: { tenantId: tenant.tenantId, username },
|
|
185
|
+
tenant: 'none',
|
|
186
|
+
});
|
|
187
|
+
await (0, assertions_1.assertStatusIn)(response, [204], 'assignment is acknowledged');
|
|
188
|
+
});
|
|
189
|
+
// Asserted from the tenant side: there is no /users/{username}/tenants
|
|
190
|
+
// sub-search on any supported version.
|
|
191
|
+
await api_1.test.step('the user appears on the tenant', async () => {
|
|
192
|
+
await (0, eventually_1.eventually)(async () => {
|
|
193
|
+
const response = await api.post('/tenants/{tenantId}/users/search', {
|
|
194
|
+
params: { tenantId: tenant.tenantId },
|
|
195
|
+
body: { page: { limit: 50 } },
|
|
196
|
+
tenant: 'none',
|
|
197
|
+
});
|
|
198
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
199
|
+
const usernames = page.items.map((item) => item.username);
|
|
200
|
+
(0, test_1.expect)(usernames).toContain(username);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
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 deployments_1 = require("../../../../utils/api/deployments");
|
|
7
|
+
const bpmn_1 = require("../../../../utils/api/bpmn");
|
|
8
|
+
const config_1 = require("../../../../utils/api/config");
|
|
9
|
+
const eventually_1 = require("../../../../utils/api/eventually");
|
|
10
|
+
const keys_1 = require("../../../../utils/api/keys");
|
|
11
|
+
async function deployForm(api, resources, formId) {
|
|
12
|
+
const response = await (0, deployments_1.deployResources)(api, resources, [
|
|
13
|
+
{
|
|
14
|
+
name: `${formId}.form`,
|
|
15
|
+
content: (0, bpmn_1.simpleForm)(formId),
|
|
16
|
+
mimeType: 'application/json',
|
|
17
|
+
},
|
|
18
|
+
]);
|
|
19
|
+
await (0, assertions_1.assertStatusIn)(response, [200], 'deployment is synchronous');
|
|
20
|
+
const json = (await response.json());
|
|
21
|
+
const deployment = json.deployments.find((entry) => entry.form !== undefined);
|
|
22
|
+
(0, test_1.expect)(deployment, `deployment response carried no form: ${JSON.stringify(json)}`).toBeTruthy();
|
|
23
|
+
const form = deployment.form;
|
|
24
|
+
return { formKey: String(form.formKey), version: Number(form.version) };
|
|
25
|
+
}
|
|
26
|
+
api_1.test.describe('Forms', () => {
|
|
27
|
+
(0, api_1.test)('deploys a form', async ({ api, resources }) => {
|
|
28
|
+
const formId = (0, bpmn_1.uniqueId)('form-api');
|
|
29
|
+
const { formKey, version } = await deployForm(api, resources, formId);
|
|
30
|
+
(0, test_1.expect)(formKey).toBeTruthy();
|
|
31
|
+
(0, test_1.expect)(version).toBe(1);
|
|
32
|
+
});
|
|
33
|
+
// `GET /v2/forms/{formKey}` is published from 8.10; before that the whole
|
|
34
|
+
// /v2/forms prefix is unrouted. Registered conditionally rather than run
|
|
35
|
+
// everywhere, because on 8.8 and 8.9 the absent-key case would answer 404
|
|
36
|
+
// for the wrong reason and pass without exercising anything.
|
|
37
|
+
if ((0, config_1.atLeastVersion)('8.10')) {
|
|
38
|
+
(0, api_1.test)('returns a deployed form by key', async ({ api, resources }) => {
|
|
39
|
+
const formId = (0, bpmn_1.uniqueId)('form-lookup');
|
|
40
|
+
const { formKey } = await deployForm(api, resources, formId);
|
|
41
|
+
await (0, eventually_1.eventually)(async () => {
|
|
42
|
+
const response = await api.get('/forms/{formKey}', { params: { formKey } });
|
|
43
|
+
const form = (await (0, assertions_1.assertOk)(response));
|
|
44
|
+
(0, assertions_1.assertRequiredFields)(form, ['formKey', 'formId', 'version', 'schema']);
|
|
45
|
+
(0, test_1.expect)(form.formId).toBe(formId);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
(0, api_1.test)('rejects a lookup for an absent form key', async ({ api }) => {
|
|
49
|
+
const response = await api.get('/forms/{formKey}', {
|
|
50
|
+
params: { formKey: keys_1.ABSENT_KEY },
|
|
51
|
+
});
|
|
52
|
+
await (0, assertions_1.assertNotFound)(response);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// Covered on every minor: a start form reached through the definition,
|
|
56
|
+
// which is the only form endpoint 8.8 and 8.9 serve.
|
|
57
|
+
(0, api_1.test)('returns the start form linked to a process definition', async ({ api, resources, }) => {
|
|
58
|
+
const formId = (0, bpmn_1.uniqueId)('form-linked');
|
|
59
|
+
const processId = (0, bpmn_1.uniqueId)('form-linked-process');
|
|
60
|
+
await deployForm(api, resources, formId);
|
|
61
|
+
const deployed = await (0, deployments_1.deployProcess)(api, resources, processId, (0, bpmn_1.startFormProcess)(processId, formId));
|
|
62
|
+
await (0, eventually_1.eventually)(async () => {
|
|
63
|
+
const response = await api.get('/process-definitions/{processDefinitionKey}/form', { params: { processDefinitionKey: deployed.processDefinitionKey } });
|
|
64
|
+
const form = (await (0, assertions_1.assertOk)(response));
|
|
65
|
+
(0, test_1.expect)(form.formId).toBe(formId);
|
|
66
|
+
(0, test_1.expect)(String(form.schema)).toContain('fieldOne');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
api_1.test.describe('Setup', () => {
|
|
71
|
+
(0, api_1.test)('refuses to bootstrap a first user on a configured cluster', async ({ api, }) => {
|
|
72
|
+
const username = (0, bpmn_1.uniqueId)('setup-user');
|
|
73
|
+
const response = await api.post('/setup/user', {
|
|
74
|
+
body: {
|
|
75
|
+
username,
|
|
76
|
+
password: 'SetupPass123!',
|
|
77
|
+
email: `${username}@example.com`,
|
|
78
|
+
name: 'Setup test user',
|
|
79
|
+
},
|
|
80
|
+
tenant: 'none',
|
|
81
|
+
});
|
|
82
|
+
// This endpoint bootstraps the first administrator. Every cluster this
|
|
83
|
+
// suite runs against is already configured, so the correct answer is a
|
|
84
|
+
// refusal. The shell suite expected `200 201 400 403 409` — every possible
|
|
85
|
+
// outcome, including quietly creating an unmanaged admin account.
|
|
86
|
+
await (0, assertions_1.assertStatusIn)(response, [403], 'initial setup is closed once a cluster has an administrator');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,172 @@
|
|
|
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 createGroup(api, resources) {
|
|
12
|
+
const group = (0, beans_1.newGroup)();
|
|
13
|
+
await (0, assertions_1.assertCreated)(await api.post('/groups', { body: group, tenant: 'none' }));
|
|
14
|
+
resources.track('group', group.groupId);
|
|
15
|
+
return group;
|
|
16
|
+
}
|
|
17
|
+
api_1.test.describe('Groups', () => {
|
|
18
|
+
(0, api_1.test)('creates a group', async ({ api, resources }) => {
|
|
19
|
+
const group = (0, beans_1.newGroup)();
|
|
20
|
+
const response = await api.post('/groups', {
|
|
21
|
+
body: group,
|
|
22
|
+
tenant: 'none',
|
|
23
|
+
});
|
|
24
|
+
const created = (await (0, assertions_1.assertCreated)(response));
|
|
25
|
+
(0, assertions_1.assertRequiredFields)(created, beans_1.groupRequiredFields);
|
|
26
|
+
(0, test_1.expect)(created.groupId).toBe(group.groupId);
|
|
27
|
+
resources.track('group', group.groupId);
|
|
28
|
+
});
|
|
29
|
+
(0, api_1.test)('returns a created group by id', async ({ api, resources }) => {
|
|
30
|
+
const group = await createGroup(api, resources);
|
|
31
|
+
await (0, eventually_1.eventually)(async () => {
|
|
32
|
+
const response = await api.get('/groups/{groupId}', {
|
|
33
|
+
params: { groupId: group.groupId },
|
|
34
|
+
tenant: 'none',
|
|
35
|
+
});
|
|
36
|
+
const json = (await (0, assertions_1.assertOk)(response));
|
|
37
|
+
(0, test_1.expect)(json.groupId).toBe(group.groupId);
|
|
38
|
+
(0, test_1.expect)(json.name).toBe(group.name);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
(0, api_1.test)('updates a group', async ({ api, resources }) => {
|
|
42
|
+
const group = await createGroup(api, resources);
|
|
43
|
+
const updatedName = `Updated ${group.name}`;
|
|
44
|
+
const response = await api.put('/groups/{groupId}', {
|
|
45
|
+
params: { groupId: group.groupId },
|
|
46
|
+
body: { name: updatedName, description: 'updated by the API suite' },
|
|
47
|
+
tenant: 'none',
|
|
48
|
+
});
|
|
49
|
+
await (0, assertions_1.assertStatusIn)(response, [200, 204], 'the update returns the group on 8.8+ and an empty body on earlier minors');
|
|
50
|
+
await (0, eventually_1.eventually)(async () => {
|
|
51
|
+
const lookup = await api.get('/groups/{groupId}', {
|
|
52
|
+
params: { groupId: group.groupId },
|
|
53
|
+
tenant: 'none',
|
|
54
|
+
});
|
|
55
|
+
const json = (await (0, assertions_1.assertOk)(lookup));
|
|
56
|
+
(0, test_1.expect)(json.name).toBe(updatedName);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
(0, api_1.test)('finds a created group through search', async ({ api, resources }) => {
|
|
60
|
+
const group = await createGroup(api, resources);
|
|
61
|
+
await (0, eventually_1.eventually)(async () => {
|
|
62
|
+
const response = await api.post('/groups/search', {
|
|
63
|
+
body: { filter: { groupId: group.groupId }, page: { limit: 10 } },
|
|
64
|
+
tenant: 'none',
|
|
65
|
+
});
|
|
66
|
+
await (0, assertions_1.assertPaginated)(response, { exactItems: 1 });
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
(0, api_1.test)('deletes a group', async ({ api, resources }) => {
|
|
70
|
+
const group = await createGroup(api, resources);
|
|
71
|
+
const response = await api.delete('/groups/{groupId}', {
|
|
72
|
+
params: { groupId: group.groupId },
|
|
73
|
+
tenant: 'none',
|
|
74
|
+
});
|
|
75
|
+
// The shell suite accepted `204 404 500` for group deletion, so a server
|
|
76
|
+
// fault on delete was a pass.
|
|
77
|
+
await (0, assertions_1.assertStatusIn)(response, [204], 'deletion is acknowledged');
|
|
78
|
+
resources.forget('group', group.groupId);
|
|
79
|
+
await (0, eventually_1.eventually)(async () => {
|
|
80
|
+
const lookup = await api.get('/groups/{groupId}', {
|
|
81
|
+
params: { groupId: group.groupId },
|
|
82
|
+
tenant: 'none',
|
|
83
|
+
});
|
|
84
|
+
await (0, assertions_1.assertNotFound)(lookup);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
(0, api_1.test)('assigns and removes a user', async ({ api, resources }) => {
|
|
88
|
+
const group = await createGroup(api, resources);
|
|
89
|
+
const username = await (0, identity_1.provisionUsername)(api, resources);
|
|
90
|
+
const assign = await api.put('/groups/{groupId}/users/{username}', {
|
|
91
|
+
params: { groupId: group.groupId, username },
|
|
92
|
+
tenant: 'none',
|
|
93
|
+
});
|
|
94
|
+
await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
|
|
95
|
+
await (0, eventually_1.eventually)(async () => {
|
|
96
|
+
const response = await api.post('/groups/{groupId}/users/search', {
|
|
97
|
+
params: { groupId: group.groupId },
|
|
98
|
+
body: { page: { limit: 20 } },
|
|
99
|
+
tenant: 'none',
|
|
100
|
+
});
|
|
101
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
102
|
+
const usernames = page.items.map((item) => item.username);
|
|
103
|
+
(0, test_1.expect)(usernames).toContain(username);
|
|
104
|
+
});
|
|
105
|
+
const remove = await api.delete('/groups/{groupId}/users/{username}', {
|
|
106
|
+
params: { groupId: group.groupId, username },
|
|
107
|
+
tenant: 'none',
|
|
108
|
+
});
|
|
109
|
+
await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
|
|
110
|
+
});
|
|
111
|
+
(0, api_1.test)('lists the roles a group holds', async ({ api, resources }) => {
|
|
112
|
+
const group = await createGroup(api, resources);
|
|
113
|
+
const response = await api.post('/groups/{groupId}/roles/search', {
|
|
114
|
+
params: { groupId: group.groupId },
|
|
115
|
+
body: { page: { limit: 20 } },
|
|
116
|
+
tenant: 'none',
|
|
117
|
+
});
|
|
118
|
+
await (0, assertions_1.assertPaginated)(response, { exactItems: 0 });
|
|
119
|
+
});
|
|
120
|
+
(0, api_1.test)('rejects a group whose id already exists', async ({ api, resources }) => {
|
|
121
|
+
const group = await createGroup(api, resources);
|
|
122
|
+
const response = await api.post('/groups', {
|
|
123
|
+
body: (0, beans_1.newGroup)({ groupId: group.groupId }),
|
|
124
|
+
tenant: 'none',
|
|
125
|
+
});
|
|
126
|
+
await (0, assertions_1.assertConflict)(response);
|
|
127
|
+
});
|
|
128
|
+
(0, api_1.test)('rejects a group with no name', async ({ api }) => {
|
|
129
|
+
const response = await api.post('/groups', {
|
|
130
|
+
body: { groupId: (0, bpmn_1.uniqueId)('group') },
|
|
131
|
+
tenant: 'none',
|
|
132
|
+
});
|
|
133
|
+
await (0, assertions_1.assertBadRequest)(response, /name/i);
|
|
134
|
+
});
|
|
135
|
+
(0, api_1.test)('rejects updating an absent group', async ({ api }) => {
|
|
136
|
+
const response = await api.put('/groups/{groupId}', {
|
|
137
|
+
params: { groupId: (0, bpmn_1.uniqueId)('absent-group') },
|
|
138
|
+
body: { name: 'does not exist' },
|
|
139
|
+
tenant: 'none',
|
|
140
|
+
});
|
|
141
|
+
await (0, assertions_1.assertNotFound)(response);
|
|
142
|
+
});
|
|
143
|
+
(0, api_1.test)('rejects a lookup for an absent group', async ({ api }) => {
|
|
144
|
+
const response = await api.get('/groups/{groupId}', {
|
|
145
|
+
params: { groupId: (0, bpmn_1.uniqueId)('absent-group') },
|
|
146
|
+
tenant: 'none',
|
|
147
|
+
});
|
|
148
|
+
await (0, assertions_1.assertNotFound)(response);
|
|
149
|
+
});
|
|
150
|
+
(0, api_1.test)('rejects assigning a user to an absent group', async ({ api, resources, }) => {
|
|
151
|
+
const username = await (0, identity_1.provisionUsername)(api, resources);
|
|
152
|
+
const response = await api.put('/groups/{groupId}/users/{username}', {
|
|
153
|
+
params: {
|
|
154
|
+
groupId: (0, bpmn_1.uniqueId)('absent-group'),
|
|
155
|
+
username,
|
|
156
|
+
},
|
|
157
|
+
tenant: 'none',
|
|
158
|
+
});
|
|
159
|
+
await (0, assertions_1.assertNotFound)(response);
|
|
160
|
+
});
|
|
161
|
+
(0, api_1.test)('rejects an unauthenticated group creation', async ({ api }) => {
|
|
162
|
+
api_1.test.skip(capabilities_1.unauthenticatedAccessAllowed !== false, capabilities_1.unauthenticatedAccessAllowed === false
|
|
163
|
+
? ''
|
|
164
|
+
: capabilities_1.unauthenticatedAccessAllowed);
|
|
165
|
+
const response = await api.post('/groups', {
|
|
166
|
+
body: (0, beans_1.newGroup)(),
|
|
167
|
+
tenant: 'none',
|
|
168
|
+
authorization: null,
|
|
169
|
+
});
|
|
170
|
+
await (0, assertions_1.assertUnauthorized)(response);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client and mapping-rule membership across roles, groups and tenants.
|
|
3
|
+
*
|
|
4
|
+
* Clients are not created through this API on an OIDC cluster — they come from
|
|
5
|
+
* the identity provider — so these tests assert the membership endpoints
|
|
6
|
+
* against a client id that need not resolve to a real client. That matches what
|
|
7
|
+
* the endpoints do: they record an association, and the association is what is
|
|
8
|
+
* read back.
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Client and mapping-rule membership across roles, groups and tenants.
|
|
4
|
+
*
|
|
5
|
+
* Clients are not created through this API on an OIDC cluster — they come from
|
|
6
|
+
* the identity provider — so these tests assert the membership endpoints
|
|
7
|
+
* against a client id that need not resolve to a real client. That matches what
|
|
8
|
+
* the endpoints do: they record an association, and the association is what is
|
|
9
|
+
* read back.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const api_1 = require("../../../../fixtures/api");
|
|
13
|
+
const test_1 = require("@playwright/test");
|
|
14
|
+
const assertions_1 = require("../../../../utils/api/assertions");
|
|
15
|
+
const beans_1 = require("../../../../utils/api/beans");
|
|
16
|
+
const eventually_1 = require("../../../../utils/api/eventually");
|
|
17
|
+
const bpmn_1 = require("../../../../utils/api/bpmn");
|
|
18
|
+
api_1.test.describe('Role membership for clients and mapping rules', () => {
|
|
19
|
+
(0, api_1.test)('assigns and removes a client', async ({ api, resources }) => {
|
|
20
|
+
const role = (0, beans_1.newRole)();
|
|
21
|
+
await (0, assertions_1.assertCreated)(await api.post('/roles', { body: role, tenant: 'none' }));
|
|
22
|
+
resources.track('role', role.roleId);
|
|
23
|
+
const clientId = (0, bpmn_1.uniqueId)('client');
|
|
24
|
+
const assign = await api.put('/roles/{roleId}/clients/{clientId}', {
|
|
25
|
+
params: { roleId: role.roleId, clientId },
|
|
26
|
+
tenant: 'none',
|
|
27
|
+
});
|
|
28
|
+
await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
|
|
29
|
+
await (0, eventually_1.eventually)(async () => {
|
|
30
|
+
const response = await api.post('/roles/{roleId}/clients/search', {
|
|
31
|
+
params: { roleId: role.roleId },
|
|
32
|
+
body: { page: { limit: 20 } },
|
|
33
|
+
tenant: 'none',
|
|
34
|
+
});
|
|
35
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
36
|
+
const clientIds = page.items.map((item) => item.clientId);
|
|
37
|
+
(0, test_1.expect)(clientIds).toContain(clientId);
|
|
38
|
+
});
|
|
39
|
+
const remove = await api.delete('/roles/{roleId}/clients/{clientId}', {
|
|
40
|
+
params: { roleId: role.roleId, clientId },
|
|
41
|
+
tenant: 'none',
|
|
42
|
+
});
|
|
43
|
+
await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
|
|
44
|
+
});
|
|
45
|
+
(0, api_1.test)('assigns and removes a mapping rule', async ({ api, resources }) => {
|
|
46
|
+
const role = (0, beans_1.newRole)();
|
|
47
|
+
await (0, assertions_1.assertCreated)(await api.post('/roles', { body: role, tenant: 'none' }));
|
|
48
|
+
resources.track('role', role.roleId);
|
|
49
|
+
const rule = (0, beans_1.newMappingRule)();
|
|
50
|
+
await (0, assertions_1.assertCreated)(await api.post('/mapping-rules', { body: rule, tenant: 'none' }));
|
|
51
|
+
resources.track('mappingRule', rule.mappingRuleId);
|
|
52
|
+
const assign = await api.put('/roles/{roleId}/mapping-rules/{mappingRuleId}', {
|
|
53
|
+
params: { roleId: role.roleId, mappingRuleId: rule.mappingRuleId },
|
|
54
|
+
tenant: 'none',
|
|
55
|
+
});
|
|
56
|
+
await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
|
|
57
|
+
await (0, eventually_1.eventually)(async () => {
|
|
58
|
+
const response = await api.post('/roles/{roleId}/mapping-rules/search', {
|
|
59
|
+
params: { roleId: role.roleId },
|
|
60
|
+
body: { page: { limit: 20 } },
|
|
61
|
+
tenant: 'none',
|
|
62
|
+
});
|
|
63
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
64
|
+
const ruleIds = page.items.map((item) => item.mappingRuleId);
|
|
65
|
+
(0, test_1.expect)(ruleIds).toContain(rule.mappingRuleId);
|
|
66
|
+
});
|
|
67
|
+
const remove = await api.delete('/roles/{roleId}/mapping-rules/{mappingRuleId}', {
|
|
68
|
+
params: { roleId: role.roleId, mappingRuleId: rule.mappingRuleId },
|
|
69
|
+
tenant: 'none',
|
|
70
|
+
});
|
|
71
|
+
await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
|
|
72
|
+
});
|
|
73
|
+
(0, api_1.test)('rejects assigning a client to an absent role', async ({ api }) => {
|
|
74
|
+
const response = await api.put('/roles/{roleId}/clients/{clientId}', {
|
|
75
|
+
params: { roleId: (0, bpmn_1.uniqueId)('absent-role'), clientId: (0, bpmn_1.uniqueId)('client') },
|
|
76
|
+
tenant: 'none',
|
|
77
|
+
});
|
|
78
|
+
await (0, assertions_1.assertNotFound)(response);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
api_1.test.describe('Group membership for clients and mapping rules', () => {
|
|
82
|
+
(0, api_1.test)('assigns and removes a client', async ({ api, resources }) => {
|
|
83
|
+
const group = (0, beans_1.newGroup)();
|
|
84
|
+
await (0, assertions_1.assertCreated)(await api.post('/groups', { body: group, tenant: 'none' }));
|
|
85
|
+
resources.track('group', group.groupId);
|
|
86
|
+
const clientId = (0, bpmn_1.uniqueId)('client');
|
|
87
|
+
const assign = await api.put('/groups/{groupId}/clients/{clientId}', {
|
|
88
|
+
params: { groupId: group.groupId, clientId },
|
|
89
|
+
tenant: 'none',
|
|
90
|
+
});
|
|
91
|
+
await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
|
|
92
|
+
await (0, eventually_1.eventually)(async () => {
|
|
93
|
+
const response = await api.post('/groups/{groupId}/clients/search', {
|
|
94
|
+
params: { groupId: group.groupId },
|
|
95
|
+
body: { page: { limit: 20 } },
|
|
96
|
+
tenant: 'none',
|
|
97
|
+
});
|
|
98
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
99
|
+
const clientIds = page.items.map((item) => item.clientId);
|
|
100
|
+
(0, test_1.expect)(clientIds).toContain(clientId);
|
|
101
|
+
});
|
|
102
|
+
const remove = await api.delete('/groups/{groupId}/clients/{clientId}', {
|
|
103
|
+
params: { groupId: group.groupId, clientId },
|
|
104
|
+
tenant: 'none',
|
|
105
|
+
});
|
|
106
|
+
await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
|
|
107
|
+
});
|
|
108
|
+
(0, api_1.test)('assigns and removes a mapping rule', async ({ api, resources }) => {
|
|
109
|
+
const group = (0, beans_1.newGroup)();
|
|
110
|
+
await (0, assertions_1.assertCreated)(await api.post('/groups', { body: group, tenant: 'none' }));
|
|
111
|
+
resources.track('group', group.groupId);
|
|
112
|
+
const rule = (0, beans_1.newMappingRule)();
|
|
113
|
+
await (0, assertions_1.assertCreated)(await api.post('/mapping-rules', { body: rule, tenant: 'none' }));
|
|
114
|
+
resources.track('mappingRule', rule.mappingRuleId);
|
|
115
|
+
const assign = await api.put('/groups/{groupId}/mapping-rules/{mappingRuleId}', {
|
|
116
|
+
params: { groupId: group.groupId, mappingRuleId: rule.mappingRuleId },
|
|
117
|
+
tenant: 'none',
|
|
118
|
+
});
|
|
119
|
+
await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
|
|
120
|
+
await (0, eventually_1.eventually)(async () => {
|
|
121
|
+
const response = await api.post('/groups/{groupId}/mapping-rules/search', {
|
|
122
|
+
params: { groupId: group.groupId },
|
|
123
|
+
body: { page: { limit: 20 } },
|
|
124
|
+
tenant: 'none',
|
|
125
|
+
});
|
|
126
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
127
|
+
const ruleIds = page.items.map((item) => item.mappingRuleId);
|
|
128
|
+
(0, test_1.expect)(ruleIds).toContain(rule.mappingRuleId);
|
|
129
|
+
});
|
|
130
|
+
const remove = await api.delete('/groups/{groupId}/mapping-rules/{mappingRuleId}', {
|
|
131
|
+
params: { groupId: group.groupId, mappingRuleId: rule.mappingRuleId },
|
|
132
|
+
tenant: 'none',
|
|
133
|
+
});
|
|
134
|
+
await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
api_1.test.describe('Tenant membership for clients', () => {
|
|
138
|
+
(0, api_1.test)('assigns and removes a client', async ({ api, resources }) => {
|
|
139
|
+
const tenant = (0, beans_1.newTenant)();
|
|
140
|
+
await (0, assertions_1.assertCreated)(await api.post('/tenants', { body: tenant, tenant: 'none' }));
|
|
141
|
+
resources.track('tenant', tenant.tenantId);
|
|
142
|
+
const clientId = (0, bpmn_1.uniqueId)('client');
|
|
143
|
+
const assign = await api.put('/tenants/{tenantId}/clients/{clientId}', {
|
|
144
|
+
params: { tenantId: tenant.tenantId, clientId },
|
|
145
|
+
tenant: 'none',
|
|
146
|
+
});
|
|
147
|
+
await (0, assertions_1.assertStatusIn)(assign, [204], 'assignment is acknowledged');
|
|
148
|
+
await (0, eventually_1.eventually)(async () => {
|
|
149
|
+
const response = await api.post('/tenants/{tenantId}/clients/search', {
|
|
150
|
+
params: { tenantId: tenant.tenantId },
|
|
151
|
+
body: { page: { limit: 20 } },
|
|
152
|
+
tenant: 'none',
|
|
153
|
+
});
|
|
154
|
+
const page = await (0, assertions_1.assertPaginated)(response, { minItems: 1 });
|
|
155
|
+
const clientIds = page.items.map((item) => item.clientId);
|
|
156
|
+
(0, test_1.expect)(clientIds).toContain(clientId);
|
|
157
|
+
});
|
|
158
|
+
const remove = await api.delete('/tenants/{tenantId}/clients/{clientId}', {
|
|
159
|
+
params: { tenantId: tenant.tenantId, clientId },
|
|
160
|
+
tenant: 'none',
|
|
161
|
+
});
|
|
162
|
+
await (0, assertions_1.assertStatusIn)(remove, [204], 'removal is acknowledged');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|