Skip to content

Commit 676b484

Browse files
authored
Add uuid flag validation (#180)
* Added custom flag type: uuid * CustomFlags is now uppercase. * Changed flag type from Flags.string to CustomFlags.uuid where appropriate. Added integration tests. * Updated documentation. * Updated test name. * Updated a test.
1 parent 613e554 commit 676b484

86 files changed

Lines changed: 494 additions & 181 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/access-control/member/group/add.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ Groups and their roles can be provided to this command in multiple ways:
1212
The ID of the iTwin to which the groups will be added.
1313
**Type:** `string` **Required:** Yes
1414

15-
- **`--group-id`**
15+
- **`-g, --group-id`**
1616
Specify id of the group to add roles to. This flag can be provided multiple times.
1717
**Type:** `string` **Required:** No **Multiple:** Yes
1818

integration-tests/access-control/group.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,30 @@ const tests = () => {
128128
expect(updateError).to.not.be.undefined;
129129
expect(updateError?.message).to.be.equal("A maximum of 50 ims groups can be provided.");
130130
});
131+
132+
it("Should return an error when invalid uuid is provided as --itwin-id", async () => {
133+
const { error: infoError } = await runCommand<Group>(`access-control group info -i an-invalid-uuid -g ${crypto.randomUUID()}`);
134+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
135+
136+
const { error: updateError } = await runCommand<Group>(`access-control group update -i an-invalid-uuid -g ${crypto.randomUUID()}`);
137+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
138+
139+
const { error: deleteError } = await runCommand<ResultResponse>(`access-control group delete --itwin-id an-invalid-uuid --group-id ${crypto.randomUUID()}`);
140+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
141+
});
142+
143+
it("Should return an error when invalid uuid is provided as --group-id", async () => {
144+
const { error: infoError } = await runCommand<Group>(`access-control group info -i ${crypto.randomUUID()} -g another-invalid-uuid`);
145+
expect(infoError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
146+
147+
const { error: updateError } = await runCommand<Group>(`access-control group update -i ${crypto.randomUUID()} -g another-invalid-uuid`);
148+
expect(updateError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
149+
150+
const { error: deleteError } = await runCommand<ResultResponse>(
151+
`access-control group delete --itwin-id ${crypto.randomUUID()} --group-id another-invalid-uuid`,
152+
);
153+
expect(deleteError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
154+
});
131155
};
132156

133157
export default tests;

integration-tests/access-control/member/group.test.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,54 @@ const tests = () => {
314314
it("Should return an error when there are too many roles assigned", async () => {
315315
let command = `access-control member group update --itwin-id ${iTwinId} --group-id ${groupId1}`;
316316

317-
for (let i = 0; i < 51; i++) command += ` --role-id role${i}`;
317+
for (let i = 0; i < 51; i++) command += ` --role-id ${crypto.randomUUID()}`;
318318

319319
const { error: createError } = await runCommand<GroupMemberInfo[]>(command);
320320
expect(createError).to.not.be.undefined;
321321
expect(createError?.message).to.be.equal("A maximum of 50 roles can be assigned.");
322322
});
323+
324+
it("Should return an error when invalid uuid is provided as --itwin-id", async () => {
325+
const { error: addError } = await runCommand<Group>(`access-control member group add -i an-invalid-uuid -g ${crypto.randomUUID()}`);
326+
expect(addError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
327+
328+
const { error: infoError } = await runCommand<Group>(`access-control member group info -i an-invalid-uuid -g ${crypto.randomUUID()}`);
329+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
330+
331+
const { error: listError } = await runCommand<Group>(`access-control member group list -i an-invalid-uuid -g ${crypto.randomUUID()}`);
332+
expect(listError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
333+
334+
const { error: updateError } = await runCommand<Group>(`access-control member group update -i an-invalid-uuid -g ${crypto.randomUUID()}`);
335+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
336+
337+
const { error: deleteError } = await runCommand<ResultResponse>(
338+
`access-control member group delete --itwin-id an-invalid-uuid --group-id ${crypto.randomUUID()}`,
339+
);
340+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
341+
});
342+
343+
it("Should return an error when invalid uuid is provided as --group-id", async () => {
344+
const { error: addError } = await runCommand<Group>(`access-control member group add -i ${crypto.randomUUID()} -g another-invalid-uuid`);
345+
expect(addError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
346+
347+
const { error: infoError } = await runCommand<Group>(`access-control member group info -i ${crypto.randomUUID()} -g another-invalid-uuid`);
348+
expect(infoError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
349+
350+
const { error: updateError } = await runCommand<Group>(`access-control member group update -i ${crypto.randomUUID()} -g another-invalid-uuid`);
351+
expect(updateError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
352+
353+
const { error: deleteError } = await runCommand<ResultResponse>(
354+
`access-control member group delete --itwin-id ${crypto.randomUUID()} --group-id another-invalid-uuid`,
355+
);
356+
expect(deleteError?.message).to.contain("'another-invalid-uuid' is not a valid UUID.");
357+
});
358+
359+
it("Should return an error when invalid uuid is provided as --role-id", async () => {
360+
const { error: updateError } = await runCommand<Group>(
361+
`access-control member group update -i ${crypto.randomUUID()} -g ${crypto.randomUUID()} --role-id ${crypto.randomUUID()} --role-id an-invalid-uuid`,
362+
);
363+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
364+
});
323365
};
324366

325367
export default tests;

integration-tests/access-control/member/owner.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@ const tests = () => {
7373
expect(userInfo!.id).to.not.be.undefined;
7474
expect(owners!.some((owner) => owner.id === userInfo!.id)).to.be.true;
7575
});
76+
77+
it("Should return an error when invalid uuid is provided as --itwin-id", async () => {
78+
const { error: addError } = await runCommand<GroupMember>(`access-control member owner add -i an-invalid-uuid --email [email protected]`);
79+
expect(addError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
80+
81+
const { error: listError } = await runCommand<GroupMember>(`access-control member owner list -i an-invalid-uuid`);
82+
expect(listError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
83+
84+
const { error: deleteError } = await runCommand<ResultResponse>(
85+
`access-control member owner delete --itwin-id an-invalid-uuid --member-id ${crypto.randomUUID()}`,
86+
);
87+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
88+
});
89+
90+
it("Should return an error when invalid uuid is provided as --member-id", async () => {
91+
const { error: deleteError } = await runCommand<ResultResponse>(
92+
`access-control member owner delete --itwin-id ${crypto.randomUUID()} --member-id an-invalid-uuid`,
93+
);
94+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
95+
});
7696
};
7797

7898
export default tests;

integration-tests/access-control/member/user.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,12 +314,57 @@ const tests = () => {
314314
expect(usersInfo!).to.have.lengthOf(1);
315315

316316
let command = `access-control member user update --itwin-id ${iTwinId} --member-id ${usersInfo![0].id}`;
317-
for (let i = 0; i < 51; i++) command += ` --role-id role${i}`;
317+
for (let i = 0; i < 51; i++) command += ` --role-id ${crypto.randomUUID()}`;
318318

319319
const result = await runCommand<MembersResponse>(command);
320320
expect(result.error).to.not.be.undefined;
321321
expect(result.error?.message).to.be.equal("A maximum of 50 roles can be assigned.");
322322
});
323+
324+
it("Should return an error when invalid uuid is provided as --itwin-id", async () => {
325+
const { error: addError } = await runCommand<Member>(
326+
`access-control member user add -i an-invalid-uuid --email [email protected] --role-ids ${crypto.randomUUID()},${crypto.randomUUID()}`,
327+
);
328+
expect(addError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
329+
330+
const { error: infoError } = await runCommand<Member>(`access-control member user info -i an-invalid-uuid --member-id ${crypto.randomUUID()}`);
331+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
332+
333+
const { error: listError } = await runCommand<Member>(`access-control member user list -i an-invalid-uuid`);
334+
expect(listError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
335+
336+
const { error: updateError } = await runCommand<Member>(
337+
`access-control member user update -i an-invalid-uuid --member-id ${crypto.randomUUID()} --role-id ${crypto.randomUUID()}`,
338+
);
339+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
340+
341+
const { error: deleteError } = await runCommand<ResultResponse>(
342+
`access-control member user delete --itwin-id an-invalid-uuid --member-id ${crypto.randomUUID()}`,
343+
);
344+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
345+
});
346+
347+
it("Should return an error when invalid uuid is provided as --member-id", async () => {
348+
const { error: infoError } = await runCommand<Member>(`access-control member user info -i ${crypto.randomUUID()} --member-id an-invalid-uuid`);
349+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
350+
351+
const { error: updateError } = await runCommand<Member>(
352+
`access-control member user update -i ${crypto.randomUUID()} --member-id an-invalid-uuid --role-id ${crypto.randomUUID()}`,
353+
);
354+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
355+
356+
const { error: deleteError } = await runCommand<ResultResponse>(
357+
`access-control member user delete --itwin-id ${crypto.randomUUID()} --member-id an-invalid-uuid`,
358+
);
359+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
360+
});
361+
362+
it("Should return an error when invalid uuid is provided as --role-id", async () => {
363+
const { error: updateError } = await runCommand<Member>(
364+
`access-control member user update -i ${crypto.randomUUID()} --member-id ${crypto.randomUUID()} --role-id an-invalid-uuid`,
365+
);
366+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
367+
});
323368
};
324369

325370
export default tests;

integration-tests/access-control/role.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,34 @@ const tests = () => {
8585
const { result: deleteResult } = await runCommand<ResultResponse>(`access-control role delete --itwin-id ${iTwinId} --role-id ${newRole!.id}`);
8686
expect(deleteResult).to.have.property("result", "deleted");
8787
});
88+
89+
it("Should return an error when invalid uuid is provided as --itwin-id", async () => {
90+
const { error: addError } = await runCommand<Role>(`access-control role create -i an-invalid-uuid -n Name -d Description`);
91+
expect(addError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
92+
93+
const { error: infoError } = await runCommand<Role>(`access-control role info -i an-invalid-uuid --role-id ${crypto.randomUUID()}`);
94+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
95+
96+
const { error: listError } = await runCommand<Role>(`access-control role list -i an-invalid-uuid`);
97+
expect(listError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
98+
99+
const { error: updateError } = await runCommand<Role>(`access-control role update -i an-invalid-uuid --role-id ${crypto.randomUUID()} --name NewName`);
100+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
101+
102+
const { error: deleteError } = await runCommand<ResultResponse>(`access-control role delete --itwin-id an-invalid-uuid --role-id ${crypto.randomUUID()}`);
103+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
104+
});
105+
106+
it("Should return an error when invalid uuid is provided as --role-id", async () => {
107+
const { error: infoError } = await runCommand<Role>(`access-control role info -i ${crypto.randomUUID()} --role-id an-invalid-uuid`);
108+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
109+
110+
const { error: updateError } = await runCommand<Role>(`access-control role update -i ${crypto.randomUUID()} --role-id an-invalid-uuid --name NewName`);
111+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
112+
113+
const { error: deleteError } = await runCommand<ResultResponse>(`access-control role delete --itwin-id ${crypto.randomUUID()} --role-id an-invalid-uuid`);
114+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
115+
});
88116
};
89117

90118
export default tests;

integration-tests/context/context.test.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,8 @@ const tests = () =>
7171
expect(output2.result).to.deep.equal({ iModelId: undefined, iTwinId: anotherITwin.id });
7272
});
7373

74-
it("should fail to set context with invalid iTwin ID", async () => {
75-
const invalidITwinId = "invalid-id";
76-
const output = await runCommand(`context set --itwin-id ${invalidITwinId}`);
74+
it("should fail to set context with not found iTwin ID", async () => {
75+
const output = await runCommand(`context set --itwin-id ${crypto.randomUUID()}`);
7776
expect(output.error).to.not.be.undefined;
7877
expect(output.error?.message).to.contain("Requested iTwin is not available.");
7978
});
@@ -124,11 +123,21 @@ const tests = () =>
124123
});
125124

126125
it("should fail to set context with only an iModel ID if the iModel does not exist", async () => {
127-
const invalidIModelId = "invalid-id";
126+
const invalidIModelId = crypto.randomUUID();
128127
const output = await runCommand(`context set --imodel-id ${invalidIModelId}`);
129128
expect(output.error).to.not.be.undefined;
130129
expect(output.error?.message).to.contain("Requested iModel is not available.");
131130
});
131+
132+
it("should fail to set context when --itwin-id or --imodel-id in not a valid uuid", async () => {
133+
const { error: iModelIdError } = await runCommand(`context set --imodel-id an-invalid-uuid`);
134+
expect(iModelIdError).to.not.be.undefined;
135+
expect(iModelIdError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
136+
137+
const { error: iTwinIdError } = await runCommand(`context set --itwin-id an-invalid-uuid`);
138+
expect(iTwinIdError).to.not.be.undefined;
139+
expect(iTwinIdError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
140+
});
132141
});
133142

134143
export default tests;

integration-tests/imodel/connection/create.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ const tests = () =>
9191
"When multiple connector-type options are provided, their amount must match file-id option amount. Alternatively, you can provide a single connector-type option, which will then be applied to all file-id options.",
9292
);
9393
});
94+
95+
it(`should return an error when invalid uuid is provided as --imodel-id`, async () => {
96+
const { error: createError } = await runCommand<StorageConnection>(
97+
`imodel connection create -m an-invalid-uuid -f ${testFileId1} --connector-type MSTN -n TestConnection`,
98+
);
99+
expect(createError).to.not.be.undefined;
100+
expect(createError!.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
101+
});
94102
});
95103

96104
export default tests;

integration-tests/imodel/connection/list.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ const tests = () =>
8080
expect(filteredConnections!.connections).to.have.lengthOf(1);
8181
expect(filteredConnections!.connections[0].id).to.be.equal(allConnections!.connections[1].id);
8282
});
83+
84+
it("should return an error when invalid uuid is provided as --imodel-id", async () => {
85+
const { error } = await runCommand<StorageConnectionListResponse>(`imodel connection list -m an-invalid-uuid`);
86+
expect(error?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
87+
});
8388
});
8489

8590
export default tests;

integration-tests/imodel/connection/sourcefile.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,21 @@ const tests = () =>
136136
);
137137
expect(deleteResult2).to.have.property("result", "deleted");
138138
});
139+
140+
it("Should return an error when invalid uuid is provided as --source-file-id", async () => {
141+
const { error: infoError } = await runCommand<SourceFile>(`imodel connection sourcefile info -c some-connection-id --source-file-id an-invalid-uuid`);
142+
expect(infoError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
143+
144+
const { error: updateError } = await runCommand<SourceFile>(
145+
`imodel connection sourcefile update -c some-connection-id --connector-type MSTN --storage-file-id some-id --source-file-id an-invalid-uuid`,
146+
);
147+
expect(updateError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
148+
149+
const { error: deleteError } = await runCommand<ResultResponse>(
150+
`imodel connection sourcefile delete -c some-connection-id --source-file-id an-invalid-uuid`,
151+
);
152+
expect(deleteError?.message).to.contain("'an-invalid-uuid' is not a valid UUID.");
153+
});
139154
});
140155

141156
export default tests;

0 commit comments

Comments
 (0)