1
+ import assert from 'assert' ;
2
+ import sinon from 'sinon' ;
3
+ import auth from '../../../../Auth.js' ;
4
+ import { CommandInfo } from "../../../../cli/CommandInfo.js" ;
5
+ import { Logger } from '../../../../cli/Logger.js' ;
6
+ import request from '../../../../request.js' ;
7
+ import { telemetry } from '../../../../telemetry.js' ;
8
+ import { pid } from '../../../../utils/pid.js' ;
9
+ import { session } from '../../../../utils/session.js' ;
10
+ import { sinonUtil } from '../../../../utils/sinonUtil.js' ;
11
+ import { cli } from '../../../../cli/cli.js' ;
12
+ import commands from '../../commands.js' ;
13
+ import command from './containertype-remove.js' ;
14
+ import { spe } from '../../../../utils/spe.js' ;
15
+ import { z } from 'zod' ;
16
+ import { CommandError } from '../../../../Command.js' ;
17
+ import config from '../../../../config.js' ;
18
+ import { spo } from '../../../../utils/spo.js' ;
19
+
20
+ describe ( commands . CONTAINERTYPE_REMOVE , ( ) => {
21
+ const spoAdminUrl = 'https://contoso-admin.sharepoint.com' ;
22
+ const containerTypeId = 'c6f08d91-77fa-485f-9369-f246ec0fc19c' ;
23
+ const containerTypeName = 'Container type name' ;
24
+
25
+ let log : string [ ] ;
26
+ let logger : Logger ;
27
+ let commandInfo : CommandInfo ;
28
+ let commandOptionsSchema : z . ZodTypeAny ;
29
+ let confirmationPromptStub : sinon . SinonStub ;
30
+
31
+ before ( ( ) => {
32
+ sinon . stub ( auth , 'restoreAuth' ) . resolves ( ) ;
33
+ sinon . stub ( telemetry , 'trackEvent' ) . resolves ( ) ;
34
+ sinon . stub ( pid , 'getProcessName' ) . returns ( '' ) ;
35
+ sinon . stub ( session , 'getId' ) . returns ( '' ) ;
36
+
37
+ auth . connection . active = true ;
38
+ auth . connection . spoUrl = spoAdminUrl . replace ( '-admin.sharepoint.com' , '.sharepoint.com' ) ;
39
+ sinon . stub ( spo , 'ensureFormDigest' ) . resolves ( { FormDigestValue : 'abc' , FormDigestTimeoutSeconds : 1800 , FormDigestExpiresAt : new Date ( ) , WebFullUrl : 'https://contoso-admin.sharepoint.com' } ) ;
40
+ commandInfo = cli . getCommandInfo ( command ) ;
41
+ commandOptionsSchema = commandInfo . command . getSchemaToParse ( ) ! ;
42
+ } ) ;
43
+
44
+ beforeEach ( ( ) => {
45
+ log = [ ] ;
46
+ logger = {
47
+ log : async ( msg : string ) => {
48
+ log . push ( msg ) ;
49
+ } ,
50
+ logRaw : async ( msg : string ) => {
51
+ log . push ( msg ) ;
52
+ } ,
53
+ logToStderr : async ( msg : string ) => {
54
+ log . push ( msg ) ;
55
+ }
56
+ } ;
57
+ confirmationPromptStub = sinon . stub ( cli , 'promptForConfirmation' ) . resolves ( false ) ;
58
+ } ) ;
59
+
60
+ afterEach ( ( ) => {
61
+ sinonUtil . restore ( [
62
+ request . post ,
63
+ spe . getContainerTypeIdByName ,
64
+ cli . promptForConfirmation
65
+ ] ) ;
66
+ } ) ;
67
+
68
+ after ( ( ) => {
69
+ sinon . restore ( ) ;
70
+ auth . connection . active = false ;
71
+ auth . connection . spoUrl = undefined ;
72
+ } ) ;
73
+
74
+ it ( 'has correct name' , ( ) => {
75
+ assert . strictEqual ( command . name , commands . CONTAINERTYPE_REMOVE ) ;
76
+ } ) ;
77
+
78
+ it ( 'has a description' , ( ) => {
79
+ assert . notStrictEqual ( command . description , null ) ;
80
+ } ) ;
81
+
82
+ it ( 'fails validation if both id and name options are passed' , async ( ) => {
83
+ const actual = commandOptionsSchema . safeParse ( { id : containerTypeId , name : containerTypeName } ) ;
84
+ assert . strictEqual ( actual . success , false ) ;
85
+ } ) ;
86
+
87
+ it ( 'fails validation if neither id nor name options are passed' , async ( ) => {
88
+ const actual = commandOptionsSchema . safeParse ( { } ) ;
89
+ assert . strictEqual ( actual . success , false ) ;
90
+ } ) ;
91
+
92
+ it ( 'fails validation if id is not a valid GUID' , async ( ) => {
93
+ const actual = commandOptionsSchema . safeParse ( { id : 'invalid' } ) ;
94
+ assert . strictEqual ( actual . success , false ) ;
95
+ } ) ;
96
+
97
+ it ( 'passes validation if id is a valid GUID' , async ( ) => {
98
+ const actual = commandOptionsSchema . safeParse ( { id : containerTypeId } ) ;
99
+ assert . strictEqual ( actual . success , true ) ;
100
+ } ) ;
101
+
102
+ it ( 'passes validation if name is passed' , async ( ) => {
103
+ const actual = commandOptionsSchema . safeParse ( { name : containerTypeName } ) ;
104
+ assert . strictEqual ( actual . success , true ) ;
105
+ } ) ;
106
+
107
+ it ( 'prompts before removing the container type' , async ( ) => {
108
+ await command . action ( logger , { options : { id : containerTypeId } } ) ;
109
+ assert ( confirmationPromptStub . calledOnce ) ;
110
+ } ) ;
111
+
112
+ it ( 'aborts removing the container type when prompt is not confirmed' , async ( ) => {
113
+ const postStub = sinon . stub ( request , 'post' ) . resolves ( [ ] ) ;
114
+
115
+ await command . action ( logger , { options : { name : containerTypeName } } ) ;
116
+ assert ( postStub . notCalled ) ;
117
+ } ) ;
118
+
119
+ it ( 'correctly removes a container type by id' , async ( ) => {
120
+ const postStub = sinon . stub ( request , 'post' ) . callsFake ( async ( opts ) => {
121
+ if ( opts . url === `${ spoAdminUrl } /_vti_bin/client.svc/ProcessQuery` ) {
122
+ return [
123
+ {
124
+ SchemaVersion : '15.0.0.0' ,
125
+ LibraryVersion : '16.0.25919.12007' ,
126
+ ErrorInfo : null ,
127
+ TraceCorrelationId : '864c91a1-f07a-c000-29c0-273ee30d83d8'
128
+ } ,
129
+ 7 ,
130
+ {
131
+ IsNull : false
132
+ }
133
+ ] ;
134
+ }
135
+
136
+ throw 'Invalid request URL: ' + opts . url ;
137
+ } ) ;
138
+
139
+ await command . action ( logger , { options : { id : containerTypeId , force : true , verbose : true } } ) ;
140
+ assert . strictEqual ( postStub . firstCall . args [ 0 ] . data , `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${ config . applicationName } " xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="7" ObjectPathId="6" /><Method Name="RemoveSPOContainerType" Id="8" ObjectPathId="6"><Parameters><Parameter TypeId="{b66ab1ca-fd51-44f9-8cfc-01f5c2a21f99}"><Property Name="ContainerTypeId" Type="Guid">{${ containerTypeId } }</Property></Parameter></Parameters></Method></Actions><ObjectPaths><Constructor Id="6" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>` ) ;
141
+ assert . strictEqual ( postStub . lastCall . args [ 0 ] . headers ! [ 'X-RequestDigest' ] , 'abc' ) ;
142
+ } ) ;
143
+
144
+ it ( 'correctly removes a container type by name' , async ( ) => {
145
+ sinon . stub ( spe , 'getContainerTypeIdByName' ) . resolves ( containerTypeId ) ;
146
+
147
+ const postStub = sinon . stub ( request , 'post' ) . callsFake ( async ( opts ) => {
148
+ if ( opts . url === `${ spoAdminUrl } /_vti_bin/client.svc/ProcessQuery` ) {
149
+ return [
150
+ {
151
+ SchemaVersion : '15.0.0.0' ,
152
+ LibraryVersion : '16.0.25919.12007' ,
153
+ ErrorInfo : null ,
154
+ TraceCorrelationId : '864c91a1-f07a-c000-29c0-273ee30d83d8'
155
+ } ,
156
+ 7 ,
157
+ {
158
+ IsNull : false
159
+ }
160
+ ] ;
161
+ }
162
+
163
+ throw 'Invalid request URL: ' + opts . url ;
164
+ } ) ;
165
+
166
+ await command . action ( logger , { options : { name : containerTypeName , verbose : true , force : true } } ) ;
167
+ assert . strictEqual ( postStub . firstCall . args [ 0 ] . data , `<Request AddExpandoFieldTypeSuffix="true" SchemaVersion="15.0.0.0" LibraryVersion="16.0.0.0" ApplicationName="${ config . applicationName } " xmlns="http://schemas.microsoft.com/sharepoint/clientquery/2009"><Actions><ObjectPath Id="7" ObjectPathId="6" /><Method Name="RemoveSPOContainerType" Id="8" ObjectPathId="6"><Parameters><Parameter TypeId="{b66ab1ca-fd51-44f9-8cfc-01f5c2a21f99}"><Property Name="ContainerTypeId" Type="Guid">{${ containerTypeId } }</Property></Parameter></Parameters></Method></Actions><ObjectPaths><Constructor Id="6" TypeId="{268004ae-ef6b-4e9b-8425-127220d84719}" /></ObjectPaths></Request>` ) ;
168
+ assert . strictEqual ( postStub . lastCall . args [ 0 ] . headers ! [ 'X-RequestDigest' ] , 'abc' ) ;
169
+ } ) ;
170
+
171
+ it ( 'correctly handles error when removing a container type' , async ( ) => {
172
+ const errorMessage = `Tenant 7d858e1d-a366-48d1-8a15-ce45a733916b cannot delete Container Type ${ containerTypeId } as it is a DirectToCustomer Container Type.` ;
173
+
174
+ sinon . stub ( request , 'post' ) . callsFake ( async ( opts ) => {
175
+ if ( opts . url === `${ spoAdminUrl } /_vti_bin/client.svc/ProcessQuery` ) {
176
+ return [
177
+ {
178
+ SchemaVersion : '15.0.0.0' ,
179
+ LibraryVersion : '16.0.25919.12007' ,
180
+ ErrorInfo : {
181
+ ErrorMessage : errorMessage ,
182
+ ErrorValue : null ,
183
+ TraceCorrelationId : 'cd4a91a1-6041-c000-29c0-26f4566b5b74' ,
184
+ ErrorCode : - 2146232832 ,
185
+ ErrorTypeName : 'Microsoft.SharePoint.SPException'
186
+ } ,
187
+ TraceCorrelationId : 'cd4a91a1-6041-c000-29c0-26f4566b5b74'
188
+ }
189
+ ] ;
190
+ }
191
+
192
+ throw 'Invalid request URL: ' + opts . url ;
193
+ } ) ;
194
+
195
+ await assert . rejects ( command . action ( logger , { options : { id : containerTypeId , force : true } } ) ,
196
+ new CommandError ( errorMessage ) ) ;
197
+ } ) ;
198
+ } ) ;
0 commit comments