Skip to main content
Glama

mcp-google-sheets

router-branching.test.ts15.6 kB
import { BranchCondition, BranchOperator, FlowAction, RouterExecutionType } from '@activepieces/shared' import { ExecutionVerdict, FlowExecutorContext } from '../../src/lib/handler/context/flow-execution-context' import { flowExecutor } from '../../src/lib/handler/flow-executor' import { buildCodeAction, buildPieceAction, buildRouterWithOneCondition, generateMockEngineConstants } from './test-helper' function executeRouterActionWithOneCondition(children: FlowAction[], conditions: (BranchCondition | null)[], executionType: RouterExecutionType): Promise<FlowExecutorContext> { return flowExecutor.execute({ action: buildRouterWithOneCondition({ children, conditions, executionType, }), executionState: FlowExecutorContext.empty(), constants: generateMockEngineConstants(), }) } describe('router with branching different conditions', () => { it('should execute router with the first matching condition', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'data_mapper_1', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'anything', caseSensitive: false, }, ], RouterExecutionType.EXECUTE_FIRST_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.data_mapper.output).toEqual({ 'key': 3 }) expect(result.steps.data_mapper_1).toBeUndefined() }) it('should execute router with the all matching conditions', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'data_mapper_1', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, ], RouterExecutionType.EXECUTE_ALL_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.data_mapper.output).toEqual({ 'key': 3 }) expect(result.steps.data_mapper_1.output).toEqual({ 'key': 3 }) }) it('should execute router but no branch will match', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'data_mapper_1', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 5 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'abc', secondValue: 'test', caseSensitive: false, }, { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'fasc', caseSensitive: false, }, ], RouterExecutionType.EXECUTE_ALL_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) const routerOutput = result.steps.router.output as { branches: boolean[] } expect(routerOutput.branches).toEqual([ { branchName: 'Test Branch', branchIndex: 1, evaluation: false, }, { branchName: 'Test Branch', branchIndex: 2, evaluation: false, }, ]) expect(result.steps.data_mapper).toBeUndefined() expect(result.steps.data_mapper_1).toBeUndefined() }) it('should execute fallback branch with first match execution type', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'data_mapper_1', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 5 }}', }, }, }), buildPieceAction({ name: 'fallback_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 10 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'abc', secondValue: 'test', caseSensitive: false, }, { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'fasc', caseSensitive: false, }, null, // Fallback branch ], RouterExecutionType.EXECUTE_FIRST_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.data_mapper).toBeUndefined() expect(result.steps.data_mapper_1).toBeUndefined() expect(result.steps.fallback_mapper.output).toEqual({ 'key': 11 }) }) it('should execute fallback branch with all match execution type', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'data_mapper_1', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 5 }}', }, }, }), buildPieceAction({ name: 'fallback_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 10 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'abc', secondValue: 'test', caseSensitive: false, }, { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'fasc', caseSensitive: false, }, null, // Fallback branch ], RouterExecutionType.EXECUTE_ALL_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.data_mapper).toBeUndefined() expect(result.steps.data_mapper_1).toBeUndefined() expect(result.steps.fallback_mapper.output).toEqual({ 'key': 11 }) }) it('should not execute fallback branch when there is a matching condition in EXECUTE_FIRST_MATCH mode', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'fallback_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 10 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, null, // Fallback branch ], RouterExecutionType.EXECUTE_FIRST_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.data_mapper.output).toEqual({ 'key': 3 }) expect(result.steps.fallback_mapper).toBeUndefined() }) it('should not execute fallback branch when there is a matching condition in EXECUTE_ALL_MATCH mode', async () => { const result = await executeRouterActionWithOneCondition([ buildPieceAction({ name: 'data_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 2 }}', }, }, }), buildPieceAction({ name: 'data_mapper_1', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 5 }}', }, }, }), buildPieceAction({ name: 'fallback_mapper', pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: { mapping: { 'key': '{{ 1 + 10 }}', }, }, }), ], [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, null, // Fallback branch ], RouterExecutionType.EXECUTE_ALL_MATCH) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.data_mapper.output).toEqual({ 'key': 3 }) expect(result.steps.data_mapper_1.output).toEqual({ 'key': 6 }) expect(result.steps.fallback_mapper).toBeUndefined() }) it('should skip router', async () => { const result = await flowExecutor.execute({ action: buildRouterWithOneCondition({ children: [ buildPieceAction({ name: 'data_mapper', skip: true, pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: {}, }), ], conditions: [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, ], executionType: RouterExecutionType.EXECUTE_FIRST_MATCH, skip: true }), executionState: FlowExecutorContext.empty(), constants: generateMockEngineConstants(), }) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.router).toBeUndefined() }) it('should skip router action in flow', async () => { const router: FlowAction = { ...buildRouterWithOneCondition({ children: [ buildPieceAction({ name: 'data_mapper', skip: true, pieceName: '@activepieces/piece-data-mapper', actionName: 'advanced_mapping', input: {}, }), ], conditions: [ { operator: BranchOperator.TEXT_EXACTLY_MATCHES, firstValue: 'test', secondValue: 'test', caseSensitive: false, }, ], executionType: RouterExecutionType.EXECUTE_FIRST_MATCH, skip: true }), nextAction: { ...buildCodeAction({ name: 'echo_step', skip: false, input: { 'key': '{{ 1 + 2 }}', }, }), nextAction: undefined, }, } const result = await flowExecutor.execute({ action: router, executionState: FlowExecutorContext.empty(), constants: generateMockEngineConstants(), }) expect(result.verdict).toBe(ExecutionVerdict.RUNNING) expect(result.steps.router).toBeUndefined() expect(result.steps.echo_step.output).toEqual({ 'key': 3 }) }) })

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/activepieces/activepieces'

If you have feedback or need assistance with the MCP directory API, please join our Discord server