Merge branch 'master' into fix-yarn-manifest
This commit is contained in:
commit
cff55783e6
|
@ -46,6 +46,7 @@ async function init() {
|
|||
HTTP_LOGGING: "0",
|
||||
VERSION: "0.0.0+local",
|
||||
PASSWORD_MIN_LENGTH: "1",
|
||||
OPENAI_API_KEY: "sk-abcdefghijklmnopqrstuvwxyz1234567890abcd",
|
||||
}
|
||||
|
||||
config = { ...config, ...existingConfig }
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
jest.mock("../../threads/automation")
|
||||
jest.mock("../../utilities/redis", () => ({
|
||||
init: jest.fn(),
|
||||
checkTestFlag: () => {
|
||||
return false
|
||||
},
|
||||
shutdown: jest.fn(),
|
||||
}))
|
||||
|
||||
jest.spyOn(global.console, "error")
|
||||
|
||||
import "../../environment"
|
||||
import * as automation from "../index"
|
||||
import * as thread from "../../threads/automation"
|
||||
import * as triggers from "../triggers"
|
||||
import { basicAutomation } from "../../tests/utilities/structures"
|
||||
import { wait } from "../../utilities"
|
||||
import { makePartial } from "../../tests/utilities"
|
||||
import { cleanInputValues } from "../automationUtils"
|
||||
import { Automation } from "@budibase/types"
|
||||
import TestConfiguration from "../../tests/utilities/TestConfiguration"
|
||||
|
||||
describe("Run through some parts of the automations system", () => {
|
||||
const config = new TestConfiguration()
|
||||
|
||||
beforeAll(async () => {
|
||||
await automation.init()
|
||||
await config.init()
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await automation.shutdown()
|
||||
config.end()
|
||||
})
|
||||
|
||||
it("should be able to init in builder", async () => {
|
||||
const automation: Automation = {
|
||||
...basicAutomation(),
|
||||
appId: config.appId!,
|
||||
}
|
||||
const fields: any = { a: 1, appId: config.appId }
|
||||
await triggers.externalTrigger(automation, fields)
|
||||
await wait(100)
|
||||
expect(thread.execute).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should check coercion", async () => {
|
||||
const table = await config.createTable()
|
||||
const automation: any = basicAutomation()
|
||||
automation.definition.trigger.inputs.tableId = table._id
|
||||
automation.definition.trigger.stepId = "APP"
|
||||
automation.definition.trigger.inputs.fields = { a: "number" }
|
||||
const fields: any = {
|
||||
appId: config.getAppId(),
|
||||
fields: {
|
||||
a: "1",
|
||||
},
|
||||
}
|
||||
await triggers.externalTrigger(automation, fields)
|
||||
await wait(100)
|
||||
expect(thread.execute).toHaveBeenCalledWith(
|
||||
makePartial({
|
||||
data: {
|
||||
event: {
|
||||
fields: {
|
||||
a: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
expect.any(Function)
|
||||
)
|
||||
})
|
||||
|
||||
it("should be able to clean inputs with the utilities", () => {
|
||||
// can't clean without a schema
|
||||
let output = cleanInputValues({ a: "1" })
|
||||
expect(output.a).toBe("1")
|
||||
output = cleanInputValues(
|
||||
{ a: "1", b: "true", c: "false", d: 1, e: "help" },
|
||||
{
|
||||
properties: {
|
||||
a: {
|
||||
type: "number",
|
||||
},
|
||||
b: {
|
||||
type: "boolean",
|
||||
},
|
||||
c: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
expect(output.a).toBe(1)
|
||||
expect(output.b).toBe(true)
|
||||
expect(output.c).toBe(false)
|
||||
expect(output.d).toBe(1)
|
||||
})
|
||||
})
|
|
@ -119,5 +119,31 @@ describe("automationUtils", () => {
|
|||
schema,
|
||||
})
|
||||
})
|
||||
|
||||
it("should be able to clean inputs with the utilities", () => {
|
||||
// can't clean without a schema
|
||||
let output = cleanInputValues({ a: "1" })
|
||||
expect(output.a).toBe("1")
|
||||
output = cleanInputValues(
|
||||
{ a: "1", b: "true", c: "false", d: 1, e: "help" },
|
||||
{
|
||||
properties: {
|
||||
a: {
|
||||
type: "number",
|
||||
},
|
||||
b: {
|
||||
type: "boolean",
|
||||
},
|
||||
c: {
|
||||
type: "boolean",
|
||||
},
|
||||
},
|
||||
}
|
||||
)
|
||||
expect(output.a).toBe(1)
|
||||
expect(output.b).toBe(true)
|
||||
expect(output.c).toBe(false)
|
||||
expect(output.d).toBe(1)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,17 +1,13 @@
|
|||
import * as automation from "../../index"
|
||||
import * as triggers from "../../triggers"
|
||||
import { basicTable, loopAutomation } from "../../../tests/utilities/structures"
|
||||
import { context } from "@budibase/backend-core"
|
||||
import { basicTable } from "../../../tests/utilities/structures"
|
||||
import {
|
||||
Table,
|
||||
LoopStepType,
|
||||
AutomationResults,
|
||||
ServerLogStepOutputs,
|
||||
CreateRowStepOutputs,
|
||||
FieldType,
|
||||
} from "@budibase/types"
|
||||
import * as loopUtils from "../../loopUtils"
|
||||
import { LoopInput } from "../../../definitions/automations"
|
||||
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"
|
||||
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
|
||||
|
||||
|
@ -34,41 +30,46 @@ describe("Attempt to run a basic loop automation", () => {
|
|||
config.end()
|
||||
})
|
||||
|
||||
async function runLoop(loopOpts?: LoopInput): Promise<AutomationResults> {
|
||||
const appId = config.getAppId()
|
||||
return await context.doInAppContext(appId, async () => {
|
||||
const params = { fields: { appId } }
|
||||
const result = await triggers.externalTrigger(
|
||||
loopAutomation(table._id!, loopOpts),
|
||||
params,
|
||||
{ getResponses: true }
|
||||
)
|
||||
if ("outputs" in result && !result.outputs.success) {
|
||||
throw new Error("Unable to proceed - failed to return anything.")
|
||||
}
|
||||
return result as AutomationResults
|
||||
})
|
||||
}
|
||||
|
||||
it("attempt to run a basic loop", async () => {
|
||||
const resp = await runLoop()
|
||||
expect(resp.steps[2].outputs.iterations).toBe(1)
|
||||
const result = await createAutomationBuilder(config)
|
||||
.onAppAction()
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.loop({
|
||||
option: LoopStepType.ARRAY,
|
||||
binding: "{{ steps.1.rows }}",
|
||||
})
|
||||
.serverLog({ text: "log statement" })
|
||||
.test({ fields: {} })
|
||||
|
||||
expect(result.steps[1].outputs.iterations).toBe(1)
|
||||
})
|
||||
|
||||
it("test a loop with a string", async () => {
|
||||
const resp = await runLoop({
|
||||
option: LoopStepType.STRING,
|
||||
binding: "a,b,c",
|
||||
})
|
||||
expect(resp.steps[2].outputs.iterations).toBe(3)
|
||||
const result = await createAutomationBuilder(config)
|
||||
.onAppAction()
|
||||
.loop({
|
||||
option: LoopStepType.STRING,
|
||||
binding: "a,b,c",
|
||||
})
|
||||
.serverLog({ text: "log statement" })
|
||||
.test({ fields: {} })
|
||||
|
||||
expect(result.steps[0].outputs.iterations).toBe(3)
|
||||
})
|
||||
|
||||
it("test a loop with a binding that returns an integer", async () => {
|
||||
const resp = await runLoop({
|
||||
option: LoopStepType.ARRAY,
|
||||
binding: "{{ 1 }}",
|
||||
})
|
||||
expect(resp.steps[2].outputs.iterations).toBe(1)
|
||||
const result = await createAutomationBuilder(config)
|
||||
.onAppAction()
|
||||
.loop({
|
||||
option: LoopStepType.ARRAY,
|
||||
binding: "{{ 1 }}",
|
||||
})
|
||||
.serverLog({ text: "log statement" })
|
||||
.test({ fields: {} })
|
||||
|
||||
expect(result.steps[0].outputs.iterations).toBe(1)
|
||||
})
|
||||
|
||||
it("should run an automation with a trigger, loop, and create row step", async () => {
|
||||
|
|
|
@ -42,4 +42,33 @@ describe("app action trigger", () => {
|
|||
})
|
||||
)
|
||||
})
|
||||
|
||||
it("should correct coerce values based on the schema", async () => {
|
||||
const { automation } = await createAutomationBuilder(config)
|
||||
.onAppAction({
|
||||
fields: { text: "string", number: "number", boolean: "boolean" },
|
||||
})
|
||||
.serverLog({
|
||||
text: "{{ fields.text }} {{ fields.number }} {{ fields.boolean }}",
|
||||
})
|
||||
.save()
|
||||
|
||||
await config.api.application.publish()
|
||||
|
||||
const jobs = await captureAutomationResults(automation, async () => {
|
||||
await config.withProdApp(async () => {
|
||||
await config.api.automation.trigger(automation._id!, {
|
||||
fields: { text: "1", number: "2", boolean: "true" },
|
||||
timeout: 1000,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
expect(jobs).toHaveLength(1)
|
||||
expect(jobs[0].data.event.fields).toEqual({
|
||||
text: "1",
|
||||
number: 2,
|
||||
boolean: true,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -145,13 +145,13 @@ class StepBuilder<
|
|||
TStep extends AutomationTriggerStepId
|
||||
> extends BranchStepBuilder<TStep> {
|
||||
private readonly config: TestConfiguration
|
||||
private readonly trigger: AutomationTrigger
|
||||
private readonly _trigger: AutomationTrigger
|
||||
private _name: string | undefined = undefined
|
||||
|
||||
constructor(config: TestConfiguration, trigger: AutomationTrigger) {
|
||||
super()
|
||||
this.config = config
|
||||
this.trigger = trigger
|
||||
this._trigger = trigger
|
||||
}
|
||||
|
||||
name(n: string): this {
|
||||
|
@ -165,7 +165,7 @@ class StepBuilder<
|
|||
name,
|
||||
definition: {
|
||||
steps: this.steps,
|
||||
trigger: this.trigger,
|
||||
trigger: this._trigger,
|
||||
stepNames: this.stepNames,
|
||||
},
|
||||
type: "automation",
|
||||
|
@ -182,6 +182,13 @@ class StepBuilder<
|
|||
const runner = await this.save()
|
||||
return await runner.test(triggerOutput)
|
||||
}
|
||||
|
||||
async trigger(
|
||||
request: TriggerAutomationRequest
|
||||
): Promise<TriggerAutomationResponse> {
|
||||
const runner = await this.save()
|
||||
return await runner.trigger(request)
|
||||
}
|
||||
}
|
||||
|
||||
class AutomationRunner<TStep extends AutomationTriggerStepId> {
|
||||
|
|
|
@ -15,6 +15,7 @@ export interface AutomationDataEvent {
|
|||
oldRow?: Row
|
||||
user?: UserBindings
|
||||
timestamp?: number
|
||||
fields?: Record<string, any>
|
||||
}
|
||||
|
||||
export interface AutomationData {
|
||||
|
|
Loading…
Reference in New Issue