From 1b1ed8a82324d9a90300199fc8df9458814adb3f Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 8 Mar 2021 15:46:12 +0000 Subject: [PATCH] self hosted middleware test --- .../src/middleware/tests/TestConfiguration.js | 247 ++++++++++++++++++ .../server/src/middleware/tests/authorized.js | 0 .../src/middleware/tests/selfhost.spec.js | 68 ++--- 3 files changed, 281 insertions(+), 34 deletions(-) create mode 100644 packages/server/src/middleware/tests/TestConfiguration.js create mode 100644 packages/server/src/middleware/tests/authorized.js diff --git a/packages/server/src/middleware/tests/TestConfiguration.js b/packages/server/src/middleware/tests/TestConfiguration.js new file mode 100644 index 0000000000..8092130ce3 --- /dev/null +++ b/packages/server/src/middleware/tests/TestConfiguration.js @@ -0,0 +1,247 @@ +// const { BUILTIN_ROLE_IDS } = require("../../../../utilities/security/roles") +// const jwt = require("jsonwebtoken") +// const env = require("../../../../environment") +// const { +// basicTable, +// basicRow, +// basicRole, +// basicAutomation, +// basicDatasource, +// basicQuery, +// } = require("./structures") +// const controllers = require("./controllers") +// const supertest = require("supertest") + +// 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) +// this.appId = null +// } + +// getRequest() { +// return this.request +// } + +// getAppId() { +// return this.appId +// } + +// async _req(config, params, controlFunc) { +// const request = {} +// // fake cookies, we don't need them +// request.cookies = { set: () => {}, get: () => {} } +// request.config = { jwtSecret: env.JWT_SECRET } +// request.appId = this.appId +// request.user = { appId: this.appId } +// request.request = { +// body: config, +// } +// if (params) { +// request.params = params +// } +// await controlFunc(request) +// return request.body +// } + +// async init(appName = "test_application") { +// return this.createApp(appName) +// } + +// end() { +// this.server.close() +// } + +// defaultHeaders() { +// const builderUser = { +// userId: "BUILDER", +// roleId: BUILTIN_ROLE_IDS.BUILDER, +// } +// const builderToken = jwt.sign(builderUser, env.JWT_SECRET) +// const headers = { +// Accept: "application/json", +// Cookie: [`budibase:builder:local=${builderToken}`], +// } +// if (this.appId) { +// headers["x-budibase-app-id"] = this.appId +// } +// return headers +// } + +// publicHeaders() { +// const headers = { +// Accept: "application/json", +// } +// if (this.appId) { +// headers["x-budibase-app-id"] = this.appId +// } +// return headers +// } + +// async callMiddleware() { +// this.middleware(this.ctx, next) +// return this.app +// } + +// async updateTable(config = null) { +// config = config || basicTable() +// this.table = await this._req(config, null, controllers.table.save) +// return this.table +// } + +// async createTable(config = null) { +// if (config != null && config._id) { +// delete config._id +// } +// return this.updateTable(config) +// } + +// async getTable(tableId = null) { +// tableId = tableId || this.table._id +// return this._req(null, { id: tableId }, controllers.table.find) +// } + +// async createLinkedTable() { +// if (!this.table) { +// throw "Must have created a table first." +// } +// const tableConfig = basicTable() +// tableConfig.primaryDisplay = "name" +// tableConfig.schema.link = { +// type: "link", +// fieldName: "link", +// tableId: this.table._id, +// } +// const linkedTable = await this.createTable(tableConfig) +// this.linkedTable = linkedTable +// return linkedTable +// } + +// async createAttachmentTable() { +// const table = basicTable() +// table.schema.attachment = { +// type: "attachment", +// } +// return this.createTable(table) +// } + +// async createRow(config = null) { +// if (!this.table) { +// throw "Test requires table to be configured." +// } +// config = config || basicRow(this.table._id) +// return this._req(config, { tableId: this.table._id }, controllers.row.save) +// } + +// async createRole(config = null) { +// config = config || basicRole() +// return this._req(config, null, controllers.role.save) +// } + +// async addPermission(roleId, resourceId, level = "read") { +// return this._req( +// null, +// { +// roleId, +// resourceId, +// level, +// }, +// controllers.perms.addPermission +// ) +// } + +// async createView(config) { +// if (!this.table) { +// throw "Test requires table to be configured." +// } +// const view = config || { +// map: "function(doc) { emit(doc[doc.key], doc._id); } ", +// tableId: this.table._id, +// } +// return this._req(view, null, controllers.view.save) +// } + +// async createAutomation(config) { +// config = config || basicAutomation() +// if (config._rev) { +// delete config._rev +// } +// this.automation = ( +// await this._req(config, null, controllers.automation.create) +// ).automation +// return this.automation +// } + +// async getAllAutomations() { +// return this._req(null, null, controllers.automation.fetch) +// } + +// async deleteAutomation(automation = null) { +// automation = automation || this.automation +// if (!automation) { +// return +// } +// return this._req( +// null, +// { id: automation._id, rev: automation._rev }, +// controllers.automation.destroy +// ) +// } + +// async createDatasource(config = null) { +// config = config || basicDatasource() +// this.datasource = await this._req(config, null, controllers.datasource.save) +// return this.datasource +// } + +// async createQuery(config = null) { +// if (!this.datasource && !config) { +// throw "No data source created for query." +// } +// config = config || basicQuery(this.datasource._id) +// return this._req(config, null, controllers.query.save) +// } + +// async createUser( +// email = EMAIL, +// password = PASSWORD, +// roleId = BUILTIN_ROLE_IDS.POWER +// ) { +// return this._req( +// { +// email, +// password, +// roleId, +// }, +// null, +// controllers.user.create +// ) +// } + +// async login(email, password) { +// if (!email || !password) { +// await this.createUser() +// email = EMAIL +// password = PASSWORD +// } +// const result = await this.request +// .post(`/api/authenticate`) +// .set({ +// "x-budibase-app-id": this.appId, +// }) +// .send({ email, password }) + +// // returning necessary request headers +// return { +// Accept: "application/json", +// Cookie: result.headers["set-cookie"], +// } +// } +// } + +// module.exports = TestConfiguration diff --git a/packages/server/src/middleware/tests/authorized.js b/packages/server/src/middleware/tests/authorized.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/server/src/middleware/tests/selfhost.spec.js b/packages/server/src/middleware/tests/selfhost.spec.js index 0f721bc890..9d66f44463 100644 --- a/packages/server/src/middleware/tests/selfhost.spec.js +++ b/packages/server/src/middleware/tests/selfhost.spec.js @@ -1,43 +1,43 @@ -const { BUILTIN_ROLE_IDS } = require("../../../utilities/security/roles") -const { checkPermissionsEndpoint } = require("./utilities/TestFunctions") -const { basicUser } = require("./utilities/structures") -const setup = require("./utilities") +const selfHostMiddleware = require("../selfhost"); +const env = require("../../environment") +const hosting = require("../../utilities/builder/hosting") +jest.mock("../../environment") +jest.mock("../../utilities/builder/hosting") describe("Self host middleware", () => { - let request = setup.getRequest() - let config = setup.getConfig() + const next = jest.fn() + const throwMock = jest.fn() - afterAll(setup.afterAll) - - beforeEach(async () => { - await config.init() + afterEach(() => { + jest.clearAllMocks() }) - describe("fetch", () => { - it("returns a list of users from an instance db", async () => { - await config.createUser("brenda@brenda.com", "brendas_password") - await config.createUser("pam@pam.com", "pam_password") - const res = await request - .get(`/api/users`) - .set(config.defaultHeaders()) - .expect("Content-Type", /json/) - .expect(200) + it("calls next() when CLOUD and SELF_HOSTED env vars are set", async () => { + env.CLOUD = 1 + env.SELF_HOSTED = 1 - expect(res.body.length).toBe(2) - expect(res.body.find(u => u.email === "brenda@brenda.com")).toBeDefined() - expect(res.body.find(u => u.email === "pam@pam.com")).toBeDefined() - }) + await selfHostMiddleware({}, next) + expect(next).toHaveBeenCalled() + }) - it("should apply authorization to endpoint", async () => { - await config.createUser("brenda@brenda.com", "brendas_password") - await checkPermissionsEndpoint({ - config, - request, - method: "GET", - url: `/api/users`, - passRole: BUILTIN_ROLE_IDS.ADMIN, - failRole: BUILTIN_ROLE_IDS.PUBLIC, - }) - }) + it("throws when hostingInfo type is cloud", async () => { + env.CLOUD = 0 + env.SELF_HOSTED = 0 + + hosting.getHostingInfo.mockImplementationOnce(() => ({ type: hosting.HostingTypes.CLOUD })) + + await selfHostMiddleware({ throw: throwMock }, next) + expect(throwMock).toHaveBeenCalledWith(400, "Endpoint unavailable in cloud hosting.") + expect(next).not.toHaveBeenCalled() + }) + + it("calls the self hosting middleware to pass through to next() when the hostingInfo type is self", async () => { + env.CLOUD = 0 + env.SELF_HOSTED = 0 + + hosting.getHostingInfo.mockImplementationOnce(() => ({ type: hosting.HostingTypes.SELF })) + + await selfHostMiddleware({}, next) + expect(next).toHaveBeenCalled() }) })