@@ -240,5 +240,217 @@ describe('Update', function () {
240240 assert . isTrue ( callArgs . autoUpdate ) ;
241241 } ) ;
242242 } ) ;
243+
244+ it ( 'should work with interactive and force flags together' , async function ( ) {
245+ const promptStub = sandbox . stub (
246+ UpdateCommand . prototype ,
247+ 'promptForVersion'
248+ ) ;
249+ promptStub . resolves ( '3.5.0' ) ;
250+ runUpdateStub . resolves ( ) ;
251+
252+ await test
253+ . stub ( UpdateCommand . prototype , 'promptForVersion' , promptStub )
254+ . stub ( GitHubUpdater . prototype , 'runUpdate' , runUpdateStub )
255+ . command ( [ 'update' , '--interactive' , '--force' ] )
256+ . it ( 'prompts for version with force flag' , ( ) => {
257+ assert . isTrue ( promptStub . called ) ;
258+ assert . isTrue ( runUpdateStub . called ) ;
259+ const callArgs = runUpdateStub . getCall ( 0 ) . args [ 0 ] ;
260+ assert . equal ( callArgs . version , '3.5.0' ) ;
261+ assert . isTrue ( callArgs . force ) ;
262+ } ) ;
263+ } ) ;
264+
265+ it ( 'should handle autoupdate and force flags together' , async function ( ) {
266+ runUpdateStub . resolves ( ) ;
267+
268+ await test
269+ . stub ( GitHubUpdater . prototype , 'runUpdate' , runUpdateStub )
270+ . command ( [ 'update' , '--autoupdate' , '--force' ] )
271+ . it ( 'updates with autoupdate and force' , ( ) => {
272+ assert . isTrue ( runUpdateStub . called ) ;
273+ const callArgs = runUpdateStub . getCall ( 0 ) . args [ 0 ] ;
274+ assert . isTrue ( callArgs . autoUpdate ) ;
275+ assert . isTrue ( callArgs . force ) ;
276+ } ) ;
277+ } ) ;
278+ } ) ;
279+
280+ describe ( 'update command without flags' , function ( ) {
281+ it ( 'should run update without any flags' , async function ( ) {
282+ runUpdateStub . resolves ( ) ;
283+
284+ await test
285+ . stub ( GitHubUpdater . prototype , 'runUpdate' , runUpdateStub )
286+ . command ( [ 'update' ] )
287+ . it ( 'runs update with defaults' , ( ) => {
288+ assert . isTrue ( runUpdateStub . called ) ;
289+ const callArgs = runUpdateStub . getCall ( 0 ) . args [ 0 ] ;
290+ assert . isFalse ( callArgs . autoUpdate ) ;
291+ assert . isFalse ( callArgs . force ) ;
292+ assert . isUndefined ( callArgs . version ) ;
293+ } ) ;
294+ } ) ;
295+ } ) ;
296+
297+ describe ( 'available versions display' , function ( ) {
298+ it ( 'should display both local and remote versions' , async function ( ) {
299+ const mockVersionIndex = {
300+ '4.0.0' :
301+ 'https://github.com/box/boxcli/releases/download/v4.0.0' ,
302+ '3.5.0' :
303+ 'https://github.com/box/boxcli/releases/download/v3.5.0' ,
304+ '3.0.0' :
305+ 'https://github.com/box/boxcli/releases/download/v3.0.0' ,
306+ } ;
307+ const mockLocalVersions = [
308+ '/path/to/versions/4.0.0-darwin-x64' ,
309+ '/path/to/versions/3.5.0-darwin-x64' ,
310+ ] ;
311+
312+ fetchVersionIndexStub . resolves ( mockVersionIndex ) ;
313+ findLocalVersionsStub . resolves ( mockLocalVersions ) ;
314+
315+ await test
316+ . stdout ( )
317+ . stub (
318+ GitHubUpdater . prototype ,
319+ 'fetchVersionIndex' ,
320+ fetchVersionIndexStub
321+ )
322+ . stub (
323+ GitHubUpdater . prototype ,
324+ 'findLocalVersions' ,
325+ findLocalVersionsStub
326+ )
327+ . command ( [ 'update' , '--available' ] )
328+ . it ( 'displays mixed local and remote versions' , ( ctx ) => {
329+ assert . isTrue ( fetchVersionIndexStub . called ) ;
330+ assert . isTrue ( findLocalVersionsStub . called ) ;
331+ assert . include ( ctx . stdout , '4.0.0' ) ;
332+ assert . include ( ctx . stdout , '3.5.0' ) ;
333+ assert . include ( ctx . stdout , '3.0.0' ) ;
334+ } ) ;
335+ } ) ;
336+
337+ it ( 'should display only remote versions when no local versions' , async function ( ) {
338+ const mockVersionIndex = {
339+ '2.0.0' :
340+ 'https://github.com/box/boxcli/releases/download/v2.0.0' ,
341+ } ;
342+ const mockLocalVersions = [ ] ;
343+
344+ fetchVersionIndexStub . resolves ( mockVersionIndex ) ;
345+ findLocalVersionsStub . resolves ( mockLocalVersions ) ;
346+
347+ await test
348+ . stdout ( )
349+ . stub (
350+ GitHubUpdater . prototype ,
351+ 'fetchVersionIndex' ,
352+ fetchVersionIndexStub
353+ )
354+ . stub (
355+ GitHubUpdater . prototype ,
356+ 'findLocalVersions' ,
357+ findLocalVersionsStub
358+ )
359+ . command ( [ 'update' , '--available' ] )
360+ . it ( 'displays only remote versions' , ( ctx ) => {
361+ assert . isTrue ( fetchVersionIndexStub . called ) ;
362+ assert . isTrue ( findLocalVersionsStub . called ) ;
363+ assert . include ( ctx . stdout , '2.0.0' ) ;
364+ } ) ;
365+ } ) ;
366+ } ) ;
367+
368+ describe ( 'edge cases' , function ( ) {
369+ it ( 'should handle empty version index' , async function ( ) {
370+ const mockVersionIndex = { } ;
371+ const mockLocalVersions = [ ] ;
372+
373+ fetchVersionIndexStub . resolves ( mockVersionIndex ) ;
374+ findLocalVersionsStub . resolves ( mockLocalVersions ) ;
375+
376+ await test
377+ . stdout ( )
378+ . stub (
379+ GitHubUpdater . prototype ,
380+ 'fetchVersionIndex' ,
381+ fetchVersionIndexStub
382+ )
383+ . stub (
384+ GitHubUpdater . prototype ,
385+ 'findLocalVersions' ,
386+ findLocalVersionsStub
387+ )
388+ . command ( [ 'update' , '--available' ] )
389+ . it ( 'handles empty version index gracefully' , ( ) => {
390+ assert . isTrue ( fetchVersionIndexStub . called ) ;
391+ assert . isTrue ( findLocalVersionsStub . called ) ;
392+ } ) ;
393+ } ) ;
394+
395+ it ( 'should handle promptForVersion returning null' , async function ( ) {
396+ const promptStub = sandbox . stub (
397+ UpdateCommand . prototype ,
398+ 'promptForVersion'
399+ ) ;
400+ promptStub . resolves ( null ) ;
401+ runUpdateStub . resolves ( ) ;
402+
403+ await test
404+ . stub ( UpdateCommand . prototype , 'promptForVersion' , promptStub )
405+ . stub ( GitHubUpdater . prototype , 'runUpdate' , runUpdateStub )
406+ . command ( [ 'update' , '--interactive' ] )
407+ . it ( 'handles null version from prompt' , ( ) => {
408+ assert . isTrue ( promptStub . called ) ;
409+ assert . isTrue ( runUpdateStub . called ) ;
410+ const callArgs = runUpdateStub . getCall ( 0 ) . args [ 0 ] ;
411+ assert . isNull ( callArgs . version ) ;
412+ } ) ;
413+ } ) ;
414+
415+ it ( 'should handle version with special characters in basename matching' , async function ( ) {
416+ const mockVersionIndex = {
417+ '1.0.0-beta' :
418+ 'https://github.com/box/boxcli/releases/download/v1.0.0-beta' ,
419+ } ;
420+ const mockLocalVersions = [ '/path/to/versions/1.0.0-beta-darwin-x64' ] ;
421+
422+ fetchVersionIndexStub . resolves ( mockVersionIndex ) ;
423+ findLocalVersionsStub . resolves ( mockLocalVersions ) ;
424+
425+ await test
426+ . stdout ( )
427+ . stub (
428+ GitHubUpdater . prototype ,
429+ 'fetchVersionIndex' ,
430+ fetchVersionIndexStub
431+ )
432+ . stub (
433+ GitHubUpdater . prototype ,
434+ 'findLocalVersions' ,
435+ findLocalVersionsStub
436+ )
437+ . command ( [ 'update' , '--available' ] )
438+ . it ( 'matches version with special characters' , ( ctx ) => {
439+ assert . include ( ctx . stdout , '1.0.0-beta' ) ;
440+ assert . include ( ctx . stdout , '/path/to/versions/1.0.0-beta-darwin-x64' ) ;
441+ } ) ;
442+ } ) ;
443+ } ) ;
444+
445+ describe ( 'command class properties' , function ( ) {
446+ it ( 'should have empty args array' , function ( ) {
447+ assert . isArray ( UpdateCommand . args ) ;
448+ assert . isEmpty ( UpdateCommand . args ) ;
449+ } ) ;
450+
451+ it ( 'should have examples without the first one' , function ( ) {
452+ // UpdateCommand.examples should have examples, just with the first one removed
453+ assert . isArray ( UpdateCommand . examples ) ;
454+ } ) ;
243455 } ) ;
244456} ) ;
0 commit comments