update automation test builder to support ...building

This commit is contained in:
Peter Clement 2024-09-04 16:37:33 +01:00
parent d80123bbcb
commit 2135dbca67
4 changed files with 84 additions and 174 deletions

View File

@ -15,6 +15,7 @@ import { Automation, FieldType, Table } from "@budibase/types"
import { mocks } from "@budibase/backend-core/tests"
import { FilterConditions } from "../../../automations/steps/filter"
import { removeDeprecated } from "../../../automations/utils"
import { createAutomationBuilder } from "../../../automations/tests/utilities/AutomationTestBuilder"
const MAX_RETRIES = 4
let {
@ -25,8 +26,6 @@ let {
collectAutomation,
filterAutomation,
updateRowAutomationWithFilters,
branchAutomationIncorrectPosition,
branchAutomation,
} = setup.structures
describe("/automations", () => {
@ -124,23 +123,22 @@ describe("/automations", () => {
})
it("Should ensure you can't have a branch as not a last step", async () => {
const automation = branchAutomationIncorrectPosition()
await config.api.automation.post(automation, {
status: 400,
body: {
message:
'Invalid body - "definition.steps[0].inputs.branches" must contain at least 1 items',
},
const automation = createAutomationBuilder({
name: "String Equality Branching",
appId: config.getAppId(),
})
})
it("Should check validation on an automation that has a branch step with no children", async () => {
const automation = branchAutomationIncorrectPosition()
automation.definition.steps[0].inputs.branches = [
{ name: "test", condition: { equal: { "steps.1.success": "true" } } },
]
automation.definition.steps[0].inputs.children = {}
.appAction({ fields: { status: "active" } })
.branch({
activeBranch: {
steps: stepBuilder =>
stepBuilder.serverLog({ text: "Active user" }),
condition: {
equal: { "trigger.fields.status": "active" },
},
},
})
.serverLog({ text: "Inactive user" })
.build()
await config.api.automation.post(automation, {
status: 400,
@ -151,41 +149,73 @@ describe("/automations", () => {
})
})
it("Should check validation on a branch step with empty conditions", async () => {
const automation = branchAutomation()
automation.definition.steps[1].inputs.branches = [
{ name: "test", condition: {} },
]
automation.definition.steps[1].inputs.children = {}
it("Should check validation on an automation that has a branch step with no children", async () => {
const automation = createAutomationBuilder({
name: "String Equality Branching",
appId: config.getAppId(),
})
.appAction({ fields: { status: "active" } })
.branch({})
.serverLog({ text: "Inactive user" })
.build()
await config.api.automation.post(automation, {
status: 400,
body: {
message:
'Invalid body - "definition.steps[1].inputs.branches[0].condition" must have at least 1 key',
'Invalid body - "definition.steps[0].inputs.branches" must contain at least 1 items',
},
})
})
it("Should check validation on a branch step with empty conditions", async () => {
const automation = createAutomationBuilder({
name: "String Equality Branching",
appId: config.getAppId(),
})
.appAction({ fields: { status: "active" } })
.branch({
activeBranch: {
steps: stepBuilder =>
stepBuilder.serverLog({ text: "Active user" }),
condition: {},
},
})
.build()
await config.api.automation.post(automation, {
status: 400,
body: {
message:
'Invalid body - "definition.steps[0].inputs.branches[0].condition" must have at least 1 key',
},
})
})
it("Should check validation on an branch that has a condition that is not valid", async () => {
const automation = branchAutomation()
automation.definition.steps[1].inputs.branches = [
{
name: "test",
condition: {
INCORRECT: { "steps.1.success": true },
const automation = createAutomationBuilder({
name: "String Equality Branching",
appId: config.getAppId(),
})
.appAction({ fields: { status: "active" } })
.branch({
activeBranch: {
steps: stepBuilder =>
stepBuilder.serverLog({ text: "Active user" }),
condition: {
//@ts-ignore
INCORRECT: { "trigger.fields.status": "active" },
},
},
},
]
automation.definition.steps[1].inputs.children = {}
})
.serverLog({ text: "Inactive user" })
.build()
await config.api.automation.post(automation, {
status: 400,
body: {
message:
'Invalid body - "definition.steps[1].inputs.branches[0].condition.INCORRECT" is not allowed',
'Invalid body - "definition.steps[0].inputs.branches[0].condition.INCORRECT" is not allowed',
},
})
})

View File

@ -291,7 +291,9 @@ function generateStepSchema(allowStepTypes: string[]) {
type: Joi.string()
.required()
.valid(...allowStepTypes),
}).unknown(true)
})
.unknown(true)
.id("step")
}
const validateStepsArray = (

View File

@ -179,7 +179,7 @@ class AutomationBuilder extends BaseStepBuilder {
private triggerOutputs: any
private triggerSet: boolean = false
constructor(options: { name?: string } = {}) {
constructor(options: { name?: string; appId?: string } = {}) {
super()
this.automationConfig = {
name: options.name || `Test Automation ${uuidv4()}`,
@ -188,7 +188,7 @@ class AutomationBuilder extends BaseStepBuilder {
trigger: {} as AutomationTrigger,
},
type: "automation",
appId: setup.getConfig().getAppId(),
appId: options.appId ?? setup.getConfig().getAppId(),
}
this.config = setup.getConfig()
}
@ -261,13 +261,14 @@ class AutomationBuilder extends BaseStepBuilder {
return this
}
branch(branchConfig: BranchConfig): {
run: () => Promise<AutomationResults>
} {
branch(branchConfig: BranchConfig): this {
this.addBranchStep(branchConfig)
return {
run: () => this.run(),
}
return this
}
build(): Automation {
this.automationConfig.definition.steps = this.steps
return this.automationConfig
}
async run() {
@ -275,7 +276,7 @@ class AutomationBuilder extends BaseStepBuilder {
throw new Error("Please add a trigger to this automation test")
}
this.automationConfig.definition.steps = this.steps
const automation = await this.config.createAutomation(this.automationConfig)
const automation = await this.config.createAutomation(this.build())
const results = await testAutomation(
this.config,
automation,
@ -295,6 +296,9 @@ class AutomationBuilder extends BaseStepBuilder {
}
}
export function createAutomationBuilder(options?: { name?: string }) {
export function createAutomationBuilder(options?: {
name?: string
appId?: string
}) {
return new AutomationBuilder(options)
}

View File

@ -292,132 +292,6 @@ export function serverLogAutomation(appId?: string): Automation {
}
}
export function branchAutomationIncorrectPosition(appId?: string): Automation {
return {
name: "My Automation",
screenId: "kasdkfldsafkl",
live: true,
uiTree: {},
definition: {
trigger: {
stepId: AutomationTriggerStepId.APP,
name: "test",
tagline: "test",
icon: "test",
description: "test",
type: AutomationStepType.TRIGGER,
id: "test",
inputs: { fields: {} },
schema: {
inputs: {
properties: {},
},
outputs: {
properties: {},
},
},
},
steps: [
{
stepId: AutomationActionStepId.BRANCH,
name: "Branch",
tagline: "Console log a value in the backend",
icon: "Monitoring",
description: "Logs the given text to the server (using console.log)",
inputs: {
branches: [],
},
schema: { inputs: { properties: {} }, outputs: { properties: {} } },
id: "y8lkZbeSe",
type: AutomationStepType.LOGIC,
},
{
stepId: AutomationActionStepId.SERVER_LOG,
name: "Backend log",
tagline: "Console log a value in the backend",
icon: "Monitoring",
description: "Logs the given text to the server (using console.log)",
internal: true,
features: {
LOOPING: true,
},
inputs: {
text: "log statement",
},
schema: BUILTIN_ACTION_DEFINITIONS.SERVER_LOG.schema,
id: "y8lkZbeSe",
type: AutomationStepType.ACTION,
},
],
},
type: "automation",
appId: appId!,
}
}
export function branchAutomation(appId?: string): Automation {
return {
name: "My Automation",
screenId: "kasdkfldsafkl",
live: true,
uiTree: {},
definition: {
trigger: {
stepId: AutomationTriggerStepId.APP,
name: "test",
tagline: "test",
icon: "test",
description: "test",
type: AutomationStepType.TRIGGER,
id: "test",
inputs: { fields: {} },
schema: {
inputs: {
properties: {},
},
outputs: {
properties: {},
},
},
},
steps: [
{
stepId: AutomationActionStepId.SERVER_LOG,
name: "Backend log",
tagline: "Console log a value in the backend",
icon: "Monitoring",
description: "Logs the given text to the server (using console.log)",
internal: true,
features: {
LOOPING: true,
},
inputs: {
text: "log statement",
},
schema: BUILTIN_ACTION_DEFINITIONS.SERVER_LOG.schema,
id: "y8lkZbeSe",
type: AutomationStepType.ACTION,
},
{
stepId: AutomationActionStepId.BRANCH,
name: "Branch",
tagline: "Console log a value in the backend",
icon: "Monitoring",
description: "Logs the given text to the server (using console.log)",
inputs: {
branches: [],
},
schema: { inputs: { properties: {} }, outputs: { properties: {} } },
id: "y8lkZbeSe",
type: AutomationStepType.LOGIC,
},
],
},
type: "automation",
appId: appId!,
}
}
export function loopAutomation(
tableId: string,
loopOpts?: LoopInput