diff --git a/packages/builder/src/analytics.js b/packages/builder/src/analytics.js index df91c16e00..e6a647a08b 100644 --- a/packages/builder/src/analytics.js +++ b/packages/builder/src/analytics.js @@ -16,7 +16,7 @@ async function activate() { // this was an issue as NODE_ENV = 'cypress' on the server, // but 'production' on the client const response = await api.get("/api/analytics") - analyticsEnabled = (await response.json()) === true + analyticsEnabled = (await response.json()).enabled === true } if (!analyticsEnabled) return if (sentryConfigured) Sentry.init({ dsn: process.env.SENTRY_DSN }) diff --git a/packages/server/src/api/controllers/analytics.js b/packages/server/src/api/controllers/analytics.js index 566b4970e9..76e5eb11f1 100644 --- a/packages/server/src/api/controllers/analytics.js +++ b/packages/server/src/api/controllers/analytics.js @@ -1,5 +1,7 @@ const env = require("../../environment") exports.isEnabled = async function(ctx) { - ctx.body = JSON.stringify(env.ENABLE_ANALYTICS === "true") + ctx.body = { + enabled: env.ENABLE_ANALYTICS === "true", + } } diff --git a/packages/server/src/api/controllers/automation.js b/packages/server/src/api/controllers/automation.js index 5fa618654b..df17371f92 100644 --- a/packages/server/src/api/controllers/automation.js +++ b/packages/server/src/api/controllers/automation.js @@ -98,6 +98,11 @@ exports.create = async function(ctx) { let automation = ctx.request.body automation.appId = ctx.user.appId + // call through to update if already exists + if (automation._id && automation._rev) { + return exports.update(ctx) + } + automation._id = generateAutomationID() automation.type = "automation" diff --git a/packages/server/src/api/controllers/screen.js b/packages/server/src/api/controllers/screen.js index f56dae153e..8f9baa8172 100644 --- a/packages/server/src/api/controllers/screen.js +++ b/packages/server/src/api/controllers/screen.js @@ -41,6 +41,8 @@ exports.save = async ctx => { exports.destroy = async ctx => { const db = new CouchDB(ctx.user.appId) await db.remove(ctx.params.screenId, ctx.params.screenRev) - ctx.message = "Screen deleted successfully" + ctx.body = { + message: "Screen deleted successfully", + } ctx.status = 200 } diff --git a/packages/server/src/api/routes/tests/automation.spec.js b/packages/server/src/api/routes/tests/automation.spec.js index 0648bfefa5..588de641b7 100644 --- a/packages/server/src/api/routes/tests/automation.spec.js +++ b/packages/server/src/api/routes/tests/automation.spec.js @@ -109,6 +109,35 @@ describe("/automations", () => { 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 () => { await checkBuilderEndpoint({ config, @@ -119,6 +148,19 @@ describe("/automations", () => { }) }) + describe("find", () => { + it("should be able to find the automation", async () => { + const automation = await config.createAutomation() + const res = await request + .get(`/api/automations/${automation._id}`) + .set(config.defaultHeaders()) + .expect('Content-Type', /json/) + .expect(200) + expect(res.body._id).toEqual(automation._id) + expect(res.body._rev).toEqual(automation._rev) + }) + }) + describe("trigger", () => { it("trigger the automation successfully", async () => { let table = await config.createTable() diff --git a/packages/server/src/api/routes/tests/misc.spec.js b/packages/server/src/api/routes/tests/misc.spec.js new file mode 100644 index 0000000000..3d3b6047e2 --- /dev/null +++ b/packages/server/src/api/routes/tests/misc.spec.js @@ -0,0 +1,38 @@ +const setup = require("./utilities") + +describe("/analytics", () => { + let request = setup.getRequest() + let config = setup.getConfig() + + afterAll(setup.afterAll) + + beforeEach(async () => { + await config.init() + }) + + describe("isEnabled", () => { + it("check if analytics enabled", async () => { + const res = await request + .get(`/api/analytics`) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + expect(typeof res.body.enabled).toEqual("boolean") + }) + }) +}) + +describe("/health", () => { + it("should confirm healthy", async () => { + let config = setup.getConfig() + await config.getRequest().get("/health").expect(200) + }) +}) + +describe("/version", () => { + it("should confirm version", async () => { + const config = setup.getConfig() + const res = await config.getRequest().get("/version").expect(200) + expect(res.text.split(".").length).toEqual(3) + }) +}) \ No newline at end of file diff --git a/packages/server/src/api/routes/tests/screen.spec.js b/packages/server/src/api/routes/tests/screen.spec.js new file mode 100644 index 0000000000..0c2799eca2 --- /dev/null +++ b/packages/server/src/api/routes/tests/screen.spec.js @@ -0,0 +1,77 @@ +const { checkBuilderEndpoint } = require("./utilities/TestFunctions") +const setup = require("./utilities") +const { basicScreen } = require("./utilities/structures") + +describe("/screens", () => { + let request = setup.getRequest() + let config = setup.getConfig() + let screen + + afterAll(setup.afterAll) + + beforeEach(async () => { + await config.init() + screen = await config.createScreen() + }) + + describe("fetch", () => { + it("should be able to create a layout", async () => { + const res = await request + .get(`/api/screens`) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + expect(res.body.length).toEqual(1) + expect(res.body[0]._id).toEqual(screen._id) + }) + + it("should apply authorization to endpoint", async () => { + await checkBuilderEndpoint({ + config, + method: "GET", + url: `/api/screens`, + }) + }) + }) + + describe("save", () => { + it("should be able to save a screen", async () => { + const screenCfg = basicScreen() + const res = await request + .post(`/api/screens`) + .send(screenCfg) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + expect(res.body._rev).toBeDefined() + expect(res.body.name).toEqual(screenCfg.name) + }) + + it("should apply authorization to endpoint", async () => { + await checkBuilderEndpoint({ + config, + method: "POST", + url: `/api/screens`, + }) + }) + }) + + describe("destroy", () => { + it("should be able to delete the screen", async () => { + const res = await request + .delete(`/api/screens/${screen._id}/${screen._rev}`) + .set(config.defaultHeaders()) + .expect("Content-Type", /json/) + .expect(200) + expect(res.body.message).toBeDefined() + }) + + it("should apply authorization to endpoint", async () => { + await checkBuilderEndpoint({ + config, + method: "DELETE", + url: `/api/screens/${screen._id}/${screen._rev}`, + }) + }) + }) +}) \ No newline at end of file diff --git a/packages/server/src/utilities/security/roles.js b/packages/server/src/utilities/security/roles.js index 79fd720078..b0cd843591 100644 --- a/packages/server/src/utilities/security/roles.js +++ b/packages/server/src/utilities/security/roles.js @@ -205,7 +205,8 @@ class AccessController { tryingRoleId == null || tryingRoleId === "" || tryingRoleId === userRoleId || - tryingRoleId === BUILTIN_IDS.BUILDER + tryingRoleId === BUILTIN_IDS.BUILDER || + userRoleId === BUILTIN_IDS.BUILDER ) { return true }