@@ -682,74 +682,81 @@ describe('workflow execute async route', () => {
682682 expect ( mockEnqueue ) . not . toHaveBeenCalled ( )
683683 } )
684684
685- it ( 'binds a Copilot workflow tool only to its server log and waits before terminal SSE' , async ( ) => {
686- let releasePostExecution : ( ( ) => void ) | undefined
687- loggingSessionMockFns . mockWaitForPostExecution . mockImplementationOnce (
688- ( ) =>
689- new Promise < void > ( ( resolve ) => {
690- releasePostExecution = resolve
691- } )
692- )
685+ it . each ( [ true , false ] ) (
686+ 'binds a Copilot tool and waits for logs before terminal SSE (draft=%s)' ,
687+ async ( useDraftState ) => {
688+ let releasePostExecution : ( ( ) => void ) | undefined
689+ loggingSessionMockFns . mockWaitForPostExecution . mockImplementationOnce (
690+ ( ) =>
691+ new Promise < void > ( ( resolve ) => {
692+ releasePostExecution = resolve
693+ } )
694+ )
693695
694- const response = await POST ( createBoundCopilotExecutionRequest ( ) , {
695- params : Promise . resolve ( { id : 'workflow-1' } ) ,
696- } )
697- const bodyPromise = response . text ( )
696+ const response = await POST ( createBoundCopilotExecutionRequest ( { useDraftState } ) , {
697+ params : Promise . resolve ( { id : 'workflow-1' } ) ,
698+ } )
699+ const bodyPromise = response . text ( )
698700
699- await vi . waitFor ( ( ) => {
700- expect ( loggingSessionMockFns . mockWaitForPostExecution ) . toHaveBeenCalledTimes ( 1 )
701- } )
702- let streamCompleted = false
703- void bodyPromise . then ( ( ) => {
704- streamCompleted = true
705- } )
706- await Promise . resolve ( )
701+ await vi . waitFor ( ( ) => {
702+ expect ( loggingSessionMockFns . mockWaitForPostExecution ) . toHaveBeenCalledTimes ( 1 )
703+ } )
704+ let streamCompleted = false
705+ void bodyPromise . then ( ( ) => {
706+ streamCompleted = true
707+ } )
708+ await Promise . resolve ( )
707709
708- expect ( response . status ) . toBe ( 200 )
709- expect ( streamCompleted ) . toBe ( false )
710- expect ( mockSettleClientWorkflowToolExecution ) . not . toHaveBeenCalled ( )
711- expect ( mockClaimWorkflowToolExecution ) . toHaveBeenCalledWith (
712- 'copilot-tool-1' ,
713- 'execution-123' ,
714- 'client'
715- )
716- expect ( mockReleaseWorkflowToolExecutionClaim ) . not . toHaveBeenCalled ( )
717- expect ( loggingSessionMockFns . mockSetTrustedExecutionCorrelation ) . toHaveBeenCalledWith ( {
718- executionId : 'execution-123' ,
719- requestId : 'req-12345678' ,
720- source : 'workflow' ,
721- workflowId : 'workflow-1' ,
722- triggerType : 'copilot' ,
723- copilotToolCallId : 'copilot-tool-1' ,
724- } )
725- const executionArgs = mockExecuteWorkflowCore . mock . calls [ 0 ] [ 0 ]
726- expect ( executionArgs ) . not . toHaveProperty ( 'copilotToolCallId' )
727- expect ( executionArgs . snapshot . metadata ) . not . toHaveProperty ( 'copilotToolCallId' )
728-
729- releasePostExecution ?.( )
730- const body = await bodyPromise
731- expect ( body ) . toContain ( 'execution:completed' )
732- await vi . waitFor ( ( ) =>
733- expect ( mockSettleClientWorkflowToolExecution ) . toHaveBeenCalledExactlyOnceWith (
710+ expect ( response . status ) . toBe ( 200 )
711+ expect ( streamCompleted ) . toBe ( false )
712+ expect ( mockSettleClientWorkflowToolExecution ) . not . toHaveBeenCalled ( )
713+ expect ( mockClaimWorkflowToolExecution ) . toHaveBeenCalledWith (
734714 'copilot-tool-1' ,
735- expect . any ( String )
715+ 'execution-123' ,
716+ 'client'
736717 )
737- )
738- } )
718+ expect ( mockReleaseWorkflowToolExecutionClaim ) . not . toHaveBeenCalled ( )
719+ expect ( loggingSessionMockFns . mockSetTrustedExecutionCorrelation ) . toHaveBeenCalledWith ( {
720+ executionId : 'execution-123' ,
721+ requestId : 'req-12345678' ,
722+ source : 'workflow' ,
723+ workflowId : 'workflow-1' ,
724+ triggerType : 'copilot' ,
725+ copilotToolCallId : 'copilot-tool-1' ,
726+ } )
727+ const executionArgs = mockExecuteWorkflowCore . mock . calls [ 0 ] [ 0 ]
728+ expect ( executionArgs . snapshot . metadata . useDraftState ) . toBe ( useDraftState )
729+ expect ( executionArgs ) . not . toHaveProperty ( 'copilotToolCallId' )
730+ expect ( executionArgs . snapshot . metadata ) . not . toHaveProperty ( 'copilotToolCallId' )
731+
732+ releasePostExecution ?.( )
733+ const body = await bodyPromise
734+ expect ( body ) . toContain ( 'execution:completed' )
735+ await vi . waitFor ( ( ) =>
736+ expect ( mockSettleClientWorkflowToolExecution ) . toHaveBeenCalledExactlyOnceWith (
737+ 'copilot-tool-1' ,
738+ expect . any ( String )
739+ )
740+ )
741+ }
742+ )
739743
740- it ( 'settles failed Copilot execution after the route finishes error handling' , async ( ) => {
741- mockExecuteWorkflowCore . mockRejectedValueOnce ( new Error ( 'Execution rejected' ) )
742- const response = await POST ( createBoundCopilotExecutionRequest ( ) , {
743- params : Promise . resolve ( { id : 'workflow-1' } ) ,
744- } )
745- expect ( await response . text ( ) ) . toContain ( 'execution:error' )
746- await vi . waitFor ( ( ) =>
747- expect ( mockSettleClientWorkflowToolExecution ) . toHaveBeenCalledExactlyOnceWith (
748- 'copilot-tool-1' ,
749- expect . any ( String )
744+ it . each ( [ true , false ] ) (
745+ 'settles failed Copilot execution after error handling (draft=%s)' ,
746+ async ( useDraftState ) => {
747+ mockExecuteWorkflowCore . mockRejectedValueOnce ( new Error ( 'Execution rejected' ) )
748+ const response = await POST ( createBoundCopilotExecutionRequest ( { useDraftState } ) , {
749+ params : Promise . resolve ( { id : 'workflow-1' } ) ,
750+ } )
751+ expect ( await response . text ( ) ) . toContain ( 'execution:error' )
752+ await vi . waitFor ( ( ) =>
753+ expect ( mockSettleClientWorkflowToolExecution ) . toHaveBeenCalledExactlyOnceWith (
754+ 'copilot-tool-1' ,
755+ expect . any ( String )
756+ )
750757 )
751- )
752- } )
758+ }
759+ )
753760
754761 it ( 'settles a detached Copilot stream only after its cancelled execution and cleanup end' , async ( ) => {
755762 let releaseCleanup : ( ( ) => void ) | undefined
0 commit comments