@@ -1393,6 +1393,107 @@ describe('EdgeManager', () => {
13931393 expect ( readyNodes ) . not . toContain ( target2Id )
13941394 expect ( readyNodes ) . toHaveLength ( 0 )
13951395 } )
1396+
1397+ it ( 'should handle no matching router route without queuing downstream sentinels' , ( ) => {
1398+ const routerId = 'router-1'
1399+ const routeTargetId = 'route-target'
1400+ const downstreamSentinelId = 'loop-downstream-sentinel-end'
1401+ const afterLoopId = 'after-loop'
1402+
1403+ const routerNode = createMockNode ( routerId , [
1404+ { target : routeTargetId , sourceHandle : 'router-route1' } ,
1405+ ] )
1406+ const routeTargetNode = createMockNode (
1407+ routeTargetId ,
1408+ [ { target : downstreamSentinelId } ] ,
1409+ [ routerId ]
1410+ )
1411+ const downstreamSentinelNode = createMockNode (
1412+ downstreamSentinelId ,
1413+ [ { target : afterLoopId , sourceHandle : EDGE . LOOP_EXIT } ] ,
1414+ [ routeTargetId ]
1415+ )
1416+ downstreamSentinelNode . metadata = {
1417+ isSentinel : true ,
1418+ sentinelType : 'end' ,
1419+ subflowId : 'downstream' ,
1420+ subflowType : 'loop' ,
1421+ }
1422+ const afterLoopNode = createMockNode ( afterLoopId , [ ] , [ downstreamSentinelId ] )
1423+
1424+ const nodes = new Map < string , DAGNode > ( [
1425+ [ routerId , routerNode ] ,
1426+ [ routeTargetId , routeTargetNode ] ,
1427+ [ downstreamSentinelId , downstreamSentinelNode ] ,
1428+ [ afterLoopId , afterLoopNode ] ,
1429+ ] )
1430+
1431+ const dag = createMockDAG ( nodes )
1432+ const edgeManager = new EdgeManager ( dag )
1433+ const readyNodes = edgeManager . processOutgoingEdges ( routerNode , {
1434+ selectedRoute : 'missing-route' ,
1435+ } )
1436+
1437+ expect ( readyNodes ) . not . toContain ( routeTargetId )
1438+ expect ( readyNodes ) . not . toContain ( downstreamSentinelId )
1439+ expect ( readyNodes ) . toHaveLength ( 0 )
1440+ } )
1441+
1442+ it ( 'should allow no matching router route to queue an enclosing subflow sentinel' , ( ) => {
1443+ const loopId = 'loop-1'
1444+ const routerId = 'router-1'
1445+ const routeTargetId = 'route-target'
1446+ const loopEndId = `loop-${ loopId } -sentinel-end`
1447+ const loopStartId = `loop-${ loopId } -sentinel-start`
1448+
1449+ const routerNode = createMockNode (
1450+ routerId ,
1451+ [ { target : routeTargetId , sourceHandle : 'router-route1' } ] ,
1452+ [ loopStartId ]
1453+ )
1454+ routerNode . metadata = {
1455+ subflowId : loopId ,
1456+ subflowType : 'loop' ,
1457+ }
1458+ const routeTargetNode = createMockNode ( routeTargetId , [ { target : loopEndId } ] , [ routerId ] )
1459+ routeTargetNode . metadata = {
1460+ subflowId : loopId ,
1461+ subflowType : 'loop' ,
1462+ }
1463+ const loopEndNode = createMockNode (
1464+ loopEndId ,
1465+ [
1466+ { target : loopStartId , sourceHandle : EDGE . LOOP_CONTINUE } ,
1467+ { target : 'after-loop' , sourceHandle : EDGE . LOOP_EXIT } ,
1468+ ] ,
1469+ [ routeTargetId ]
1470+ )
1471+ loopEndNode . metadata = {
1472+ isSentinel : true ,
1473+ sentinelType : 'end' ,
1474+ subflowId : loopId ,
1475+ subflowType : 'loop' ,
1476+ }
1477+ const loopStartNode = createMockNode ( loopStartId , [ { target : routerId } ] , [ loopEndId ] )
1478+ const afterLoopNode = createMockNode ( 'after-loop' , [ ] , [ loopEndId ] )
1479+
1480+ const nodes = new Map < string , DAGNode > ( [
1481+ [ routerId , routerNode ] ,
1482+ [ routeTargetId , routeTargetNode ] ,
1483+ [ loopEndId , loopEndNode ] ,
1484+ [ loopStartId , loopStartNode ] ,
1485+ [ 'after-loop' , afterLoopNode ] ,
1486+ ] )
1487+
1488+ const dag = createMockDAG ( nodes )
1489+ const edgeManager = new EdgeManager ( dag )
1490+ const readyNodes = edgeManager . processOutgoingEdges ( routerNode , {
1491+ selectedRoute : 'missing-route' ,
1492+ } )
1493+
1494+ expect ( readyNodes ) . not . toContain ( routeTargetId )
1495+ expect ( readyNodes ) . toContain ( loopEndId )
1496+ } )
13961497 } )
13971498
13981499 describe ( 'Condition inside loop - loop control edges should not be cascade-deactivated' , ( ) => {
0 commit comments