@@ -64,16 +64,14 @@ describe('Migration Command', () => {
6464 // Don't stub fs operations - use real temporary files/directories instead
6565 // This avoids issues with non-configurable properties in newer Node.js versions
6666
67- // Stub utilities - use configHandler to control isAuthenticated behavior
68- // Default: isAuthenticated returns true (OAUTH) - individual tests can override
67+ // Stub utilities - use configHandler and isAuthenticated
6968 const cliUtilities = require ( '@contentstack/cli-utilities' ) ;
7069 sandbox . stub ( cliUtilities . configHandler , 'get' ) . callsFake ( ( key : string ) => {
7170 if ( key === 'authorisationType' ) {
7271 return 'OAUTH' ; // Default: authenticated
7372 }
7473 return undefined ;
7574 } ) ;
76-
7775 try {
7876 managementSDKClientStub = sandbox . stub ( cliUtilities , 'managementSDKClient' ) . resolves ( {
7977 stack : sandbox . stub ( ) . returns ( { } ) ,
@@ -118,23 +116,25 @@ describe('Migration Command', () => {
118116 expect ( MigrationCommand . flags ) . to . have . property ( 'file-path' ) ;
119117 expect ( MigrationCommand . flags ) . to . have . property ( 'alias' ) ;
120118 } ) ;
119+
120+ it ( 'should have usage string containing migration' , ( ) => {
121+ expect ( MigrationCommand . usage ) . to . be . a ( 'string' ) ;
122+ expect ( MigrationCommand . usage ) . to . include ( 'migration' ) ;
123+ } ) ;
124+
125+ it ( 'should have aliases including cm:migration' , ( ) => {
126+ expect ( MigrationCommand . aliases ) . to . be . an ( 'array' ) ;
127+ expect ( MigrationCommand . aliases ) . to . include ( 'cm:migration' ) ;
128+ } ) ;
121129 } ) ;
122130
123131 describe ( 'run() method' , ( ) => {
124132 it . skip ( 'should exit when no authtoken and no alias' , async ( ) => {
125- // Override configHandler.get to return undefined (not authenticated)
126133 const cliUtilities = require ( '@contentstack/cli-utilities' ) ;
127- sandbox . stub ( cliUtilities . configHandler , 'get' ) . callsFake ( ( key : string ) => {
128- if ( key === 'authorisationType' ) {
129- return undefined ; // Not authenticated
130- }
131- return undefined ;
132- } ) ;
133-
134+ sandbox . stub ( cliUtilities . configHandler , 'get' ) . callsFake ( ( key : string ) => undefined ) ;
134135 parseStub . resolves ( {
135136 flags : {
136137 'file-path' : tempFile ,
137- // No alias provided
138138 } ,
139139 } as any ) ;
140140
@@ -145,7 +145,6 @@ describe('Migration Command', () => {
145145 } ) ;
146146
147147 it . skip ( 'should exit when file path is not provided' , async ( ) => {
148- // Don't stub execSingleFile since we exit before reaching it
149148 parseStub . resolves ( {
150149 flags : { } ,
151150 } as any ) ;
@@ -157,7 +156,6 @@ describe('Migration Command', () => {
157156 } ) ;
158157
159158 it . skip ( 'should exit when file path does not exist' , async ( ) => {
160- // Use a path that definitely doesn't exist
161159 parseStub . resolves ( {
162160 flags : {
163161 'file-path' : '/nonexistent/path/that/does/not/exist.js' ,
@@ -430,6 +428,123 @@ describe('Migration Command', () => {
430428 fs . rmSync ( migrationLogsPath , { recursive : true , force : true } ) ;
431429 }
432430 } ) ;
431+
432+ it ( 'should not log migration-logs path when directory does not exist' , async ( ) => {
433+ sandbox . stub ( command , 'execSingleFile' ) . resolves ( ) ;
434+ const cwdStub = sandbox . stub ( process , 'cwd' ) . returns ( tempDir ) ;
435+ parseStub . resolves ( {
436+ flags : {
437+ 'file-path' : tempFile ,
438+ } ,
439+ } as any ) ;
440+
441+ await command . run ( ) ;
442+
443+ const migrationLogCall = logStub . getCalls ( ) . find (
444+ ( c : any ) => c . args [ 1 ] && String ( c . args [ 1 ] ) . includes ( 'migration-logs' )
445+ ) ;
446+ expect ( migrationLogCall ) . to . be . undefined ;
447+ } ) ;
448+ } ) ;
449+
450+ describe ( 'getTasks() method' , ( ) => {
451+ let safePromiseStub : SinonStub ;
452+ let waterfallStub : SinonStub ;
453+
454+ beforeEach ( ( ) => {
455+ safePromiseStub = sandbox . stub ( utilsModule , 'safePromise' ) . callsFake ( async ( p : any ) => {
456+ try {
457+ const result = await p ;
458+ return [ null , result ] ;
459+ } catch ( err ) {
460+ return [ err , null ] ;
461+ }
462+ } ) ;
463+ const asyncModule = require ( 'async' ) ;
464+ waterfallStub = sandbox . stub ( asyncModule , 'waterfall' ) . callsFake ( ( tasks : any [ ] , callback ?: any ) => {
465+ if ( typeof callback === 'function' ) {
466+ callback ( null , 'result' ) ;
467+ }
468+ return Promise . resolve ( 'result' ) ;
469+ } ) ;
470+ } ) ;
471+
472+ it ( 'should return array of task objects from requests' , ( ) => {
473+ const requests = [
474+ { title : 'Task 1' , failedTitle : 'F1' , successTitle : 'S1' , tasks : [ async ( ) => 'r1' ] } ,
475+ { title : 'Task 2' , failedTitle : 'F2' , successTitle : 'S2' , tasks : [ async ( ) => 'r2' ] } ,
476+ ] ;
477+ const tasks = command . getTasks ( requests ) ;
478+ expect ( tasks ) . to . be . an ( 'array' ) . with . lengthOf ( 2 ) ;
479+ expect ( tasks [ 0 ] . title ) . to . equal ( 'Task 1' ) ;
480+ expect ( tasks [ 0 ] . task ) . to . be . a ( 'function' ) ;
481+ expect ( tasks [ 1 ] . title ) . to . equal ( 'Task 2' ) ;
482+ expect ( tasks [ 1 ] . task ) . to . be . a ( 'function' ) ;
483+ } ) ;
484+
485+ it ( 'should return empty array when requests is empty' , ( ) => {
486+ const tasks = command . getTasks ( [ ] ) ;
487+ expect ( tasks ) . to . be . an ( 'array' ) . with . lengthOf ( 0 ) ;
488+ } ) ;
489+
490+ it ( 'should run task and set success title on success' , async ( ) => {
491+ const requests = [
492+ { title : 'T' , failedTitle : 'F' , successTitle : 'S' , tasks : [ async ( ) => 'ok' ] } ,
493+ ] ;
494+ const tasks = command . getTasks ( requests ) ;
495+ const mockCtx : any = { } ;
496+ const mockTask : any = { title : 'T' } ;
497+ await tasks [ 0 ] . task ( mockCtx , mockTask ) ;
498+ expect ( mockTask . title ) . to . equal ( 'S' ) ;
499+ } ) ;
500+
501+ it ( 'should set failedTitle and ctx.error and throw when waterfall fails' , async ( ) => {
502+ safePromiseStub . callsFake ( async ( p : any ) => {
503+ await p ;
504+ return [ new Error ( 'waterfall failed' ) , null ] ;
505+ } ) ;
506+ const requests = [
507+ { title : 'T' , failedTitle : 'Failed' , successTitle : 'S' , tasks : [ async ( ) => 'ok' ] } ,
508+ ] ;
509+ const tasks = command . getTasks ( requests ) ;
510+ const mockCtx : any = { } ;
511+ const mockTask : any = { title : 'T' } ;
512+ try {
513+ await tasks [ 0 ] . task ( mockCtx , mockTask ) ;
514+ expect . fail ( 'task should have thrown' ) ;
515+ } catch ( err : any ) {
516+ expect ( err . message ) . to . equal ( 'waterfall failed' ) ;
517+ }
518+ expect ( mockTask . title ) . to . equal ( 'Failed' ) ;
519+ expect ( mockCtx . error ) . to . be . true ;
520+ } ) ;
521+
522+ it ( 'should return result from task when successful' , async ( ) => {
523+ const requests = [
524+ { title : 'T' , failedTitle : 'F' , successTitle : 'S' , tasks : [ async ( ) => ( { id : '123' } ) ] } ,
525+ ] ;
526+ const tasks = command . getTasks ( requests ) ;
527+ const mockCtx : any = { } ;
528+ const mockTask : any = { title : 'T' } ;
529+ const result = await tasks [ 0 ] . task ( mockCtx , mockTask ) ;
530+ expect ( result ) . to . equal ( 'result' ) ;
531+ } ) ;
532+ } ) ;
533+
534+ describe ( 'handleErrors() method' , ( ) => {
535+ beforeEach ( ( ) => {
536+ getStub . returns ( [ ] ) ;
537+ } ) ;
538+
539+ it ( 'should run without throwing when actions array is empty' , ( ) => {
540+ expect ( ( ) => command . handleErrors ( ) ) . to . not . throw ( ) ;
541+ } ) ;
542+
543+ it ( 'should run and invoke validation when actions exist' , ( ) => {
544+ getStub . returns ( [ { type : 'create' , payload : { } } ] ) ;
545+ expect ( ( ) => command . handleErrors ( ) ) . to . not . throw ( ) ;
546+ } ) ;
547+
433548 } ) ;
434549
435550 describe . skip ( 'execSingleFile() method' , ( ) => {
@@ -561,137 +676,4 @@ describe('Migration Command', () => {
561676 } ) ;
562677 } ) ;
563678
564- describe . skip ( 'getTasks() method' , ( ) => {
565- let safePromiseStub : SinonStub ;
566- let waterfallStub : SinonStub ;
567-
568- beforeEach ( ( ) => {
569- safePromiseStub = sandbox . stub ( utilsModule , 'safePromise' ) . resolves ( [ null , 'result' ] ) ;
570- waterfallStub = sandbox . stub ( require ( 'async' ) , 'waterfall' ) . callsFake ( ( tasks : any [ ] , callback : any ) => {
571- callback ( null , 'result' ) ;
572- } ) ;
573- } ) ;
574-
575- it ( 'should create tasks from requests' , ( ) => {
576- const requests = [
577- {
578- title : 'Task 1' ,
579- failedTitle : 'Task 1 Failed' ,
580- successTitle : 'Task 1 Success' ,
581- tasks : [ sandbox . stub ( ) . callsArg ( 1 ) ] ,
582- } ,
583- {
584- title : 'Task 2' ,
585- failedTitle : 'Task 2 Failed' ,
586- successTitle : 'Task 2 Success' ,
587- tasks : [ sandbox . stub ( ) . callsArg ( 1 ) ] ,
588- } ,
589- ] ;
590-
591- const tasks = command . getTasks ( requests ) ;
592-
593- expect ( tasks ) . to . be . an ( 'array' ) ;
594- expect ( tasks . length ) . to . equal ( 2 ) ;
595- expect ( tasks [ 0 ] ) . to . have . property ( 'title' , 'Task 1' ) ;
596- expect ( tasks [ 0 ] ) . to . have . property ( 'task' ) ;
597- expect ( tasks [ 1 ] ) . to . have . property ( 'title' , 'Task 2' ) ;
598- expect ( tasks [ 1 ] ) . to . have . property ( 'task' ) ;
599- } ) ;
600-
601- it ( 'should create task function that handles success' , async ( ) => {
602- const requests = [
603- {
604- title : 'Test Task' ,
605- failedTitle : 'Test Failed' ,
606- successTitle : 'Test Success' ,
607- tasks : [ sandbox . stub ( ) . callsArg ( 1 ) ] ,
608- } ,
609- ] ;
610-
611- const tasks = command . getTasks ( requests ) ;
612- const taskFn = tasks [ 0 ] . task ;
613- const mockCtx : any = { } ;
614- const mockTask : any = {
615- title : 'Test Task' ,
616- } ;
617-
618- await taskFn ( mockCtx , mockTask ) ;
619-
620- expect ( mockTask . title ) . to . equal ( 'Test Success' ) ;
621- } ) ;
622-
623- it ( 'should create task function that handles errors' , async ( ) => {
624- const testError = new Error ( 'Test error' ) ;
625- // Make safePromise return the error
626- safePromiseStub . resolves ( [ testError , null ] ) ;
627- // waterfall will be called with tasks array, and safePromise wraps it
628- // So when safePromise resolves with [error, null], the task function should handle it
629- waterfallStub . restore ( ) ;
630- waterfallStub = sandbox . stub ( require ( 'async' ) , 'waterfall' ) . callsFake ( ( tasks : any [ ] , callback : any ) => {
631- // Simulate waterfall calling callback with error
632- if ( callback ) {
633- callback ( testError ) ;
634- }
635- } ) ;
636-
637- const requests = [
638- {
639- title : 'Test Task' ,
640- failedTitle : 'Test Failed' ,
641- successTitle : 'Test Success' ,
642- tasks : [ sandbox . stub ( ) . callsArgWith ( 0 , testError ) ] ,
643- } ,
644- ] ;
645-
646- const tasks = command . getTasks ( requests ) ;
647- const taskFn = tasks [ 0 ] . task ;
648- const mockCtx : any = { } ;
649- const mockTask : any = {
650- title : 'Test Task' ,
651- } ;
652-
653- try {
654- await taskFn ( mockCtx , mockTask ) ;
655- // Should not reach here
656- expect . fail ( 'Should have thrown an error' ) ;
657- } catch ( err ) {
658- expect ( err ) . to . equal ( testError ) ;
659- expect ( mockCtx . error ) . to . be . true ;
660- expect ( mockTask . title ) . to . equal ( 'Test Failed' ) ;
661- }
662- } ) ;
663- } ) ;
664-
665- describe . skip ( 'handleErrors() method' , ( ) => {
666- let actionListInstance : any ;
667- let ActionListConstructorStub : SinonStub ;
668-
669- beforeEach ( ( ) => {
670- actionListInstance = {
671- addValidators : sandbox . stub ( ) ,
672- validate : sandbox . stub ( ) . returns ( [ ] ) ,
673- } ;
674- const actionListModule = require ( '../../../../../src/actions/action-list' ) ;
675- ActionListConstructorStub = sandbox . stub ( actionListModule , 'default' ) . returns ( actionListInstance ) ;
676- getStub . returns ( [ ] ) ;
677- } ) ;
678-
679- it ( 'should validate actions and handle errors' , ( ) => {
680- command . handleErrors ( ) ;
681-
682- expect ( getMapInstanceStub . called ) . to . be . true ;
683- expect ( getStub . called ) . to . be . true ;
684- expect ( ActionListConstructorStub . called ) . to . be . true ;
685- expect ( actionListInstance . addValidators . callCount ) . to . equal ( 4 ) ;
686- expect ( actionListInstance . validate . called ) . to . be . true ;
687- expect ( errorHelperStub . called ) . to . be . true ;
688- } ) ;
689-
690- it ( 'should add all validators' , ( ) => {
691- command . handleErrors ( ) ;
692-
693- const validatorCalls = actionListInstance . addValidators . getCalls ( ) ;
694- expect ( validatorCalls . length ) . to . equal ( 4 ) ;
695- } ) ;
696- } ) ;
697679} ) ;
0 commit comments