1- import '@/executor/__test-utils__/mock-dependencies'
2-
31import { beforeEach , describe , expect , it , vi } from 'vitest'
42import { BlockType } from '@/executor/constants'
53import { ConditionBlockHandler } from '@/executor/handlers/condition/condition-handler'
64import type { BlockState , ExecutionContext } from '@/executor/types'
75import type { SerializedBlock , SerializedWorkflow } from '@/serializer/types'
86
7+ vi . mock ( '@/lib/logs/console/logger' , ( ) => ( {
8+ createLogger : vi . fn ( ( ) => ( {
9+ info : vi . fn ( ) ,
10+ error : vi . fn ( ) ,
11+ warn : vi . fn ( ) ,
12+ debug : vi . fn ( ) ,
13+ } ) ) ,
14+ } ) )
15+
16+ vi . mock ( '@/lib/core/utils/request' , ( ) => ( {
17+ generateRequestId : vi . fn ( ( ) => 'test-request-id' ) ,
18+ } ) )
19+
20+ vi . mock ( '@/lib/execution/isolated-vm' , ( ) => ( {
21+ executeInIsolatedVM : vi . fn ( ) ,
22+ } ) )
23+
24+ import { executeInIsolatedVM } from '@/lib/execution/isolated-vm'
25+
26+ const mockExecuteInIsolatedVM = executeInIsolatedVM as ReturnType < typeof vi . fn >
27+
28+ function simulateIsolatedVMExecution (
29+ code : string ,
30+ contextVariables : Record < string , unknown >
31+ ) : { result : unknown ; stdout : string ; error ?: { message : string ; name : string } } {
32+ try {
33+ const fn = new Function ( ...Object . keys ( contextVariables ) , code )
34+ const result = fn ( ...Object . values ( contextVariables ) )
35+ return { result, stdout : '' }
36+ } catch ( error : any ) {
37+ return {
38+ result : null ,
39+ stdout : '' ,
40+ error : { message : error . message , name : error . name || 'Error' } ,
41+ }
42+ }
43+ }
44+
945describe ( 'ConditionBlockHandler' , ( ) => {
1046 let handler : ConditionBlockHandler
1147 let mockBlock : SerializedBlock
@@ -18,7 +54,6 @@ describe('ConditionBlockHandler', () => {
1854 let mockPathTracker : any
1955
2056 beforeEach ( ( ) => {
21- // Define blocks first
2257 mockSourceBlock = {
2358 id : 'source-block-1' ,
2459 metadata : { id : 'source' , name : 'Source Block' } ,
@@ -33,7 +68,7 @@ describe('ConditionBlockHandler', () => {
3368 metadata : { id : BlockType . CONDITION , name : 'Test Condition' } ,
3469 position : { x : 50 , y : 50 } ,
3570 config : { tool : BlockType . CONDITION , params : { } } ,
36- inputs : { conditions : 'json' } , // Corrected based on previous step
71+ inputs : { conditions : 'json' } ,
3772 outputs : { } ,
3873 enabled : true ,
3974 }
@@ -56,7 +91,6 @@ describe('ConditionBlockHandler', () => {
5691 enabled : true ,
5792 }
5893
59- // Then define workflow using the block objects
6094 mockWorkflow = {
6195 blocks : [ mockSourceBlock , mockBlock , mockTargetBlock1 , mockTargetBlock2 ] ,
6296 connections : [
@@ -84,7 +118,6 @@ describe('ConditionBlockHandler', () => {
84118
85119 handler = new ConditionBlockHandler ( mockPathTracker , mockResolver )
86120
87- // Define mock context *after* workflow and blocks are set up
88121 mockContext = {
89122 workflowId : 'test-workflow-id' ,
90123 blockStates : new Map < string , BlockState > ( [
@@ -99,7 +132,7 @@ describe('ConditionBlockHandler', () => {
99132 ] ) ,
100133 blockLogs : [ ] ,
101134 metadata : { duration : 0 } ,
102- environmentVariables : { } , // Now set the context's env vars
135+ environmentVariables : { } ,
103136 decisions : { router : new Map ( ) , condition : new Map ( ) } ,
104137 loopExecutions : new Map ( ) ,
105138 executedBlocks : new Set ( [ mockSourceBlock . id ] ) ,
@@ -108,11 +141,11 @@ describe('ConditionBlockHandler', () => {
108141 completedLoops : new Set ( ) ,
109142 }
110143
111- // Reset mocks using vi
112144 vi . clearAllMocks ( )
113145
114- // Default mock implementations - Removed as it's in the shared mock now
115- // mockResolver.resolveBlockReferences.mockImplementation((value) => value)
146+ mockExecuteInIsolatedVM . mockImplementation ( async ( { code, contextVariables } ) => {
147+ return simulateIsolatedVMExecution ( code , contextVariables )
148+ } )
116149 } )
117150
118151 it ( 'should handle condition blocks' , ( ) => {
@@ -141,7 +174,6 @@ describe('ConditionBlockHandler', () => {
141174 selectedOption : 'cond1' ,
142175 }
143176
144- // Mock the full resolution pipeline
145177 mockResolver . resolveVariableReferences . mockReturnValue ( 'context.value > 5' )
146178 mockResolver . resolveBlockReferences . mockReturnValue ( 'context.value > 5' )
147179 mockResolver . resolveEnvVariables . mockReturnValue ( 'context.value > 5' )
@@ -182,7 +214,6 @@ describe('ConditionBlockHandler', () => {
182214 selectedOption : 'else1' ,
183215 }
184216
185- // Mock the full resolution pipeline
186217 mockResolver . resolveVariableReferences . mockReturnValue ( 'context.value < 0' )
187218 mockResolver . resolveBlockReferences . mockReturnValue ( 'context.value < 0' )
188219 mockResolver . resolveEnvVariables . mockReturnValue ( 'context.value < 0' )
@@ -207,7 +238,7 @@ describe('ConditionBlockHandler', () => {
207238 const inputs = { conditions : '{ "invalid json ' }
208239
209240 await expect ( handler . execute ( mockContext , mockBlock , inputs ) ) . rejects . toThrow (
210- / ^ I n v a l i d c o n d i t i o n s f o r m a t : U n t e r m i n a t e d s t r i n g . * /
241+ / ^ I n v a l i d c o n d i t i o n s f o r m a t : /
211242 )
212243 } )
213244
@@ -218,7 +249,6 @@ describe('ConditionBlockHandler', () => {
218249 ]
219250 const inputs = { conditions : JSON . stringify ( conditions ) }
220251
221- // Mock the full resolution pipeline
222252 mockResolver . resolveVariableReferences . mockReturnValue ( '{{source-block-1.value}} > 5' )
223253 mockResolver . resolveBlockReferences . mockReturnValue ( '10 > 5' )
224254 mockResolver . resolveEnvVariables . mockReturnValue ( '10 > 5' )
@@ -245,7 +275,6 @@ describe('ConditionBlockHandler', () => {
245275 ]
246276 const inputs = { conditions : JSON . stringify ( conditions ) }
247277
248- // Mock the full resolution pipeline for variable resolution
249278 mockResolver . resolveVariableReferences . mockReturnValue ( '"john" !== null' )
250279 mockResolver . resolveBlockReferences . mockReturnValue ( '"john" !== null' )
251280 mockResolver . resolveEnvVariables . mockReturnValue ( '"john" !== null' )
@@ -272,7 +301,6 @@ describe('ConditionBlockHandler', () => {
272301 ]
273302 const inputs = { conditions : JSON . stringify ( conditions ) }
274303
275- // Mock the full resolution pipeline for env variable resolution
276304 mockResolver . resolveVariableReferences . mockReturnValue ( '{{POOP}} === "hi"' )
277305 mockResolver . resolveBlockReferences . mockReturnValue ( '{{POOP}} === "hi"' )
278306 mockResolver . resolveEnvVariables . mockReturnValue ( '"hi" === "hi"' )
@@ -300,7 +328,6 @@ describe('ConditionBlockHandler', () => {
300328 const inputs = { conditions : JSON . stringify ( conditions ) }
301329
302330 const resolutionError = new Error ( 'Could not resolve reference: invalid-ref' )
303- // Mock the pipeline to throw at the variable resolution stage
304331 mockResolver . resolveVariableReferences . mockImplementation ( ( ) => {
305332 throw resolutionError
306333 } )
@@ -317,23 +344,21 @@ describe('ConditionBlockHandler', () => {
317344 ]
318345 const inputs = { conditions : JSON . stringify ( conditions ) }
319346
320- // Mock the full resolution pipeline
321347 mockResolver . resolveVariableReferences . mockReturnValue (
322348 'context.nonExistentProperty.doSomething()'
323349 )
324350 mockResolver . resolveBlockReferences . mockReturnValue ( 'context.nonExistentProperty.doSomething()' )
325351 mockResolver . resolveEnvVariables . mockReturnValue ( 'context.nonExistentProperty.doSomething()' )
326352
327353 await expect ( handler . execute ( mockContext , mockBlock , inputs ) ) . rejects . toThrow (
328- / ^ E v a l u a t i o n e r r o r i n c o n d i t i o n " i f " : E v a l u a t i o n e r r o r i n c o n d i t i o n : C a n n o t r e a d p r o p e r t i e s o f u n d e f i n e d \( r e a d i n g ' d o S o m e t h i n g ' \) \. \( R e s o l v e d : c o n t e x t \. n o n E x i s t e n t P r o p e r t y \. d o S o m e t h i n g \( \) \) $ /
354+ / E v a l u a t i o n e r r o r i n c o n d i t i o n " i f " . * d o S o m e t h i n g /
329355 )
330356 } )
331357
332358 it ( 'should handle missing source block output gracefully' , async ( ) => {
333359 const conditions = [ { id : 'cond1' , title : 'if' , value : 'true' } ]
334360 const inputs = { conditions : JSON . stringify ( conditions ) }
335361
336- // Create a new context with empty blockStates instead of trying to delete from readonly map
337362 const contextWithoutSource = {
338363 ...mockContext ,
339364 blockStates : new Map < string , BlockState > ( ) ,
@@ -355,7 +380,6 @@ describe('ConditionBlockHandler', () => {
355380
356381 mockContext . workflow ! . blocks = [ mockSourceBlock , mockBlock , mockTargetBlock2 ]
357382
358- // Mock the full resolution pipeline
359383 mockResolver . resolveVariableReferences . mockReturnValue ( 'true' )
360384 mockResolver . resolveBlockReferences . mockReturnValue ( 'true' )
361385 mockResolver . resolveEnvVariables . mockReturnValue ( 'true' )
@@ -381,7 +405,6 @@ describe('ConditionBlockHandler', () => {
381405 } ,
382406 ]
383407
384- // Mock the full resolution pipeline
385408 mockResolver . resolveVariableReferences
386409 . mockReturnValueOnce ( 'false' )
387410 . mockReturnValueOnce ( 'context.value === 99' )
@@ -394,12 +417,10 @@ describe('ConditionBlockHandler', () => {
394417
395418 const result = await handler . execute ( mockContext , mockBlock , inputs )
396419
397- // Should return success with no path selected (branch ends gracefully)
398420 expect ( ( result as any ) . conditionResult ) . toBe ( false )
399421 expect ( ( result as any ) . selectedPath ) . toBeNull ( )
400422 expect ( ( result as any ) . selectedConditionId ) . toBeNull ( )
401423 expect ( ( result as any ) . selectedOption ) . toBeNull ( )
402- // Decision should not be set when no condition matches
403424 expect ( mockContext . decisions . condition . has ( mockBlock . id ) ) . toBe ( false )
404425 } )
405426
@@ -410,7 +431,6 @@ describe('ConditionBlockHandler', () => {
410431 ]
411432 const inputs = { conditions : JSON . stringify ( conditions ) }
412433
413- // Mock the full resolution pipeline
414434 mockResolver . resolveVariableReferences . mockReturnValue ( 'context.item === "apple"' )
415435 mockResolver . resolveBlockReferences . mockReturnValue ( 'context.item === "apple"' )
416436 mockResolver . resolveEnvVariables . mockReturnValue ( 'context.item === "apple"' )
0 commit comments