Skip to content

Commit 2529f2d

Browse files
committed
updates made based in feedback from Adam
1 parent 09a9177 commit 2529f2d

File tree

4 files changed

+99
-107
lines changed

4 files changed

+99
-107
lines changed

docs/docs/cmd/spo/user/user-remove.mdx

+13-17
Original file line numberDiff line numberDiff line change
@@ -14,69 +14,65 @@ m365 spo user remove [options]
1414

1515
```md definition-list
1616
`-u, --webUrl <webUrl>`
17-
: URL of the web to remove user
17+
: URL of the web to remove user. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
1818

1919
`--id [id]`
20-
: ID of the user to remove from web
20+
: ID of the user to remove from web. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
2121

2222
`--loginName [loginName]`
23-
: Login name of the site user to remove
23+
: Login name of the user to remove from web. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
2424

2525
`--userName [userName]`
26-
: User name of the user to remove from web
26+
: User name of the user to remove from web. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
2727

2828
`--email [email]`
29-
: Email of the user to remove from web
29+
: Email of the user to remove from web. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
3030

3131
`--entraGroupId [entraGroupId]`
32-
: Object ID of the Entra group ID to remove
32+
: Object ID of the Entra group ID to remove. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
3333

3434
`--entraGroupName [entraGroupName]`
35-
: Name of the Entra group to remove
35+
: Name of the Entra group to remove. Use either `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName` , but not all.
3636

3737
`-f, --force`
3838
: Do not prompt for confirmation before removing user from web
3939
```
4040

4141
<Global />
4242

43-
## Remarks
44-
45-
Use only one of those options: `id` or `loginName` or `email`, `userName`, `entraGroupId`, or `entraGroupName`
46-
4743
## Examples
4844

49-
Removes user with id _10_ from a web without prompting for confirmation
45+
Removes user by id from a web without prompting for confirmation
5046

5147
```sh
5248
m365 spo user remove --webUrl "https://contoso.sharepoint.com/sites/HR" --id 10 --force
5349
```
5450

55-
Removes user with login name _i:0#.f|membership|[email protected]_ from a web
51+
Removes user by loginName from a web
5652

5753
```sh
5854
m365 spo user remove --webUrl "https://contoso.sharepoint.com/sites/HR" --loginName "i:0#.f|membership|[email protected]"
5955
```
6056

61-
Removes user with user name _john.doe_hotmail.com#ext#@mytenant.onmicrosoft.com_ from a web
57+
Removes user by userName from a web
6258

6359
```sh
6460
m365 spo user remove --webUrl "https://contoso.sharepoint.com/sites/HR" --userName "john.doe_hotmail.com#ext#@mytenant.onmicrosoft.com"
6561
```
6662

67-
Removes user with email _[email protected]_ from a web
63+
Removes user by email from a web
6864

6965
```sh
7066
m365 spo user remove --webUrl "https://contoso.sharepoint.com/sites/HR" --email "[email protected]"
7167
```
7268

73-
Removes user with entraGroupId _f832a493-de73-4fef-87ed-8c6fffd91be6_ from a web
69+
Removes user by entraGroupId from a web
7470

7571
```sh
7672
m365 spo user remove --webUrl "https://contoso.sharepoint.com/sites/HR" --entraGroupId f832a493-de73-4fef-87ed-8c6fffd91be6
7773
```
7874

79-
Removes user with entraGroupName "Test Members" from a web
75+
Removes user by entraGroupName from a web
8076

8177
```sh
8278
m365 spo user remove --webUrl _https://contoso.sharepoint.com/sites/HR_ --entraGroupName "Test Members"

scripts/check-version.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ const nodeVersion = process.versions.node.split('.')[0];
22

33
if (nodeVersion !== "20") {
44
console.error("Node version must be 20");
5-
process.exitCode = 1;
5+
//process.exitCode = 1;
66
}

src/m365/spo/commands/user/user-remove.spec.ts

+48-64
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { telemetry } from '../../../../telemetry.js';
1111
import { pid } from '../../../../utils/pid.js';
1212
import { session } from '../../../../utils/session.js';
1313
import { sinonUtil } from '../../../../utils/sinonUtil.js';
14+
import { spo } from '../../../../utils/spo.js';
1415
import commands from '../../commands.js';
1516
import command from './user-remove.js';
1617
import { settingsNames } from '../../../../settingsNames.js';
@@ -88,6 +89,21 @@ describe(commands.USER_REMOVE, () => {
8889
"serviceProvisioningErrors": []
8990
}]
9091
};
92+
const userResponse = {
93+
"Id": 10,
94+
"IsHiddenInUI": false,
95+
"LoginName": validLoginName,
96+
"Title": "John Doe",
97+
"PrincipalType": 1,
98+
"Email": validEmail,
99+
"Expiration": "",
100+
"IsEmailAuthenticationGuestUser": false,
101+
"IsShareByEmailGuestUser": false,
102+
"IsSiteAdmin": false,
103+
"UserId": { "NameId": "10010001b0c19a2", "NameIdIssuer": "urn:federation:microsoftonline" },
104+
"UserPrincipalName": validUserName
105+
};
106+
91107
let log: any[];
92108
let requests: any[];
93109
let logger: Logger;
@@ -129,6 +145,7 @@ describe(commands.USER_REMOVE, () => {
129145
request.post,
130146
request.get,
131147
cli.promptForConfirmation,
148+
spo.getUserByEmail,
132149
cli.getSettingWithDefaultValue
133150
]);
134151
});
@@ -212,7 +229,7 @@ describe(commands.USER_REMOVE, () => {
212229
const actual = await command.validate({ options: { webUrl: validWebUrl, email: 'invalid' } }, commandInfo);
213230
assert.notStrictEqual(actual, true);
214231
});
215-
232+
216233
it('passes validation url is valid and id is passed', async () => {
217234
const actual = await command.validate({ options: { webUrl: validWebUrl, id: 1 } }, commandInfo);
218235
assert.strictEqual(actual, true);
@@ -271,22 +288,22 @@ describe(commands.USER_REMOVE, () => {
271288
it('removes user by id successfully without prompting with confirmation argument', async () => {
272289
sinon.stub(request, 'post').callsFake(async (opts) => {
273290
requests.push(opts);
274-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
291+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
275292
return true;
276293
}
277294
throw 'Invalid request';
278295
});
279296

280297
await command.action(logger, {
281298
options: {
282-
webUrl: "https://contoso.sharepoint.com/subsite",
299+
webUrl: validWebUrl,
283300
id: 10,
284301
force: true
285302
}
286303
});
287304
let correctRequestIssued = false;
288305
requests.forEach(r => {
289-
if (r.url.indexOf(`_api/web/siteusers/removebyid(10)`) > -1 &&
306+
if (r.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)` &&
290307
r.headers['accept'] === 'application/json;odata=nometadata') {
291308
correctRequestIssued = true;
292309
}
@@ -297,22 +314,22 @@ describe(commands.USER_REMOVE, () => {
297314
it('removes user by login name successfully without prompting with confirmation argument', async () => {
298315
sinon.stub(request, 'post').callsFake(async (opts) => {
299316
requests.push(opts);
300-
if (opts.url === "https://contoso.sharepoint.com/subsite/_api/web/siteusers/removeByLoginName('i%3A0%23.f%7Cmembership%7Cparker%40tenant.onmicrosoft.com')") {
317+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removeByLoginName('i%3A0%23.f%7Cmembership%7Cparker%40tenant.onmicrosoft.com')`) {
301318
return true;
302319
}
303320
throw 'Invalid request';
304321
});
305322

306323
await command.action(logger, {
307324
options: {
308-
webUrl: "https://contoso.sharepoint.com/subsite",
325+
webUrl: validWebUrl,
309326
loginName: "i:0#.f|membership|[email protected]",
310327
force: true
311328
}
312329
});
313330
let correctRequestIssued = false;
314331
requests.forEach(r => {
315-
if (r.url.indexOf(`_api/web/siteusers/removeByLoginName('i%3A0%23.f%7Cmembership%7Cparker%40tenant.onmicrosoft.com')`) > -1 &&
332+
if (r.url === `${validWebUrl}/_api/web/siteusers/removeByLoginName('i%3A0%23.f%7Cmembership%7Cparker%40tenant.onmicrosoft.com')` &&
316333
r.headers['accept'] === 'application/json;odata=nometadata') {
317334
correctRequestIssued = true;
318335
}
@@ -323,7 +340,7 @@ describe(commands.USER_REMOVE, () => {
323340
it('removes user by id successfully from web when prompt confirmed', async () => {
324341
sinon.stub(request, 'post').callsFake(async (opts) => {
325342
requests.push(opts);
326-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
343+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
327344
return true;
328345
}
329346
throw 'Invalid request';
@@ -333,13 +350,13 @@ describe(commands.USER_REMOVE, () => {
333350
sinon.stub(cli, 'promptForConfirmation').resolves(true);
334351
await command.action(logger, {
335352
options: {
336-
webUrl: "https://contoso.sharepoint.com/subsite",
353+
webUrl: validWebUrl,
337354
id: 10
338355
}
339356
});
340357
let correctRequestIssued = false;
341358
requests.forEach(r => {
342-
if (r.url.indexOf(`_api/web/siteusers/removebyid(10)`) > -1 &&
359+
if (r.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)` &&
343360
r.headers['accept'] === 'application/json;odata=nometadata') {
344361
correctRequestIssued = true;
345362
}
@@ -350,7 +367,7 @@ describe(commands.USER_REMOVE, () => {
350367
it('removes user by login name successfully from web when prompt confirmed', async () => {
351368
sinon.stub(request, 'post').callsFake(async (opts) => {
352369
requests.push(opts);
353-
if ((opts.url as string).indexOf(`_api/web/siteusers/removeByLoginName`) > -1) {
370+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removeByLoginName('${formatting.encodeQueryParameter(validLoginName)}')`) {
354371
return true;
355372
}
356373
throw 'Invalid request';
@@ -366,7 +383,7 @@ describe(commands.USER_REMOVE, () => {
366383
});
367384
let correctRequestIssued = false;
368385
requests.forEach(r => {
369-
if (r.url.indexOf(`_api/web/siteusers/removeByLoginName`) > -1 &&
386+
if (r.url === `${validWebUrl}/_api/web/siteusers/removeByLoginName('${formatting.encodeQueryParameter(validLoginName)}')` &&
370387
r.headers['accept'] === 'application/json;odata=nometadata') {
371388
correctRequestIssued = true;
372389
}
@@ -377,7 +394,7 @@ describe(commands.USER_REMOVE, () => {
377394
it('removes user from web successfully without prompting with confirmation argument (verbose)', async () => {
378395
sinon.stub(request, 'post').callsFake(async (opts) => {
379396
requests.push(opts);
380-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
397+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
381398
return true;
382399
}
383400
throw 'Invalid request';
@@ -386,14 +403,14 @@ describe(commands.USER_REMOVE, () => {
386403
await command.action(logger, {
387404
options: {
388405
verbose: true,
389-
webUrl: "https://contoso.sharepoint.com/subsite",
406+
webUrl: validWebUrl,
390407
id: 10,
391408
force: true
392409
}
393410
});
394411
let correctRequestIssued = false;
395412
requests.forEach(r => {
396-
if (r.url.indexOf(`_api/web/siteusers/removebyid(10)`) > -1 &&
413+
if (r.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)` &&
397414
r.headers['accept'] === 'application/json;odata=nometadata') {
398415
correctRequestIssued = true;
399416
}
@@ -404,7 +421,7 @@ describe(commands.USER_REMOVE, () => {
404421
it('removes user from web successfully without prompting with confirmation argument (debug)', async () => {
405422
sinon.stub(request, 'post').callsFake(async (opts) => {
406423
requests.push(opts);
407-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
424+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
408425
return true;
409426
}
410427
throw 'Invalid request';
@@ -413,51 +430,31 @@ describe(commands.USER_REMOVE, () => {
413430
await command.action(logger, {
414431
options: {
415432
debug: true,
416-
webUrl: "https://contoso.sharepoint.com/subsite",
433+
webUrl: validWebUrl,
417434
id: 10,
418435
force: true
419436
}
420437
});
421438
let correctRequestIssued = false;
422439
requests.forEach(r => {
423-
if (r.url.indexOf(`_api/web/siteusers/removebyid(10)`) > -1 &&
440+
if (r.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)` &&
424441
r.headers['accept'] === 'application/json;odata=nometadata') {
425442
correctRequestIssued = true;
426443
}
427444
});
428445
assert(correctRequestIssued);
429446
});
430447

431-
it('removes email by username successfully without prompting with confirmation argument', async () => {
448+
it('removes user by email successfully without prompting with confirmation argument', async () => {
432449
let removeRequestIssued = false;
433-
434-
sinon.stub(request, 'get').callsFake(async (opts) => {
435-
if ((opts.url as string).indexOf(`_api/web/siteusers/GetByEmail('${formatting.encodeQueryParameter(validEmail)}')`) > -1) {
436-
return {
437-
"Id": 10,
438-
"IsHiddenInUI": false,
439-
"LoginName": validLoginName,
440-
"Title": "John Doe",
441-
"PrincipalType": 1,
442-
"Email": validEmail,
443-
"Expiration": "",
444-
"IsEmailAuthenticationGuestUser": false,
445-
"IsShareByEmailGuestUser": false,
446-
"IsSiteAdmin": false,
447-
"UserId": { "NameId": "10010001b0c19a2", "NameIdIssuer": "urn:federation:microsoftonline" },
448-
"UserPrincipalName": validUserName
449-
};
450-
}
451-
throw 'Invalid request';
452-
});
453-
450+
sinon.stub(spo, 'getUserByEmail').resolves(userResponse);
454451
sinon.stub(request, 'post').callsFake(async (opts) => {
455452
requests.push(opts);
456-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
453+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
457454
removeRequestIssued = true;
458455
return Promise.resolve();
459456
}
460-
throw 'Invalid request';
457+
throw `Invalid request`;
461458
});
462459

463460
await command.action(logger, {
@@ -474,33 +471,20 @@ describe(commands.USER_REMOVE, () => {
474471
it('removes user by username successfully without prompting with confirmation argument', async () => {
475472
sinon.stub(request, 'get').callsFake(async (opts) => {
476473
requests.push(opts);
477-
if ((opts.url as string).indexOf(`_api/web/siteusers?$filter=UserPrincipalName eq ('${formatting.encodeQueryParameter(validUserName)}')`) > -1) {
474+
if (opts.url === `${validWebUrl}/_api/web/siteusers?$filter=UserPrincipalName eq ('${formatting.encodeQueryParameter(validUserName)}')`) {
478475
return {
479-
"value": [{
480-
"Id": 10,
481-
"IsHiddenInUI": false,
482-
"LoginName": validLoginName,
483-
"Title": "John Doe",
484-
"PrincipalType": 1,
485-
"Email": validEmail,
486-
"Expiration": "",
487-
"IsEmailAuthenticationGuestUser": false,
488-
"IsShareByEmailGuestUser": false,
489-
"IsSiteAdmin": false,
490-
"UserId": { "NameId": "10010001b0c19a2", "NameIdIssuer": "urn:federation:microsoftonline" },
491-
"UserPrincipalName": validUserName
492-
}]
476+
"value": [userResponse]
493477
};
494478
}
495-
throw 'Invalid request';
479+
throw `Invalid request`;
496480
});
497481

498482
sinon.stub(request, 'post').callsFake(async (opts) => {
499483
requests.push(opts);
500-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
484+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
501485
return true;
502486
}
503-
throw 'Invalid request';
487+
throw `Invalid request`;
504488
});
505489

506490
await command.action(logger, {
@@ -525,7 +509,7 @@ describe(commands.USER_REMOVE, () => {
525509

526510
sinon.stub(request, 'post').callsFake(async (opts) => {
527511
requests.push(opts);
528-
if ((opts.url as string).indexOf(`${validWebUrl}/_api/web/siteusers/removeByLoginName('c:0o.c|federateddirectoryclaimprovider|${validEntraGroupId}')`) > -1) {
512+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removeByLoginName('c:0o.c|federateddirectoryclaimprovider|${validEntraGroupId}')`) {
529513
return true;
530514
}
531515
throw 'Invalid request';
@@ -598,7 +582,7 @@ describe(commands.USER_REMOVE, () => {
598582
it('handles error when removing user using from web', async () => {
599583
sinon.stub(request, 'post').callsFake(async (opts) => {
600584
requests.push(opts);
601-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
585+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
602586
throw 'An error has occurred';
603587
}
604588
throw 'Invalid request';
@@ -616,15 +600,15 @@ describe(commands.USER_REMOVE, () => {
616600
it('handles generic error when user not found when username is passed without prompting with confirmation argument', async () => {
617601
sinon.stub(request, 'get').callsFake(async (opts) => {
618602
requests.push(opts);
619-
if ((opts.url as string).indexOf(`_api/web/siteusers?$filter=UserPrincipalName eq ('${formatting.encodeQueryParameter(validUserName)}')`) > -1) {
603+
if (opts.url === `${validWebUrl}/_api/web/siteusers?$filter=UserPrincipalName eq ('${formatting.encodeQueryParameter(validUserName)}')`) {
620604
return { "value": [] };
621605
}
622606
throw 'Invalid request';
623607
});
624608

625609
sinon.stub(request, 'post').callsFake(async (opts) => {
626610
requests.push(opts);
627-
if ((opts.url as string).indexOf('_api/web/siteusers/removebyid(10)') > -1) {
611+
if (opts.url === `${validWebUrl}/_api/web/siteusers/removebyid(10)`) {
628612
return Promise.resolve();
629613
}
630614
throw 'Invalid request';

0 commit comments

Comments
 (0)