Tests updating, all now passing, fixed some issues discovered by them.

This commit is contained in:
mike12345567 2022-01-28 15:43:51 +00:00
parent d3a90acc55
commit d5f8cc1023
12 changed files with 195 additions and 129 deletions

View File

@ -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

View File

@ -6,6 +6,7 @@ const db = jest.fn(() => {
}
})
jest.mock("../../../../../db", () => db)
require("@budibase/backend-core").init(require("../../../../../db"))
const { RestImporter } = require("../index")

View File

@ -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)) {

View File

@ -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)

View File

@ -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

View File

@ -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)
}

View File

@ -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")
)
}

View File

@ -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()
})
}

View File

@ -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) {

View File

@ -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", () => ({

View File

@ -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,
}
})
}
}

View File

@ -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 => {