Server flaky tests fixes - improving tenancy config
This commit is contained in:
parent
2d993adec8
commit
4e1bebe897
|
@ -10,7 +10,6 @@ import {
|
|||
isCloudAccount,
|
||||
isSSOAccount,
|
||||
TenantGroup,
|
||||
SettingsConfig,
|
||||
CloudAccount,
|
||||
UserIdentity,
|
||||
InstallationGroup,
|
||||
|
|
|
@ -58,7 +58,7 @@ export async function exportApps(ctx: Ctx) {
|
|||
}
|
||||
|
||||
async function checkHasBeenImported() {
|
||||
if (!env.SELF_HOSTED || env.MULTI_TENANCY) {
|
||||
if (!env.SELF_HOSTED) {
|
||||
return true
|
||||
}
|
||||
const apps = await dbCore.getAllApps({ all: true })
|
||||
|
@ -72,7 +72,7 @@ export async function hasBeenImported(ctx: Ctx) {
|
|||
}
|
||||
|
||||
export async function importApps(ctx: Ctx) {
|
||||
if (!env.SELF_HOSTED || env.MULTI_TENANCY) {
|
||||
if (!env.SELF_HOSTED) {
|
||||
ctx.throw(400, "Importing only allowed in self hosted environments.")
|
||||
}
|
||||
const beenImported = await checkHasBeenImported()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import { App } from "@budibase/types"
|
||||
|
||||
jest.setTimeout(30000)
|
||||
|
||||
import { AppStatus } from "../../../db/utils"
|
||||
|
@ -5,6 +7,7 @@ import { AppStatus } from "../../../db/utils"
|
|||
import * as setup from "./utilities"
|
||||
|
||||
import { wipeDb } from "./utilities/TestFunctions"
|
||||
import { tenancy } from "@budibase/backend-core"
|
||||
|
||||
describe("/cloud", () => {
|
||||
let request = setup.getRequest()!
|
||||
|
@ -12,18 +15,10 @@ describe("/cloud", () => {
|
|||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(async () => {
|
||||
// Importing is only allowed in self hosted environments
|
||||
config.modeSelf()
|
||||
})
|
||||
|
||||
beforeEach(async () => {
|
||||
await config.init()
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
// clear all mocks
|
||||
jest.clearAllMocks()
|
||||
config.modeSelf()
|
||||
})
|
||||
|
||||
describe("import", () => {
|
||||
|
@ -32,30 +27,28 @@ describe("/cloud", () => {
|
|||
// import will not run
|
||||
await wipeDb()
|
||||
|
||||
// get a count of apps before the import
|
||||
const preImportApps = await request
|
||||
.get(`/api/applications?status=${AppStatus.ALL}`)
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
|
||||
// Perform the import
|
||||
const res = await request
|
||||
.post(`/api/cloud/import`)
|
||||
.set(config.publicHeaders())
|
||||
.attach("importFile", "src/api/routes/tests/data/export-test.tar.gz")
|
||||
.set(config.defaultHeaders())
|
||||
.expect(200)
|
||||
expect(res.body.message).toEqual("Apps successfully imported.")
|
||||
|
||||
// get a count of apps after the import
|
||||
const postImportApps = await request
|
||||
.get(`/api/applications?status=${AppStatus.ALL}`)
|
||||
.set(config.defaultHeaders())
|
||||
.set(config.publicHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
|
||||
const apps = postImportApps.body as App[]
|
||||
// There are two apps in the file that was imported so check for this
|
||||
expect(postImportApps.body.length).toEqual(2)
|
||||
expect(apps.length).toEqual(2)
|
||||
// The new tenant id was assigned to the imported apps
|
||||
expect(tenancy.getTenantIDFromAppID(apps[0].appId)).toBe(
|
||||
config.getTenantId()
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
|
@ -2,7 +2,6 @@ import * as rowController from "../../../controllers/row"
|
|||
import * as appController from "../../../controllers/application"
|
||||
import { AppStatus } from "../../../../db/utils"
|
||||
import { roles, tenancy, context } from "@budibase/backend-core"
|
||||
import { TENANT_ID } from "../../../../tests/utilities/structures"
|
||||
import env from "../../../../environment"
|
||||
import { db } from "@budibase/backend-core"
|
||||
import Nano from "@budibase/nano"
|
||||
|
@ -33,7 +32,7 @@ export const getAllTableRows = async (config: any) => {
|
|||
}
|
||||
|
||||
export const clearAllApps = async (
|
||||
tenantId = TENANT_ID,
|
||||
tenantId: string,
|
||||
exceptions: Array<string> = []
|
||||
) => {
|
||||
await tenancy.doInTenant(tenantId, async () => {
|
||||
|
|
|
@ -8,9 +8,8 @@ jest.mock("@budibase/backend-core", () => {
|
|||
}
|
||||
}
|
||||
})
|
||||
const { tenancy, db: dbCore } = require("@budibase/backend-core")
|
||||
const { context, db: dbCore } = require("@budibase/backend-core")
|
||||
const TestConfig = require("../../../tests/utilities/TestConfiguration")
|
||||
const { TENANT_ID } = require("../../../tests/utilities/structures")
|
||||
|
||||
// mock email view creation
|
||||
|
||||
|
@ -26,8 +25,8 @@ describe("run", () => {
|
|||
afterAll(config.end)
|
||||
|
||||
it("runs successfully", async () => {
|
||||
await tenancy.doInTenant(TENANT_ID, async () => {
|
||||
const globalDb = tenancy.getGlobalDB()
|
||||
await config.doInTenant(async () => {
|
||||
const globalDb = context.getGlobalDB()
|
||||
await migration.run(globalDb)
|
||||
expect(dbCore.createNewUserEmailView).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
|
|
@ -8,3 +8,4 @@ process.env.BUDIBASE_DIR = tmpdir("budibase-unittests")
|
|||
process.env.LOG_LEVEL = process.env.LOG_LEVEL || "error"
|
||||
process.env.ENABLE_4XX_HTTP_LOGGING = "0"
|
||||
process.env.MOCK_REDIS = "1"
|
||||
process.env.PLATFORM_URL = "http://localhost:10000"
|
||||
|
|
|
@ -21,7 +21,6 @@ import {
|
|||
basicScreen,
|
||||
basicLayout,
|
||||
basicWebhook,
|
||||
TENANT_ID,
|
||||
} from "./structures"
|
||||
import {
|
||||
constants,
|
||||
|
@ -41,8 +40,8 @@ import { generateUserMetadataID } from "../../db/utils"
|
|||
import { startup } from "../../startup"
|
||||
import supertest from "supertest"
|
||||
import {
|
||||
App,
|
||||
AuthToken,
|
||||
Database,
|
||||
Datasource,
|
||||
Row,
|
||||
SourceName,
|
||||
|
@ -63,7 +62,7 @@ class TestConfiguration {
|
|||
started: boolean
|
||||
appId: string | null
|
||||
allApps: any[]
|
||||
app: any
|
||||
app?: App
|
||||
prodApp: any
|
||||
prodAppId: any
|
||||
user: any
|
||||
|
@ -73,7 +72,7 @@ class TestConfiguration {
|
|||
linkedTable: any
|
||||
automation: any
|
||||
datasource: any
|
||||
tenantId: string | null
|
||||
tenantId?: string
|
||||
defaultUserValues: DefaultUserValues
|
||||
|
||||
constructor(openServer = true) {
|
||||
|
@ -89,7 +88,6 @@ class TestConfiguration {
|
|||
}
|
||||
this.appId = null
|
||||
this.allApps = []
|
||||
this.tenantId = null
|
||||
this.defaultUserValues = this.populateDefaultUserValues()
|
||||
}
|
||||
|
||||
|
@ -154,19 +152,10 @@ class TestConfiguration {
|
|||
|
||||
// use a new id as the name to avoid name collisions
|
||||
async init(appName = newid()) {
|
||||
this.defaultUserValues = this.populateDefaultUserValues()
|
||||
if (context.isMultiTenant()) {
|
||||
this.tenantId = structures.tenant.id()
|
||||
}
|
||||
|
||||
if (!this.started) {
|
||||
await startup()
|
||||
}
|
||||
this.user = await this.globalUser()
|
||||
this.globalUserId = this.user._id
|
||||
this.userMetadataId = generateUserMetadataID(this.globalUserId)
|
||||
|
||||
return this.createApp(appName)
|
||||
return this.newTenant(appName)
|
||||
}
|
||||
|
||||
end() {
|
||||
|
@ -182,24 +171,22 @@ class TestConfiguration {
|
|||
}
|
||||
|
||||
// MODES
|
||||
#setMultiTenancy = (value: boolean) => {
|
||||
setMultiTenancy = (value: boolean) => {
|
||||
env._set("MULTI_TENANCY", value)
|
||||
coreEnv._set("MULTI_TENANCY", value)
|
||||
}
|
||||
|
||||
#setSelfHosted = (value: boolean) => {
|
||||
setSelfHosted = (value: boolean) => {
|
||||
env._set("SELF_HOSTED", value)
|
||||
coreEnv._set("SELF_HOSTED", value)
|
||||
}
|
||||
|
||||
modeCloud = () => {
|
||||
this.#setSelfHosted(false)
|
||||
this.#setMultiTenancy(true)
|
||||
this.setSelfHosted(false)
|
||||
}
|
||||
|
||||
modeSelf = () => {
|
||||
this.#setSelfHosted(true)
|
||||
this.#setMultiTenancy(false)
|
||||
this.setSelfHosted(true)
|
||||
}
|
||||
|
||||
// UTILS
|
||||
|
@ -354,6 +341,8 @@ class TestConfiguration {
|
|||
})
|
||||
}
|
||||
|
||||
// HEADERS
|
||||
|
||||
defaultHeaders(extras = {}) {
|
||||
const tenantId = this.getTenantId()
|
||||
const authObj: AuthToken = {
|
||||
|
@ -374,6 +363,7 @@ class TestConfiguration {
|
|||
`${constants.Cookie.CurrentApp}=${appToken}`,
|
||||
],
|
||||
[constants.Header.CSRF_TOKEN]: this.defaultUserValues.csrfToken,
|
||||
Host: this.tenantHost(),
|
||||
...extras,
|
||||
}
|
||||
|
||||
|
@ -383,10 +373,6 @@ class TestConfiguration {
|
|||
return headers
|
||||
}
|
||||
|
||||
getTenantId() {
|
||||
return this.tenantId || TENANT_ID
|
||||
}
|
||||
|
||||
publicHeaders({ prodApp = true } = {}) {
|
||||
const appId = prodApp ? this.prodAppId : this.appId
|
||||
|
||||
|
@ -397,9 +383,7 @@ class TestConfiguration {
|
|||
headers[constants.Header.APP_ID] = appId
|
||||
}
|
||||
|
||||
if (this.tenantId) {
|
||||
headers[constants.Header.TENANT_ID] = this.tenantId
|
||||
}
|
||||
headers[constants.Header.TENANT_ID] = this.getTenantId()
|
||||
|
||||
return headers
|
||||
}
|
||||
|
@ -413,6 +397,34 @@ class TestConfiguration {
|
|||
return this.login({ email, roleId, builder, prodApp })
|
||||
}
|
||||
|
||||
// TENANCY
|
||||
|
||||
tenantHost() {
|
||||
const tenantId = this.getTenantId()
|
||||
const platformHost = new URL(coreEnv.PLATFORM_URL).host.split(":")[0]
|
||||
return `${tenantId}.${platformHost}`
|
||||
}
|
||||
|
||||
getTenantId() {
|
||||
if (!this.tenantId) {
|
||||
throw new Error("no test tenant id - init has not been called")
|
||||
}
|
||||
return this.tenantId
|
||||
}
|
||||
|
||||
async newTenant(appName = newid()): Promise<App> {
|
||||
this.defaultUserValues = this.populateDefaultUserValues()
|
||||
this.tenantId = structures.tenant.id()
|
||||
this.user = await this.globalUser()
|
||||
this.globalUserId = this.user._id
|
||||
this.userMetadataId = generateUserMetadataID(this.globalUserId)
|
||||
return this.createApp(appName)
|
||||
}
|
||||
|
||||
doInTenant(task: any) {
|
||||
return context.doInTenant(this.getTenantId(), task)
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
async generateApiKey(userId = this.defaultUserValues.globalUserId) {
|
||||
|
@ -432,7 +444,7 @@ class TestConfiguration {
|
|||
}
|
||||
|
||||
// APP
|
||||
async createApp(appName: string) {
|
||||
async createApp(appName: string): Promise<App> {
|
||||
// create dev app
|
||||
// clear any old app
|
||||
this.appId = null
|
||||
|
@ -442,7 +454,7 @@ class TestConfiguration {
|
|||
null,
|
||||
controllers.app.create
|
||||
)
|
||||
this.appId = this.app.appId
|
||||
this.appId = this.app?.appId!
|
||||
})
|
||||
return await context.doInAppContext(this.appId, async () => {
|
||||
// create production app
|
||||
|
|
|
@ -13,8 +13,6 @@ import {
|
|||
|
||||
const { v4: uuidv4 } = require("uuid")
|
||||
|
||||
export const TENANT_ID = "default"
|
||||
|
||||
export function basicTable() {
|
||||
return {
|
||||
name: "TestTable",
|
||||
|
|
Loading…
Reference in New Issue