1
+ import assert from 'assert' ;
2
+ import sinon from 'sinon' ;
3
+ import auth from '../../../../Auth.js' ;
4
+ import { cli } from '../../../../cli/cli.js' ;
5
+ import { CommandInfo } from '../../../../cli/CommandInfo.js' ;
6
+ import { Logger } from '../../../../cli/Logger.js' ;
7
+ import { CommandError } from '../../../../Command.js' ;
8
+ import request from '../../../../request.js' ;
9
+ import { telemetry } from '../../../../telemetry.js' ;
10
+ import { pid } from '../../../../utils/pid.js' ;
11
+ import { session } from '../../../../utils/session.js' ;
12
+ import { sinonUtil } from '../../../../utils/sinonUtil.js' ;
13
+ import commands from '../../commands.js' ;
14
+ import command from './model-remove.js' ;
15
+
16
+ describe ( commands . MODEL_REMOVE , ( ) => {
17
+ let log : string [ ] ;
18
+ let logger : Logger ;
19
+ let commandInfo : CommandInfo ;
20
+
21
+ before ( ( ) => {
22
+ sinon . stub ( auth , 'restoreAuth' ) . resolves ( ) ;
23
+ sinon . stub ( telemetry , 'trackEvent' ) . returns ( ) ;
24
+ sinon . stub ( pid , 'getProcessName' ) . returns ( '' ) ;
25
+ sinon . stub ( session , 'getId' ) . returns ( '' ) ;
26
+ auth . connection . active = true ;
27
+ commandInfo = cli . getCommandInfo ( command ) ;
28
+ } ) ;
29
+
30
+ beforeEach ( ( ) => {
31
+ log = [ ] ;
32
+ logger = {
33
+ log : async ( msg : string ) => {
34
+ log . push ( msg ) ;
35
+ } ,
36
+ logRaw : async ( msg : string ) => {
37
+ log . push ( msg ) ;
38
+ } ,
39
+ logToStderr : async ( msg : string ) => {
40
+ log . push ( msg ) ;
41
+ }
42
+ } ;
43
+ } ) ;
44
+
45
+ afterEach ( ( ) => {
46
+ sinonUtil . restore ( [
47
+ request . get ,
48
+ request . delete ,
49
+ cli . promptForConfirmation
50
+ ] ) ;
51
+ } ) ;
52
+
53
+ after ( ( ) => {
54
+ sinon . restore ( ) ;
55
+ auth . connection . active = false ;
56
+ } ) ;
57
+
58
+ it ( 'has correct name' , ( ) => {
59
+ assert . strictEqual ( command . name , commands . MODEL_REMOVE ) ;
60
+ } ) ;
61
+
62
+ it ( 'has a description' , ( ) => {
63
+ assert . notStrictEqual ( command . description , null ) ;
64
+ } ) ;
65
+
66
+ it ( 'passes validation when required parameters are valid with id' , async ( ) => {
67
+ const actual = await command . validate ( { options : { siteUrl : 'https://contoso.sharepoint.com/sites/sales' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } } , commandInfo ) ;
68
+ assert . strictEqual ( actual , true ) ;
69
+ } ) ;
70
+
71
+ it ( 'passes validation when required parameters are valid with title' , async ( ) => {
72
+ const actual = await command . validate ( { options : { siteUrl : 'https://contoso.sharepoint.com/sites/sales' , title : 'ModelName' } } , commandInfo ) ;
73
+ assert . strictEqual ( actual , true ) ;
74
+ } ) ;
75
+
76
+ it ( 'passes validation when required parameters are valid with id and force' , async ( ) => {
77
+ const actual = await command . validate ( { options : { siteUrl : 'https://contoso.sharepoint.com/sites/sales' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' , force : true } } , commandInfo ) ;
78
+ assert . strictEqual ( actual , true ) ;
79
+ } ) ;
80
+
81
+ it ( 'fails validation when siteUrl is not valid' , async ( ) => {
82
+ const actual = await command . validate ( { options : { siteUrl : 'invalidUrl' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } } , commandInfo ) ;
83
+ assert . notStrictEqual ( actual , true ) ;
84
+ } ) ;
85
+
86
+ it ( 'fails validation when id is not valid' , async ( ) => {
87
+ const actual = await command . validate ( { options : { siteUrl : 'https://contoso.sharepoint.com/sites/sales' , id : 'foo' } } , commandInfo ) ;
88
+ assert . notStrictEqual ( actual , true ) ;
89
+ } ) ;
90
+
91
+ it ( 'correctly handles site is not Content Site' , async ( ) => {
92
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
93
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
94
+ return {
95
+ WebTemplateConfiguration : 'SITEPAGEPUBLISHING#0'
96
+ } ;
97
+ }
98
+
99
+ throw 'Invalid request' ;
100
+ } ) ;
101
+
102
+ await assert . rejects ( command . action ( logger , { options : { verbose : true , siteUrl : 'https://contoso.sharepoint.com/sites/portal' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' , force : true } } ) ,
103
+ new CommandError ( 'https://contoso.sharepoint.com/sites/portal is not a content site.' ) ) ;
104
+ } ) ;
105
+
106
+
107
+ it ( 'correctly handles an access denied error' , async ( ) => {
108
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
109
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
110
+ throw {
111
+ error : {
112
+ "odata.error" : {
113
+ message : {
114
+ lang : "en-US" ,
115
+ value : "Attempted to perform an unauthorized operation."
116
+ }
117
+ }
118
+ }
119
+ } ;
120
+ }
121
+
122
+ throw 'Invalid request' ;
123
+ } ) ;
124
+
125
+ await assert . rejects ( command . action ( logger , { options : { verbose : true , siteUrl : 'https://contoso.sharepoint.com/sites/portal' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' , force : true } } ) ,
126
+ new CommandError ( 'Attempted to perform an unauthorized operation.' ) ) ;
127
+ } ) ;
128
+
129
+
130
+ it ( 'deletes model by id' , async ( ) => {
131
+ const confirmationStub = sinon . stub ( cli , 'promptForConfirmation' ) . resolves ( true ) ;
132
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
133
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
134
+ return {
135
+ WebTemplateConfiguration : 'CONTENTCTR#0'
136
+ } ;
137
+ }
138
+ throw 'Invalid request' ;
139
+ } ) ;
140
+
141
+ const stubDelete = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
142
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')` ) {
143
+ return ;
144
+ }
145
+
146
+ throw 'Invalid request' ;
147
+ } ) ;
148
+
149
+ await command . action ( logger , { options : { siteUrl : 'https://contoso.sharepoint.com/sites/portal' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } } ) ;
150
+ assert . strictEqual ( stubDelete . lastCall . args [ 0 ] . url , `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')` ) ;
151
+ assert ( confirmationStub . calledOnce ) ;
152
+ } ) ;
153
+
154
+ it ( 'does not delete model when confirmation is not accepted' , async ( ) => {
155
+ const confirmationStub = sinon . stub ( cli , 'promptForConfirmation' ) . resolves ( false ) ;
156
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
157
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
158
+ return {
159
+ WebTemplateConfiguration : 'CONTENTCTR#0'
160
+ } ;
161
+ }
162
+ throw 'Invalid request' ;
163
+ } ) ;
164
+
165
+ const stubDelete = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
166
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')` ) {
167
+ return ;
168
+ }
169
+
170
+ throw 'Invalid request' ;
171
+ } ) ;
172
+
173
+ await command . action ( logger , { options : { siteUrl : 'https://contoso.sharepoint.com/sites/portal' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } } ) ;
174
+ assert ( stubDelete . notCalled ) ;
175
+ assert ( confirmationStub . calledOnce ) ;
176
+ } ) ;
177
+
178
+ it ( 'deletes model by id with force' , async ( ) => {
179
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
180
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
181
+ return {
182
+ WebTemplateConfiguration : 'CONTENTCTR#0'
183
+ } ;
184
+ }
185
+ throw 'Invalid request' ;
186
+ } ) ;
187
+
188
+ const stubDelete = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
189
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('164720c8-35ee-4157-ba26-db6726264f9d')` ) {
190
+ return ;
191
+ }
192
+
193
+ throw 'Invalid request' ;
194
+ } ) ;
195
+
196
+ await command . action ( logger , { options : { siteUrl : 'https://contoso.sharepoint.com/sites/portal' , id : '164720c8-35ee-4157-ba26-db6726264f9d' , force : true } } ) ;
197
+ assert . strictEqual ( stubDelete . lastCall . args [ 0 ] . url , `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('164720c8-35ee-4157-ba26-db6726264f9d')` ) ;
198
+ } ) ;
199
+
200
+ it ( 'deletes model when the the site URL has trailing slash' , async ( ) => {
201
+ const confirmationStub = sinon . stub ( cli , 'promptForConfirmation' ) . resolves ( true ) ;
202
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
203
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
204
+ return {
205
+ WebTemplateConfiguration : 'CONTENTCTR#0'
206
+ } ;
207
+ }
208
+ throw 'Invalid request' ;
209
+ } ) ;
210
+
211
+ const stubDelete = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
212
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')` ) {
213
+ return ;
214
+ }
215
+
216
+ throw 'Invalid request' ;
217
+ } ) ;
218
+
219
+ await command . action ( logger , { options : { siteUrl : 'https://contoso.sharepoint.com/sites/portal/' , id : '9b1b1e42-794b-4c71-93ac-5ed92488b67f' } } ) ;
220
+ assert . strictEqual ( stubDelete . lastCall . args [ 0 ] . url , `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbyuniqueid('9b1b1e42-794b-4c71-93ac-5ed92488b67f')` ) ;
221
+ assert ( confirmationStub . calledOnce ) ;
222
+ } ) ;
223
+
224
+ it ( 'deletes model by title' , async ( ) => {
225
+ const confirmationStub = sinon . stub ( cli , 'promptForConfirmation' ) . resolves ( true ) ;
226
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
227
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/web?$select=WebTemplateConfiguration` ) {
228
+ return {
229
+ WebTemplateConfiguration : 'CONTENTCTR#0'
230
+ } ;
231
+ }
232
+
233
+ throw 'Invalid request' ;
234
+ } ) ;
235
+
236
+ const stubDelete = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
237
+ if ( opts . url === `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('ModelName')` ) {
238
+ return ;
239
+ }
240
+
241
+ throw 'Invalid request' ;
242
+ } ) ;
243
+
244
+ await command . action ( logger , { options : { siteUrl : 'https://contoso.sharepoint.com/sites/portal' , title : 'ModelName' } } ) ;
245
+ assert . strictEqual ( stubDelete . lastCall . args [ 0 ] . url , `https://contoso.sharepoint.com/sites/portal/_api/machinelearning/models/getbytitle('ModelName')` ) ;
246
+ assert ( confirmationStub . calledOnce ) ;
247
+ } ) ;
248
+ } ) ;
0 commit comments