@@ -417,6 +417,71 @@ describe('Workflow deploy route', () => {
417417 } )
418418 } )
419419
420+ it ( 'fails first deploy rollback when undeploy reports failure before deletion' , async ( ) => {
421+ mockValidateWorkflowAccess . mockResolvedValue ( {
422+ workflow : { id : 'wf-1' , name : 'Test Workflow' , workspaceId : 'ws-1' } ,
423+ auth : {
424+ success : true ,
425+ userId : 'api-user' ,
426+ userName : 'API Key Actor' ,
427+ userEmail : 'api@example.com' ,
428+ authType : 'api_key' ,
429+ } ,
430+ } )
431+ mockDeployWorkflow . mockResolvedValue ( {
432+ success : true ,
433+ deployedAt : '2024-02-01T00:00:00Z' ,
434+ deploymentVersionId : 'dep-failed' ,
435+ } )
436+ mockSaveTriggerWebhooksForDeploy . mockResolvedValue ( {
437+ success : false ,
438+ error : { message : 'Failed to save trigger configuration' , status : 500 } ,
439+ } )
440+ mockDbLimit . mockResolvedValue ( [ ] )
441+ mockUndeployWorkflow . mockResolvedValue ( { success : false , error : 'undeploy failed' } )
442+
443+ const req = new NextRequest ( 'http://localhost:3000/api/workflows/wf-1/deploy' , {
444+ method : 'POST' ,
445+ headers : { 'x-api-key' : 'test-key' } ,
446+ } )
447+ const response = await POST ( req , { params : Promise . resolve ( { id : 'wf-1' } ) } )
448+
449+ expect ( response . status ) . toBe ( 500 )
450+ expect ( await response . json ( ) ) . toEqual ( { error : 'undeploy failed' , code : 'UNDEPLOY_FAILED' } )
451+ expect ( mockUndeployWorkflow ) . toHaveBeenCalledWith ( { workflowId : 'wf-1' } )
452+ expect ( mockDeleteDeploymentVersionById ) . not . toHaveBeenCalled ( )
453+ } )
454+
455+ it ( 'fails when deployment version id is missing and undeploy reports failure' , async ( ) => {
456+ mockValidateWorkflowAccess . mockResolvedValue ( {
457+ workflow : { id : 'wf-1' , name : 'Test Workflow' , workspaceId : 'ws-1' } ,
458+ auth : {
459+ success : true ,
460+ userId : 'api-user' ,
461+ userName : 'API Key Actor' ,
462+ userEmail : 'api@example.com' ,
463+ authType : 'api_key' ,
464+ } ,
465+ } )
466+ mockDeployWorkflow . mockResolvedValue ( {
467+ success : true ,
468+ deployedAt : '2024-02-01T00:00:00Z' ,
469+ deploymentVersionId : undefined ,
470+ } )
471+ mockUndeployWorkflow . mockResolvedValue ( { success : false , error : 'undeploy failed' } )
472+
473+ const req = new NextRequest ( 'http://localhost:3000/api/workflows/wf-1/deploy' , {
474+ method : 'POST' ,
475+ headers : { 'x-api-key' : 'test-key' } ,
476+ } )
477+ const response = await POST ( req , { params : Promise . resolve ( { id : 'wf-1' } ) } )
478+
479+ expect ( response . status ) . toBe ( 500 )
480+ expect ( await response . json ( ) ) . toEqual ( { error : 'undeploy failed' , code : 'UNDEPLOY_FAILED' } )
481+ expect ( mockUndeployWorkflow ) . toHaveBeenCalledWith ( { workflowId : 'wf-1' } )
482+ expect ( mockDeleteDeploymentVersionById ) . not . toHaveBeenCalled ( )
483+ } )
484+
420485 it ( 'allows API-key auth for undeploy using hybrid auth userId' , async ( ) => {
421486 mockValidateWorkflowAccess . mockResolvedValue ( {
422487 workflow : { id : 'wf-1' , name : 'Test Workflow' , workspaceId : 'ws-1' } ,
0 commit comments