Tests updating, all now passing, fixed some issues discovered by them.
This commit is contained in:
parent
d3a90acc55
commit
d5f8cc1023
|
@ -59,6 +59,10 @@ exports.updateTenantId = tenantId => {
|
|||
exports.updateAppId = appId => {
|
||||
try {
|
||||
cls.setOnContext(ContextKeys.APP_ID, appId)
|
||||
cls.setOnContext(ContextKeys.PROD_DB, null)
|
||||
cls.setOnContext(ContextKeys.DEV_DB, null)
|
||||
cls.setOnContext(ContextKeys.CURRENT_DB, null)
|
||||
cls.setOnContext(ContextKeys.DB_OPTS, null)
|
||||
} catch (err) {
|
||||
if (env.isTest()) {
|
||||
TEST_APP_ID = appId
|
||||
|
|
|
@ -6,6 +6,7 @@ const db = jest.fn(() => {
|
|||
}
|
||||
})
|
||||
jest.mock("../../../../../db", () => db)
|
||||
require("@budibase/backend-core").init(require("../../../../../db"))
|
||||
|
||||
const { RestImporter } = require("../index")
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ exports.fetch = async ctx => {
|
|||
}
|
||||
|
||||
exports.clientFetch = async ctx => {
|
||||
const routing = await getRoutingStructure(ctx.appId)
|
||||
const routing = await getRoutingStructure()
|
||||
let roleId = ctx.user.role._id
|
||||
const roleIds = await getUserRoleHierarchy(roleId)
|
||||
for (let topLevel of Object.values(routing.routes)) {
|
||||
|
|
|
@ -145,6 +145,7 @@ describe("/automations", () => {
|
|||
let table = await config.createTable()
|
||||
automation.definition.trigger.inputs.tableId = table._id
|
||||
automation.definition.steps[0].inputs.row.tableId = table._id
|
||||
automation.appId = config.appId
|
||||
automation = await config.createAutomation(automation)
|
||||
await setup.delay(500)
|
||||
const res = await testAutomation(config, automation)
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
const setup = require("./utilities")
|
||||
const { basicScreen } = setup.structures
|
||||
const { checkBuilderEndpoint } = require("./utilities/TestFunctions")
|
||||
const { checkBuilderEndpoint, runInProd } = require("./utilities/TestFunctions")
|
||||
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
|
||||
const { doInAppContext } = require("@budibase/backend-core/context")
|
||||
|
||||
const route = "/test"
|
||||
|
||||
// there are checks which are disabled in test env,
|
||||
// these checks need to be enabled for this test
|
||||
|
||||
|
||||
describe("/routing", () => {
|
||||
let request = setup.getRequest()
|
||||
let config = setup.getConfig()
|
||||
|
@ -26,20 +31,24 @@ describe("/routing", () => {
|
|||
|
||||
describe("fetch", () => {
|
||||
it("prevents a public user from accessing development app", async () => {
|
||||
await request
|
||||
.get(`/api/routing/client`)
|
||||
.set(config.publicHeaders({ prodApp: false }))
|
||||
.expect(302)
|
||||
await runInProd(() => {
|
||||
return request
|
||||
.get(`/api/routing/client`)
|
||||
.set(config.publicHeaders({ prodApp: false }))
|
||||
.expect(302)
|
||||
})
|
||||
})
|
||||
|
||||
it("prevents a non builder from accessing development app", async () => {
|
||||
await request
|
||||
.get(`/api/routing/client`)
|
||||
.set(await config.roleHeaders({
|
||||
roleId: BUILTIN_ROLE_IDS.BASIC,
|
||||
prodApp: false
|
||||
}))
|
||||
.expect(302)
|
||||
await runInProd(async () => {
|
||||
return request
|
||||
.get(`/api/routing/client`)
|
||||
.set(await config.roleHeaders({
|
||||
roleId: BUILTIN_ROLE_IDS.BASIC,
|
||||
prodApp: false
|
||||
}))
|
||||
.expect(302)
|
||||
})
|
||||
})
|
||||
it("returns the correct routing for basic user", async () => {
|
||||
const res = await request
|
||||
|
|
|
@ -3,7 +3,8 @@ const appController = require("../../../controllers/application")
|
|||
const { AppStatus } = require("../../../../db/utils")
|
||||
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
|
||||
const { TENANT_ID } = require("../../../../tests/utilities/structures")
|
||||
const { getAppDB } = require("@budibase/backend-core/context")
|
||||
const { getAppDB, doInAppContext } = require("@budibase/backend-core/context")
|
||||
const env = require("../../../../environment")
|
||||
|
||||
function Request(appId, params) {
|
||||
this.appId = appId
|
||||
|
@ -11,9 +12,15 @@ function Request(appId, params) {
|
|||
this.request = {}
|
||||
}
|
||||
|
||||
function runRequest(appId, controlFunc, request) {
|
||||
return doInAppContext(appId, async () => {
|
||||
return controlFunc(request)
|
||||
})
|
||||
}
|
||||
|
||||
exports.getAllTableRows = async config => {
|
||||
const req = new Request(config.appId, { tableId: config.table._id })
|
||||
await rowController.fetch(req)
|
||||
await runRequest(config.appId, rowController.fetch, req)
|
||||
return req.body
|
||||
}
|
||||
|
||||
|
@ -26,14 +33,17 @@ exports.clearAllApps = async (tenantId = TENANT_ID) => {
|
|||
}
|
||||
for (let app of apps) {
|
||||
const { appId } = app
|
||||
await appController.delete(new Request(null, { appId }))
|
||||
const req = new Request(null, { appId })
|
||||
await runRequest(appId, appController.delete, req)
|
||||
}
|
||||
}
|
||||
|
||||
exports.clearAllAutomations = async config => {
|
||||
const automations = await config.getAllAutomations()
|
||||
for (let auto of automations) {
|
||||
await config.deleteAutomation(auto)
|
||||
await doInAppContext(config.appId, async () => {
|
||||
await config.deleteAutomation(auto)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,15 +111,27 @@ exports.getDB = () => {
|
|||
}
|
||||
|
||||
exports.testAutomation = async (config, automation) => {
|
||||
return await config.request
|
||||
.post(`/api/automations/${automation._id}/test`)
|
||||
.send({
|
||||
row: {
|
||||
name: "Test",
|
||||
description: "TEST",
|
||||
},
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
return runRequest(automation.appId, async () => {
|
||||
return await config.request
|
||||
.post(`/api/automations/${automation._id}/test`)
|
||||
.send({
|
||||
row: {
|
||||
name: "Test",
|
||||
description: "TEST",
|
||||
},
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
})
|
||||
}
|
||||
|
||||
exports.runInProd = async func => {
|
||||
const nodeEnv = env.NODE_ENV
|
||||
const workerId = env.JEST_WORKER_ID
|
||||
env._set("NODE_ENV", "PRODUCTION")
|
||||
env._set("JEST_WORKER_ID", null)
|
||||
await func()
|
||||
env._set("NODE_ENV", nodeEnv)
|
||||
env._set("JEST_WORKER_ID", workerId)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,8 @@ function isTest() {
|
|||
return (
|
||||
process.env.NODE_ENV === "jest" ||
|
||||
process.env.NODE_ENV === "cypress" ||
|
||||
process.env.JEST_WORKER_ID != null
|
||||
(process.env.JEST_WORKER_ID != null &&
|
||||
process.env.JEST_WORKER_ID !== "null")
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ const { isUserInAppTenant } = require("@budibase/backend-core/tenancy")
|
|||
const { getCachedSelf } = require("../utilities/global")
|
||||
const env = require("../environment")
|
||||
const { isWebhookEndpoint } = require("./utils")
|
||||
const { doInAppContext } = require("@budibase/backend-core/context")
|
||||
|
||||
module.exports = async (ctx, next) => {
|
||||
// try to get the appID from the request
|
||||
|
@ -40,13 +41,15 @@ module.exports = async (ctx, next) => {
|
|||
}
|
||||
|
||||
// deny access to application preview
|
||||
if (
|
||||
isDevAppID(requestAppId) &&
|
||||
!isWebhookEndpoint(ctx) &&
|
||||
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
||||
) {
|
||||
clearCookie(ctx, Cookies.CurrentApp)
|
||||
return ctx.redirect("/")
|
||||
if (!env.isTest()) {
|
||||
if (
|
||||
isDevAppID(requestAppId) &&
|
||||
!isWebhookEndpoint(ctx) &&
|
||||
(!ctx.user || !ctx.user.builder || !ctx.user.builder.global)
|
||||
) {
|
||||
clearCookie(ctx, Cookies.CurrentApp)
|
||||
return ctx.redirect("/")
|
||||
}
|
||||
}
|
||||
|
||||
let appId,
|
||||
|
@ -67,44 +70,46 @@ module.exports = async (ctx, next) => {
|
|||
return next()
|
||||
}
|
||||
|
||||
let noCookieSet = false
|
||||
// if the user not in the right tenant then make sure they have no permissions
|
||||
// need to judge this only based on the request app ID,
|
||||
if (
|
||||
env.MULTI_TENANCY &&
|
||||
ctx.user &&
|
||||
requestAppId &&
|
||||
!isUserInAppTenant(requestAppId)
|
||||
) {
|
||||
// don't error, simply remove the users rights (they are a public user)
|
||||
delete ctx.user.builder
|
||||
delete ctx.user.admin
|
||||
delete ctx.user.roles
|
||||
roleId = BUILTIN_ROLE_IDS.PUBLIC
|
||||
noCookieSet = true
|
||||
}
|
||||
|
||||
ctx.appId = appId
|
||||
if (roleId) {
|
||||
ctx.roleId = roleId
|
||||
const userId = ctx.user ? generateUserMetadataID(ctx.user._id) : null
|
||||
ctx.user = {
|
||||
...ctx.user,
|
||||
// override userID with metadata one
|
||||
_id: userId,
|
||||
userId,
|
||||
roleId,
|
||||
role: await getRole(appId, roleId),
|
||||
return doInAppContext(appId, async () => {
|
||||
let noCookieSet = false
|
||||
// if the user not in the right tenant then make sure they have no permissions
|
||||
// need to judge this only based on the request app ID,
|
||||
if (
|
||||
env.MULTI_TENANCY &&
|
||||
ctx.user &&
|
||||
requestAppId &&
|
||||
!isUserInAppTenant(requestAppId)
|
||||
) {
|
||||
// don't error, simply remove the users rights (they are a public user)
|
||||
delete ctx.user.builder
|
||||
delete ctx.user.admin
|
||||
delete ctx.user.roles
|
||||
roleId = BUILTIN_ROLE_IDS.PUBLIC
|
||||
noCookieSet = true
|
||||
}
|
||||
}
|
||||
if (
|
||||
(requestAppId !== appId ||
|
||||
appCookie == null ||
|
||||
appCookie.appId !== requestAppId) &&
|
||||
!noCookieSet
|
||||
) {
|
||||
setCookie(ctx, { appId }, Cookies.CurrentApp)
|
||||
}
|
||||
|
||||
return next()
|
||||
ctx.appId = appId
|
||||
if (roleId) {
|
||||
ctx.roleId = roleId
|
||||
const userId = ctx.user ? generateUserMetadataID(ctx.user._id) : null
|
||||
ctx.user = {
|
||||
...ctx.user,
|
||||
// override userID with metadata one
|
||||
_id: userId,
|
||||
userId,
|
||||
roleId,
|
||||
role: await getRole(roleId),
|
||||
}
|
||||
}
|
||||
if (
|
||||
(requestAppId !== appId ||
|
||||
appCookie == null ||
|
||||
appCookie.appId !== requestAppId) &&
|
||||
!noCookieSet
|
||||
) {
|
||||
setCookie(ctx, { appId }, Cookies.CurrentApp)
|
||||
}
|
||||
|
||||
return next()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@ const authorizedMiddleware = require("../authorized")
|
|||
const env = require("../../environment")
|
||||
const { PermissionTypes, PermissionLevels } = require("@budibase/backend-core/permissions")
|
||||
require("@budibase/backend-core").init(require("../../db"))
|
||||
const { doInAppContext } = require("@budibase/backend-core/context")
|
||||
|
||||
const APP_ID = ""
|
||||
|
||||
class TestConfiguration {
|
||||
constructor(role) {
|
||||
|
@ -22,7 +25,7 @@ class TestConfiguration {
|
|||
request: {
|
||||
url: ""
|
||||
},
|
||||
appId: "",
|
||||
appId: APP_ID,
|
||||
auth: {},
|
||||
next: this.next,
|
||||
throw: this.throw
|
||||
|
@ -30,7 +33,9 @@ class TestConfiguration {
|
|||
}
|
||||
|
||||
executeMiddleware() {
|
||||
return this.middleware(this.ctx, this.next)
|
||||
return doInAppContext(APP_ID, () => {
|
||||
return this.middleware(this.ctx, this.next)
|
||||
})
|
||||
}
|
||||
|
||||
setUser(user) {
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
mockAuthWithNoCookie()
|
||||
mockWorker()
|
||||
|
||||
jest.mock("@budibase/backend-core/db", () => ({
|
||||
...jest.requireActual("@budibase/backend-core/db"),
|
||||
dbExists: () => true,
|
||||
}))
|
||||
|
||||
function mockWorker() {
|
||||
jest.mock("../../utilities/workerRequests", () => ({
|
||||
getGlobalSelf: () => {
|
||||
|
@ -50,6 +55,7 @@ function mockAuthWithCookie() {
|
|||
return "app_test"
|
||||
},
|
||||
setCookie: jest.fn(),
|
||||
clearCookie: jest.fn(),
|
||||
getCookie: () => ({appId: "app_different", roleId: "PUBLIC"}),
|
||||
}))
|
||||
jest.mock("@budibase/backend-core/constants", () => ({
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
const core = require("@budibase/backend-core")
|
||||
const CouchDB = require("../../db")
|
||||
core.init(CouchDB)
|
||||
const { BUILTIN_ROLE_IDS } = require("@budibase/backend-core/roles")
|
||||
const env = require("../../environment")
|
||||
const {
|
||||
|
@ -17,14 +20,11 @@ const supertest = require("supertest")
|
|||
const { cleanup } = require("../../utilities/fileSystem")
|
||||
const { Cookies, Headers } = require("@budibase/backend-core/constants")
|
||||
const { jwt } = require("@budibase/backend-core/auth")
|
||||
const core = require("@budibase/backend-core")
|
||||
const { getGlobalDB } = require("@budibase/backend-core/tenancy")
|
||||
const { createASession } = require("@budibase/backend-core/sessions")
|
||||
const { user: userCache } = require("@budibase/backend-core/cache")
|
||||
const CouchDB = require("../../db")
|
||||
const newid = require("../../db/newid")
|
||||
const context = require("@budibase/backend-core/context")
|
||||
core.init(CouchDB)
|
||||
|
||||
const GLOBAL_USER_ID = "us_uuid1"
|
||||
const EMAIL = "babs@babs.com"
|
||||
|
@ -51,7 +51,6 @@ class TestConfiguration {
|
|||
}
|
||||
|
||||
async _req(config, params, controlFunc) {
|
||||
context.updateAppId(this.appId)
|
||||
const request = {}
|
||||
// fake cookies, we don't need them
|
||||
request.cookies = { set: () => {}, get: () => {} }
|
||||
|
@ -62,11 +61,21 @@ class TestConfiguration {
|
|||
request.request = {
|
||||
body: config,
|
||||
}
|
||||
if (params) {
|
||||
request.params = params
|
||||
async function run() {
|
||||
if (params) {
|
||||
request.params = params
|
||||
}
|
||||
await controlFunc(request)
|
||||
return request.body
|
||||
}
|
||||
// check if already in a context
|
||||
if (context.getAppId() == null) {
|
||||
return context.doInAppContext(this.appId, async () => {
|
||||
return run()
|
||||
})
|
||||
} else {
|
||||
return run()
|
||||
}
|
||||
await controlFunc(request)
|
||||
return request.body
|
||||
}
|
||||
|
||||
async globalUser({
|
||||
|
@ -182,12 +191,14 @@ class TestConfiguration {
|
|||
async deploy() {
|
||||
await this._req(null, null, controllers.deploy.deployApp)
|
||||
const prodAppId = this.getAppId().replace("_dev", "")
|
||||
const appPackage = await this._req(
|
||||
null,
|
||||
{ appId: prodAppId },
|
||||
controllers.app.fetchAppPackage
|
||||
)
|
||||
return appPackage.application
|
||||
return context.doInAppContext(prodAppId, async () => {
|
||||
const appPackage = await this._req(
|
||||
null,
|
||||
{ appId: prodAppId },
|
||||
controllers.app.fetchAppPackage
|
||||
)
|
||||
return appPackage.application
|
||||
})
|
||||
}
|
||||
|
||||
async updateTable(config = null) {
|
||||
|
@ -416,46 +427,47 @@ class TestConfiguration {
|
|||
|
||||
async login({ roleId, userId, builder, prodApp = false } = {}) {
|
||||
const appId = prodApp ? this.prodAppId : this.appId
|
||||
|
||||
userId = !userId ? `us_uuid1` : userId
|
||||
if (!this.request) {
|
||||
throw "Server has not been opened, cannot login."
|
||||
}
|
||||
// make sure the user exists in the global DB
|
||||
if (roleId !== BUILTIN_ROLE_IDS.PUBLIC) {
|
||||
await this.globalUser({
|
||||
userId,
|
||||
builder,
|
||||
roles: { [this.prodAppId]: roleId },
|
||||
return context.doInAppContext(appId, async () => {
|
||||
userId = !userId ? `us_uuid1` : userId
|
||||
if (!this.request) {
|
||||
throw "Server has not been opened, cannot login."
|
||||
}
|
||||
// make sure the user exists in the global DB
|
||||
if (roleId !== BUILTIN_ROLE_IDS.PUBLIC) {
|
||||
await this.globalUser({
|
||||
id: userId,
|
||||
builder,
|
||||
roles: { [this.prodAppId]: roleId },
|
||||
})
|
||||
}
|
||||
await createASession(userId, {
|
||||
sessionId: "sessionid",
|
||||
tenantId: TENANT_ID,
|
||||
})
|
||||
}
|
||||
await createASession(userId, {
|
||||
sessionId: "sessionid",
|
||||
tenantId: TENANT_ID,
|
||||
})
|
||||
// have to fake this
|
||||
const auth = {
|
||||
userId,
|
||||
sessionId: "sessionid",
|
||||
tenantId: TENANT_ID,
|
||||
}
|
||||
const app = {
|
||||
roleId: roleId,
|
||||
appId,
|
||||
}
|
||||
const authToken = jwt.sign(auth, env.JWT_SECRET)
|
||||
const appToken = jwt.sign(app, env.JWT_SECRET)
|
||||
// have to fake this
|
||||
const auth = {
|
||||
userId,
|
||||
sessionId: "sessionid",
|
||||
tenantId: TENANT_ID,
|
||||
}
|
||||
const app = {
|
||||
roleId: roleId,
|
||||
appId,
|
||||
}
|
||||
const authToken = jwt.sign(auth, env.JWT_SECRET)
|
||||
const appToken = jwt.sign(app, env.JWT_SECRET)
|
||||
|
||||
// returning necessary request headers
|
||||
await userCache.invalidateUser(userId)
|
||||
return {
|
||||
Accept: "application/json",
|
||||
Cookie: [
|
||||
`${Cookies.Auth}=${authToken}`,
|
||||
`${Cookies.CurrentApp}=${appToken}`,
|
||||
],
|
||||
[Headers.APP_ID]: appId,
|
||||
}
|
||||
// returning necessary request headers
|
||||
await userCache.invalidateUser(userId)
|
||||
return {
|
||||
Accept: "application/json",
|
||||
Cookie: [
|
||||
`${Cookies.Auth}=${authToken}`,
|
||||
`${Cookies.CurrentApp}=${appToken}`,
|
||||
],
|
||||
[Headers.APP_ID]: appId,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ exports.getCachedSelf = async (ctx, appId) => {
|
|||
// this has to be tenant aware, can't depend on the context to find it out
|
||||
// running some middlewares before the tenancy causes context to break
|
||||
const user = await userCache.getUser(ctx.user._id)
|
||||
return processUser(user, appId)
|
||||
return processUser(user, { appId })
|
||||
}
|
||||
|
||||
exports.getRawGlobalUser = async userId => {
|
||||
|
|
Loading…
Reference in New Issue