1
0
Fork 0
mirror of synced 2024-08-12 00:22:02 +12:00

Use multitenancy for tests

This commit is contained in:
Adria Navarro Redo 2023-01-25 17:11:37 +00:00 committed by adrinr
parent 13af7aa730
commit 067462f458
4 changed files with 73 additions and 53 deletions

View file

@ -122,10 +122,11 @@
"@babel/core": "7.17.4",
"@babel/preset-env": "7.16.11",
"@budibase/standard-components": "^0.9.139",
"@faker-js/faker": "^7.6.0",
"@jest/test-sequencer": "24.9.0",
"@trendyol/jest-testcontainers": "^2.1.1",
"@swc/core": "^1.3.25",
"@swc/jest": "^0.2.24",
"@trendyol/jest-testcontainers": "^2.1.1",
"@types/apidoc": "0.50.0",
"@types/bson": "4.2.0",
"@types/global-agent": "2.1.1",

View file

@ -3,6 +3,7 @@ import { tmpdir } from "os"
env._set("SELF_HOSTED", "1")
env._set("NODE_ENV", "jest")
env._set("MULTI_TENANCY", "1")
// @ts-ignore
env._set("BUDIBASE_DIR", tmpdir("budibase-unittests"))
env._set("LOG_LEVEL", "silent")

View file

@ -1,3 +1,4 @@
import { faker } from "@faker-js/faker"
import { mocks } from "@budibase/backend-core/tests"
// init the licensing mock
@ -40,14 +41,9 @@ import { generateUserMetadataID } from "../../db/utils"
import { startup } from "../../startup"
import { db } from "@budibase/backend-core"
import Nano from "@budibase/nano"
import { AuthToken } from "@budibase/types"
const supertest = require("supertest")
const GLOBAL_USER_ID = "us_uuid1"
const EMAIL = "babs@babs.com"
const FIRSTNAME = "Barbara"
const LASTNAME = "Barbington"
const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
class TestConfiguration {
server: any
request: any
@ -64,6 +60,14 @@ class TestConfiguration {
linkedTable: any
automation: any
datasource: any
tenantId: string | null
defaultValues: {
globalUserId: string
email: string
firstName: string
lastName: string
csrfToken: string
}
constructor(openServer = true) {
if (openServer) {
@ -78,6 +82,18 @@ class TestConfiguration {
}
this.appId = null
this.allApps = []
this.tenantId = null
this.defaultValues = this.populateDefaultValues()
}
populateDefaultValues() {
return {
globalUserId: faker.datatype.uuid(),
email: faker.internet.email(),
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
csrfToken: faker.datatype.uuid(),
}
}
getRequest() {
@ -102,10 +118,10 @@ class TestConfiguration {
getUserDetails() {
return {
globalId: GLOBAL_USER_ID,
email: EMAIL,
firstName: FIRSTNAME,
lastName: LASTNAME,
globalId: this.defaultValues.globalUserId,
email: this.defaultValues.email,
firstName: this.defaultValues.firstName,
lastName: this.defaultValues.lastName,
}
}
@ -113,7 +129,9 @@ class TestConfiguration {
if (!appId) {
appId = this.appId
}
return tenancy.doInTenant(TENANT_ID, () => {
const tenant = this.getTenantId()
return tenancy.doInTenant(tenant, () => {
// check if already in a context
if (context.getAppId() == null && appId !== null) {
return context.doInAppContext(appId, async () => {
@ -129,7 +147,12 @@ class TestConfiguration {
// use a new id as the name to avoid name collisions
async init(appName = newid()) {
await this.cleanAllDbs()
this.defaultValues = this.populateDefaultValues()
if (context.isMultiTenant()) {
this.tenantId = `tenant-${newid()}`
context.updateTenantId(this.tenantId)
}
if (!this.started) {
await startup()
}
@ -140,24 +163,6 @@ class TestConfiguration {
return this.createApp(appName)
}
async cleanAllDbs() {
const couchInfo = db.getCouchInfo()
const nano = Nano({
url: couchInfo.url,
requestDefaults: {
headers: {
Authorization: couchInfo.cookie,
},
},
parseUrl: false,
})
let dbs
do {
dbs = await nano.db.list()
await Promise.all(dbs.map(x => nano.db.destroy(x)))
} while (dbs.length)
}
end() {
if (!this) {
return
@ -180,7 +185,7 @@ class TestConfiguration {
// fake cookies, we don't need them
request.cookies = { set: () => {}, get: () => {} }
request.config = { jwtSecret: env.JWT_SECRET }
request.user = { appId, tenantId: TENANT_ID }
request.user = { appId, tenantId: this.getTenantId() }
request.query = {}
request.request = {
body,
@ -196,15 +201,15 @@ class TestConfiguration {
// USER / AUTH
async globalUser({
id = GLOBAL_USER_ID,
firstName = FIRSTNAME,
lastName = LASTNAME,
id = this.defaultValues.globalUserId,
firstName = this.defaultValues.firstName,
lastName = this.defaultValues.lastName,
builder = true,
admin = false,
email = EMAIL,
email = this.defaultValues.email,
roles,
}: any = {}) {
return tenancy.doWithGlobalDB(TENANT_ID, async (db: any) => {
return tenancy.doWithGlobalDB(this.getTenantId(), async (db: any) => {
let existing
try {
existing = await db.get(id)
@ -215,14 +220,14 @@ class TestConfiguration {
_id: id,
...existing,
roles: roles || {},
tenantId: TENANT_ID,
tenantId: this.getTenantId(),
firstName,
lastName,
}
await sessions.createASession(id, {
sessionId: "sessionid",
tenantId: TENANT_ID,
csrfToken: CSRF_TOKEN,
tenantId: this.getTenantId(),
csrfToken: this.defaultValues.csrfToken,
})
if (builder) {
user.builder = { global: true }
@ -244,9 +249,9 @@ class TestConfiguration {
async createUser(
id = null,
firstName = FIRSTNAME,
lastName = LASTNAME,
email = EMAIL,
firstName = this.defaultValues.firstName,
lastName = this.defaultValues.lastName,
email = this.defaultValues.email,
builder = true,
admin = false,
roles = {}
@ -285,13 +290,13 @@ class TestConfiguration {
}
await sessions.createASession(userId, {
sessionId: "sessionid",
tenantId: TENANT_ID,
tenantId: this.getTenantId(),
})
// have to fake this
const authObj = {
userId,
sessionId: "sessionid",
tenantId: TENANT_ID,
tenantId: this.getTenantId(),
}
const app = {
roleId: roleId,
@ -314,10 +319,11 @@ class TestConfiguration {
}
defaultHeaders(extras = {}) {
const authObj = {
userId: GLOBAL_USER_ID,
const tenantId = this.getTenantId()
const authObj: AuthToken = {
userId: this.defaultValues.globalUserId,
sessionId: "sessionid",
tenantId: TENANT_ID,
tenantId,
}
const app = {
roleId: roles.BUILTIN_ROLE_IDS.ADMIN,
@ -331,15 +337,22 @@ class TestConfiguration {
`${constants.Cookie.Auth}=${authToken}`,
`${constants.Cookie.CurrentApp}=${appToken}`,
],
[constants.Header.CSRF_TOKEN]: CSRF_TOKEN,
[constants.Header.CSRF_TOKEN]: this.defaultValues.csrfToken,
...extras,
}
if (this.appId) {
headers[constants.Header.APP_ID] = this.appId
}
if (this.tenantId) {
headers[constants.Header.TENANT_ID] = this.tenantId
}
return headers
}
getTenantId() {
return this.tenantId || TENANT_ID
}
publicHeaders({ prodApp = true } = {}) {
const appId = prodApp ? this.prodAppId : this.appId
@ -353,7 +366,7 @@ class TestConfiguration {
}
async roleHeaders({
email = EMAIL,
email = this.defaultValues.email,
roleId = roles.BUILTIN_ROLE_IDS.ADMIN,
builder = false,
prodApp = true,
@ -363,8 +376,8 @@ class TestConfiguration {
// API
async generateApiKey(userId = GLOBAL_USER_ID) {
return tenancy.doWithGlobalDB(TENANT_ID, async (db: any) => {
async generateApiKey(userId = this.defaultValues.globalUserId) {
return tenancy.doWithGlobalDB(this.getTenantId(), async (db: any) => {
const id = dbCore.generateDevInfoID(userId)
let devInfo
try {
@ -373,7 +386,7 @@ class TestConfiguration {
devInfo = { _id: id, userId }
}
devInfo.apiKey = encryption.encrypt(
`${TENANT_ID}${dbCore.SEPARATOR}${newid()}`
`${this.getTenantId()}${dbCore.SEPARATOR}${newid()}`
)
await db.put(devInfo)
return devInfo.apiKey

View file

@ -1527,6 +1527,11 @@
pump "^3.0.0"
secure-json-parse "^2.1.0"
"@faker-js/faker@^7.6.0":
version "7.6.0"
resolved "https://registry.yarnpkg.com/@faker-js/faker/-/faker-7.6.0.tgz#9ea331766084288634a9247fcd8b84f16ff4ba07"
integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==
"@google-cloud/firestore@5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@google-cloud/firestore/-/firestore-5.0.2.tgz#36923fde45987f928a220d347f341c5602f9e340"