Merge pull request #1288 from Budibase/tests/automation-tests
Tests/automation tests
This commit is contained in:
commit
d7890eb7b5
|
@ -53,7 +53,11 @@
|
|||
$: uneditable =
|
||||
$backendUiStore.selectedTable?._id === TableNames.USERS &&
|
||||
UNEDITABLE_USER_FIELDS.includes(field.name)
|
||||
$: invalid = field.type === LINK_TYPE && !field.tableId
|
||||
$: invalid =
|
||||
(field.type === LINK_TYPE && !field.tableId) ||
|
||||
Object.keys($backendUiStore.draftTable.schema).some(
|
||||
key => key === field.name
|
||||
)
|
||||
|
||||
// used to select what different options can be displayed for column type
|
||||
$: canBeSearched =
|
||||
|
|
|
@ -1,38 +1,42 @@
|
|||
<script>
|
||||
import { createEventDispatcher } from 'svelte'
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import Colorpicker from "@budibase/colorpicker"
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
export let value
|
||||
|
||||
const WAIT = 150;
|
||||
|
||||
|
||||
const WAIT = 150
|
||||
|
||||
function throttle(callback, wait, immediate = false) {
|
||||
let timeout = null
|
||||
let timeout = null
|
||||
let initialCall = true
|
||||
|
||||
|
||||
return function() {
|
||||
const callNow = immediate && initialCall
|
||||
const next = () => {
|
||||
callback.apply(this, arguments)
|
||||
timeout = null
|
||||
}
|
||||
|
||||
if (callNow) {
|
||||
|
||||
if (callNow) {
|
||||
initialCall = false
|
||||
next()
|
||||
}
|
||||
|
||||
|
||||
if (!timeout) {
|
||||
timeout = setTimeout(next, wait)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const onChange = throttle(e => {
|
||||
dispatch('change', e.detail)
|
||||
}, WAIT, true)
|
||||
|
||||
const onChange = throttle(
|
||||
e => {
|
||||
dispatch("change", e.detail)
|
||||
},
|
||||
WAIT,
|
||||
true
|
||||
)
|
||||
</script>
|
||||
|
||||
<Colorpicker value={value || '#C4C4C4'} on:change={onChange} />
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
class Email {
|
||||
constructor() {
|
||||
this.apiKey = null
|
||||
}
|
||||
|
||||
setApiKey(apiKey) {
|
||||
this.apiKey = apiKey
|
||||
}
|
||||
|
||||
async send(msg) {
|
||||
if (msg.to === "invalid@test.com") {
|
||||
throw "Invalid"
|
||||
}
|
||||
return msg
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new Email()
|
|
@ -1,17 +1,35 @@
|
|||
const fetch = jest.requireActual("node-fetch")
|
||||
|
||||
module.exports = async (url, opts) => {
|
||||
// mocked data based on url
|
||||
if (url.includes("api/apps")) {
|
||||
function json(body, status = 200) {
|
||||
return {
|
||||
status,
|
||||
json: async () => {
|
||||
return {
|
||||
app1: {
|
||||
url: "/app1",
|
||||
},
|
||||
}
|
||||
return body
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// mocked data based on url
|
||||
if (url.includes("api/apps")) {
|
||||
return json({
|
||||
app1: {
|
||||
url: "/app1",
|
||||
},
|
||||
})
|
||||
} else if (url.includes("test.com")) {
|
||||
return json({
|
||||
body: opts.body,
|
||||
url,
|
||||
method: opts.method,
|
||||
})
|
||||
} else if (url.includes("invalid.com")) {
|
||||
return json(
|
||||
{
|
||||
invalid: true,
|
||||
},
|
||||
404
|
||||
)
|
||||
}
|
||||
return fetch(url, opts)
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"test": "jest --testPathIgnorePatterns=routes && npm run test:integration",
|
||||
"test:integration": "jest --runInBand --coverage",
|
||||
"test:integration": "jest --coverage --detectOpenHandles",
|
||||
"test:watch": "jest --watch",
|
||||
"run:docker": "node src/index",
|
||||
"dev:builder": "cross-env PORT=4001 nodemon src/index.js",
|
||||
|
@ -53,11 +53,16 @@
|
|||
"src/**/*.js",
|
||||
"!**/node_modules/**",
|
||||
"!src/db/views/*.js",
|
||||
"!src/api/routes/tests/**/*.js",
|
||||
"!src/api/controllers/deploy/**/*.js",
|
||||
"!src/api/controllers/static/templates/**/*",
|
||||
"!src/api/controllers/static/selfhost/**/*",
|
||||
"!src/*.js"
|
||||
"!src/*.js",
|
||||
"!src/api/controllers/static/**/*",
|
||||
"!src/db/dynamoClient.js",
|
||||
"!src/utilities/usageQuota.js",
|
||||
"!src/api/routes/tests/**/*",
|
||||
"!src/tests/**/*",
|
||||
"!src/automations/tests/**/*",
|
||||
"!src/utilities/fileProcessor.js",
|
||||
"!src/utilities/initialiseBudibase.js"
|
||||
],
|
||||
"coverageReporters": [
|
||||
"lcov",
|
||||
|
|
|
@ -65,12 +65,14 @@ exports.save = async function(ctx) {
|
|||
|
||||
// Don't rename if the name is the same
|
||||
let { _rename } = tableToSave
|
||||
/* istanbul ignore next */
|
||||
if (_rename && _rename.old === _rename.updated) {
|
||||
_rename = null
|
||||
delete tableToSave._rename
|
||||
}
|
||||
|
||||
// rename row fields when table column is renamed
|
||||
/* istanbul ignore next */
|
||||
if (_rename && tableToSave.schema[_rename.updated].type === FieldTypes.LINK) {
|
||||
ctx.throw(400, "Cannot rename a linked column.")
|
||||
} else if (_rename && tableToSave.primaryDisplay === _rename.old) {
|
||||
|
@ -159,7 +161,7 @@ exports.destroy = async function(ctx) {
|
|||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emitTable(`table:delete`, appId, tableToDelete)
|
||||
ctx.status = 200
|
||||
ctx.message = `Table ${ctx.params.tableId} deleted.`
|
||||
ctx.body = { message: `Table ${ctx.params.tableId} deleted.` }
|
||||
}
|
||||
|
||||
exports.validateCSVSchema = async function(ctx) {
|
||||
|
|
|
@ -90,7 +90,8 @@ exports.handleDataImport = async (user, table, dataImport) => {
|
|||
return table
|
||||
}
|
||||
|
||||
exports.handleSearchIndexes = async (db, table) => {
|
||||
exports.handleSearchIndexes = async (appId, table) => {
|
||||
const db = new CouchDB(appId)
|
||||
// create relevant search indexes
|
||||
if (table.indexes && table.indexes.length > 0) {
|
||||
const currentIndexes = await db.getIndexes()
|
||||
|
@ -150,6 +151,9 @@ class TableSaveFunctions {
|
|||
constructor({ db, ctx, oldTable, dataImport }) {
|
||||
this.db = db
|
||||
this.ctx = ctx
|
||||
if (this.ctx && this.ctx.user) {
|
||||
this.appId = this.ctx.user.appId
|
||||
}
|
||||
this.oldTable = oldTable
|
||||
this.dataImport = dataImport
|
||||
// any rows that need updated
|
||||
|
@ -178,7 +182,7 @@ class TableSaveFunctions {
|
|||
|
||||
// after saving
|
||||
async after(table) {
|
||||
table = await exports.handleSearchIndexes(this.db, table)
|
||||
table = await exports.handleSearchIndexes(this.appId, table)
|
||||
table = await exports.handleDataImport(
|
||||
this.ctx.user,
|
||||
table,
|
||||
|
|
|
@ -29,11 +29,13 @@ const controller = {
|
|||
save: async ctx => {
|
||||
const db = new CouchDB(ctx.user.appId)
|
||||
const { originalName, ...viewToSave } = ctx.request.body
|
||||
|
||||
const designDoc = await db.get("_design/database")
|
||||
|
||||
const view = viewTemplate(viewToSave)
|
||||
|
||||
if (!viewToSave.name) {
|
||||
ctx.throw(400, "Cannot create view without a name")
|
||||
}
|
||||
|
||||
designDoc.views = {
|
||||
...designDoc.views,
|
||||
[viewToSave.name]: view,
|
||||
|
@ -60,17 +62,16 @@ const controller = {
|
|||
|
||||
await db.put(table)
|
||||
|
||||
ctx.body = table.views[viewToSave.name]
|
||||
ctx.message = `View ${viewToSave.name} saved successfully.`
|
||||
ctx.body = {
|
||||
...table.views[viewToSave.name],
|
||||
name: viewToSave.name,
|
||||
}
|
||||
},
|
||||
destroy: async ctx => {
|
||||
const db = new CouchDB(ctx.user.appId)
|
||||
const designDoc = await db.get("_design/database")
|
||||
|
||||
const viewName = decodeURI(ctx.params.viewName)
|
||||
|
||||
const view = designDoc.views[viewName]
|
||||
|
||||
delete designDoc.views[viewName]
|
||||
|
||||
await db.put(designDoc)
|
||||
|
@ -80,16 +81,17 @@ const controller = {
|
|||
await db.put(table)
|
||||
|
||||
ctx.body = view
|
||||
ctx.message = `View ${ctx.params.viewName} saved successfully.`
|
||||
},
|
||||
exportView: async ctx => {
|
||||
const db = new CouchDB(ctx.user.appId)
|
||||
const designDoc = await db.get("_design/database")
|
||||
|
||||
const viewName = decodeURI(ctx.query.view)
|
||||
|
||||
const view = designDoc.views[viewName]
|
||||
const format = ctx.query.format
|
||||
if (!format) {
|
||||
ctx.throw(400, "Format must be specified, either csv or json")
|
||||
}
|
||||
|
||||
if (view) {
|
||||
ctx.params.viewName = viewName
|
||||
|
@ -102,6 +104,7 @@ const controller = {
|
|||
}
|
||||
} else {
|
||||
// table all_ view
|
||||
/* istanbul ignore next */
|
||||
ctx.params.viewName = viewName
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ const {
|
|||
getAllTableRows,
|
||||
clearAllAutomations,
|
||||
} = require("./utilities/TestFunctions")
|
||||
const { basicAutomation } = require("./utilities/structures")
|
||||
const setup = require("./utilities")
|
||||
const { basicAutomation } = setup.structures
|
||||
|
||||
const MAX_RETRIES = 4
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
let {basicDatasource} = require("./utilities/structures")
|
||||
let {checkBuilderEndpoint} = require("./utilities/TestFunctions")
|
||||
let setup = require("./utilities")
|
||||
let { basicDatasource } = setup.structures
|
||||
let { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
|
||||
describe("/datasources", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const setup = require("./utilities")
|
||||
const { basicLayout } = require("./utilities/structures")
|
||||
const { basicLayout } = setup.structures
|
||||
|
||||
describe("/layouts", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const setup = require("./utilities")
|
||||
const tableUtils = require("../../controllers/table/utils")
|
||||
|
||||
describe("/analytics", () => {
|
||||
describe("run misc tests", () => {
|
||||
let request = setup.getRequest()
|
||||
let config = setup.getConfig()
|
||||
|
||||
|
@ -10,29 +11,44 @@ describe("/analytics", () => {
|
|||
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("/analytics", () => {
|
||||
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 () => {
|
||||
await request.get("/health").expect(200)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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 res = await request.get("/version").expect(200)
|
||||
expect(res.text.split(".").length).toEqual(3)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
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)
|
||||
describe("test table utilities", () => {
|
||||
it("should be able to import a CSV", async () => {
|
||||
const table = await config.createTable()
|
||||
const dataImport = {
|
||||
csvString: "a,b,c,d\n1,2,3,4"
|
||||
}
|
||||
await tableUtils.handleDataImport({
|
||||
appId: config.getAppId(),
|
||||
userId: "test",
|
||||
}, table, dataImport)
|
||||
const rows = await config.getRows()
|
||||
expect(rows[0].a).toEqual("1")
|
||||
expect(rows[0].b).toEqual("2")
|
||||
expect(rows[0].c).toEqual("3")
|
||||
})
|
||||
})
|
||||
})
|
|
@ -1,6 +1,6 @@
|
|||
const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles")
|
||||
const setup = require("./utilities")
|
||||
const { basicRow } = require("./utilities/structures")
|
||||
const { basicRow } = setup.structures
|
||||
|
||||
const HIGHER_ROLE_ID = BUILTIN_ROLE_IDS.BASIC
|
||||
const STD_ROLE_ID = BUILTIN_ROLE_IDS.PUBLIC
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
// mock out postgres for this
|
||||
jest.mock("pg")
|
||||
|
||||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const { basicQuery, basicDatasource } = require("./utilities/structures")
|
||||
const setup = require("./utilities")
|
||||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const { basicQuery, basicDatasource } = setup.structures
|
||||
|
||||
describe("/queries", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -2,8 +2,8 @@ const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles")
|
|||
const {
|
||||
BUILTIN_PERMISSION_IDS,
|
||||
} = require("../../../utilities/security/permissions")
|
||||
const { basicRole } = require("./utilities/structures")
|
||||
const setup = require("./utilities")
|
||||
const { basicRole } = setup.structures
|
||||
|
||||
describe("/roles", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const setup = require("./utilities")
|
||||
const { basicScreen } = require("./utilities/structures")
|
||||
const { basicScreen } = setup.structures
|
||||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles")
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
const { outputProcessing } = require("../../../utilities/rowProcessor")
|
||||
const env = require("../../../environment")
|
||||
const { basicRow } = require("./utilities/structures")
|
||||
const setup = require("./utilities")
|
||||
const { basicRow } = setup.structures
|
||||
|
||||
describe("/rows", () => {
|
||||
let request = setup.getRequest()
|
||||
|
@ -349,7 +348,7 @@ describe("/rows", () => {
|
|||
const view = await config.createView()
|
||||
const row = await config.createRow()
|
||||
const res = await request
|
||||
.get(`/api/views/${view._id}`)
|
||||
.get(`/api/views/${view.name}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const setup = require("./utilities")
|
||||
const { basicScreen } = require("./utilities/structures")
|
||||
const { basicScreen } = setup.structures
|
||||
|
||||
describe("/screens", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const { checkBuilderEndpoint, getDB } = require("./utilities/TestFunctions")
|
||||
const setup = require("./utilities")
|
||||
const { basicTable } = setup.structures
|
||||
|
||||
describe("/tables", () => {
|
||||
let request = setup.getRequest()
|
||||
|
@ -12,25 +13,22 @@ describe("/tables", () => {
|
|||
})
|
||||
|
||||
describe("create", () => {
|
||||
it("returns a success message when the table is successfully created", done => {
|
||||
request
|
||||
it("returns a success message when the table is successfully created", async () => {
|
||||
const res = await request
|
||||
.post(`/api/tables`)
|
||||
.send({
|
||||
.send({
|
||||
name: "TestTable",
|
||||
key: "name",
|
||||
schema: {
|
||||
name: { type: "string" }
|
||||
name: {type: "string"}
|
||||
}
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
.end(async (err, res) => {
|
||||
expect(res.res.statusMessage).toEqual("Table TestTable saved successfully.")
|
||||
expect(res.body.name).toEqual("TestTable")
|
||||
done()
|
||||
})
|
||||
})
|
||||
expect(res.res.statusMessage).toEqual("Table TestTable saved successfully.")
|
||||
expect(res.body.name).toEqual("TestTable")
|
||||
})
|
||||
|
||||
it("renames all the row fields for a table when a schema key is renamed", async () => {
|
||||
const testTable = await config.createTable()
|
||||
|
@ -46,7 +44,7 @@ describe("/tables", () => {
|
|||
|
||||
const updatedTable = await request
|
||||
.post(`/api/tables`)
|
||||
.send({
|
||||
.send({
|
||||
_id: testTable._id,
|
||||
_rev: testTable._rev,
|
||||
name: "TestTable",
|
||||
|
@ -56,41 +54,40 @@ describe("/tables", () => {
|
|||
updated: "updatedName"
|
||||
},
|
||||
schema: {
|
||||
updatedName: { type: "string" }
|
||||
updatedName: {type: "string"}
|
||||
}
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
expect(updatedTable.res.statusMessage).toEqual("Table TestTable saved successfully.")
|
||||
expect(updatedTable.body.name).toEqual("TestTable")
|
||||
|
||||
expect(updatedTable.res.statusMessage).toEqual("Table TestTable saved successfully.")
|
||||
expect(updatedTable.body.name).toEqual("TestTable")
|
||||
const res = await request
|
||||
.get(`/api/${testTable._id}/rows/${testRow.body._id}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
|
||||
const res = await request
|
||||
.get(`/api/${testTable._id}/rows/${testRow.body._id}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
expect(res.body.updatedName).toEqual("test")
|
||||
expect(res.body.name).toBeUndefined()
|
||||
})
|
||||
|
||||
expect(res.body.updatedName).toEqual("test")
|
||||
expect(res.body.name).toBeUndefined()
|
||||
})
|
||||
|
||||
it("should apply authorization to endpoint", async () => {
|
||||
await checkBuilderEndpoint({
|
||||
config,
|
||||
method: "POST",
|
||||
url: `/api/tables`,
|
||||
body: {
|
||||
name: "TestTable",
|
||||
key: "name",
|
||||
schema: {
|
||||
name: { type: "string" }
|
||||
}
|
||||
it("should apply authorization to endpoint", async () => {
|
||||
await checkBuilderEndpoint({
|
||||
config,
|
||||
method: "POST",
|
||||
url: `/api/tables`,
|
||||
body: {
|
||||
name: "TestTable",
|
||||
key: "name",
|
||||
schema: {
|
||||
name: {type: "string"}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("fetch", () => {
|
||||
let testTable
|
||||
|
@ -103,28 +100,91 @@ describe("/tables", () => {
|
|||
delete testTable._rev
|
||||
})
|
||||
|
||||
it("returns all the tables for that instance in the response body", done => {
|
||||
request
|
||||
it("returns all the tables for that instance in the response body", async () => {
|
||||
const res = await request
|
||||
.get(`/api/tables`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
.end(async (_, res) => {
|
||||
const fetchedTable = res.body[0]
|
||||
expect(fetchedTable.name).toEqual(testTable.name)
|
||||
expect(fetchedTable.type).toEqual("table")
|
||||
done()
|
||||
})
|
||||
const fetchedTable = res.body[0]
|
||||
expect(fetchedTable.name).toEqual(testTable.name)
|
||||
expect(fetchedTable.type).toEqual("table")
|
||||
})
|
||||
|
||||
it("should apply authorization to endpoint", async () => {
|
||||
await checkBuilderEndpoint({
|
||||
config,
|
||||
method: "GET",
|
||||
url: `/api/tables`,
|
||||
})
|
||||
await checkBuilderEndpoint({
|
||||
config,
|
||||
method: "GET",
|
||||
url: `/api/tables`,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("indexing", () => {
|
||||
it("should be able to create a table with indexes", async () => {
|
||||
const db = getDB(config)
|
||||
const indexCount = (await db.getIndexes()).total_rows
|
||||
const table = basicTable()
|
||||
table.indexes = ["name"]
|
||||
const res = await request
|
||||
.post(`/api/tables`)
|
||||
.send(table)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
expect(res.body._id).toBeDefined()
|
||||
expect(res.body._rev).toBeDefined()
|
||||
expect((await db.getIndexes()).total_rows).toEqual(indexCount + 1)
|
||||
// update index to see what happens
|
||||
table.indexes = ["name", "description"]
|
||||
await request
|
||||
.post(`/api/tables`)
|
||||
.send({
|
||||
...table,
|
||||
_id: res.body._id,
|
||||
_rev: res.body._rev,
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
// shouldn't have created a new index
|
||||
expect((await db.getIndexes()).total_rows).toEqual(indexCount + 1)
|
||||
})
|
||||
})
|
||||
|
||||
describe("updating user table", () => {
|
||||
it("should add roleId and email field when adjusting user table schema", async () => {
|
||||
const res = await request
|
||||
.post(`/api/tables`)
|
||||
.send({
|
||||
...basicTable(),
|
||||
_id: "ta_users",
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
expect(res.body.schema.email).toBeDefined()
|
||||
expect(res.body.schema.roleId).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe("validate csv", () => {
|
||||
it("should be able to validate a CSV layout", async () => {
|
||||
const res = await request
|
||||
.post(`/api/tables/csv/validate`)
|
||||
.send({
|
||||
csvString: "a,b,c,d\n1,2,3,4"
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
expect(res.body.schema).toBeDefined()
|
||||
expect(res.body.schema.a).toEqual({
|
||||
type: "string",
|
||||
success: true,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("destroy", () => {
|
||||
let testTable
|
||||
|
@ -137,19 +197,16 @@ describe("/tables", () => {
|
|||
delete testTable._rev
|
||||
})
|
||||
|
||||
it("returns a success response when a table is deleted.", async done => {
|
||||
request
|
||||
it("returns a success response when a table is deleted.", async () => {
|
||||
const res = await request
|
||||
.delete(`/api/tables/${testTable._id}/${testTable._rev}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
.end(async (_, res) => {
|
||||
expect(res.res.statusMessage).toEqual(`Table ${testTable._id} deleted.`)
|
||||
done()
|
||||
})
|
||||
})
|
||||
expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`)
|
||||
})
|
||||
|
||||
it("deletes linked references to the table after deletion", async done => {
|
||||
it("deletes linked references to the table after deletion", async () => {
|
||||
const linkedTable = await config.createTable({
|
||||
name: "LinkedTable",
|
||||
type: "table",
|
||||
|
@ -171,18 +228,15 @@ describe("/tables", () => {
|
|||
},
|
||||
})
|
||||
|
||||
request
|
||||
const res = await request
|
||||
.delete(`/api/tables/${testTable._id}/${testTable._rev}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(200)
|
||||
.end(async (_, res) => {
|
||||
expect(res.res.statusMessage).toEqual(`Table ${testTable._id} deleted.`)
|
||||
const dependentTable = await config.getTable(linkedTable._id)
|
||||
expect(dependentTable.schema.TestTable).not.toBeDefined()
|
||||
done()
|
||||
})
|
||||
})
|
||||
expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`)
|
||||
const dependentTable = await config.getTable(linkedTable._id)
|
||||
expect(dependentTable.schema.TestTable).not.toBeDefined()
|
||||
})
|
||||
|
||||
it("should apply authorization to endpoint", async () => {
|
||||
await checkBuilderEndpoint({
|
||||
|
@ -191,6 +245,5 @@ describe("/tables", () => {
|
|||
url: `/api/tables/${testTable._id}/${testTable._rev}`,
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles")
|
||||
const { checkPermissionsEndpoint } = require("./utilities/TestFunctions")
|
||||
const { basicUser } = require("./utilities/structures")
|
||||
const setup = require("./utilities")
|
||||
const { basicUser } = setup.structures
|
||||
|
||||
describe("/users", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const rowController = require("../../../controllers/row")
|
||||
const appController = require("../../../controllers/application")
|
||||
const CouchDB = require("../../../../db")
|
||||
|
||||
function Request(appId, params) {
|
||||
this.user = { appId }
|
||||
|
@ -77,3 +78,7 @@ exports.checkPermissionsEndpoint = async ({
|
|||
.set(failHeader)
|
||||
.expect(403)
|
||||
}
|
||||
|
||||
exports.getDB = config => {
|
||||
return new CouchDB(config.getAppId())
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
module.exports = {
|
||||
table: require("../../../controllers/table"),
|
||||
row: require("../../../controllers/row"),
|
||||
role: require("../../../controllers/role"),
|
||||
perms: require("../../../controllers/permission"),
|
||||
view: require("../../../controllers/view"),
|
||||
app: require("../../../controllers/application"),
|
||||
user: require("../../../controllers/user"),
|
||||
automation: require("../../../controllers/automation"),
|
||||
datasource: require("../../../controllers/datasource"),
|
||||
query: require("../../../controllers/query"),
|
||||
screen: require("../../../controllers/screen"),
|
||||
webhook: require("../../../controllers/webhook"),
|
||||
layout: require("../../../controllers/layout"),
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
const TestConfig = require("./TestConfiguration")
|
||||
const TestConfig = require("../../../../tests/utilities/TestConfiguration")
|
||||
const structures = require("../../../../tests/utilities/structures")
|
||||
const env = require("../../../../environment")
|
||||
|
||||
exports.delay = ms => new Promise(resolve => setTimeout(resolve, ms))
|
||||
|
@ -51,3 +52,5 @@ exports.switchToCloudForFunction = async func => {
|
|||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
exports.structures = structures
|
||||
|
|
|
@ -29,9 +29,7 @@ describe("/views", () => {
|
|||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
|
||||
expect(res.res.statusMessage).toEqual(
|
||||
"View TestView saved successfully."
|
||||
)
|
||||
expect(res.body.tableId).toBe(table._id)
|
||||
})
|
||||
|
||||
it("updates the table row with the new view metadata", async () => {
|
||||
|
@ -46,10 +44,8 @@ describe("/views", () => {
|
|||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
expect(res.body.tableId).toBe(table._id)
|
||||
|
||||
expect(res.res.statusMessage).toEqual(
|
||||
"View TestView saved successfully."
|
||||
)
|
||||
const updatedTable = await config.getTable(table._id)
|
||||
expect(updatedTable.views).toEqual({
|
||||
TestView: {
|
||||
|
@ -173,4 +169,49 @@ describe("/views", () => {
|
|||
expect(res.body).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
||||
describe("destroy", () => {
|
||||
it("should be able to delete a view", async () => {
|
||||
const table = await config.createTable()
|
||||
const view = await config.createView()
|
||||
const res = await request
|
||||
.delete(`/api/views/${view.name}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
expect(res.body.map).toBeDefined()
|
||||
expect(res.body.meta.tableId).toEqual(table._id)
|
||||
})
|
||||
})
|
||||
|
||||
describe("exportView", () => {
|
||||
it("should be able to delete a view", async () => {
|
||||
await config.createTable()
|
||||
await config.createRow()
|
||||
const view = await config.createView()
|
||||
let res = await request
|
||||
.get(`/api/views/export?view=${view.name}&format=json`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect(200)
|
||||
let error
|
||||
try {
|
||||
const obj = JSON.parse(res.text)
|
||||
expect(obj.length).toBe(1)
|
||||
} catch (err) {
|
||||
error = err
|
||||
}
|
||||
expect(error).toBeUndefined()
|
||||
res = await request
|
||||
.get(`/api/views/export?view=${view.name}&format=csv`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect(200)
|
||||
// this shouldn't be JSON
|
||||
try {
|
||||
JSON.parse(res.text)
|
||||
} catch (err) {
|
||||
error = err
|
||||
}
|
||||
expect(error).toBeDefined()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
const setup = require("./utilities")
|
||||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const { basicWebhook, basicAutomation } = require("./utilities/structures")
|
||||
const { basicWebhook, basicAutomation } = setup.structures
|
||||
|
||||
describe("/webhooks", () => {
|
||||
let request = setup.getRequest()
|
||||
|
|
|
@ -9,7 +9,6 @@ const env = require("./environment")
|
|||
const eventEmitter = require("./events")
|
||||
const automations = require("./automations/index")
|
||||
const Sentry = require("@sentry/node")
|
||||
const selfhost = require("./selfhost")
|
||||
|
||||
const app = new Koa()
|
||||
|
||||
|
@ -66,11 +65,7 @@ module.exports = server.listen(env.PORT || 0, async () => {
|
|||
console.log(`Budibase running on ${JSON.stringify(server.address())}`)
|
||||
env._set("PORT", server.address().port)
|
||||
eventEmitter.emitPort(env.PORT)
|
||||
automations.init()
|
||||
// only init the self hosting DB info in the Pouch, not needed in self hosting prod
|
||||
if (!env.CLOUD) {
|
||||
await selfhost.init()
|
||||
}
|
||||
await automations.init()
|
||||
})
|
||||
|
||||
process.on("uncaughtException", err => {
|
||||
|
|
|
@ -37,10 +37,12 @@ let AUTOMATION_BUCKET = env.AUTOMATION_BUCKET
|
|||
let AUTOMATION_DIRECTORY = env.AUTOMATION_DIRECTORY
|
||||
let MANIFEST = null
|
||||
|
||||
/* istanbul ignore next */
|
||||
function buildBundleName(pkgName, version) {
|
||||
return `${pkgName}@${version}.min.js`
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
async function downloadPackage(name, version, bundleName) {
|
||||
await download(
|
||||
`${AUTOMATION_BUCKET}/${name}/${version}/${bundleName}`,
|
||||
|
@ -49,6 +51,7 @@ async function downloadPackage(name, version, bundleName) {
|
|||
return require(join(AUTOMATION_DIRECTORY, bundleName))
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
module.exports.getAction = async function(actionName) {
|
||||
if (BUILTIN_ACTIONS[actionName] != null) {
|
||||
return BUILTIN_ACTIONS[actionName]
|
||||
|
@ -96,5 +99,6 @@ module.exports.init = async function() {
|
|||
return MANIFEST
|
||||
}
|
||||
|
||||
// definitions will have downloaded ones added to it, while builtin won't
|
||||
module.exports.DEFINITIONS = BUILTIN_DEFINITIONS
|
||||
module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
|
||||
|
|
|
@ -30,23 +30,22 @@ async function updateQuota(automation) {
|
|||
/**
|
||||
* This module is built purely to kick off the worker farm and manage the inputs/outputs
|
||||
*/
|
||||
module.exports.init = function() {
|
||||
actions.init().then(() => {
|
||||
triggers.automationQueue.process(async job => {
|
||||
try {
|
||||
if (env.CLOUD && job.data.automation && !env.SELF_HOSTED) {
|
||||
job.data.automation.apiKey = await updateQuota(job.data.automation)
|
||||
}
|
||||
if (env.BUDIBASE_ENVIRONMENT === "PRODUCTION") {
|
||||
await runWorker(job)
|
||||
} else {
|
||||
await singleThread(job)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${err}`
|
||||
)
|
||||
module.exports.init = async function() {
|
||||
await actions.init()
|
||||
triggers.automationQueue.process(async job => {
|
||||
try {
|
||||
if (env.CLOUD && job.data.automation && !env.SELF_HOSTED) {
|
||||
job.data.automation.apiKey = await updateQuota(job.data.automation)
|
||||
}
|
||||
})
|
||||
if (env.BUDIBASE_ENVIRONMENT === "PRODUCTION") {
|
||||
await runWorker(job)
|
||||
} else {
|
||||
await singleThread(job)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`${job.data.automation.appId} automation ${job.data.automation._id} was unable to run - ${err}`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -59,15 +59,14 @@ module.exports.definition = {
|
|||
}
|
||||
|
||||
module.exports.run = async function({ inputs, appId, apiKey, emitter }) {
|
||||
// TODO: better logging of when actions are missed due to missing parameters
|
||||
if (inputs.row == null || inputs.row.tableId == null) {
|
||||
return
|
||||
return {
|
||||
success: false,
|
||||
response: {
|
||||
message: "Invalid inputs",
|
||||
},
|
||||
}
|
||||
}
|
||||
inputs.row = await automationUtils.cleanUpRow(
|
||||
appId,
|
||||
inputs.row.tableId,
|
||||
inputs.row
|
||||
)
|
||||
// have to clean up the row, remove the table from it
|
||||
const ctx = {
|
||||
params: {
|
||||
|
@ -81,6 +80,11 @@ module.exports.run = async function({ inputs, appId, apiKey, emitter }) {
|
|||
}
|
||||
|
||||
try {
|
||||
inputs.row = await automationUtils.cleanUpRow(
|
||||
appId,
|
||||
inputs.row.tableId,
|
||||
inputs.row
|
||||
)
|
||||
if (env.CLOUD) {
|
||||
await usage.update(apiKey, usage.Properties.ROW, 1)
|
||||
}
|
||||
|
|
|
@ -51,9 +51,13 @@ module.exports.definition = {
|
|||
}
|
||||
|
||||
module.exports.run = async function({ inputs, appId, apiKey, emitter }) {
|
||||
// TODO: better logging of when actions are missed due to missing parameters
|
||||
if (inputs.id == null || inputs.revision == null) {
|
||||
return
|
||||
return {
|
||||
success: false,
|
||||
response: {
|
||||
message: "Invalid inputs",
|
||||
},
|
||||
}
|
||||
}
|
||||
let ctx = {
|
||||
params: {
|
||||
|
|
|
@ -12,6 +12,9 @@ const PrettyLogicConditions = {
|
|||
[LogicConditions.LESS_THAN]: "Less than",
|
||||
}
|
||||
|
||||
module.exports.LogicConditions = LogicConditions
|
||||
module.exports.PrettyLogicConditions = PrettyLogicConditions
|
||||
|
||||
module.exports.definition = {
|
||||
name: "Filter",
|
||||
tagline: "{{inputs.field}} {{inputs.condition}} {{inputs.value}}",
|
||||
|
@ -64,7 +67,7 @@ module.exports.run = async function filter({ inputs }) {
|
|||
value = Date.parse(value)
|
||||
field = Date.parse(field)
|
||||
}
|
||||
let success
|
||||
let success = false
|
||||
if (typeof field !== "object" && typeof value !== "object") {
|
||||
switch (condition) {
|
||||
case LogicConditions.EQUAL:
|
||||
|
@ -79,8 +82,6 @@ module.exports.run = async function filter({ inputs }) {
|
|||
case LogicConditions.LESS_THAN:
|
||||
success = field < value
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
} else {
|
||||
success = false
|
||||
|
|
|
@ -87,6 +87,7 @@ module.exports.run = async function({ inputs }) {
|
|||
success: response.status === 200,
|
||||
}
|
||||
} catch (err) {
|
||||
/* istanbul ignore next */
|
||||
return {
|
||||
success: false,
|
||||
response: err,
|
||||
|
|
|
@ -55,14 +55,14 @@ module.exports.definition = {
|
|||
|
||||
module.exports.run = async function({ inputs, appId, emitter }) {
|
||||
if (inputs.rowId == null || inputs.row == null) {
|
||||
return
|
||||
return {
|
||||
success: false,
|
||||
response: {
|
||||
message: "Invalid inputs",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
inputs.row = await automationUtils.cleanUpRowById(
|
||||
appId,
|
||||
inputs.rowId,
|
||||
inputs.row
|
||||
)
|
||||
// clear any falsy properties so that they aren't updated
|
||||
for (let propKey of Object.keys(inputs.row)) {
|
||||
if (!inputs.row[propKey] || inputs.row[propKey] === "") {
|
||||
|
@ -73,7 +73,7 @@ module.exports.run = async function({ inputs, appId, emitter }) {
|
|||
// have to clean up the row, remove the table from it
|
||||
const ctx = {
|
||||
params: {
|
||||
id: inputs.rowId,
|
||||
rowId: inputs.rowId,
|
||||
},
|
||||
request: {
|
||||
body: inputs.row,
|
||||
|
@ -83,6 +83,11 @@ module.exports.run = async function({ inputs, appId, emitter }) {
|
|||
}
|
||||
|
||||
try {
|
||||
inputs.row = await automationUtils.cleanUpRowById(
|
||||
appId,
|
||||
inputs.rowId,
|
||||
inputs.row
|
||||
)
|
||||
await rowController.patch(ctx)
|
||||
return {
|
||||
row: ctx.body,
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
const automation = require("../index")
|
||||
const usageQuota = require("../../utilities/usageQuota")
|
||||
const thread = require("../thread")
|
||||
const triggers = require("../triggers")
|
||||
const { basicAutomation, basicTable } = require("../../tests/utilities/structures")
|
||||
const { wait } = require("../../utilities")
|
||||
const env = require("../../environment")
|
||||
const { makePartial } = require("../../tests/utilities")
|
||||
const { cleanInputValues } = require("../automationUtils")
|
||||
const setup = require("./utilities")
|
||||
|
||||
let workerJob
|
||||
|
||||
jest.mock("../../utilities/usageQuota")
|
||||
usageQuota.getAPIKey.mockReturnValue({ apiKey: "test" })
|
||||
jest.mock("../thread")
|
||||
jest.spyOn(global.console, "error")
|
||||
jest.mock("worker-farm", () => {
|
||||
return () => {
|
||||
const value = jest
|
||||
.fn()
|
||||
.mockReturnValueOnce(undefined)
|
||||
.mockReturnValueOnce("Error")
|
||||
return (input, callback) => {
|
||||
workerJob = input
|
||||
if (callback) {
|
||||
callback(value())
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
describe("Run through some parts of the automations system", () => {
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeEach(async () => {
|
||||
await automation.init()
|
||||
await config.init()
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to init in builder", async () => {
|
||||
await triggers.externalTrigger(basicAutomation(), { a: 1 })
|
||||
await wait(100)
|
||||
expect(workerJob).toBeUndefined()
|
||||
expect(thread).toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should be able to init in cloud", async () => {
|
||||
env.CLOUD = true
|
||||
env.BUDIBASE_ENVIRONMENT = "PRODUCTION"
|
||||
await triggers.externalTrigger(basicAutomation(), { a: 1 })
|
||||
await wait(100)
|
||||
// haven't added a mock implementation so getAPIKey of usageQuota just returns undefined
|
||||
expect(usageQuota.update).toHaveBeenCalledWith("test", "automationRuns", 1)
|
||||
expect(workerJob).toBeDefined()
|
||||
env.BUDIBASE_ENVIRONMENT = "JEST"
|
||||
env.CLOUD = false
|
||||
})
|
||||
|
||||
it("try error scenario", async () => {
|
||||
env.CLOUD = true
|
||||
env.BUDIBASE_ENVIRONMENT = "PRODUCTION"
|
||||
// the second call will throw an error
|
||||
await triggers.externalTrigger(basicAutomation(), { a: 1 })
|
||||
await wait(100)
|
||||
expect(console.error).toHaveBeenCalled()
|
||||
env.BUDIBASE_ENVIRONMENT = "JEST"
|
||||
env.CLOUD = false
|
||||
})
|
||||
|
||||
it("should be able to check triggering row filling", async () => {
|
||||
const automation = basicAutomation()
|
||||
let table = basicTable()
|
||||
table.schema.boolean = {
|
||||
type: "boolean",
|
||||
constraints: {
|
||||
type: "boolean",
|
||||
},
|
||||
}
|
||||
table.schema.number = {
|
||||
type: "number",
|
||||
constraints: {
|
||||
type: "number",
|
||||
},
|
||||
}
|
||||
table.schema.datetime = {
|
||||
type: "datetime",
|
||||
constraints: {
|
||||
type: "datetime",
|
||||
},
|
||||
}
|
||||
table = await config.createTable(table)
|
||||
automation.definition.trigger.inputs.tableId = table._id
|
||||
const params = await triggers.fillRowOutput(automation, { appId: config.getAppId() })
|
||||
expect(params.row).toBeDefined()
|
||||
const date = new Date(params.row.datetime)
|
||||
expect(typeof params.row.name).toBe("string")
|
||||
expect(typeof params.row.boolean).toBe("boolean")
|
||||
expect(typeof params.row.number).toBe("number")
|
||||
expect(date.getFullYear()).toBe(1970)
|
||||
})
|
||||
|
||||
it("should check coercion", async () => {
|
||||
const table = await config.createTable()
|
||||
const automation = basicAutomation()
|
||||
automation.definition.trigger.inputs.tableId = table._id
|
||||
automation.definition.trigger.stepId = "APP"
|
||||
automation.definition.trigger.inputs.fields = { a: "number" }
|
||||
await triggers.externalTrigger(automation, {
|
||||
appId: config.getAppId(),
|
||||
fields: {
|
||||
a: "1"
|
||||
}
|
||||
})
|
||||
await wait(100)
|
||||
expect(thread).toHaveBeenCalledWith(makePartial({
|
||||
data: {
|
||||
event: {
|
||||
fields: {
|
||||
a: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
it("should be able to clean inputs with the utilities", () => {
|
||||
// can't clean without a schema
|
||||
let output = cleanInputValues({a: "1"})
|
||||
expect(output.a).toBe("1")
|
||||
output = cleanInputValues({a: "1", b: "true", c: "false", d: 1, e: "help"}, {
|
||||
properties: {
|
||||
a: {
|
||||
type: "number",
|
||||
},
|
||||
b: {
|
||||
type: "boolean",
|
||||
},
|
||||
c: {
|
||||
type: "boolean",
|
||||
}
|
||||
}
|
||||
})
|
||||
expect(output.a).toBe(1)
|
||||
expect(output.b).toBe(true)
|
||||
expect(output.c).toBe(false)
|
||||
expect(output.d).toBe(1)
|
||||
expect(output.e).toBe("help")
|
||||
})
|
||||
})
|
|
@ -0,0 +1,57 @@
|
|||
const usageQuota = require("../../utilities/usageQuota")
|
||||
const env = require("../../environment")
|
||||
const setup = require("./utilities")
|
||||
|
||||
jest.mock("../../utilities/usageQuota")
|
||||
|
||||
describe("test the create row action", () => {
|
||||
let table, row
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
table = await config.createTable()
|
||||
row = {
|
||||
tableId: table._id,
|
||||
name: "test",
|
||||
description: "test",
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to run the action", async () => {
|
||||
const res = await setup.runStep(setup.actions.CREATE_ROW.stepId, {
|
||||
row,
|
||||
})
|
||||
expect(res.id).toBeDefined()
|
||||
expect(res.revision).toBeDefined()
|
||||
const gottenRow = await config.getRow(table._id, res.id)
|
||||
expect(gottenRow.name).toEqual("test")
|
||||
expect(gottenRow.description).toEqual("test")
|
||||
})
|
||||
|
||||
it("should return an error (not throw) when bad info provided", async () => {
|
||||
const res = await setup.runStep(setup.actions.CREATE_ROW.stepId, {
|
||||
row: {
|
||||
tableId: "invalid",
|
||||
invalid: "invalid",
|
||||
}
|
||||
})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
|
||||
it("check usage quota attempts", async () => {
|
||||
env.CLOUD = true
|
||||
await setup.runStep(setup.actions.CREATE_ROW.stepId, {
|
||||
row
|
||||
})
|
||||
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "rows", 1)
|
||||
env.CLOUD = false
|
||||
})
|
||||
|
||||
it("should check invalid inputs return an error", async () => {
|
||||
const res = await setup.runStep(setup.actions.CREATE_ROW.stepId, {})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,43 @@
|
|||
const usageQuota = require("../../utilities/usageQuota")
|
||||
const env = require("../../environment")
|
||||
const setup = require("./utilities")
|
||||
const { BUILTIN_ROLE_IDS } = require("../../utilities/security/roles")
|
||||
const { ViewNames } = require("../../db/utils")
|
||||
|
||||
jest.mock("../../utilities/usageQuota")
|
||||
|
||||
describe("test the create user action", () => {
|
||||
let config = setup.getConfig()
|
||||
let user
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
user = {
|
||||
email: "test@test.com",
|
||||
password: "password",
|
||||
roleId: BUILTIN_ROLE_IDS.POWER
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to run the action", async () => {
|
||||
const res = await setup.runStep(setup.actions.CREATE_USER.stepId, user)
|
||||
expect(res.id).toBeDefined()
|
||||
expect(res.revision).toBeDefined()
|
||||
const userDoc = await config.getRow(ViewNames.USERS, res.id)
|
||||
expect(userDoc.email).toEqual(user.email)
|
||||
})
|
||||
|
||||
it("should return an error if no inputs provided", async () => {
|
||||
const res = await setup.runStep(setup.actions.CREATE_USER.stepId, {})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
|
||||
it("check usage quota attempts", async () => {
|
||||
env.CLOUD = true
|
||||
await setup.runStep(setup.actions.CREATE_USER.stepId, user)
|
||||
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "users", 1)
|
||||
env.CLOUD = false
|
||||
})
|
||||
})
|
|
@ -0,0 +1,12 @@
|
|||
const setup = require("./utilities")
|
||||
|
||||
describe("test the delay logic", () => {
|
||||
it("should be able to run the delay", async () => {
|
||||
const time = 100
|
||||
const before = Date.now()
|
||||
await setup.runStep(setup.logic.DELAY.stepId, { time: time })
|
||||
const now = Date.now()
|
||||
// divide by two just so that test will always pass as long as there was some sort of delay
|
||||
expect(now - before).toBeGreaterThanOrEqual(time / 2)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,58 @@
|
|||
const usageQuota = require("../../utilities/usageQuota")
|
||||
const env = require("../../environment")
|
||||
const setup = require("./utilities")
|
||||
|
||||
jest.mock("../../utilities/usageQuota")
|
||||
|
||||
describe("test the delete row action", () => {
|
||||
let table, row, inputs
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
table = await config.createTable()
|
||||
row = await config.createRow()
|
||||
inputs = {
|
||||
tableId: table._id,
|
||||
id: row._id,
|
||||
revision: row._rev,
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to run the action", async () => {
|
||||
const res = await setup.runStep(setup.actions.DELETE_ROW.stepId, inputs)
|
||||
expect(res.success).toEqual(true)
|
||||
expect(res.response).toBeDefined()
|
||||
expect(res.row._id).toEqual(row._id)
|
||||
let error
|
||||
try {
|
||||
await config.getRow(table._id, res.id)
|
||||
} catch (err) {
|
||||
error = err
|
||||
}
|
||||
expect(error).toBeDefined()
|
||||
})
|
||||
|
||||
it("check usage quota attempts", async () => {
|
||||
env.CLOUD = true
|
||||
await setup.runStep(setup.actions.DELETE_ROW.stepId, inputs)
|
||||
expect(usageQuota.update).toHaveBeenCalledWith(setup.apiKey, "rows", -1)
|
||||
env.CLOUD = false
|
||||
})
|
||||
|
||||
it("should check invalid inputs return an error", async () => {
|
||||
const res = await setup.runStep(setup.actions.DELETE_ROW.stepId, {})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
|
||||
it("should return an error when table doesn't exist", async () => {
|
||||
const res = await setup.runStep(setup.actions.DELETE_ROW.stepId, {
|
||||
tableId: "invalid",
|
||||
id: "invalid",
|
||||
revision: "invalid",
|
||||
})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,48 @@
|
|||
const setup = require("./utilities")
|
||||
const { LogicConditions } = require("../steps/filter")
|
||||
|
||||
describe("test the filter logic", () => {
|
||||
async function checkFilter(field, condition, value, pass = true) {
|
||||
let res = await setup.runStep(setup.logic.FILTER.stepId,
|
||||
{ field, condition, value }
|
||||
)
|
||||
expect(res.success).toEqual(pass)
|
||||
}
|
||||
|
||||
it("should be able test equality", async () => {
|
||||
await checkFilter("hello", LogicConditions.EQUAL, "hello", true)
|
||||
await checkFilter("hello", LogicConditions.EQUAL, "no", false)
|
||||
})
|
||||
|
||||
it("should be able to test greater than", async () => {
|
||||
await checkFilter(10, LogicConditions.GREATER_THAN, 5, true)
|
||||
await checkFilter(10, LogicConditions.GREATER_THAN, 15, false)
|
||||
})
|
||||
|
||||
it("should be able to test less than", async () => {
|
||||
await checkFilter(5, LogicConditions.LESS_THAN, 10, true)
|
||||
await checkFilter(15, LogicConditions.LESS_THAN, 10, false)
|
||||
})
|
||||
|
||||
it("should be able to in-equality", async () => {
|
||||
await checkFilter("hello", LogicConditions.NOT_EQUAL, "no", true)
|
||||
await checkFilter(10, LogicConditions.NOT_EQUAL, 10, false)
|
||||
})
|
||||
|
||||
it("check number coercion", async () => {
|
||||
await checkFilter("10", LogicConditions.GREATER_THAN, "5", true)
|
||||
})
|
||||
|
||||
it("check date coercion", async () => {
|
||||
await checkFilter(
|
||||
(new Date()).toISOString(),
|
||||
LogicConditions.GREATER_THAN,
|
||||
(new Date(-10000)).toISOString(),
|
||||
true
|
||||
)
|
||||
})
|
||||
|
||||
it("check objects always false", async () => {
|
||||
await checkFilter({}, LogicConditions.EQUAL, {}, false)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,39 @@
|
|||
const setup = require("./utilities")
|
||||
const fetch = require("node-fetch")
|
||||
|
||||
jest.mock("node-fetch")
|
||||
|
||||
describe("test the outgoing webhook action", () => {
|
||||
let inputs
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
inputs = {
|
||||
requestMethod: "POST",
|
||||
url: "www.test.com",
|
||||
requestBody: JSON.stringify({
|
||||
a: 1,
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to run the action", async () => {
|
||||
const res = await setup.runStep(setup.actions.OUTGOING_WEBHOOK.stepId, inputs)
|
||||
expect(res.success).toEqual(true)
|
||||
expect(res.response.url).toEqual("http://www.test.com")
|
||||
expect(res.response.method).toEqual("POST")
|
||||
expect(res.response.body.a).toEqual(1)
|
||||
})
|
||||
|
||||
it("should return an error if something goes wrong in fetch", async () => {
|
||||
const res = await setup.runStep(setup.actions.OUTGOING_WEBHOOK.stepId, {
|
||||
requestMethod: "GET",
|
||||
url: "www.invalid.com"
|
||||
})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
|
||||
})
|
|
@ -0,0 +1,36 @@
|
|||
const setup = require("./utilities")
|
||||
|
||||
jest.mock("@sendgrid/mail")
|
||||
|
||||
describe("test the send email action", () => {
|
||||
let inputs
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
inputs = {
|
||||
to: "me@test.com",
|
||||
from: "budibase@test.com",
|
||||
subject: "Testing",
|
||||
text: "Email contents",
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to run the action", async () => {
|
||||
const res = await setup.runStep(setup.actions.SEND_EMAIL.stepId, inputs)
|
||||
expect(res.success).toEqual(true)
|
||||
// the mocked module throws back the input
|
||||
expect(res.response.to).toEqual("me@test.com")
|
||||
})
|
||||
|
||||
it("should return an error if input an invalid email address", async () => {
|
||||
const res = await setup.runStep(setup.actions.SEND_EMAIL.stepId, {
|
||||
...inputs,
|
||||
to: "invalid@test.com",
|
||||
})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
|
||||
})
|
|
@ -0,0 +1,45 @@
|
|||
const env = require("../../environment")
|
||||
const setup = require("./utilities")
|
||||
|
||||
describe("test the update row action", () => {
|
||||
let table, row, inputs
|
||||
let config = setup.getConfig()
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
table = await config.createTable()
|
||||
row = await config.createRow()
|
||||
inputs = {
|
||||
rowId: row._id,
|
||||
row: {
|
||||
...row,
|
||||
name: "Updated name",
|
||||
// put a falsy option in to be removed
|
||||
description: "",
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
it("should be able to run the action", async () => {
|
||||
const res = await setup.runStep(setup.actions.UPDATE_ROW.stepId, inputs)
|
||||
expect(res.success).toEqual(true)
|
||||
const updatedRow = await config.getRow(table._id, res.id)
|
||||
expect(updatedRow.name).toEqual("Updated name")
|
||||
expect(updatedRow.description).not.toEqual("")
|
||||
})
|
||||
|
||||
it("should check invalid inputs return an error", async () => {
|
||||
const res = await setup.runStep(setup.actions.UPDATE_ROW.stepId, {})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
|
||||
it("should return an error when table doesn't exist", async () => {
|
||||
const res = await setup.runStep(setup.actions.UPDATE_ROW.stepId, {
|
||||
row: { _id: "invalid" },
|
||||
rowId: "invalid",
|
||||
})
|
||||
expect(res.success).toEqual(false)
|
||||
})
|
||||
})
|
|
@ -0,0 +1,43 @@
|
|||
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
||||
const actions = require("../../actions")
|
||||
const logic = require("../../logic")
|
||||
const emitter = require("../../../events/index")
|
||||
|
||||
let config
|
||||
|
||||
exports.getConfig = () => {
|
||||
if (!config) {
|
||||
config = new TestConfig(false)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
exports.afterAll = () => {
|
||||
config.end()
|
||||
}
|
||||
|
||||
exports.runStep = async function runStep(stepId, inputs) {
|
||||
let step
|
||||
if (
|
||||
Object.values(exports.actions)
|
||||
.map(action => action.stepId)
|
||||
.includes(stepId)
|
||||
) {
|
||||
step = await actions.getAction(stepId)
|
||||
} else {
|
||||
step = logic.getLogic(stepId)
|
||||
}
|
||||
expect(step).toBeDefined()
|
||||
return step({
|
||||
inputs,
|
||||
appId: config ? config.getAppId() : null,
|
||||
// don't really need an API key, mocked out usage quota, not being tested here
|
||||
apiKey: exports.apiKey,
|
||||
emitter,
|
||||
})
|
||||
}
|
||||
|
||||
exports.apiKey = "test"
|
||||
|
||||
exports.actions = actions.BUILTIN_DEFINITIONS
|
||||
exports.logic = logic.BUILTIN_DEFINITIONS
|
|
@ -225,6 +225,7 @@ async function queueRelevantRowAutomations(event, eventType) {
|
|||
}
|
||||
|
||||
emitter.on("row:save", async function(event) {
|
||||
/* istanbul ignore next */
|
||||
if (!event || !event.row || !event.row.tableId) {
|
||||
return
|
||||
}
|
||||
|
@ -232,6 +233,7 @@ emitter.on("row:save", async function(event) {
|
|||
})
|
||||
|
||||
emitter.on("row:update", async function(event) {
|
||||
/* istanbul ignore next */
|
||||
if (!event || !event.row || !event.row.tableId) {
|
||||
return
|
||||
}
|
||||
|
@ -239,6 +241,7 @@ emitter.on("row:update", async function(event) {
|
|||
})
|
||||
|
||||
emitter.on("row:delete", async function(event) {
|
||||
/* istanbul ignore next */
|
||||
if (!event || !event.row || !event.row.tableId) {
|
||||
return
|
||||
}
|
||||
|
@ -272,6 +275,7 @@ async function fillRowOutput(automation, params) {
|
|||
}
|
||||
params.row = row
|
||||
} catch (err) {
|
||||
/* istanbul ignore next */
|
||||
throw "Failed to find table for trigger"
|
||||
}
|
||||
return params
|
||||
|
@ -297,6 +301,7 @@ module.exports.externalTrigger = async function(automation, params) {
|
|||
automationQueue.add({ automation, event: params })
|
||||
}
|
||||
|
||||
module.exports.fillRowOutput = fillRowOutput
|
||||
module.exports.automationQueue = automationQueue
|
||||
|
||||
module.exports.BUILTIN_DEFINITIONS = BUILTIN_DEFINITIONS
|
||||
|
|
|
@ -30,6 +30,7 @@ const Pouch = PouchDB.defaults(POUCH_DB_DEFAULTS)
|
|||
allDbs(Pouch)
|
||||
|
||||
// replicate your local levelDB pouch to a running HTTP compliant couch or pouchdb server.
|
||||
/* istanbul ignore next */
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function replicateLocal() {
|
||||
Pouch.allDbs().then(dbs => {
|
||||
|
|
|
@ -3,7 +3,7 @@ const usageQuota = require("../../utilities/usageQuota")
|
|||
const CouchDB = require("../../db")
|
||||
const env = require("../../environment")
|
||||
|
||||
jest.mock("../../db");
|
||||
jest.mock("../../db")
|
||||
jest.mock("../../utilities/usageQuota")
|
||||
jest.mock("../../environment")
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
### Self hosting
|
||||
This directory contains utilities that are needed for self hosted platforms to operate.
|
||||
These will mostly be utilities, necessary to the operation of the server e.g. storing self
|
||||
hosting specific options and attributes to CouchDB.
|
||||
|
||||
All the internal operations should be exposed through the `index.js` so importing
|
||||
the self host directory should give you everything you need.
|
|
@ -1,44 +0,0 @@
|
|||
const CouchDB = require("../db")
|
||||
const env = require("../environment")
|
||||
const newid = require("../db/newid")
|
||||
|
||||
const SELF_HOST_DB = "self-host-db"
|
||||
const SELF_HOST_DOC = "self-host-info"
|
||||
|
||||
async function createSelfHostDB(db) {
|
||||
await db.put({
|
||||
_id: "_design/database",
|
||||
views: {},
|
||||
})
|
||||
const selfHostInfo = {
|
||||
_id: SELF_HOST_DOC,
|
||||
apiKeyId: newid(),
|
||||
}
|
||||
await db.put(selfHostInfo)
|
||||
return selfHostInfo
|
||||
}
|
||||
|
||||
exports.init = async () => {
|
||||
if (!env.SELF_HOSTED) {
|
||||
return
|
||||
}
|
||||
const db = new CouchDB(SELF_HOST_DB)
|
||||
try {
|
||||
await db.get(SELF_HOST_DOC)
|
||||
} catch (err) {
|
||||
// failed to retrieve
|
||||
if (err.status === 404) {
|
||||
await createSelfHostDB(db)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports.getSelfHostInfo = async () => {
|
||||
const db = new CouchDB(SELF_HOST_DB)
|
||||
return db.get(SELF_HOST_DOC)
|
||||
}
|
||||
|
||||
exports.getSelfHostAPIKey = async () => {
|
||||
const info = await exports.getSelfHostInfo()
|
||||
return info ? info.apiKeyId : null
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
const { BUILTIN_ROLE_IDS } = require("../../../../utilities/security/roles")
|
||||
const { BUILTIN_ROLE_IDS } = require("../../utilities/security/roles")
|
||||
const jwt = require("jsonwebtoken")
|
||||
const env = require("../../../../environment")
|
||||
const env = require("../../environment")
|
||||
const {
|
||||
basicTable,
|
||||
basicRow,
|
||||
|
@ -15,18 +15,20 @@ const {
|
|||
const controllers = require("./controllers")
|
||||
const supertest = require("supertest")
|
||||
const fs = require("fs")
|
||||
const { budibaseAppsDir } = require("../../../../utilities/budibaseDir")
|
||||
const { budibaseAppsDir } = require("../../utilities/budibaseDir")
|
||||
const { join } = require("path")
|
||||
|
||||
const EMAIL = "babs@babs.com"
|
||||
const PASSWORD = "babs_password"
|
||||
|
||||
class TestConfiguration {
|
||||
constructor() {
|
||||
env.PORT = 4002
|
||||
this.server = require("../../../../app")
|
||||
// we need the request for logging in, involves cookies, hard to fake
|
||||
this.request = supertest(this.server)
|
||||
constructor(openServer = true) {
|
||||
if (openServer) {
|
||||
env.PORT = 4002
|
||||
this.server = require("../../app")
|
||||
// we need the request for logging in, involves cookies, hard to fake
|
||||
this.request = supertest(this.server)
|
||||
}
|
||||
this.appId = null
|
||||
this.allApps = []
|
||||
}
|
||||
|
@ -61,7 +63,9 @@ class TestConfiguration {
|
|||
}
|
||||
|
||||
end() {
|
||||
this.server.close()
|
||||
if (this.server) {
|
||||
this.server.close()
|
||||
}
|
||||
const appDir = budibaseAppsDir()
|
||||
const files = fs.readdirSync(appDir)
|
||||
for (let file of files) {
|
||||
|
@ -163,6 +167,17 @@ class TestConfiguration {
|
|||
return this._req(config, { tableId: this.table._id }, controllers.row.save)
|
||||
}
|
||||
|
||||
async getRow(tableId, rowId) {
|
||||
return this._req(null, { tableId, rowId }, controllers.row.find)
|
||||
}
|
||||
|
||||
async getRows(tableId) {
|
||||
if (!tableId && this.table) {
|
||||
tableId = this.table._id
|
||||
}
|
||||
return this._req(null, { tableId }, controllers.row.fetchTableRows)
|
||||
}
|
||||
|
||||
async createRole(config = null) {
|
||||
config = config || basicRole()
|
||||
return this._req(config, null, controllers.role.save)
|
||||
|
@ -187,6 +202,7 @@ class TestConfiguration {
|
|||
const view = config || {
|
||||
map: "function(doc) { emit(doc[doc.key], doc._id); } ",
|
||||
tableId: this.table._id,
|
||||
name: "ViewTest",
|
||||
}
|
||||
return this._req(view, null, controllers.view.save)
|
||||
}
|
||||
|
@ -285,6 +301,9 @@ class TestConfiguration {
|
|||
}
|
||||
|
||||
async login(email, password) {
|
||||
if (!this.request) {
|
||||
throw "Server has not been opened, cannot login."
|
||||
}
|
||||
if (!email || !password) {
|
||||
await this.createUser()
|
||||
email = EMAIL
|
|
@ -0,0 +1,15 @@
|
|||
module.exports = {
|
||||
table: require("../../api/controllers/table"),
|
||||
row: require("../../api/controllers/row"),
|
||||
role: require("../../api/controllers/role"),
|
||||
perms: require("../../api/controllers/permission"),
|
||||
view: require("../../api/controllers/view"),
|
||||
app: require("../../api/controllers/application"),
|
||||
user: require("../../api/controllers/user"),
|
||||
automation: require("../../api/controllers/automation"),
|
||||
datasource: require("../../api/controllers/datasource"),
|
||||
query: require("../../api/controllers/query"),
|
||||
screen: require("../../api/controllers/screen"),
|
||||
webhook: require("../../api/controllers/webhook"),
|
||||
layout: require("../../api/controllers/layout"),
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
exports.makePartial = obj => {
|
||||
const newObj = {}
|
||||
for (let key of Object.keys(obj)) {
|
||||
if (typeof obj[key] === "object") {
|
||||
newObj[key] = exports.makePartial(obj[key])
|
||||
} else {
|
||||
newObj[key] = obj[key]
|
||||
}
|
||||
}
|
||||
return expect.objectContaining(newObj)
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
const { BUILTIN_ROLE_IDS } = require("../../../../utilities/security/roles")
|
||||
const { BUILTIN_ROLE_IDS } = require("../../utilities/security/roles")
|
||||
const {
|
||||
BUILTIN_PERMISSION_IDS,
|
||||
} = require("../../../../utilities/security/permissions")
|
||||
const { createHomeScreen } = require("../../../../constants/screens")
|
||||
const { EMPTY_LAYOUT } = require("../../../../constants/layouts")
|
||||
} = require("../../utilities/security/permissions")
|
||||
const { createHomeScreen } = require("../../constants/screens")
|
||||
const { EMPTY_LAYOUT } = require("../../constants/layouts")
|
||||
const { cloneDeep } = require("lodash/fp")
|
||||
|
||||
exports.basicTable = () => {
|
|
@ -7,6 +7,8 @@ const packageJson = require("../../package.json")
|
|||
|
||||
const streamPipeline = promisify(stream.pipeline)
|
||||
|
||||
// can't really test this due to the downloading nature of it, wouldn't be a great test case
|
||||
/* istanbul ignore next */
|
||||
exports.downloadExtractComponentLibraries = async appFolder => {
|
||||
const LIBRARIES = ["standard-components"]
|
||||
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
const statusCodes = require("./statusCodes")
|
||||
|
||||
const errorWithStatus = (message, statusCode) => {
|
||||
const e = new Error(message)
|
||||
e.statusCode = statusCode
|
||||
return e
|
||||
}
|
||||
|
||||
module.exports.unauthorized = message =>
|
||||
errorWithStatus(message, statusCodes.UNAUTHORIZED)
|
||||
|
||||
module.exports.forbidden = message =>
|
||||
errorWithStatus(message, statusCodes.FORBIDDEN)
|
||||
|
||||
module.exports.notfound = message =>
|
||||
errorWithStatus(message, statusCodes.NOT_FOUND)
|
|
@ -12,6 +12,7 @@ exports.getRoutingInfo = async appId => {
|
|||
return allRouting.rows.map(row => row.value)
|
||||
} catch (err) {
|
||||
// check if the view doesn't exist, it should for all new instances
|
||||
/* istanbul ignore next */
|
||||
if (err != null && err.name === "not_found") {
|
||||
await createRoutingView(appId)
|
||||
return exports.getRoutingInfo(appId)
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
const { apiKeyTable } = require("../../db/dynamoClient")
|
||||
const env = require("../../environment")
|
||||
const { getSelfHostAPIKey } = require("../../selfhost")
|
||||
|
||||
/**
|
||||
* This file purely exists so that we can centralise all logic pertaining to API keys, as their usage differs
|
||||
|
@ -8,16 +7,13 @@ const { getSelfHostAPIKey } = require("../../selfhost")
|
|||
*/
|
||||
|
||||
exports.isAPIKeyValid = async apiKeyId => {
|
||||
if (env.CLOUD && !env.SELF_HOSTED) {
|
||||
if (!env.SELF_HOSTED) {
|
||||
let apiKeyInfo = await apiKeyTable.get({
|
||||
primary: apiKeyId,
|
||||
})
|
||||
return apiKeyInfo != null
|
||||
}
|
||||
if (env.SELF_HOSTED) {
|
||||
const selfHostKey = await getSelfHostAPIKey()
|
||||
} else {
|
||||
// if the api key supplied is correct then return structure similar
|
||||
return apiKeyId === selfHostKey ? { pk: apiKeyId } : null
|
||||
return apiKeyId === env.HOSTING_KEY
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue