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 { formatting } from '../../../../utils/formatting.js' ;
11
+ import { pid } from '../../../../utils/pid.js' ;
12
+ import { session } from '../../../../utils/session.js' ;
13
+ import { sinonUtil } from '../../../../utils/sinonUtil.js' ;
14
+ import { z } from 'zod' ;
15
+ import commands from '../../commands.js' ;
16
+ import command from './file-version-keep.js' ;
17
+
18
+ describe ( commands . FILE_VERSION_KEEP , ( ) => {
19
+ let log : any [ ] ;
20
+ let logger : Logger ;
21
+ let commandInfo : CommandInfo ;
22
+ let commandOptionsSchema : z . ZodTypeAny ;
23
+ const validWebUrl = "https://contoso.sharepoint.com" ;
24
+ const validFileUrl = "/Shared Documents/Document.docx" ;
25
+ const validFileId = "7a9b8bb6-d5c4-4de9-ab76-5210a7879e89" ;
26
+ const validLabel = "1.0" ;
27
+
28
+ before ( ( ) => {
29
+ sinon . stub ( auth , 'restoreAuth' ) . resolves ( ) ;
30
+ sinon . stub ( telemetry , 'trackEvent' ) . resolves ( ) ;
31
+ sinon . stub ( pid , 'getProcessName' ) . returns ( '' ) ;
32
+ sinon . stub ( session , 'getId' ) . returns ( '' ) ;
33
+ commandInfo = cli . getCommandInfo ( command ) ;
34
+ commandOptionsSchema = commandInfo . command . getSchemaToParse ( ) ! ;
35
+ auth . connection . active = true ;
36
+ } ) ;
37
+
38
+ beforeEach ( ( ) => {
39
+ log = [ ] ;
40
+ logger = {
41
+ log : async ( msg : string ) => {
42
+ log . push ( msg ) ;
43
+ } ,
44
+ logRaw : async ( msg : string ) => {
45
+ log . push ( msg ) ;
46
+ } ,
47
+ logToStderr : async ( msg : string ) => {
48
+ log . push ( msg ) ;
49
+ }
50
+ } ;
51
+ } ) ;
52
+
53
+ afterEach ( ( ) => {
54
+ sinonUtil . restore ( [
55
+ request . get ,
56
+ request . post
57
+ ] ) ;
58
+ } ) ;
59
+
60
+ after ( ( ) => {
61
+ sinon . restore ( ) ;
62
+ auth . connection . active = false ;
63
+ } ) ;
64
+
65
+ it ( 'has correct name' , ( ) => {
66
+ assert . strictEqual ( command . name , commands . FILE_VERSION_KEEP ) ;
67
+ } ) ;
68
+
69
+ it ( 'has a description' , ( ) => {
70
+ assert . notStrictEqual ( command . description , null ) ;
71
+ } ) ;
72
+
73
+ it ( 'fails validation if webUrl is not a valid URL' , async ( ) => {
74
+ const actual = commandOptionsSchema . safeParse ( { webUrl : 'foo' , label : validLabel , fileUrl : validFileUrl } ) ;
75
+ assert . strictEqual ( actual . success , false ) ;
76
+ } ) ;
77
+
78
+ it ( 'fails validation if fileId is not a valid GUID' , async ( ) => {
79
+ const actual = commandOptionsSchema . safeParse ( { webUrl : validWebUrl , fileId : 'invalid' } ) ;
80
+ assert . strictEqual ( actual . success , false ) ;
81
+ } ) ;
82
+
83
+ it ( 'fails validation if fileUrl and fileId are specified' , async ( ) => {
84
+ const actual = commandOptionsSchema . safeParse ( { webUrl : validWebUrl , fileUrl : validFileUrl , fileId : validFileId } ) ;
85
+ assert . strictEqual ( actual . success , false ) ;
86
+ } ) ;
87
+
88
+ it ( 'passes validation if fileUrl is specified' , async ( ) => {
89
+ const actual = await command . validate ( { options : { webUrl : validWebUrl , label : validLabel , fileUrl : validFileUrl } } , commandInfo ) ;
90
+ assert . strictEqual ( actual , true ) ;
91
+ } ) ;
92
+
93
+ it ( 'passes validation if fileId is specified' , async ( ) => {
94
+ const actual = await command . validate ( { options : { webUrl : validWebUrl , label : validLabel , fileId : validFileId } } , commandInfo ) ;
95
+ assert . strictEqual ( actual , true ) ;
96
+ } ) ;
97
+
98
+ it ( 'ensures that a specific file version will never expire (fileUrl)' , async ( ) => {
99
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
100
+ if ( opts . url === `${ validWebUrl } /_api/web/GetFileByServerRelativePath(DecodedUrl='${ formatting . encodeQueryParameter ( validFileUrl ) } ')/versions/?$filter=VersionLabel eq '${ validLabel } '` ) {
101
+ return {
102
+ value : [
103
+ {
104
+ ID : 1 ,
105
+ VersionLabel : validLabel
106
+ }
107
+ ]
108
+ } ;
109
+ }
110
+
111
+ throw 'Invalid request' ;
112
+ } ) ;
113
+
114
+ sinon . stub ( request , 'post' ) . callsFake ( async ( opts ) => {
115
+ if ( opts . url === `${ validWebUrl } /_api/web/GetFileByServerRelativePath(DecodedUrl='${ formatting . encodeQueryParameter ( validFileUrl ) } ')/versions(1)/SetExpirationDate()` ) {
116
+ return ;
117
+ }
118
+
119
+ throw 'Invalid request' ;
120
+ } ) ;
121
+
122
+ await command . action ( logger , { options : { webUrl : validWebUrl , fileUrl : validFileUrl , label : validLabel , verbose : true } } ) ;
123
+ } ) ;
124
+
125
+ it ( 'ensures that a specific file version will never expire (fileId)' , async ( ) => {
126
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
127
+ if ( opts . url === `${ validWebUrl } /_api/web/GetFileById('${ validFileId } ')/versions/?$filter=VersionLabel eq '${ validLabel } '` ) {
128
+ return {
129
+ value : [
130
+ {
131
+ ID : 1 ,
132
+ VersionLabel : validLabel
133
+ }
134
+ ]
135
+ } ;
136
+ }
137
+
138
+ throw 'Invalid request' ;
139
+ } ) ;
140
+
141
+ sinon . stub ( request , 'post' ) . callsFake ( async ( opts ) => {
142
+ if ( opts . url === `${ validWebUrl } /_api/web/GetFileById('${ validFileId } ')/versions(1)/SetExpirationDate()` ) {
143
+ return ;
144
+ }
145
+
146
+ throw 'Invalid request' ;
147
+ } ) ;
148
+
149
+ await command . action ( logger , { options : { webUrl : validWebUrl , fileId : validFileId , label : validLabel , verbose : true } } ) ;
150
+ } ) ;
151
+
152
+ it ( 'correctly handles error when the specified version does not exist' , async ( ) => {
153
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
154
+ if ( opts . url === `${ validWebUrl } /_api/web/GetFileByServerRelativePath(DecodedUrl='${ formatting . encodeQueryParameter ( validFileUrl ) } ')/versions/?$filter=VersionLabel eq '${ validLabel } '` ) {
155
+ return { value : [ ] } ;
156
+ }
157
+
158
+ throw 'Invalid request' ;
159
+ } ) ;
160
+ await assert . rejects ( command . action ( logger , { options : { webUrl : validWebUrl , fileUrl : validFileUrl , label : validLabel } } ) ,
161
+ new CommandError ( `Version with label '${ validLabel } ' not found.` ) ) ;
162
+ } ) ;
163
+
164
+ it ( 'correctly handles API OData error' , async ( ) => {
165
+ sinon . stub ( request , 'get' ) . callsFake ( async ( opts ) => {
166
+ if ( opts . url === `${ validWebUrl } /_api/web/GetFileById('${ validFileId } ')/versions/?$filter=VersionLabel eq '${ validLabel } '` ) {
167
+ throw {
168
+ error : {
169
+ 'odata.error' : {
170
+ code : '-1, Microsoft.SharePoint.Client.InvalidOperationException' ,
171
+ message : {
172
+ value : 'Invalid version request'
173
+ }
174
+ }
175
+ }
176
+ } ;
177
+ }
178
+
179
+ throw 'Invalid request' ;
180
+ } ) ;
181
+
182
+ await assert . rejects ( command . action ( logger , { options : { webUrl : validWebUrl , fileId : validFileId , label : validLabel } } ) ,
183
+ new CommandError ( 'Invalid version request' ) ) ;
184
+ } ) ;
185
+ } ) ;
0 commit comments