Use test-containers for backend-core tests

This commit is contained in:
adrinr 2023-01-27 11:43:36 +00:00
parent a9772c19e1
commit e4c898c327
15 changed files with 104 additions and 68 deletions

View File

@ -1,16 +1,6 @@
module.exports = dependenciesEnv => { module.exports = dependenciesEnv => {
if (process.env.DEV_TOOLS) {
return {
dockerCompose: {
composeFilePath: `${__dirname}/hosting`,
composeFile: 'docker-compose.dev.yaml',
startupTimeout: 10000,
}
}
}
return { return {
devEnv: { devEnv: {
image: "budibase/dependencies", image: "budibase/dependencies",

View File

@ -0,0 +1,8 @@
const { join } = require("path")
const { parsed: env } = require("dotenv").config({
path: join(__dirname, "..", "..", "hosting", ".env"),
})
const jestTestcontainersConfigGenerator = require("../../jestTestcontainersConfigGenerator")
module.exports = jestTestcontainersConfigGenerator(env)

View File

@ -4,8 +4,8 @@ const preset = require("ts-jest/jest-preset")
const config: Config.InitialOptions = { const config: Config.InitialOptions = {
...preset, ...preset,
preset: "@trendyol/jest-testcontainers", preset: "@trendyol/jest-testcontainers",
testEnvironment: "node", setupFiles: ["./tests/jestEnv.ts"],
setupFiles: ["./tests/jestSetup.ts"], setupFilesAfterEnv: ["./tests/jestSetup.ts"],
collectCoverageFrom: ["src/**/*.{js,ts}"], collectCoverageFrom: ["src/**/*.{js,ts}"],
coverageReporters: ["lcov", "json", "clover"], coverageReporters: ["lcov", "json", "clover"],
transform: { transform: {

View File

@ -57,9 +57,10 @@
"zlib": "1.0.5" "zlib": "1.0.5"
}, },
"devDependencies": { "devDependencies": {
"@trendyol/jest-testcontainers": "^2.1.1", "@faker-js/faker": "^7.6.0",
"@swc/core": "^1.3.25", "@swc/core": "^1.3.25",
"@swc/jest": "^0.2.24", "@swc/jest": "^0.2.24",
"@trendyol/jest-testcontainers": "^2.1.1",
"@types/chance": "1.1.3", "@types/chance": "1.1.3",
"@types/ioredis": "4.28.0", "@types/ioredis": "4.28.0",
"@types/jest": "27.5.1", "@types/jest": "27.5.1",

View File

@ -6,10 +6,12 @@ const tk = require("timekeeper")
const START_DATE = Date.now() const START_DATE = Date.now()
tk.freeze(START_DATE) tk.freeze(START_DATE)
const { faker } = require( "@faker-js/faker")
const DELAY = 5000 const DELAY = 5000
const db = getDB("test") const db = getDB(faker.random.alpha(10))
const db2 = getDB("test2") const db2 = getDB(faker.random.alpha(10))
const writethrough = new Writethrough(db, DELAY), writethrough2 = new Writethrough(db2, DELAY) const writethrough = new Writethrough(db, DELAY), writethrough2 = new Writethrough(db2, DELAY)
describe("writethrough", () => { describe("writethrough", () => {

View File

@ -1,19 +1,18 @@
require("../../../tests") require("../../../tests")
const { getDB } = require("../") const { getDB } = require("../db")
const { faker } = require( "@faker-js/faker")
describe("db", () => { describe("db", () => {
describe("getDB", () => { describe("getDB", () => {
it("returns a db", async () => { it("returns a db", async () => {
const db = getDB("test") const dbName = faker.random.alpha(10)
const db = getDB(dbName)
expect(db).toBeDefined() expect(db).toBeDefined()
expect(db._adapter).toBe("memory") expect(db.name).toBe(dbName)
expect(db.prefix).toBe("_pouch_")
expect(db.name).toBe("test")
}) })
it("uses the custom put function", async () => { it("uses the custom put function", async () => {
const db = getDB("test") const db = getDB(faker.random.alpha(10))
let doc = { _id: "test" } let doc = { _id: "test" }
await db.put(doc) await db.put(doc)
doc = await db.get(doc._id) doc = await db.get(doc._id)
@ -23,4 +22,3 @@ describe("db", () => {
}) })
}) })
}) })

View File

@ -8,6 +8,7 @@ const {
const { generateAppID, getPlatformUrl, getScopedConfig } = require("../utils") const { generateAppID, getPlatformUrl, getScopedConfig } = require("../utils")
const tenancy = require("../../tenancy") const tenancy = require("../../tenancy")
const { Config, DEFAULT_TENANT_ID } = require("../../constants") const { Config, DEFAULT_TENANT_ID } = require("../../constants")
import { faker } from "@faker-js/faker"
import env from "../../environment" import env from "../../environment"
describe("utils", () => { describe("utils", () => {
@ -66,17 +67,16 @@ describe("utils", () => {
}) })
}) })
const DB_URL = "http://dburl.com"
const DEFAULT_URL = "http://localhost:10000" const DEFAULT_URL = "http://localhost:10000"
const ENV_URL = "http://env.com" const ENV_URL = "http://env.com"
const setDbPlatformUrl = async () => { const setDbPlatformUrl = async (dbUrl: string) => {
const db = tenancy.getGlobalDB() const db = tenancy.getGlobalDB()
db.put({ await db.put({
_id: "config_settings", _id: "config_settings",
type: Config.SETTINGS, type: Config.SETTINGS,
config: { config: {
platformUrl: DB_URL, platformUrl: dbUrl,
}, },
}) })
} }
@ -119,9 +119,10 @@ describe("getPlatformUrl", () => {
it("gets the platform url from the database", async () => { it("gets the platform url from the database", async () => {
await tenancy.doInTenant(null, async () => { await tenancy.doInTenant(null, async () => {
await setDbPlatformUrl() const dbUrl = faker.internet.url()
await setDbPlatformUrl(dbUrl)
const url = await getPlatformUrl() const url = await getPlatformUrl()
expect(url).toBe(DB_URL) expect(url).toBe(dbUrl)
}) })
}) })
}) })
@ -152,7 +153,7 @@ describe("getPlatformUrl", () => {
it("never gets the platform url from the database", async () => { it("never gets the platform url from the database", async () => {
await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
await setDbPlatformUrl() await setDbPlatformUrl(faker.internet.url())
const url = await getPlatformUrl() const url = await getPlatformUrl()
expect(url).toBe(TENANT_AWARE_URL) expect(url).toBe(TENANT_AWARE_URL)
}) })
@ -170,10 +171,11 @@ describe("getScopedConfig", () => {
it("returns the platform url with an existing config", async () => { it("returns the platform url with an existing config", async () => {
await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => { await tenancy.doInTenant(DEFAULT_TENANT_ID, async () => {
await setDbPlatformUrl() const dbUrl = faker.internet.url()
await setDbPlatformUrl(dbUrl)
const db = tenancy.getGlobalDB() const db = tenancy.getGlobalDB()
const config = await getScopedConfig(db, { type: Config.SETTINGS }) const config = await getScopedConfig(db, { type: Config.SETTINGS })
expect(config.platformUrl).toBe(DB_URL) expect(config.platformUrl).toBe(dbUrl)
}) })
}) })

View File

@ -6,6 +6,8 @@ const { DEFAULT_TENANT_ID } = require("../../../constants")
const { generateGlobalUserID } = require("../../../db/utils") const { generateGlobalUserID } = require("../../../db/utils")
const { newid } = require("../../../utils") const { newid } = require("../../../utils")
const { doWithGlobalDB, doInTenant } = require("../../../tenancy") const { doWithGlobalDB, doInTenant } = require("../../../tenancy")
const { default: environment } = require("../../../environment")
environment._set("MULTI_TENANCY", 'TRUE')
const done = jest.fn() const done = jest.fn()

View File

@ -3,7 +3,7 @@
exports[`migrations should match snapshot 1`] = ` exports[`migrations should match snapshot 1`] = `
Object { Object {
"_id": "migrations", "_id": "migrations",
"_rev": "1-a32b0b708e59eeb006ed5e063cfeb36a", "_rev": "1-2f64479842a0513aa8b97f356b0b9127",
"createdAt": "2020-01-01T00:00:00.000Z", "createdAt": "2020-01-01T00:00:00.000Z",
"test": 1577836800000, "test": 1577836800000,
"updatedAt": "2020-01-01T00:00:00.000Z", "updatedAt": "2020-01-01T00:00:00.000Z",

View File

@ -1,9 +1,11 @@
require("../../../tests") require("../../../tests")
const { runMigrations, getMigrationsDoc } = require("../index") const { runMigrations, getMigrationsDoc } = require("../index")
const { getDB } = require("../../db") const { getGlobalDBName, getDB } = require("../../db")
const {
StaticDatabases, const { faker } = require( "@faker-js/faker")
} = require("../../constants")
const { default: environment } = require("../../environment")
environment._set("MULTI_TENANCY", 'TRUE')
let db let db
@ -17,8 +19,11 @@ describe("migrations", () => {
fn: migrationFunction fn: migrationFunction
}] }]
let tenantId
beforeEach(() => { beforeEach(() => {
db = getDB(StaticDatabases.GLOBAL.name) tenantId =faker.random.alpha(10)
db = getDB(getGlobalDBName(tenantId))
}) })
afterEach(async () => { afterEach(async () => {
@ -27,7 +32,7 @@ describe("migrations", () => {
}) })
const migrate = () => { const migrate = () => {
return runMigrations(MIGRATIONS) return runMigrations(MIGRATIONS, { tenantIds: [tenantId]})
} }
it("should run a new migration", async () => { it("should run a new migration", async () => {

View File

@ -2,13 +2,19 @@ import { structures } from "../../../tests"
import * as utils from "../../utils" import * as utils from "../../utils"
import * as events from "../../events" import * as events from "../../events"
import * as db from "../../db" import * as db from "../../db"
import { DEFAULT_TENANT_ID, Header } from "../../constants" import { Header } from "../../constants"
import { doInTenant } from "../../context" import { doInTenant } from "../../context"
import { faker } from "@faker-js/faker"
import environment from "../../environment"
describe("utils", () => { describe("utils", () => {
describe("platformLogout", () => { describe("platformLogout", () => {
beforeEach(() => {
environment._set("MULTI_TENANCY", "TRUE")
})
it("should call platform logout", async () => { it("should call platform logout", async () => {
await doInTenant(DEFAULT_TENANT_ID, async () => { await doInTenant(faker.random.alpha(10), async () => {
const ctx = structures.koa.newContext() const ctx = structures.koa.newContext()
await utils.platformLogout({ ctx, userId: "test" }) await utils.platformLogout({ ctx, userId: "test" })
expect(events.auth.logout).toBeCalledTimes(1) expect(events.auth.logout).toBeCalledTimes(1)
@ -17,6 +23,10 @@ describe("utils", () => {
}) })
describe("getAppIdFromCtx", () => { describe("getAppIdFromCtx", () => {
beforeEach(() => {
environment._set("MULTI_TENANCY", undefined)
})
it("gets appId from header", async () => { it("gets appId from header", async () => {
const ctx = structures.koa.newContext() const ctx = structures.koa.newContext()
const expected = db.generateAppID() const expected = db.generateAppID()
@ -54,7 +64,7 @@ describe("utils", () => {
const app = structures.apps.app(expected) const app = structures.apps.app(expected)
// set custom url // set custom url
const appUrl = "custom-url" const appUrl = faker.datatype.uuid()
app.url = `/${appUrl}` app.url = `/${appUrl}`
ctx.path = `/app/${appUrl}` ctx.path = `/app/${appUrl}`

View File

@ -0,0 +1,23 @@
import env from "../src/environment"
import { mocks } from "./utilities"
// must explicitly enable fetch mock
mocks.fetch.enable()
// mock all dates to 2020-01-01T00:00:00.000Z
// use tk.reset() to use real dates in individual tests
import tk from "timekeeper"
tk.freeze(mocks.date.MOCK_DATE)
env._set("SELF_HOSTED", "1")
env._set("NODE_ENV", "jest")
if (!process.env.DEBUG) {
global.console.log = jest.fn() // console.log are ignored in tests
}
if (!process.env.CI) {
// set a longer timeout in dev for debugging
// 100 seconds
jest.setTimeout(100000)
}

View File

@ -1,28 +1,14 @@
import env from "../src/environment" import env from "../src/environment"
import { mocks } from "./utilities"
// must explicitly enable fetch mock const globalSafe = global as any
mocks.fetch.enable()
// mock all dates to 2020-01-01T00:00:00.000Z env._set("COUCH_DB_PORT", globalSafe.__TESTCONTAINERS_DEVENV_PORT_5984__)
// use tk.reset() to use real dates in individual tests env._set(
import tk from "timekeeper" "COUCH_DB_URL",
tk.freeze(mocks.date.MOCK_DATE) `http://${globalSafe.__TESTCONTAINERS_DEVENV_IP__}:${globalSafe.__TESTCONTAINERS_DEVENV_PORT_5984__}`
)
env._set("SELF_HOSTED", "1") env._set(
env._set("NODE_ENV", "jest") "MINIO_URL",
env._set("JWT_SECRET", "test-jwtsecret") `http://${globalSafe.__TESTCONTAINERS_DEVENV_IP__}:${globalSafe.__TESTCONTAINERS_DEVENV_PORT_9000__}`
env._set("LOG_LEVEL", "silent") )
env._set("MINIO_URL", "http://localhost")
env._set("MINIO_ACCESS_KEY", "test")
env._set("MINIO_SECRET_KEY", "test")
if (!process.env.DEBUG) {
global.console.log = jest.fn() // console.log are ignored in tests
}
if (!process.env.CI) {
// set a longer timeout in dev for debugging
// 100 seconds
jest.setTimeout(100000)
}

View File

@ -487,6 +487,11 @@
qs "^6.11.0" qs "^6.11.0"
tough-cookie "^4.1.2" tough-cookie "^4.1.2"
"@budibase/types@2.2.12-alpha.40":
version "2.2.12-alpha.40"
resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.40.tgz#114c2de00f502736d90b18238ed31eb0b2ef6a19"
integrity sha512-YLCycoImazSypq89w+1l3LHEMZ9qEh5NPBJ5DQ07Un/1Sq5H4QxVLK8r7Z1VtxIqtAh95H3nMPnAB/vLpJEL8Q==
"@cspotcode/source-map-support@^0.8.0": "@cspotcode/source-map-support@^0.8.0":
version "0.8.1" version "0.8.1"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1"
@ -494,6 +499,11 @@
dependencies: dependencies:
"@jridgewell/trace-mapping" "0.3.9" "@jridgewell/trace-mapping" "0.3.9"
"@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==
"@hapi/hoek@^9.0.0": "@hapi/hoek@^9.0.0":
version "9.3.0" version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"

View File

@ -1 +0,0 @@
../../hosting/tests/jest-testcontainers-config.js