Re-writing automation tests.

This commit is contained in:
mike12345567 2021-03-03 18:41:49 +00:00
parent f55c5dec00
commit 79818122fd
5 changed files with 104 additions and 80 deletions

View File

@ -39,7 +39,6 @@ describe("/applications", () => {
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
await checkBuilderEndpoint({ await checkBuilderEndpoint({
config, config,
request,
method: "POST", method: "POST",
url: `/api/applications`, url: `/api/applications`,
body: { name: "My App" } body: { name: "My App" }
@ -65,7 +64,6 @@ describe("/applications", () => {
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
await checkBuilderEndpoint({ await checkBuilderEndpoint({
config, config,
request,
method: "GET", method: "GET",
url: `/api/applications`, url: `/api/applications`,
}) })

View File

@ -1,34 +1,18 @@
const { const {
createApplication,
createTable,
getAllFromTable,
defaultHeaders, defaultHeaders,
supertest, supertest,
insertDocument, } = require("./utilities")
destroyDocument, const TestConfig = require("./utilities/TestConfiguration")
builderEndpointShouldBlockNormalUsers const {
} = require("./couchTestUtils") checkBuilderEndpoint,
let { generateAutomationID } = require("../../../db/utils") getAllTableRows,
clearAllAutomations,
} = require("./utilities/TestFunctions")
const { basicAutomation } = require("./utilities/structures")
const { delay } = require("./testUtils") const { delay } = require("./testUtils")
const MAX_RETRIES = 4 const MAX_RETRIES = 4
const AUTOMATION_ID = generateAutomationID()
const TEST_AUTOMATION = {
_id: AUTOMATION_ID,
name: "My Automation",
screenId: "kasdkfldsafkl",
live: true,
uiTree: {
},
definition: {
trigger: {},
steps: [
],
},
type: "automation",
}
let ACTION_DEFINITIONS = {} let ACTION_DEFINITIONS = {}
let TRIGGER_DEFINITIONS = {} let TRIGGER_DEFINITIONS = {}
@ -39,34 +23,26 @@ describe("/automations", () => {
let server let server
let app let app
let appId let appId
let config
let automation let automation
let automationId
beforeAll(async () => { beforeAll(async () => {
({ request, server } = await supertest()) ({ request, server } = await supertest())
}) })
beforeEach(async () => { beforeEach(async () => {
app = await createApplication(request) config = new TestConfig(request)
app = await config.init()
appId = app.instance._id appId = app.instance._id
if (automation) await destroyDocument(automation.id)
}) })
afterAll(() => { afterAll(() => {
server.close() server.close()
}) })
const createAutomation = async () => { const triggerWorkflow = async automation => {
automation = await insertDocument(appId, {
type: "automation",
...TEST_AUTOMATION
})
automation = { ...automation, ...TEST_AUTOMATION }
}
const triggerWorkflow = async (automationId) => {
return await request return await request
.post(`/api/automations/${automationId}/trigger`) .post(`/api/automations/${automation._id}/trigger`)
.send({ name: "Test", description: "TEST" }) .send({ name: "Test", description: "TEST" })
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
@ -121,6 +97,7 @@ describe("/automations", () => {
}) })
describe("create", () => { describe("create", () => {
const autoConfig = basicAutomation()
it("should setup the automation fully", () => { it("should setup the automation fully", () => {
let trigger = TRIGGER_DEFINITIONS["ROW_SAVED"] let trigger = TRIGGER_DEFINITIONS["ROW_SAVED"]
trigger.id = "wadiawdo34" trigger.id = "wadiawdo34"
@ -131,52 +108,51 @@ describe("/automations", () => {
} }
createAction.id = "awde444wk" createAction.id = "awde444wk"
TEST_AUTOMATION.definition.steps.push(createAction) autoConfig.definition.steps.push(createAction)
TEST_AUTOMATION.definition.trigger = trigger autoConfig.definition.trigger = trigger
}) })
it("returns a success message when the automation is successfully created", async () => { it("returns a success message when the automation is successfully created", async () => {
const res = await request const res = await request
.post(`/api/automations`) .post(`/api/automations`)
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.send(TEST_AUTOMATION) .send(autoConfig)
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
expect(res.body.message).toEqual("Automation created successfully") expect(res.body.message).toEqual("Automation created successfully")
expect(res.body.automation.name).toEqual("My Automation") expect(res.body.automation.name).toEqual("My Automation")
expect(res.body.automation._id).not.toEqual(null) expect(res.body.automation._id).not.toEqual(null)
automationId = res.body.automation._id automation = res.body.automation
}) })
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
await builderEndpointShouldBlockNormalUsers({ await checkBuilderEndpoint({
request, config,
method: "POST", method: "POST",
url: `/api/automations`, url: `/api/automations`,
appId: appId, body: autoConfig
body: TEST_AUTOMATION
}) })
}) })
}) })
describe("trigger", () => { describe("trigger", () => {
it("trigger the automation successfully", async () => { it("trigger the automation successfully", async () => {
let table = await createTable(request, appId) let table = await config.createTable()
TEST_AUTOMATION.definition.trigger.inputs.tableId = table._id automation.definition.trigger.inputs.tableId = table._id
TEST_AUTOMATION.definition.steps[0].inputs.row.tableId = table._id automation.definition.steps[0].inputs.row.tableId = table._id
await createAutomation() automation = await config.createAutomation(automation)
await delay(500) await delay(500)
const res = await triggerWorkflow(automation._id) const res = await triggerWorkflow(automation)
// this looks a bit mad but we don't actually have a way to wait for a response from the automation to // this looks a bit mad but we don't actually have a way to wait for a response from the automation to
// know that it has finished all of its actions - this is currently the best way // know that it has finished all of its actions - this is currently the best way
// also when this runs in CI it is very temper-mental so for now trying to make run stable by repeating until it works // also when this runs in CI it is very temper-mental so for now trying to make run stable by repeating until it works
// TODO: update when workflow logs are a thing // TODO: update when workflow logs are a thing
for (let tries = 0; tries < MAX_RETRIES; tries++) { for (let tries = 0; tries < MAX_RETRIES; tries++) {
expect(res.body.message).toEqual(`Automation ${automation._id} has been triggered.`) expect(res.body.message).toEqual(`Automation ${automation._id} has been triggered.`)
expect(res.body.automation.name).toEqual(TEST_AUTOMATION.name) expect(res.body.automation.name).toEqual(automation.name)
await delay(500) await delay(500)
let elements = await getAllFromTable(request, appId, table._id) let elements = await getAllTableRows(config)
// don't test it unless there are values to test // don't test it unless there are values to test
if (elements.length > 1) { if (elements.length > 1) {
expect(elements.length).toEqual(5) expect(elements.length).toEqual(5)
@ -191,9 +167,7 @@ describe("/automations", () => {
describe("update", () => { describe("update", () => {
it("updates a automations data", async () => { it("updates a automations data", async () => {
await createAutomation() automation = await config.createAutomation(automation)
automation._id = automation.id
automation._rev = automation.rev
automation.name = "Updated Name" automation.name = "Updated Name"
automation.type = "automation" automation.type = "automation"
@ -204,52 +178,52 @@ describe("/automations", () => {
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
expect(res.body.message).toEqual(`Automation ${AUTOMATION_ID} updated successfully.`) expect(res.body.message).toEqual(`Automation ${automation._id} updated successfully.`)
expect(res.body.automation.name).toEqual("Updated Name") expect(res.body.automation.name).toEqual("Updated Name")
}) })
}) })
describe("fetch", () => { describe("fetch", () => {
it("return all the automations for an instance", async () => { it("return all the automations for an instance", async () => {
await createAutomation() await clearAllAutomations(config)
const autoConfig = basicAutomation()
automation = await config.createAutomation(autoConfig)
const res = await request const res = await request
.get(`/api/automations`) .get(`/api/automations`)
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
expect(res.body[0]).toEqual(expect.objectContaining(TEST_AUTOMATION)) expect(res.body[0]).toEqual(expect.objectContaining(autoConfig))
}) })
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
await builderEndpointShouldBlockNormalUsers({ await checkBuilderEndpoint({
request, config,
method: "GET", method: "GET",
url: `/api/automations`, url: `/api/automations`,
appId: appId,
}) })
}) })
}) })
describe("destroy", () => { describe("destroy", () => {
it("deletes a automation by its ID", async () => { it("deletes a automation by its ID", async () => {
await createAutomation() const automation = await config.createAutomation()
const res = await request const res = await request
.delete(`/api/automations/${automation.id}/${automation.rev}`) .delete(`/api/automations/${automation.id}/${automation.rev}`)
.set(defaultHeaders(appId)) .set(defaultHeaders(appId))
.expect('Content-Type', /json/) .expect('Content-Type', /json/)
.expect(200) .expect(200)
expect(res.body.id).toEqual(TEST_AUTOMATION._id) expect(res.body.id).toEqual(automation._id)
}) })
it("should apply authorization to endpoint", async () => { it("should apply authorization to endpoint", async () => {
await createAutomation() const automation = await config.createAutomation()
await builderEndpointShouldBlockNormalUsers({ await checkBuilderEndpoint({
request, config,
method: "DELETE", method: "DELETE",
url: `/api/automations/${automation.id}/${automation._rev}`, url: `/api/automations/${automation.id}/${automation._rev}`,
appId: appId,
}) })
}) })
}) })

View File

@ -1,6 +1,11 @@
const { BUILTIN_ROLE_IDS } = require("../../../../utilities/security/roles") const { BUILTIN_ROLE_IDS } = require("../../../../utilities/security/roles")
const env = require("../../../../environment") const env = require("../../../../environment")
const { basicTable, basicRow, basicRole } = require("./structures") const {
basicTable,
basicRow,
basicRole,
basicAutomation,
} = require("./structures")
const tableController = require("../../../controllers/table") const tableController = require("../../../controllers/table")
const rowController = require("../../../controllers/row") const rowController = require("../../../controllers/row")
const roleController = require("../../../controllers/role") const roleController = require("../../../controllers/role")
@ -8,6 +13,7 @@ const permsController = require("../../../controllers/permission")
const viewController = require("../../../controllers/view") const viewController = require("../../../controllers/view")
const appController = require("../../../controllers/application") const appController = require("../../../controllers/application")
const userController = require("../../../controllers/user") const userController = require("../../../controllers/user")
const autoController = require("../../../controllers/automation")
const EMAIL = "babs@babs.com" const EMAIL = "babs@babs.com"
const PASSWORD = "babs_password" const PASSWORD = "babs_password"
@ -19,6 +25,7 @@ class TestConfiguration {
this.appId = null this.appId = null
this.table = null this.table = null
this.linkedTable = null this.linkedTable = null
this.automation = null
} }
async _req(config, params, controlFunc) { async _req(config, params, controlFunc) {
@ -119,6 +126,33 @@ class TestConfiguration {
return this._req(view, null, viewController.save) return this._req(view, null, viewController.save)
} }
async createAutomation(config) {
config = config || basicAutomation()
if (config._rev) {
delete config._rev
}
this.automation = (
await this._req(config, null, autoController.create)
).automation
return this.automation
}
async getAllAutomations() {
return this._req(null, null, autoController.fetch)
}
async deleteAutomation(automation) {
automation = automation || this.automation
if (!automation) {
return
}
return this._req(
null,
{ id: automation._id, rev: automation._rev },
autoController.destroy
)
}
async createUser( async createUser(
email = EMAIL, email = EMAIL,
password = PASSWORD, password = PASSWORD,

View File

@ -1,5 +1,6 @@
const rowController = require("../../../controllers/row") const rowController = require("../../../controllers/row")
const appController = require("../../../controllers/application") const appController = require("../../../controllers/application")
const autoController = require("../../../controllers/automation")
const CouchDB = require("../../../../db") const CouchDB = require("../../../../db")
function Request(appId, params) { function Request(appId, params) {
@ -7,8 +8,8 @@ function Request(appId, params) {
this.params = params this.params = params
} }
exports.getAllTableRows = async (appId, tableId) => { exports.getAllTableRows = async config => {
const req = new Request(appId, { tableId }) const req = new Request(config.appId, { tableId: config.table._id })
await rowController.fetchTableRows(req) await rowController.fetchTableRows(req)
return req.body return req.body
} }
@ -26,6 +27,13 @@ exports.clearAllApps = async () => {
} }
} }
exports.clearAllAutomations = async config => {
const automations = await config.getAllAutomations()
for (let auto of automations) {
await config.deleteAutomation(auto)
}
}
exports.createRequest = (request, method, url, body) => { exports.createRequest = (request, method, url, body) => {
let req let req
@ -38,16 +46,10 @@ exports.createRequest = (request, method, url, body) => {
return req return req
} }
exports.checkBuilderEndpoint = async ({ exports.checkBuilderEndpoint = async ({ config, method, url, body }) => {
config,
request,
method,
url,
body,
}) => {
const headers = await config.login() const headers = await config.login()
await exports await exports
.createRequest(request, method, url, body) .createRequest(config.request, method, url, body)
.set(headers) .set(headers)
.expect(403) .expect(403)
} }

View File

@ -25,6 +25,22 @@ exports.basicTable = () => {
} }
} }
exports.basicAutomation = () => {
return {
name: "My Automation",
screenId: "kasdkfldsafkl",
live: true,
uiTree: {},
definition: {
trigger: {
inputs: {},
},
steps: [],
},
type: "automation",
}
}
exports.basicRow = tableId => { exports.basicRow = tableId => {
return { return {
name: "Test Contact", name: "Test Contact",