Skip to content

Commit 9899eac

Browse files
committed
fix: create steps with parameters for if then
1 parent edc9571 commit 9899eac

File tree

3 files changed

+229
-7
lines changed

3 files changed

+229
-7
lines changed

packages/backend/src/graphql/__tests__/mutations/create-flow-with-steps.itest.ts

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,4 +452,213 @@ describe('createFlowWithSteps mutation integration tests', () => {
452452
const flows = await Flow.query()
453453
expect(flows).toHaveLength(0)
454454
})
455+
456+
describe('if-then step validation', () => {
457+
it('should successfully create flow with valid if-then steps', async () => {
458+
const params = {
459+
input: {
460+
flowName: 'Test Flow with If-Then',
461+
steps: [
462+
{
463+
type: 'trigger' as StepEnumType,
464+
appKey: 'scheduler',
465+
key: 'every-hour',
466+
position: 1,
467+
config: {},
468+
},
469+
{
470+
type: 'action' as StepEnumType,
471+
appKey: 'toolbox',
472+
key: 'ifThen',
473+
position: 2,
474+
config: {},
475+
parameters: {
476+
depth: 0,
477+
branchName: 'If',
478+
},
479+
},
480+
{
481+
type: 'action' as StepEnumType,
482+
appKey: 'gmail',
483+
key: 'send-email',
484+
position: 3,
485+
config: {},
486+
parameters: {},
487+
},
488+
{
489+
type: 'action' as StepEnumType,
490+
appKey: 'toolbox',
491+
key: 'ifThen',
492+
position: 4,
493+
config: {},
494+
parameters: {
495+
depth: 0,
496+
branchName: 'Else',
497+
},
498+
},
499+
{
500+
type: 'action' as StepEnumType,
501+
appKey: 'slack',
502+
key: 'send-message',
503+
position: 5,
504+
config: {},
505+
parameters: {
506+
depth: 1,
507+
branchName: 'Else',
508+
},
509+
},
510+
],
511+
},
512+
}
513+
514+
const result = await createFlowWithSteps(null, params, context)
515+
516+
expect(result).toBeDefined()
517+
expect(result.name).toBe('Test Flow with If-Then')
518+
519+
const steps = await Step.query()
520+
.where('flow_id', result.id)
521+
.orderBy('position', 'asc')
522+
523+
expect(steps).toHaveLength(5)
524+
expect(steps[1].key).toBe('ifThen')
525+
expect(steps[1].parameters).toEqual({ depth: 0, branchName: 'If' })
526+
expect(steps[3].key).toBe('ifThen')
527+
expect(steps[3].parameters).toEqual({ depth: 0, branchName: 'Else' })
528+
})
529+
530+
it('should throw error when if-then step is missing depth parameter', async () => {
531+
const params = {
532+
input: {
533+
flowName: 'Test Flow',
534+
steps: [
535+
{
536+
type: 'trigger' as StepEnumType,
537+
appKey: 'scheduler',
538+
key: 'every-hour',
539+
position: 1,
540+
config: {},
541+
},
542+
{
543+
type: 'action' as StepEnumType,
544+
appKey: 'toolbox',
545+
key: 'ifThen',
546+
position: 2,
547+
config: {},
548+
parameters: {
549+
branchName: 'If',
550+
// missing depth
551+
},
552+
},
553+
],
554+
},
555+
}
556+
557+
await expect(createFlowWithSteps(null, params, context)).rejects.toThrow(
558+
'If-then step must have depth and branch parameters',
559+
)
560+
561+
const flows = await Flow.query()
562+
expect(flows).toHaveLength(0)
563+
})
564+
565+
it('should throw error when if-then step is missing branchName parameter', async () => {
566+
const params = {
567+
input: {
568+
flowName: 'Test Flow',
569+
steps: [
570+
{
571+
type: 'trigger' as StepEnumType,
572+
appKey: 'scheduler',
573+
key: 'every-hour',
574+
position: 1,
575+
config: {},
576+
},
577+
{
578+
type: 'action' as StepEnumType,
579+
appKey: 'toolbox',
580+
key: 'ifThen',
581+
position: 2,
582+
config: {},
583+
parameters: {
584+
depth: 0,
585+
// missing branchName
586+
},
587+
},
588+
],
589+
},
590+
}
591+
592+
await expect(createFlowWithSteps(null, params, context)).rejects.toThrow(
593+
'If-then step must have depth and branch parameters',
594+
)
595+
596+
const flows = await Flow.query()
597+
expect(flows).toHaveLength(0)
598+
})
599+
600+
it('should throw error when if-then step has no parameters', async () => {
601+
const params = {
602+
input: {
603+
flowName: 'Test Flow',
604+
steps: [
605+
{
606+
type: 'trigger' as StepEnumType,
607+
appKey: 'scheduler',
608+
key: 'every-hour',
609+
position: 1,
610+
config: {},
611+
},
612+
{
613+
type: 'action' as StepEnumType,
614+
appKey: 'toolbox',
615+
key: 'ifThen',
616+
position: 2,
617+
config: {},
618+
// missing parameters entirely
619+
},
620+
],
621+
},
622+
}
623+
624+
await expect(createFlowWithSteps(null, params, context)).rejects.toThrow(
625+
'If-then step must have depth and branch parameters',
626+
)
627+
628+
const flows = await Flow.query()
629+
expect(flows).toHaveLength(0)
630+
})
631+
632+
it('should throw error when if-then step has empty parameters object', async () => {
633+
const params = {
634+
input: {
635+
flowName: 'Test Flow',
636+
steps: [
637+
{
638+
type: 'trigger' as StepEnumType,
639+
appKey: 'scheduler',
640+
key: 'every-hour',
641+
position: 1,
642+
config: {},
643+
},
644+
{
645+
type: 'action' as StepEnumType,
646+
appKey: 'toolbox',
647+
key: 'ifThen',
648+
position: 2,
649+
config: {},
650+
parameters: {},
651+
},
652+
],
653+
},
654+
}
655+
656+
await expect(createFlowWithSteps(null, params, context)).rejects.toThrow(
657+
'If-then step must have depth and branch parameters',
658+
)
659+
660+
const flows = await Flow.query()
661+
expect(flows).toHaveLength(0)
662+
})
663+
})
455664
})

packages/backend/src/graphql/mutations/create-flow-with-steps.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,24 @@ const createFlowWithSteps: MutationResolvers['createFlowWithSteps'] = async (
4747
},
4848
})
4949

50-
const stepsToInsert = steps.map((step: StepInput) => ({
51-
type: step.type,
52-
appKey: step.appKey,
53-
key: step.key,
54-
config: step?.config || {},
55-
position: step.position,
56-
}))
50+
const stepsToInsert = steps.map((step: StepInput) => {
51+
// add a check that if step.appKey === 'toolbox', it should have step.parameters with depth and branchname
52+
if (
53+
step.key === 'ifThen' &&
54+
(step.parameters?.depth == null || step.parameters?.branchName == null)
55+
) {
56+
throw new Error('If-then step must have depth and branch parameters')
57+
}
58+
59+
return {
60+
type: step.type,
61+
appKey: step.appKey,
62+
key: step.key,
63+
config: step?.config || {},
64+
parameters: step?.parameters || {},
65+
position: step.position,
66+
}
67+
})
5768

5869
await flow.$relatedQuery('steps', trx).insert(stepsToInsert)
5970

packages/frontend/src/components/AiBuilder/components/StepsPreview.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ export default function StepsPreview() {
164164
stepName: step?.config?.stepName || null,
165165
}
166166
: {},
167+
// NOTE: we need to pass the parameters especially for if-then branches
168+
parameters: step?.parameters || {},
167169
position: step.position,
168170
})),
169171
},

0 commit comments

Comments
 (0)