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[1].outputs.message).toContain("- 3")
|
||||||
expect(results.steps[3].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 () => {
|
it("should trigger an automation which querys the database", async () => {
|
||||||
const table = await config.createTable()
|
const table = await config.createTable()
|
||||||
const row = {
|
const row = {
|
||||||
name: "Test Row",
|
name: "Test Row",
|
||||||
description: "original description",
|
description: "original description",
|
||||||
tableId: table._id,
|
tableId: table._id,
|
||||||
}
|
}
|
||||||
await config.createRow(row)
|
await config.createRow(row)
|
||||||
await config.createRow(row)
|
await config.createRow(row)
|
||||||
const builder = createAutomationBuilder({
|
const builder = createAutomationBuilder({
|
||||||
name: "Test Row Save and Create",
|
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
|
it("should trigger an automation which querys the database then deletes a row", async () => {
|
||||||
.appAction({ fields: {} })
|
const table = await config.createTable()
|
||||||
.queryRows({
|
const row = {
|
||||||
tableId: table._id!,
|
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)
|
const results = await builder
|
||||||
expect(results.steps[0].outputs.rows).toHaveLength(2)
|
.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 () => {
|
expect(results.steps).toHaveLength(3)
|
||||||
const table = await config.createTable()
|
expect(results.steps[1].outputs.success).toBeTruthy()
|
||||||
const row = {
|
expect(results.steps[2].outputs.rows).toHaveLength(1)
|
||||||
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",
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const results = await builder
|
it("should query an external database for some data then insert than into an internal table", async () => {
|
||||||
.appAction({ fields: {} })
|
const { datasource, client } = await setup.setupTestDatasource(
|
||||||
.queryRows({
|
config,
|
||||||
tableId: table._id!,
|
DatabaseName.MYSQL
|
||||||
})
|
|
||||||
.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)])
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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 {
|
class BaseStepBuilder {
|
||||||
protected steps: AutomationStep[] = []
|
protected steps: AutomationStep[] = []
|
||||||
|
protected stepNames: { [key: string]: string } = {}
|
||||||
|
|
||||||
protected step<TStep extends AutomationActionStepId>(
|
protected step<TStep extends AutomationActionStepId>(
|
||||||
stepId: TStep,
|
stepId: TStep,
|
||||||
stepSchema: Omit<AutomationStep, "id" | "stepId" | "inputs">,
|
stepSchema: Omit<AutomationStep, "id" | "stepId" | "inputs">,
|
||||||
inputs: AutomationStepInputs<TStep>
|
inputs: AutomationStepInputs<TStep>,
|
||||||
|
stepName?: string
|
||||||
): this {
|
): this {
|
||||||
|
const id = uuidv4()
|
||||||
this.steps.push({
|
this.steps.push({
|
||||||
...stepSchema,
|
...stepSchema,
|
||||||
inputs: inputs as any,
|
inputs: inputs as any,
|
||||||
id: uuidv4(),
|
id,
|
||||||
stepId,
|
stepId,
|
||||||
|
name: stepName || stepSchema.name,
|
||||||
})
|
})
|
||||||
|
if (stepName) {
|
||||||
|
this.stepNames[id] = stepName
|
||||||
|
}
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
protected addBranchStep(branchConfig: BranchConfig): void {
|
protected addBranchStep(branchConfig: BranchConfig): void {
|
||||||
const branchStepInputs: BranchStepInputs = {
|
const branchStepInputs: BranchStepInputs = {
|
||||||
branches: [] as Branch[],
|
branches: [] as Branch[],
|
||||||
|
@ -99,66 +105,74 @@ class BaseStepBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
// STEPS
|
// STEPS
|
||||||
createRow(inputs: CreateRowStepInputs): this {
|
createRow(inputs: CreateRowStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.CREATE_ROW,
|
AutomationActionStepId.CREATE_ROW,
|
||||||
BUILTIN_ACTION_DEFINITIONS.CREATE_ROW,
|
BUILTIN_ACTION_DEFINITIONS.CREATE_ROW,
|
||||||
inputs
|
inputs,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRow(inputs: UpdateRowStepInputs): this {
|
updateRow(inputs: UpdateRowStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.UPDATE_ROW,
|
AutomationActionStepId.UPDATE_ROW,
|
||||||
BUILTIN_ACTION_DEFINITIONS.UPDATE_ROW,
|
BUILTIN_ACTION_DEFINITIONS.UPDATE_ROW,
|
||||||
inputs
|
inputs,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteRow(inputs: DeleteRowStepInputs): this {
|
deleteRow(inputs: DeleteRowStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.DELETE_ROW,
|
AutomationActionStepId.DELETE_ROW,
|
||||||
BUILTIN_ACTION_DEFINITIONS.DELETE_ROW,
|
BUILTIN_ACTION_DEFINITIONS.DELETE_ROW,
|
||||||
inputs
|
inputs,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sendSmtpEmail(inputs: SmtpEmailStepInputs): this {
|
sendSmtpEmail(inputs: SmtpEmailStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.SEND_EMAIL_SMTP,
|
AutomationActionStepId.SEND_EMAIL_SMTP,
|
||||||
BUILTIN_ACTION_DEFINITIONS.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(
|
return this.step(
|
||||||
AutomationActionStepId.EXECUTE_QUERY,
|
AutomationActionStepId.EXECUTE_QUERY,
|
||||||
BUILTIN_ACTION_DEFINITIONS.EXECUTE_QUERY,
|
BUILTIN_ACTION_DEFINITIONS.EXECUTE_QUERY,
|
||||||
inputs
|
inputs,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
queryRows(inputs: QueryRowsStepInputs): this {
|
queryRows(inputs: QueryRowsStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.QUERY_ROWS,
|
AutomationActionStepId.QUERY_ROWS,
|
||||||
BUILTIN_ACTION_DEFINITIONS.QUERY_ROWS,
|
BUILTIN_ACTION_DEFINITIONS.QUERY_ROWS,
|
||||||
inputs
|
inputs,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
loop(inputs: LoopStepInputs): this {
|
loop(inputs: LoopStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.LOOP,
|
AutomationActionStepId.LOOP,
|
||||||
BUILTIN_ACTION_DEFINITIONS.LOOP,
|
BUILTIN_ACTION_DEFINITIONS.LOOP,
|
||||||
inputs
|
inputs,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
serverLog(input: ServerLogStepInputs): this {
|
serverLog(input: ServerLogStepInputs, stepName?: string): this {
|
||||||
return this.step(
|
return this.step(
|
||||||
AutomationActionStepId.SERVER_LOG,
|
AutomationActionStepId.SERVER_LOG,
|
||||||
BUILTIN_ACTION_DEFINITIONS.SERVER_LOG,
|
BUILTIN_ACTION_DEFINITIONS.SERVER_LOG,
|
||||||
input
|
input,
|
||||||
|
stepName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,6 +200,7 @@ class AutomationBuilder extends BaseStepBuilder {
|
||||||
definition: {
|
definition: {
|
||||||
steps: [],
|
steps: [],
|
||||||
trigger: {} as AutomationTrigger,
|
trigger: {} as AutomationTrigger,
|
||||||
|
stepNames: {},
|
||||||
},
|
},
|
||||||
type: "automation",
|
type: "automation",
|
||||||
appId: options.appId ?? setup.getConfig().getAppId(),
|
appId: options.appId ?? setup.getConfig().getAppId(),
|
||||||
|
@ -268,6 +283,7 @@ class AutomationBuilder extends BaseStepBuilder {
|
||||||
|
|
||||||
build(): Automation {
|
build(): Automation {
|
||||||
this.automationConfig.definition.steps = this.steps
|
this.automationConfig.definition.steps = this.steps
|
||||||
|
this.automationConfig.definition.stepNames = this.stepNames
|
||||||
return this.automationConfig
|
return this.automationConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,7 @@ export interface Automation extends Document {
|
||||||
definition: {
|
definition: {
|
||||||
steps: AutomationStep[]
|
steps: AutomationStep[]
|
||||||
trigger: AutomationTrigger
|
trigger: AutomationTrigger
|
||||||
|
stepNames?: Record<string, string>
|
||||||
}
|
}
|
||||||
screenId?: string
|
screenId?: string
|
||||||
uiTree?: any
|
uiTree?: any
|
||||||
|
|
Loading…
Reference in New Issue