@@ -16,6 +16,7 @@ const {
1616 mockEndScopedExecution,
1717 mockExecute,
1818 mockExecuteFromBlock,
19+ mockFindStartBlock,
1920 mockFetch,
2021 mockHandleExecutionCancelledConsole,
2122 mockHandleExecutionErrorConsole,
@@ -101,6 +102,7 @@ const {
101102 mockEndScopedExecution : vi . fn ( ( ) => true ) ,
102103 mockExecute : vi . fn ( ) ,
103104 mockExecuteFromBlock : vi . fn ( ) ,
105+ mockFindStartBlock : vi . fn ( ( ) => ( { blockId : 'start' } ) ) ,
104106 mockFetch : vi . fn ( ) ,
105107 mockHandleExecutionCancelledConsole : vi . fn ( ) ,
106108 mockHandleExecutionErrorConsole : vi . fn ( ) ,
@@ -180,7 +182,7 @@ vi.mock('@/lib/workflows/triggers/triggers', () => ({
180182 EXTERNAL_TRIGGER : 'external-trigger' ,
181183 } ,
182184 TriggerUtils : {
183- findStartBlock : ( ) => ( { blockId : 'start' } ) ,
185+ findStartBlock : mockFindStartBlock ,
184186 getTriggerValidationMessage : ( ) => 'Missing trigger' ,
185187 } ,
186188} ) )
@@ -1097,6 +1099,7 @@ describe('useWorkflowExecution attachment uploads', () => {
10971099 }
10981100 executionStoreState . getLastExecutionSnapshot . mockReturnValueOnce ( sourceSnapshot )
10991101 workflowStoreState . edges . push ( { source : 'start' , target : 'function-1' } as never )
1102+ workflowStoreState . edges . push ( { source : 'function-1' , target : 'disabledBranch' } as never )
11001103 const currentBlocks = {
11011104 ...workflowBlocks ,
11021105 'function-1' : {
@@ -1106,6 +1109,18 @@ describe('useWorkflowExecution attachment uploads', () => {
11061109 enabled : true ,
11071110 subBlocks : { code : { value : 'return "current editor state"' } } ,
11081111 } ,
1112+ disabledBranch : {
1113+ id : 'disabledBranch' ,
1114+ type : 'slack' ,
1115+ name : 'Disabled Branch' ,
1116+ enabled : false ,
1117+ subBlocks : { } ,
1118+ } ,
1119+ disabledTrigger : {
1120+ ...workflowBlocks . start ,
1121+ id : 'disabledTrigger' ,
1122+ enabled : false ,
1123+ } ,
11091124 }
11101125 workflowStoreState . getWorkflowState . mockReturnValueOnce ( {
11111126 blocks : currentBlocks ,
@@ -1147,10 +1162,23 @@ describe('useWorkflowExecution attachment uploads', () => {
11471162 ...workflowBlocks . start ,
11481163 subBlocks : { inputFormat : { value : 'current-editor-state' } } ,
11491164 } ,
1165+ disabledBranch : {
1166+ id : 'disabledBranch' ,
1167+ type : 'slack' ,
1168+ name : 'Disabled Branch' ,
1169+ enabled : false ,
1170+ subBlocks : { } ,
1171+ } ,
1172+ disabledTrigger : {
1173+ ...workflowBlocks . start ,
1174+ id : 'disabledTrigger' ,
1175+ enabled : false ,
1176+ } ,
11501177 }
1178+ const currentEdges = [ { source : 'start' , target : 'disabledBranch' } ]
11511179 workflowStoreState . getWorkflowState . mockReturnValueOnce ( {
11521180 blocks : currentBlocks ,
1153- edges : [ ] ,
1181+ edges : currentEdges ,
11541182 loops : { } ,
11551183 parallels : { } ,
11561184 } )
@@ -1181,12 +1209,16 @@ describe('useWorkflowExecution attachment uploads', () => {
11811209 isClientSession : true ,
11821210 workflowStateOverride : {
11831211 blocks : currentBlocks ,
1184- edges : [ ] ,
1212+ edges : currentEdges ,
11851213 loops : { } ,
11861214 parallels : { } ,
11871215 } ,
11881216 } )
11891217 )
1218+ expect ( mockResolveStartCandidates ) . toHaveBeenCalledWith (
1219+ { start : currentBlocks . start } ,
1220+ { execution : 'manual' }
1221+ )
11901222 expect ( mockExecute . mock . calls [ 0 ] ?. [ 0 ] ) . not . toHaveProperty ( 'sourceSnapshot' )
11911223 expect ( mockExecuteFromBlock ) . not . toHaveBeenCalled ( )
11921224 expect ( executionStoreState . setLastExecutionSnapshot ) . toHaveBeenCalledWith (
@@ -1277,3 +1309,102 @@ describe('useWorkflowExecution attachment uploads', () => {
12771309 unmount ( )
12781310 } )
12791311} )
1312+
1313+ describe ( 'useWorkflowExecution workflow state override' , ( ) => {
1314+ beforeEach ( ( ) => {
1315+ resetWorkflowExecutionTestState ( )
1316+ vi . stubGlobal ( 'fetch' , mockFetch )
1317+ const startCandidate = {
1318+ blockId : 'start' ,
1319+ block : workflowBlocks . start ,
1320+ path : 'legacy-starter' ,
1321+ }
1322+ mockResolveStartCandidates . mockReturnValue ( [ startCandidate ] )
1323+ mockSelectBestTrigger . mockReturnValue ( [ startCandidate ] )
1324+ } )
1325+
1326+ afterEach ( ( ) => {
1327+ vi . unstubAllGlobals ( )
1328+ } )
1329+
1330+ it . each ( [ 'manual' , 'chat' , 'run-until' ] as const ) (
1331+ 'keeps disabled blocks and edges in %s payloads while excluding disabled triggers' ,
1332+ async ( triggerType ) => {
1333+ const blocks = {
1334+ ...workflowBlocks ,
1335+ condition1 : {
1336+ id : 'condition1' ,
1337+ type : 'condition' ,
1338+ name : 'Check' ,
1339+ enabled : true ,
1340+ subBlocks : { } ,
1341+ } ,
1342+ disabledBranch : {
1343+ id : 'disabledBranch' ,
1344+ type : 'slack' ,
1345+ name : 'Send Empty' ,
1346+ enabled : false ,
1347+ subBlocks : { } ,
1348+ } ,
1349+ disabledTrigger : {
1350+ ...workflowBlocks . start ,
1351+ id : 'disabledTrigger' ,
1352+ enabled : false ,
1353+ } ,
1354+ }
1355+ const edges = [
1356+ {
1357+ id : 'edge-1' ,
1358+ source : 'condition1' ,
1359+ target : 'disabledBranch' ,
1360+ sourceHandle : 'condition-else1' ,
1361+ } ,
1362+ ]
1363+ workflowStoreState . getWorkflowState . mockReturnValueOnce ( {
1364+ blocks : { ...blocks , layout : { id : 'layout' } } ,
1365+ edges,
1366+ loops : { } ,
1367+ parallels : { } ,
1368+ } )
1369+ const { result, unmount } = renderWorkflowExecutionHook ( )
1370+
1371+ await act ( async ( ) => {
1372+ if ( triggerType === 'run-until' ) {
1373+ await result ( ) . handleRunUntilBlock ( 'condition1' , 'workflow-1' )
1374+ return
1375+ }
1376+ const runResult = await result ( ) . handleRunWorkflow (
1377+ triggerType === 'chat'
1378+ ? {
1379+ input : 'go' ,
1380+ conversationId : 'conversation-1' ,
1381+ }
1382+ : undefined
1383+ )
1384+ await drainStream ( runResult )
1385+ } )
1386+
1387+ expect ( mockExecute ) . toHaveBeenCalledTimes ( 1 )
1388+ const { workflowStateOverride } = mockExecute . mock . calls [ 0 ] [ 0 ]
1389+ const sentBlockIds = new Set ( Object . keys ( workflowStateOverride . blocks ) )
1390+
1391+ expect ( workflowStateOverride . blocks ) . toEqual ( blocks )
1392+ expect ( workflowStateOverride . edges ) . toEqual ( edges )
1393+ expect ( sentBlockIds . has ( 'disabledBranch' ) ) . toBe ( true )
1394+ for ( const edge of workflowStateOverride . edges ) {
1395+ expect ( sentBlockIds . has ( edge . source ) ) . toBe ( true )
1396+ expect ( sentBlockIds . has ( edge . target ) ) . toBe ( true )
1397+ }
1398+ const enabledBlocks = { start : blocks . start , condition1 : blocks . condition1 }
1399+ if ( triggerType === 'chat' ) {
1400+ expect ( mockFindStartBlock ) . toHaveBeenCalledWith ( enabledBlocks , 'chat' )
1401+ } else {
1402+ expect ( mockResolveStartCandidates ) . toHaveBeenCalledWith ( enabledBlocks , {
1403+ execution : 'manual' ,
1404+ } )
1405+ }
1406+
1407+ unmount ( )
1408+ }
1409+ )
1410+ } )
0 commit comments