tests to cover automation naming
This commit is contained in:
parent
2cdbf4190b
commit
a831a4bf07
|
@ -242,4 +242,28 @@ describe("Loop automations", () => {
|
|||
expect(results.steps[1].outputs.message).toContain("- 3")
|
||||
expect(results.steps[3].outputs.message).toContain("- 3")
|
||||
})
|
||||
|
||||
it("should use automation names to loop with", async () => {
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test Trigger with Loop and Create Row",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.loop(
|
||||
{
|
||||
option: LoopStepType.ARRAY,
|
||||
binding: [1, 2, 3],
|
||||
},
|
||||
"FirstLoopStep"
|
||||
)
|
||||
.serverLog({ text: "Message {{loop.currentItem}}" }, "FirstLoopLog")
|
||||
.serverLog(
|
||||
{ text: "{{steps.FirstLoopLog.iterations}}" },
|
||||
"FirstLoopIterationLog"
|
||||
)
|
||||
.run()
|
||||
|
||||
expect(results.steps[1].outputs.message).toContain("- 3")
|
||||
})
|
||||
})
|
||||
|
|
|
@ -49,151 +49,188 @@ describe("Automation Scenarios", () => {
|
|||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it("should trigger an automation which querys the database", async () => {
|
||||
const table = await config.createTable()
|
||||
const row = {
|
||||
name: "Test Row",
|
||||
description: "original description",
|
||||
tableId: table._id,
|
||||
}
|
||||
await config.createRow(row)
|
||||
await config.createRow(row)
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test Row Save and Create",
|
||||
it("should trigger an automation which querys the database", async () => {
|
||||
const table = await config.createTable()
|
||||
const row = {
|
||||
name: "Test Row",
|
||||
description: "original description",
|
||||
tableId: table._id,
|
||||
}
|
||||
await config.createRow(row)
|
||||
await config.createRow(row)
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test Row Save and Create",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.run()
|
||||
|
||||
expect(results.steps).toHaveLength(1)
|
||||
expect(results.steps[0].outputs.rows).toHaveLength(2)
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
it("should trigger an automation which querys the database then deletes a row", async () => {
|
||||
const table = await config.createTable()
|
||||
const row = {
|
||||
name: "DFN",
|
||||
description: "original description",
|
||||
tableId: table._id,
|
||||
}
|
||||
await config.createRow(row)
|
||||
await config.createRow(row)
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test Row Save and Create",
|
||||
})
|
||||
.run()
|
||||
|
||||
expect(results.steps).toHaveLength(1)
|
||||
expect(results.steps[0].outputs.rows).toHaveLength(2)
|
||||
})
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.deleteRow({
|
||||
tableId: table._id!,
|
||||
id: "{{ steps.1.rows.0._id }}",
|
||||
})
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.run()
|
||||
|
||||
it("should trigger an automation which querys the database then deletes a row", async () => {
|
||||
const table = await config.createTable()
|
||||
const row = {
|
||||
name: "DFN",
|
||||
description: "original description",
|
||||
tableId: table._id,
|
||||
}
|
||||
await config.createRow(row)
|
||||
await config.createRow(row)
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test Row Save and Create",
|
||||
expect(results.steps).toHaveLength(3)
|
||||
expect(results.steps[1].outputs.success).toBeTruthy()
|
||||
expect(results.steps[2].outputs.rows).toHaveLength(1)
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.deleteRow({
|
||||
tableId: table._id!,
|
||||
id: "{{ steps.1.rows.0._id }}",
|
||||
})
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.run()
|
||||
|
||||
expect(results.steps).toHaveLength(3)
|
||||
expect(results.steps[1].outputs.success).toBeTruthy()
|
||||
expect(results.steps[2].outputs.rows).toHaveLength(1)
|
||||
})
|
||||
|
||||
it("should query an external database for some data then insert than into an internal table", async () => {
|
||||
const { datasource, client } = await setup.setupTestDatasource(
|
||||
config,
|
||||
DatabaseName.MYSQL
|
||||
)
|
||||
|
||||
const newTable = await config.createTable({
|
||||
name: "table",
|
||||
type: "table",
|
||||
schema: {
|
||||
name: {
|
||||
name: "name",
|
||||
type: FieldType.STRING,
|
||||
constraints: {
|
||||
presence: true,
|
||||
},
|
||||
},
|
||||
age: {
|
||||
name: "age",
|
||||
type: FieldType.NUMBER,
|
||||
constraints: {
|
||||
presence: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const tableName = await setup.createTestTable(client, {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
})
|
||||
|
||||
const rows = [
|
||||
{ name: "Joe", age: 20 },
|
||||
{ name: "Bob", age: 25 },
|
||||
{ name: "Paul", age: 30 },
|
||||
]
|
||||
|
||||
await setup.insertTestData(client, tableName, rows)
|
||||
|
||||
const query = await setup.saveTestQuery(
|
||||
config,
|
||||
client,
|
||||
tableName,
|
||||
datasource
|
||||
)
|
||||
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test external query and save",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({
|
||||
fields: {},
|
||||
})
|
||||
.executeQuery({
|
||||
query: {
|
||||
queryId: query._id!,
|
||||
},
|
||||
})
|
||||
.loop({
|
||||
option: LoopStepType.ARRAY,
|
||||
binding: "{{ steps.1.response }}",
|
||||
})
|
||||
.createRow({
|
||||
row: {
|
||||
name: "{{ loop.currentItem.name }}",
|
||||
age: "{{ loop.currentItem.age }}",
|
||||
tableId: newTable._id!,
|
||||
},
|
||||
})
|
||||
.queryRows({
|
||||
tableId: newTable._id!,
|
||||
})
|
||||
.run()
|
||||
|
||||
expect(results.steps).toHaveLength(3)
|
||||
|
||||
expect(results.steps[1].outputs.iterations).toBe(3)
|
||||
expect(results.steps[1].outputs.items).toHaveLength(3)
|
||||
|
||||
expect(results.steps[2].outputs.rows).toHaveLength(3)
|
||||
|
||||
rows.forEach(expectedRow => {
|
||||
expect(results.steps[2].outputs.rows).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining(expectedRow)])
|
||||
it("should query an external database for some data then insert than into an internal table", async () => {
|
||||
const { datasource, client } = await setup.setupTestDatasource(
|
||||
config,
|
||||
DatabaseName.MYSQL
|
||||
)
|
||||
|
||||
const newTable = await config.createTable({
|
||||
name: "table",
|
||||
type: "table",
|
||||
schema: {
|
||||
name: {
|
||||
name: "name",
|
||||
type: FieldType.STRING,
|
||||
constraints: {
|
||||
presence: true,
|
||||
},
|
||||
},
|
||||
age: {
|
||||
name: "age",
|
||||
type: FieldType.NUMBER,
|
||||
constraints: {
|
||||
presence: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const tableName = await setup.createTestTable(client, {
|
||||
name: { type: "string" },
|
||||
age: { type: "number" },
|
||||
})
|
||||
|
||||
const rows = [
|
||||
{ name: "Joe", age: 20 },
|
||||
{ name: "Bob", age: 25 },
|
||||
{ name: "Paul", age: 30 },
|
||||
]
|
||||
|
||||
await setup.insertTestData(client, tableName, rows)
|
||||
|
||||
const query = await setup.saveTestQuery(
|
||||
config,
|
||||
client,
|
||||
tableName,
|
||||
datasource
|
||||
)
|
||||
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test external query and save",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({
|
||||
fields: {},
|
||||
})
|
||||
.executeQuery({
|
||||
query: {
|
||||
queryId: query._id!,
|
||||
},
|
||||
})
|
||||
.loop({
|
||||
option: LoopStepType.ARRAY,
|
||||
binding: "{{ steps.1.response }}",
|
||||
})
|
||||
.createRow({
|
||||
row: {
|
||||
name: "{{ loop.currentItem.name }}",
|
||||
age: "{{ loop.currentItem.age }}",
|
||||
tableId: newTable._id!,
|
||||
},
|
||||
})
|
||||
.queryRows({
|
||||
tableId: newTable._id!,
|
||||
})
|
||||
.run()
|
||||
|
||||
expect(results.steps).toHaveLength(3)
|
||||
|
||||
expect(results.steps[1].outputs.iterations).toBe(3)
|
||||
expect(results.steps[1].outputs.items).toHaveLength(3)
|
||||
|
||||
expect(results.steps[2].outputs.rows).toHaveLength(3)
|
||||
|
||||
rows.forEach(expectedRow => {
|
||||
expect(results.steps[2].outputs.rows).toEqual(
|
||||
expect.arrayContaining([expect.objectContaining(expectedRow)])
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("Name Based Automations", () => {
|
||||
it("should fetch and delete a rpw using automation naming", async () => {
|
||||
const table = await config.createTable()
|
||||
const row = {
|
||||
name: "DFN",
|
||||
description: "original description",
|
||||
tableId: table._id,
|
||||
}
|
||||
await config.createRow(row)
|
||||
await config.createRow(row)
|
||||
const builder = createAutomationBuilder({
|
||||
name: "Test Query and Delete Row",
|
||||
})
|
||||
|
||||
const results = await builder
|
||||
.appAction({ fields: {} })
|
||||
.queryRows(
|
||||
{
|
||||
tableId: table._id!,
|
||||
},
|
||||
"InitialQueryStep"
|
||||
)
|
||||
.deleteRow({
|
||||
tableId: table._id!,
|
||||
id: "{{ steps.InitialQueryStep.rows.0._id }}",
|
||||
})
|
||||
.queryRows({
|
||||
tableId: table._id!,
|
||||
})
|
||||
.run()
|
||||
|
||||
expect(results.steps).toHaveLength(3)
|
||||
expect(results.steps[1].outputs.success).toBeTruthy()
|
||||
expect(results.steps[2].outputs.rows).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -57,21 +57,27 @@ type BranchConfig = {
|
|||
|
||||
class BaseStepBuilder {
|
||||
protected steps: AutomationStep[] = []
|
||||
protected stepNames: { [key: string]: string } = {}
|
||||
|
||||
protected step<TStep extends AutomationActionStepId>(
|
||||
stepId: TStep,
|
||||
stepSchema: Omit<AutomationStep, "id" | "stepId" | "inputs">,
|
||||
inputs: AutomationStepInputs<TStep>
|
||||
inputs: AutomationStepInputs<TStep>,
|
||||
stepName?: string
|
||||
): this {
|
||||
const id = uuidv4()
|
||||
this.steps.push({
|
||||
...stepSchema,
|
||||
inputs: inputs as any,
|
||||
id: uuidv4(),
|
||||
id,
|
||||
stepId,
|
||||
name: stepName || stepSchema.name,
|
||||
})
|
||||
if (stepName) {
|
||||
this.stepNames[id] = stepName
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
protected addBranchStep(branchConfig: BranchConfig): void {
|
||||
const branchStepInputs: BranchStepInputs = {
|
||||
branches: [] as Branch[],
|
||||
|
@ -99,66 +105,74 @@ class BaseStepBuilder {
|
|||
}
|
||||
|
||||
// STEPS
|
||||
createRow(inputs: CreateRowStepInputs): this {
|
||||
createRow(inputs: CreateRowStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.CREATE_ROW,
|
||||
BUILTIN_ACTION_DEFINITIONS.CREATE_ROW,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
|
||||
updateRow(inputs: UpdateRowStepInputs): this {
|
||||
updateRow(inputs: UpdateRowStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.UPDATE_ROW,
|
||||
BUILTIN_ACTION_DEFINITIONS.UPDATE_ROW,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
|
||||
deleteRow(inputs: DeleteRowStepInputs): this {
|
||||
deleteRow(inputs: DeleteRowStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.DELETE_ROW,
|
||||
BUILTIN_ACTION_DEFINITIONS.DELETE_ROW,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
|
||||
sendSmtpEmail(inputs: SmtpEmailStepInputs): this {
|
||||
sendSmtpEmail(inputs: SmtpEmailStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.SEND_EMAIL_SMTP,
|
||||
BUILTIN_ACTION_DEFINITIONS.SEND_EMAIL_SMTP,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
|
||||
executeQuery(inputs: ExecuteQueryStepInputs): this {
|
||||
executeQuery(inputs: ExecuteQueryStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.EXECUTE_QUERY,
|
||||
BUILTIN_ACTION_DEFINITIONS.EXECUTE_QUERY,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
|
||||
queryRows(inputs: QueryRowsStepInputs): this {
|
||||
queryRows(inputs: QueryRowsStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.QUERY_ROWS,
|
||||
BUILTIN_ACTION_DEFINITIONS.QUERY_ROWS,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
loop(inputs: LoopStepInputs): this {
|
||||
loop(inputs: LoopStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.LOOP,
|
||||
BUILTIN_ACTION_DEFINITIONS.LOOP,
|
||||
inputs
|
||||
inputs,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
|
||||
serverLog(input: ServerLogStepInputs): this {
|
||||
serverLog(input: ServerLogStepInputs, stepName?: string): this {
|
||||
return this.step(
|
||||
AutomationActionStepId.SERVER_LOG,
|
||||
BUILTIN_ACTION_DEFINITIONS.SERVER_LOG,
|
||||
input
|
||||
input,
|
||||
stepName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +200,7 @@ class AutomationBuilder extends BaseStepBuilder {
|
|||
definition: {
|
||||
steps: [],
|
||||
trigger: {} as AutomationTrigger,
|
||||
stepNames: {},
|
||||
},
|
||||
type: "automation",
|
||||
appId: options.appId ?? setup.getConfig().getAppId(),
|
||||
|
@ -268,6 +283,7 @@ class AutomationBuilder extends BaseStepBuilder {
|
|||
|
||||
build(): Automation {
|
||||
this.automationConfig.definition.steps = this.steps
|
||||
this.automationConfig.definition.stepNames = this.stepNames
|
||||
return this.automationConfig
|
||||
}
|
||||
|
||||
|
|
|
@ -124,6 +124,7 @@ export interface Automation extends Document {
|
|||
definition: {
|
||||
steps: AutomationStep[]
|
||||
trigger: AutomationTrigger
|
||||
stepNames?: Record<string, string>
|
||||
}
|
||||
screenId?: string
|
||||
uiTree?: any
|
||||
|
|
Loading…
Reference in New Issue