1+ import assert from 'assert' ;
2+ import sinon from 'sinon' ;
3+ import auth from '../../../../Auth.js' ;
4+ import { Logger } from '../../../../cli/Logger.js' ;
5+ import { CommandInfo } from "../../../../cli/CommandInfo.js" ;
6+ import { CommandError } from '../../../../Command.js' ;
7+ import request from '../../../../request.js' ;
8+ import { telemetry } from '../../../../telemetry.js' ;
9+ import { pid } from '../../../../utils/pid.js' ;
10+ import { sinonUtil } from '../../../../utils/sinonUtil.js' ;
11+ import commands from '../../commands.js' ;
12+ import command , { options } from './container-permission-remove.js' ;
13+ import { formatting } from '../../../../utils/formatting.js' ;
14+ import { session } from '../../../../utils/session.js' ;
15+ import { spe } from '../../../../utils/spe.js' ;
16+ import { cli } from '../../../../cli/cli.js' ;
17+
18+ describe ( commands . CONTAINER_PERMISSION_REMOVE , ( ) => {
19+ let log : string [ ] ;
20+ let logger : Logger ;
21+ let commandInfo : CommandInfo ;
22+ let commandOptionsSchema : typeof options ;
23+ let promptIssued : boolean ;
24+
25+ const permissionId = 'cmVhZGVyX2k6MCMuZnxtZW1iZXJzaGlwfHJvcnlicjExMUBvdXRsb29rLmNvbQ' ;
26+ const containerTypeId = 'c6f08d91-77fa-485f-9369-f246ec0fc19c' ;
27+ const containerTypeName = 'Container type name' ;
28+ const containerId = 'b!McTeU0-dW0GxKwECWdW04TIvEK-Js9xJib_RFqF-CqZxNe3OHVAIT4SqBxGm4fND' ;
29+ const containerName = 'Container name' ;
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+ sinon . stub ( spe , 'getContainerTypeIdByName' ) . withArgs ( containerTypeName ) . resolves ( containerTypeId ) ;
38+ sinon . stub ( spe , 'getContainerIdByName' ) . withArgs ( containerTypeId , containerName ) . resolves ( containerId ) ;
39+
40+ auth . connection . active = true ;
41+ commandInfo = cli . getCommandInfo ( command ) ;
42+ commandOptionsSchema = commandInfo . command . getSchemaToParse ( ) as typeof options ;
43+ } ) ;
44+
45+ beforeEach ( ( ) => {
46+ log = [ ] ;
47+ logger = {
48+ log : async ( msg : string ) => {
49+ log . push ( msg ) ;
50+ } ,
51+ logRaw : async ( msg : string ) => {
52+ log . push ( msg ) ;
53+ } ,
54+ logToStderr : async ( msg : string ) => {
55+ log . push ( msg ) ;
56+ }
57+ } ;
58+ sinon . stub ( cli , 'promptForConfirmation' ) . callsFake ( ( ) => {
59+ promptIssued = true ;
60+ return Promise . resolve ( false ) ;
61+ } ) ;
62+ } ) ;
63+
64+ afterEach ( ( ) => {
65+ sinonUtil . restore ( [
66+ request . delete ,
67+ cli . promptForConfirmation
68+ ] ) ;
69+ } ) ;
70+
71+ after ( ( ) => {
72+ sinon . restore ( ) ;
73+ auth . connection . active = false ;
74+ } ) ;
75+
76+ it ( 'has correct name' , ( ) => {
77+ assert . strictEqual ( command . name , commands . CONTAINER_PERMISSION_REMOVE ) ;
78+ } ) ;
79+
80+ it ( 'has a description' , ( ) => {
81+ assert . notStrictEqual ( command . description , null ) ;
82+ } ) ;
83+
84+ it ( 'fails validation if permission id is not passed' , async ( ) => {
85+ const actual = commandOptionsSchema . safeParse ( { containerId : containerId } ) ;
86+ assert . strictEqual ( actual . success , false ) ;
87+ } ) ;
88+
89+ it ( 'fails validation if both containerId and containerName options are passed' , async ( ) => {
90+ const actual = commandOptionsSchema . safeParse ( { id : permissionId , containerId : containerId , containerName : containerName } ) ;
91+ assert . strictEqual ( actual . success , false ) ;
92+ } ) ;
93+
94+ it ( 'fails validation if neither containerId nor containerName options are passed' , async ( ) => {
95+ const actual = commandOptionsSchema . safeParse ( { id : permissionId } ) ;
96+ assert . strictEqual ( actual . success , false ) ;
97+ } ) ;
98+
99+ it ( 'fails validation if containerId and containerTypeId options are passed' , async ( ) => {
100+ const actual = commandOptionsSchema . safeParse ( { id : permissionId , containerId : containerId , containerTypeId : containerTypeId } ) ;
101+ assert . strictEqual ( actual . success , false ) ;
102+ } ) ;
103+
104+ it ( 'fails validation if containerId and containerTypeName options are passed' , async ( ) => {
105+ const actual = commandOptionsSchema . safeParse ( { id : permissionId , containerId : containerId , containerTypeName : containerTypeName } ) ;
106+ assert . strictEqual ( actual . success , false ) ;
107+ } ) ;
108+
109+ it ( 'fails validation if containerName and both containerTypeId and containerTypeName options are passed' , async ( ) => {
110+ const actual = commandOptionsSchema . safeParse ( { id : permissionId , containerName : containerName , containerTypeId : containerTypeId , containerTypeName : containerTypeName } ) ;
111+ assert . strictEqual ( actual . success , false ) ;
112+ } ) ;
113+
114+ it ( 'correctly removes permissions for a container by id' , async ( ) => {
115+ const deleteStub = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
116+ if ( opts . url === `https://graph.microsoft.com/v1.0/storage/fileStorage/containers/${ formatting . encodeQueryParameter ( containerId ) } /permissions/${ permissionId } ` ) {
117+ return ;
118+ }
119+
120+ throw 'Invalid DELETE request: ' + opts . url ;
121+ } ) ;
122+
123+ await command . action ( logger , { options : commandOptionsSchema . parse ( { id : permissionId , containerId : containerId , verbose : true , force : true } ) } ) ;
124+ assert ( deleteStub . calledOnce ) ;
125+ } ) ;
126+
127+ it ( 'correctly removes permissions for a container by name and container type by id and prompts for confirmation' , async ( ) => {
128+ sinonUtil . restore ( cli . promptForConfirmation ) ;
129+ sinon . stub ( cli , 'promptForConfirmation' ) . resolves ( true ) ;
130+
131+ const deleteStub = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
132+ if ( opts . url === `https://graph.microsoft.com/v1.0/storage/fileStorage/containers/${ formatting . encodeQueryParameter ( containerId ) } /permissions/${ permissionId } ` ) {
133+ return ;
134+ }
135+
136+ throw 'Invalid DELETE request: ' + opts . url ;
137+ } ) ;
138+
139+ await command . action ( logger , { options : commandOptionsSchema . parse ( { id : permissionId , containerName : containerName , containerTypeId : containerTypeId , verbose : true } ) } ) ;
140+ assert ( deleteStub . calledOnce ) ;
141+ } ) ;
142+
143+ it ( 'correctly removes permissions for a container by name and container type by name' , async ( ) => {
144+ const deleteStub = sinon . stub ( request , 'delete' ) . callsFake ( async ( opts ) => {
145+ if ( opts . url === `https://graph.microsoft.com/v1.0/storage/fileStorage/containers/${ formatting . encodeQueryParameter ( containerId ) } /permissions/${ permissionId } ` ) {
146+ return ;
147+ }
148+
149+ throw 'Invalid PATCH request: ' + opts . url ;
150+ } ) ;
151+
152+ await command . action ( logger , { options : commandOptionsSchema . parse ( { id : permissionId , containerName : containerName , containerTypeName : containerTypeName , verbose : true , force : true } ) } ) ;
153+ assert ( deleteStub . calledOnce ) ;
154+ } ) ;
155+
156+ it ( 'prompts before removing permissions when confirm option not passed' , async ( ) => {
157+ await command . action ( logger , { options : commandOptionsSchema . parse ( { id : permissionId , containerId : containerId } ) } ) ;
158+
159+ assert ( promptIssued ) ;
160+ } ) ;
161+
162+ it ( 'aborts removing permissions when prompt not confirmed' , async ( ) => {
163+ const deleteSpy = sinon . stub ( request , 'delete' ) . resolves ( ) ;
164+
165+ await command . action ( logger , { options : commandOptionsSchema . parse ( { id : permissionId , containerId : containerId } ) } ) ;
166+ assert ( deleteSpy . notCalled ) ;
167+ } ) ;
168+
169+ it ( 'correctly handles unexpected error' , async ( ) => {
170+ const errorMessage = 'Access denied' ;
171+ sinon . stub ( request , 'delete' ) . rejects ( {
172+ error : {
173+ code : 'accessDenied' ,
174+ message : errorMessage
175+ }
176+ } ) ;
177+
178+ await assert . rejects ( command . action ( logger , { options : commandOptionsSchema . parse ( { id : permissionId , containerId : containerId , force : true } ) } ) ,
179+ new CommandError ( errorMessage ) ) ;
180+ } ) ;
181+ } ) ;
0 commit comments