diff --git a/packages/server/src/api/routes/tests/automation.spec.js b/packages/server/src/api/routes/tests/automation.spec.js index 5c4936e4ea..cce51fc94b 100644 --- a/packages/server/src/api/routes/tests/automation.spec.js +++ b/packages/server/src/api/routes/tests/automation.spec.js @@ -5,18 +5,15 @@ const { testAutomation, } = require("./utilities/TestFunctions") const setup = require("./utilities") -const { basicAutomation } = setup.structures +const { basicAutomation, newAutomation, automationTrigger, automationStep } = setup.structures const { mocks } = require("@budibase/backend-core/testUtils") mocks.date.mock() const MAX_RETRIES = 4 - -let ACTION_DEFINITIONS = {} -let TRIGGER_DEFINITIONS = {} +const { TRIGGER_DEFINITIONS, ACTION_DEFINITIONS } = require("../../../automations") describe("/automations", () => { let request = setup.getRequest() let config = setup.getConfig() - let automation afterAll(setup.afterAll) @@ -33,7 +30,6 @@ describe("/automations", () => { .expect(200) expect(Object.keys(res.body).length).not.toEqual(0) - ACTION_DEFINITIONS = res.body }) it("returns a list of definitions for triggerInfo", async () => { @@ -44,7 +40,6 @@ describe("/automations", () => { .expect(200) expect(Object.keys(res.body).length).not.toEqual(0) - TRIGGER_DEFINITIONS = res.body }) it("returns all of the definitions in one", async () => { @@ -54,76 +49,37 @@ describe("/automations", () => { .expect('Content-Type', /json/) .expect(200) - expect(Object.keys(res.body.action).length).toBeGreaterThanOrEqual(Object.keys(ACTION_DEFINITIONS).length) + let definitionsLength = Object.keys(ACTION_DEFINITIONS).length + definitionsLength-- // OUTGOING_WEBHOOK is deprecated + + expect(Object.keys(res.body.action).length).toBeGreaterThanOrEqual(definitionsLength) expect(Object.keys(res.body.trigger).length).toEqual(Object.keys(TRIGGER_DEFINITIONS).length) }) }) describe("create", () => { - const autoConfig = basicAutomation() - it("should setup the automation fully", () => { - let trigger = TRIGGER_DEFINITIONS["ROW_SAVED"] - trigger.id = "wadiawdo34" - let createAction = ACTION_DEFINITIONS["CREATE_ROW"] - createAction.inputs.row = { - name: "{{trigger.row.name}}", - description: "{{trigger.row.description}}" - } - createAction.id = "awde444wk" - - autoConfig.definition.steps.push(createAction) - autoConfig.definition.trigger = trigger - }) - it("returns a success message when the automation is successfully created", async () => { + const automation = newAutomation() + const res = await request .post(`/api/automations`) .set(config.defaultHeaders()) - .send(autoConfig) + .send(automation) .expect('Content-Type', /json/) .expect(200) expect(res.body.message).toEqual("Automation created successfully") expect(res.body.automation.name).toEqual("My Automation") expect(res.body.automation._id).not.toEqual(null) - automation = res.body.automation - }) - - it("should be able to create an automation with a webhook trigger", async () => { - const autoConfig = basicAutomation() - autoConfig.definition.trigger = TRIGGER_DEFINITIONS["WEBHOOK"] - autoConfig.definition.trigger.id = "webhook_trigger_id" - const res = await request - .post(`/api/automations`) - .set(config.defaultHeaders()) - .send(autoConfig) - .expect('Content-Type', /json/) - .expect(200) - const originalAuto = res.body.automation - expect(originalAuto._id).toBeDefined() - expect(originalAuto._rev).toBeDefined() - // try removing the webhook trigger - const newConfig = originalAuto - newConfig.definition.trigger = TRIGGER_DEFINITIONS["ROW_SAVED"] - newConfig.definition.trigger.id = "row_saved_id" - const newRes = await request - .post(`/api/automations`) - .set(config.defaultHeaders()) - .send(newConfig) - .expect('Content-Type', /json/) - .expect(200) - const newAuto = newRes.body.automation - expect(newAuto._id).toEqual(originalAuto._id) - expect(newAuto._rev).toBeDefined() - expect(newAuto._rev).not.toEqual(originalAuto._rev) }) it("should apply authorization to endpoint", async () => { + const automation = newAutomation() await checkBuilderEndpoint({ config, method: "POST", url: `/api/automations`, - body: autoConfig + body: automation }) }) }) @@ -144,8 +100,15 @@ describe("/automations", () => { describe("trigger", () => { it("trigger the automation successfully", async () => { let table = await config.createTable() + let automation = newAutomation() automation.definition.trigger.inputs.tableId = table._id - automation.definition.steps[0].inputs.row.tableId = table._id + automation.definition.steps[0].inputs = { + row: { + name: "{{trigger.row.name}}", + description: "{{trigger.row.description}}", + tableId: table._id + } + } automation.appId = config.appId automation = await config.createAutomation(automation) await setup.delay(500) @@ -172,9 +135,9 @@ describe("/automations", () => { describe("update", () => { it("updates a automations data", async () => { - automation = await config.createAutomation(automation) + let automation = newAutomation() + await config.createAutomation(automation) automation.name = "Updated Name" - automation.type = "automation" const res = await request .put(`/api/automations`) @@ -186,6 +149,39 @@ describe("/automations", () => { expect(res.body.message).toEqual(`Automation ${automation._id} updated successfully.`) expect(res.body.automation.name).toEqual("Updated Name") }) + + it("should be able to update an automation trigger", async () => { + // create webhook automation + const webhookTrigger = automationTrigger(TRIGGER_DEFINITIONS.WEBHOOK) + let automation = newAutomation({ trigger: webhookTrigger }) + + let res = await request + .post(`/api/automations`) + .set(config.defaultHeaders()) + .send(automation) + .expect('Content-Type', /json/) + .expect(200) + + automation = res.body.automation + expect(automation._id).toBeDefined() + expect(automation._rev).toBeDefined() + + // change the trigger + automation.trigger = automationTrigger(TRIGGER_DEFINITIONS.ROW_SAVED) + + // check the post request honours updates with same id + res = await request + .post(`/api/automations`) + .set(config.defaultHeaders()) + .send(automation) + .expect('Content-Type', /json/) + .expect(200) + + const automationRes = res.body.automation + expect(automationRes._id).toEqual(automation._id) + expect(automationRes._rev).toBeDefined() + expect(automationRes._rev).not.toEqual(automation._rev) + }) }) describe("fetch", () => { diff --git a/packages/server/src/automations/index.js b/packages/server/src/automations/index.js index 87f35ce763..6fd3ca87a9 100644 --- a/packages/server/src/automations/index.js +++ b/packages/server/src/automations/index.js @@ -1,5 +1,7 @@ const { processEvent } = require("./utils") const { queue } = require("./bullboard") +const { TRIGGER_DEFINITIONS } = require("./triggers") +const { ACTION_DEFINITIONS } = require("./actions") /** * This module is built purely to kick off the worker farm and manage the inputs/outputs @@ -14,4 +16,7 @@ exports.init = function () { exports.getQueues = () => { return [queue] } + exports.queue = queue +exports.TRIGGER_DEFINITIONS = TRIGGER_DEFINITIONS +exports.ACTION_DEFINITIONS = ACTION_DEFINITIONS diff --git a/packages/server/src/tests/utilities/structures.js b/packages/server/src/tests/utilities/structures.js index 45a8f2dece..4cb6c3b141 100644 --- a/packages/server/src/tests/utilities/structures.js +++ b/packages/server/src/tests/utilities/structures.js @@ -3,6 +3,8 @@ const { BUILTIN_PERMISSION_IDS } = require("@budibase/backend-core/permissions") const { createHomeScreen } = require("../../constants/screens") const { EMPTY_LAYOUT } = require("../../constants/layouts") const { cloneDeep } = require("lodash/fp") +const { v4: uuidv4 } = require("uuid") +const { TRIGGER_DEFINITIONS, ACTION_DEFINITIONS } = require("../../automations") exports.TENANT_ID = "default" @@ -28,6 +30,40 @@ exports.basicTable = () => { } } +exports.automationStep = (actionDefinition = ACTION_DEFINITIONS.CREATE_ROW) => { + return { + id: uuidv4(), + ...actionDefinition, + } +} + +exports.automationTrigger = ( + triggerDefinition = TRIGGER_DEFINITIONS.ROW_SAVED +) => { + return { + id: uuidv4(), + ...triggerDefinition, + } +} + +exports.newAutomation = ({ steps, trigger } = {}) => { + const automation = exports.basicAutomation() + + if (trigger) { + automation.definition.trigger = trigger + } else { + automation.definition.trigger = exports.automationTrigger() + } + + if (steps) { + automation.definition.steps = steps + } else { + automation.definition.steps = [exports.automationStep()] + } + + return automation +} + exports.basicAutomation = () => { return { name: "My Automation", diff --git a/packages/worker/src/api/routes/tests/configs.spec.js b/packages/worker/src/api/routes/tests/configs.spec.js index a89e394fdb..9f0570023e 100644 --- a/packages/worker/src/api/routes/tests/configs.spec.js +++ b/packages/worker/src/api/routes/tests/configs.spec.js @@ -155,7 +155,7 @@ describe("configs", () => { await config.deleteConfig(Configs.OIDC) }) - it ("should update google config to activated", async () => { + it ("should update OIDC config to activated", async () => { const oidcConf = await saveOIDCConfig({ activated: false }) jest.clearAllMocks() await saveOIDCConfig({ ...oidcConf.config.configs[0], activated: true}, oidcConf._id, oidcConf._rev)