Fixing issues with test cases - a lot of test cases didn't setup tenancy in any format, which now means that the API endpoints they call would not have access to a Global DB instance. Also had to disable the closing of the database in test as this was removing the database from memory, meaning future calls would find an empty database when they opened it.

This commit is contained in:
mike12345567 2022-04-21 14:56:14 +01:00
parent 9d01028bd0
commit fe846f86a5
15 changed files with 108 additions and 96 deletions

View File

@ -169,12 +169,11 @@ exports.updateTenantId = tenantId => {
cls.setOnContext(ContextKeys.TENANT_ID, tenantId) cls.setOnContext(ContextKeys.TENANT_ID, tenantId)
} }
exports.updateAppId = appId => { exports.updateAppId = async appId => {
try { try {
// have to close first, before removing the databases from context // have to close first, before removing the databases from context
const promise = closeAppDBs() await closeAppDBs()
cls.setOnContext(ContextKeys.APP_ID, appId) cls.setOnContext(ContextKeys.APP_ID, appId)
return promise
} catch (err) { } catch (err) {
if (env.isTest()) { if (env.isTest()) {
TEST_APP_ID = appId TEST_APP_ID = appId

View File

@ -1,4 +1,5 @@
const pouch = require("./pouch") const pouch = require("./pouch")
const env = require("../environment")
let PouchDB let PouchDB
let initialised = false let initialised = false
@ -36,7 +37,7 @@ exports.dangerousGetDB = (dbName, opts) => {
// use this function if you have called dangerousGetDB - close // use this function if you have called dangerousGetDB - close
// the databases you've opened once finished // the databases you've opened once finished
exports.closeDB = async db => { exports.closeDB = async db => {
if (!db) { if (!db || env.isTest()) {
return return
} }
try { try {

View File

@ -123,7 +123,7 @@ async function createInstance(template) {
const tenantId = isMultiTenant() ? getTenantId() : null const tenantId = isMultiTenant() ? getTenantId() : null
const baseAppId = generateAppID(tenantId) const baseAppId = generateAppID(tenantId)
const appId = generateDevAppID(baseAppId) const appId = generateDevAppID(baseAppId)
updateAppId(appId) await updateAppId(appId)
const db = getAppDB() const db = getAppDB()
await db.put({ await db.put({

View File

@ -6,6 +6,7 @@ const {
DocumentTypes, DocumentTypes,
InternalTables, InternalTables,
} = require("../../../db/utils") } = require("../../../db/utils")
const { dangerousGetDB } = require("@budibase/backend-core/db")
const userController = require("../user") const userController = require("../user")
const { const {
inputProcessing, inputProcessing,
@ -250,7 +251,7 @@ exports.fetch = async ctx => {
} }
exports.find = async ctx => { exports.find = async ctx => {
const db = getAppDB() const db = dangerousGetDB(ctx.appId)
const table = await db.get(ctx.params.tableId) const table = await db.get(ctx.params.tableId)
let row = await findRow(ctx, ctx.params.tableId, ctx.params.rowId) let row = await findRow(ctx, ctx.params.tableId, ctx.params.rowId)
row = await outputProcessing(table, row) row = await outputProcessing(table, row)

View File

@ -54,7 +54,7 @@ exports.destroy = async ctx => {
} }
exports.buildSchema = async ctx => { exports.buildSchema = async ctx => {
updateAppId(ctx.params.instance) await updateAppId(ctx.params.instance)
const db = getAppDB() const db = getAppDB()
const webhook = await db.get(ctx.params.id) const webhook = await db.get(ctx.params.id)
webhook.bodySchema = toJsonSchema(ctx.request.body) webhook.bodySchema = toJsonSchema(ctx.request.body)
@ -80,7 +80,7 @@ exports.buildSchema = async ctx => {
exports.trigger = async ctx => { exports.trigger = async ctx => {
const prodAppId = getProdAppID(ctx.params.instance) const prodAppId = getProdAppID(ctx.params.instance)
updateAppId(prodAppId) await updateAppId(prodAppId)
try { try {
const db = getAppDB() const db = getAppDB()
const webhook = await db.get(ctx.params.id) const webhook = await db.get(ctx.params.id)

View File

@ -27,7 +27,7 @@ describe("test the delete row action", () => {
expect(res.row._id).toEqual(row._id) expect(res.row._id).toEqual(row._id)
let error let error
try { try {
await config.getRow(table._id, res.id) await config.getRow(table._id, res.row._id)
} catch (err) { } catch (err) {
error = err error = err
} }

View File

@ -7,7 +7,9 @@ class TestConfiguration {
this.integration = new AirtableIntegration.integration(config) this.integration = new AirtableIntegration.integration(config)
this.client = { this.client = {
create: jest.fn(), create: jest.fn(),
select: jest.fn(), select: jest.fn(() => ({
firstPage: jest.fn(() => []),
})),
update: jest.fn(), update: jest.fn(),
destroy: jest.fn(), destroy: jest.fn(),
} }

View File

@ -2,8 +2,10 @@ jest.mock("pouchdb", () => function CouchDBMock() {
this.post = jest.fn() this.post = jest.fn()
this.allDocs = jest.fn(() => ({ rows: [] })) this.allDocs = jest.fn(() => ({ rows: [] }))
this.put = jest.fn() this.put = jest.fn()
this.get = jest.fn()
this.remove = jest.fn() this.remove = jest.fn()
this.plugin = jest.fn() this.plugin = jest.fn()
this.close = jest.fn()
}) })
const CouchDBIntegration = require("../couchdb") const CouchDBIntegration = require("../couchdb")
@ -62,6 +64,7 @@ describe("CouchDB Integration", () => {
it("calls the delete method with the correct params", async () => { it("calls the delete method with the correct params", async () => {
const id = "1234" const id = "1234"
const response = await config.integration.delete({ id }) const response = await config.integration.delete({ id })
expect(config.integration.client.remove).toHaveBeenCalledWith(id) expect(config.integration.client.get).toHaveBeenCalledWith(id)
expect(config.integration.client.remove).toHaveBeenCalled()
}) })
}) })

View File

@ -6,7 +6,10 @@ jest.mock("@budibase/backend-core/tenancy", () => ({
const usageQuotaMiddleware = require("../usageQuota") const usageQuotaMiddleware = require("../usageQuota")
const usageQuota = require("../../utilities/usageQuota") const usageQuota = require("../../utilities/usageQuota")
const CouchDB = require("../../db")
jest.mock("@budibase/backend-core/db")
const { dangerousGetDB } = require("@budibase/backend-core/db")
const env = require("../../environment") const env = require("../../environment")
class TestConfiguration { class TestConfiguration {
@ -80,7 +83,7 @@ describe("usageQuota middleware", () => {
_rev: "test", _rev: "test",
}) })
CouchDB.mockImplementationOnce(() => ({ dangerousGetDB.mockImplementationOnce(() => ({
get: async () => true get: async () => true
})) }))
@ -96,7 +99,7 @@ describe("usageQuota middleware", () => {
}) })
config.setProd(true) config.setProd(true)
CouchDB.mockImplementationOnce(() => ({ dangerousGetDB.mockImplementationOnce(() => ({
get: async () => { get: async () => {
throw new Error() throw new Error()
} }
@ -114,21 +117,4 @@ describe("usageQuota middleware", () => {
expect(usageQuota.update).toHaveBeenCalledWith("rows", 1) expect(usageQuota.update).toHaveBeenCalledWith("rows", 1)
expect(config.next).toHaveBeenCalled() expect(config.next).toHaveBeenCalled()
}) })
// it("calculates the correct file size from a file upload call and adds it to quota", async () => {
// config.setUrl("/upload")
// config.setProd(true)
// config.setFiles([
// {
// size: 100
// },
// {
// size: 10000
// },
// ])
// await config.executeMiddleware()
// expect(usageQuota.update).toHaveBeenCalledWith("storage", 10100)
// expect(config.next).toHaveBeenCalled()
// })
}) })

View File

@ -14,7 +14,7 @@ describe("run", () => {
it("runs successfully", async () => { it("runs successfully", async () => {
const app = await config.createApp("testApp") const app = await config.createApp("testApp")
const metadata = doWithDB(app.appId, async db => { const metadata = await doWithDB(app.appId, async db => {
const metadataDoc = await db.get(DocumentTypes.APP_METADATA) const metadataDoc = await db.get(DocumentTypes.APP_METADATA)
delete metadataDoc.url delete metadataDoc.url
await db.put(metadataDoc) await db.put(metadataDoc)

View File

@ -1,5 +1,6 @@
const TestConfig = require("../../../tests/utilities/TestConfiguration") const TestConfig = require("../../../tests/utilities/TestConfiguration")
const { getGlobalDB } = require("@budibase/backend-core/tenancy") const { TENANT_ID } = require("../../../tests/utilities/structures")
const { getGlobalDB, doInTenant } = require("@budibase/backend-core/tenancy")
// mock email view creation // mock email view creation
const coreDb = require("@budibase/backend-core/db") const coreDb = require("@budibase/backend-core/db")
@ -9,6 +10,7 @@ coreDb.createUserEmailView = createUserEmailView
const migration = require("../userEmailViewCasing") const migration = require("../userEmailViewCasing")
describe("run", () => { describe("run", () => {
doInTenant(TENANT_ID, () => {
let config = new TestConfig(false) let config = new TestConfig(false)
const globalDb = getGlobalDB() const globalDb = getGlobalDB()
@ -23,3 +25,4 @@ describe("run", () => {
expect(createUserEmailView).toHaveBeenCalledTimes(1) expect(createUserEmailView).toHaveBeenCalledTimes(1)
}) })
}) })
})

View File

@ -1,10 +1,12 @@
const { getGlobalDB } = require("@budibase/backend-core/tenancy") const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
const TestConfig = require("../../../../tests/utilities/TestConfiguration") const TestConfig = require("../../../../tests/utilities/TestConfiguration")
const { TENANT_ID } = require("../../../../tests/utilities/structures")
const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota") const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota")
const syncApps = require("../syncApps") const syncApps = require("../syncApps")
const env = require("../../../../environment") const env = require("../../../../environment")
describe("syncApps", () => { describe("syncApps", () => {
let config = new TestConfig(false) let config = new TestConfig(false)
beforeEach(async () => { beforeEach(async () => {
@ -15,8 +17,9 @@ describe("syncApps", () => {
afterAll(config.end) afterAll(config.end)
it("runs successfully", async () => { it("runs successfully", async () => {
// create the usage quota doc and mock usages await doInTenant(TENANT_ID, async () => {
const db = getGlobalDB() const db = getGlobalDB()
// create the usage quota doc and mock usages
await getUsageQuotaDoc(db) await getUsageQuotaDoc(db)
await update(Properties.APPS, 3) await update(Properties.APPS, 3)
@ -34,4 +37,5 @@ describe("syncApps", () => {
expect(usageDoc.usageQuota.apps).toEqual(2) expect(usageDoc.usageQuota.apps).toEqual(2)
}) })
}) })
})

View File

@ -1,5 +1,6 @@
const { getGlobalDB } = require("@budibase/backend-core/tenancy") const { doInTenant, getGlobalDB } = require("@budibase/backend-core/tenancy")
const TestConfig = require("../../../../tests/utilities/TestConfiguration") const TestConfig = require("../../../../tests/utilities/TestConfiguration")
const { TENANT_ID } = require("../../../../tests/utilities/structures")
const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota") const { getUsageQuotaDoc, update, Properties } = require("../../../../utilities/usageQuota")
const syncRows = require("../syncRows") const syncRows = require("../syncRows")
const env = require("../../../../environment") const env = require("../../../../environment")
@ -15,7 +16,7 @@ describe("syncRows", () => {
afterAll(config.end) afterAll(config.end)
it("runs successfully", async () => { it("runs successfully", async () => {
// create the usage quota doc and mock usages await doInTenant(TENANT_ID, async () => {
const db = getGlobalDB() const db = getGlobalDB()
await getUsageQuotaDoc(db) await getUsageQuotaDoc(db)
await update(Properties.ROW, 300) await update(Properties.ROW, 300)
@ -40,4 +41,5 @@ describe("syncRows", () => {
expect(usageDoc.usageQuota.rows).toEqual(3) expect(usageDoc.usageQuota.rows).toEqual(3)
}) })
}) })
})

View File

@ -18,7 +18,7 @@ const supertest = require("supertest")
const { cleanup } = require("../../utilities/fileSystem") const { cleanup } = require("../../utilities/fileSystem")
const { Cookies, Headers } = require("@budibase/backend-core/constants") const { Cookies, Headers } = require("@budibase/backend-core/constants")
const { jwt } = require("@budibase/backend-core/auth") const { jwt } = require("@budibase/backend-core/auth")
const { doWithGlobalDB } = require("@budibase/backend-core/tenancy") const { doInTenant, doWithGlobalDB } = require("@budibase/backend-core/tenancy")
const { createASession } = require("@budibase/backend-core/sessions") const { createASession } = require("@budibase/backend-core/sessions")
const { user: userCache } = require("@budibase/backend-core/cache") const { user: userCache } = require("@budibase/backend-core/cache")
const newid = require("../../db/newid") const newid = require("../../db/newid")
@ -55,6 +55,22 @@ class TestConfiguration {
return this.appId return this.appId
} }
async doInContext(appId, task) {
if (!appId) {
appId = this.appId
}
return doInTenant(TENANT_ID, () => {
// check if already in a context
if (context.getAppId() == null && appId !== null) {
return context.doInAppContext(appId, async () => {
return task()
})
} else {
return task()
}
})
}
async _req(config, params, controlFunc) { async _req(config, params, controlFunc) {
const request = {} const request = {}
// fake cookies, we don't need them // fake cookies, we don't need them
@ -66,21 +82,13 @@ class TestConfiguration {
request.request = { request.request = {
body: config, body: config,
} }
async function run() { return this.doInContext(this.appId, async () => {
if (params) { if (params) {
request.params = params request.params = params
} }
await controlFunc(request) await controlFunc(request)
return request.body return request.body
}
// check if already in a context
if (context.getAppId() == null && this.appId !== null) {
return context.doInAppContext(this.appId, async () => {
return run()
}) })
} else {
return run()
}
} }
async generateApiKey(userId = GLOBAL_USER_ID) { async generateApiKey(userId = GLOBAL_USER_ID) {
@ -201,6 +209,9 @@ class TestConfiguration {
async createApp(appName) { async createApp(appName) {
// create dev app // create dev app
// clear any old app
this.appId = null
await context.updateAppId(null)
this.app = await this._req({ name: appName }, null, controllers.app.create) this.app = await this._req({ name: appName }, null, controllers.app.create)
this.appId = this.app.appId this.appId = this.app.appId
await context.updateAppId(this.appId) await context.updateAppId(this.appId)

View File

@ -62,7 +62,7 @@ exports.getUniqueRows = async appIds => {
continue continue
} }
try { try {
appRows.push(await getAppRows(appId)) appRows = appRows.concat(await getAppRows(appId))
} catch (e) { } catch (e) {
console.error(e) console.error(e)
// don't error out if we can't count the app rows, just continue // don't error out if we can't count the app rows, just continue