Fix worker tests
This commit is contained in:
parent
afab373cba
commit
651c367f75
|
@ -0,0 +1,23 @@
|
||||||
|
import fs from "fs"
|
||||||
|
module FetchMock {
|
||||||
|
const fetch = jest.requireActual("node-fetch")
|
||||||
|
|
||||||
|
const func = async (url: any, opts: any) => {
|
||||||
|
if (url.includes("http://someconfigurl")) {
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
json: () => ({
|
||||||
|
issuer: "test",
|
||||||
|
authorization_endpoint: "http://localhost/auth",
|
||||||
|
token_endpoint: "http://localhost/token",
|
||||||
|
userinfo_endpoint: "http://localhost/userinfo",
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fetch(url, opts)
|
||||||
|
}
|
||||||
|
|
||||||
|
func.Headers = fetch.Headers
|
||||||
|
|
||||||
|
module.exports = func
|
||||||
|
}
|
|
@ -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)
|
|
@ -1,8 +1,10 @@
|
||||||
import { Config } from "@jest/types"
|
import { Config } from "@jest/types"
|
||||||
import * as fs from "fs"
|
import * as fs from "fs"
|
||||||
|
const preset = require("ts-jest/jest-preset")
|
||||||
|
|
||||||
const config: Config.InitialOptions = {
|
const config: Config.InitialOptions = {
|
||||||
testEnvironment: "node",
|
...preset,
|
||||||
|
preset: "@trendyol/jest-testcontainers",
|
||||||
setupFiles: ["./src/tests/jestEnv.ts"],
|
setupFiles: ["./src/tests/jestEnv.ts"],
|
||||||
setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
|
setupFilesAfterEnv: ["./src/tests/jestSetup.ts"],
|
||||||
collectCoverageFrom: ["src/**/*.{js,ts}"],
|
collectCoverageFrom: ["src/**/*.{js,ts}"],
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
jest.mock("nodemailer")
|
jest.mock("nodemailer")
|
||||||
import { TestConfiguration, mocks } from "../../../../tests"
|
import { TestConfiguration, mocks } from "../../../../tests"
|
||||||
const sendMailMock = mocks.email.mock()
|
const sendMailMock = mocks.email.mock()
|
||||||
import { events } from "@budibase/backend-core"
|
import { events, tenancy, utils } from "@budibase/backend-core"
|
||||||
|
|
||||||
const expectSetAuthCookie = (res: any) => {
|
const expectSetAuthCookie = (res: any) => {
|
||||||
expect(
|
expect(
|
||||||
|
@ -40,36 +40,43 @@ describe("/api/global/auth", () => {
|
||||||
|
|
||||||
describe("POST /api/global/auth/:tenantId/reset", () => {
|
describe("POST /api/global/auth/:tenantId/reset", () => {
|
||||||
it("should generate password reset email", async () => {
|
it("should generate password reset email", async () => {
|
||||||
const { res, code } = await config.api.auth.requestPasswordReset(
|
await tenancy.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
sendMailMock
|
const userEmail = `${utils.newid()}@test.com`
|
||||||
)
|
const { res, code } = await config.api.auth.requestPasswordReset(
|
||||||
const user = await config.getUser("test@test.com")
|
sendMailMock,
|
||||||
|
userEmail
|
||||||
|
)
|
||||||
|
const user = await config.getUser(userEmail)
|
||||||
|
|
||||||
expect(res.body).toEqual({
|
expect(res.body).toEqual({
|
||||||
message: "Please check your email for a reset link.",
|
message: "Please check your email for a reset link.",
|
||||||
|
})
|
||||||
|
expect(sendMailMock).toHaveBeenCalled()
|
||||||
|
|
||||||
|
expect(code).toBeDefined()
|
||||||
|
expect(events.user.passwordResetRequested).toBeCalledTimes(1)
|
||||||
|
expect(events.user.passwordResetRequested).toBeCalledWith(user)
|
||||||
})
|
})
|
||||||
expect(sendMailMock).toHaveBeenCalled()
|
|
||||||
|
|
||||||
expect(code).toBeDefined()
|
|
||||||
expect(events.user.passwordResetRequested).toBeCalledTimes(1)
|
|
||||||
expect(events.user.passwordResetRequested).toBeCalledWith(user)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("POST /api/global/auth/:tenantId/reset/update", () => {
|
describe("POST /api/global/auth/:tenantId/reset/update", () => {
|
||||||
it("should reset password", async () => {
|
it("should reset password", async () => {
|
||||||
const { code } = await config.api.auth.requestPasswordReset(
|
await tenancy.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
sendMailMock
|
const userEmail = `${utils.newid()}@test.com`
|
||||||
)
|
const { code } = await config.api.auth.requestPasswordReset(
|
||||||
const user = await config.getUser("test@test.com")
|
sendMailMock,
|
||||||
delete user.password
|
userEmail
|
||||||
|
)
|
||||||
|
const user = await config.getUser(userEmail)
|
||||||
|
delete user.password
|
||||||
|
|
||||||
const res = await config.api.auth.updatePassword(code)
|
const res = await config.api.auth.updatePassword(code)
|
||||||
|
|
||||||
expect(res.body).toEqual({ message: "password reset successfully." })
|
|
||||||
expect(events.user.passwordReset).toBeCalledTimes(1)
|
|
||||||
expect(events.user.passwordReset).toBeCalledWith(user)
|
|
||||||
|
|
||||||
|
expect(res.body).toEqual({ message: "password reset successfully." })
|
||||||
|
expect(events.user.passwordReset).toBeCalledTimes(1)
|
||||||
|
expect(events.user.passwordReset).toBeCalledWith(user)
|
||||||
|
})
|
||||||
// TODO: Login using new password
|
// TODO: Login using new password
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
jest.mock("nodemailer")
|
jest.mock("nodemailer")
|
||||||
import { TestConfiguration, structures, mocks } from "../../../../tests"
|
import { TestConfiguration, structures, mocks } from "../../../../tests"
|
||||||
mocks.email.mock()
|
mocks.email.mock()
|
||||||
import { Config, events } from "@budibase/backend-core"
|
import { Config, context, events } from "@budibase/backend-core"
|
||||||
|
|
||||||
describe("configs", () => {
|
describe("configs", () => {
|
||||||
const config = new TestConfiguration()
|
const config = new TestConfiguration()
|
||||||
|
@ -113,56 +113,64 @@ describe("configs", () => {
|
||||||
|
|
||||||
describe("create", () => {
|
describe("create", () => {
|
||||||
it("should create activated OIDC config", async () => {
|
it("should create activated OIDC config", async () => {
|
||||||
await saveOIDCConfig()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
await saveOIDCConfig()
|
||||||
expect(events.auth.SSOCreated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSOCreated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
expect(events.auth.SSOActivated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
||||||
await config.deleteConfig(Config.OIDC)
|
expect(events.auth.SSOActivated).toBeCalledWith(Config.OIDC)
|
||||||
|
await config.deleteConfig(Config.OIDC)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create deactivated OIDC config", async () => {
|
it("should create deactivated OIDC config", async () => {
|
||||||
await saveOIDCConfig({ activated: false })
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
await saveOIDCConfig({ activated: false })
|
||||||
expect(events.auth.SSOCreated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSOCreated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOActivated).not.toBeCalled()
|
expect(events.auth.SSOCreated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
||||||
await config.deleteConfig(Config.OIDC)
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
|
await config.deleteConfig(Config.OIDC)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("update", () => {
|
describe("update", () => {
|
||||||
it("should update OIDC config to deactivated", async () => {
|
it("should update OIDC config to deactivated", async () => {
|
||||||
const oidcConf = await saveOIDCConfig()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
jest.clearAllMocks()
|
const oidcConf = await saveOIDCConfig()
|
||||||
await saveOIDCConfig(
|
jest.clearAllMocks()
|
||||||
{ ...oidcConf.config.configs[0], activated: false },
|
await saveOIDCConfig(
|
||||||
oidcConf._id,
|
{ ...oidcConf.config.configs[0], activated: false },
|
||||||
oidcConf._rev
|
oidcConf._id,
|
||||||
)
|
oidcConf._rev
|
||||||
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSOActivated).not.toBeCalled()
|
expect(events.auth.SSOUpdated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSODeactivated).toBeCalledTimes(1)
|
expect(events.auth.SSOActivated).not.toBeCalled()
|
||||||
expect(events.auth.SSODeactivated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSODeactivated).toBeCalledTimes(1)
|
||||||
await config.deleteConfig(Config.OIDC)
|
expect(events.auth.SSODeactivated).toBeCalledWith(Config.OIDC)
|
||||||
|
await config.deleteConfig(Config.OIDC)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should update OIDC config to activated", async () => {
|
it("should update OIDC config to activated", async () => {
|
||||||
const oidcConf = await saveOIDCConfig({ activated: false })
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
jest.clearAllMocks()
|
const oidcConf = await saveOIDCConfig({ activated: false })
|
||||||
await saveOIDCConfig(
|
jest.clearAllMocks()
|
||||||
{ ...oidcConf.config.configs[0], activated: true },
|
await saveOIDCConfig(
|
||||||
oidcConf._id,
|
{ ...oidcConf.config.configs[0], activated: true },
|
||||||
oidcConf._rev
|
oidcConf._id,
|
||||||
)
|
oidcConf._rev
|
||||||
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
)
|
||||||
expect(events.auth.SSOUpdated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSOUpdated).toBeCalledTimes(1)
|
||||||
expect(events.auth.SSODeactivated).not.toBeCalled()
|
expect(events.auth.SSOUpdated).toBeCalledWith(Config.OIDC)
|
||||||
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
expect(events.auth.SSODeactivated).not.toBeCalled()
|
||||||
expect(events.auth.SSOActivated).toBeCalledWith(Config.OIDC)
|
expect(events.auth.SSOActivated).toBeCalledTimes(1)
|
||||||
await config.deleteConfig(Config.OIDC)
|
expect(events.auth.SSOActivated).toBeCalledWith(Config.OIDC)
|
||||||
|
await config.deleteConfig(Config.OIDC)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -179,22 +187,26 @@ describe("configs", () => {
|
||||||
|
|
||||||
describe("create", () => {
|
describe("create", () => {
|
||||||
it("should create SMTP config", async () => {
|
it("should create SMTP config", async () => {
|
||||||
await config.deleteConfig(Config.SMTP)
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
await saveSMTPConfig()
|
await config.deleteConfig(Config.SMTP)
|
||||||
expect(events.email.SMTPUpdated).not.toBeCalled()
|
await saveSMTPConfig()
|
||||||
expect(events.email.SMTPCreated).toBeCalledTimes(1)
|
expect(events.email.SMTPUpdated).not.toBeCalled()
|
||||||
await config.deleteConfig(Config.SMTP)
|
expect(events.email.SMTPCreated).toBeCalledTimes(1)
|
||||||
|
await config.deleteConfig(Config.SMTP)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("update", () => {
|
describe("update", () => {
|
||||||
it("should update SMTP config", async () => {
|
it("should update SMTP config", async () => {
|
||||||
const smtpConf = await saveSMTPConfig()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
jest.clearAllMocks()
|
const smtpConf = await saveSMTPConfig()
|
||||||
await saveSMTPConfig(smtpConf.config, smtpConf._id, smtpConf._rev)
|
jest.clearAllMocks()
|
||||||
expect(events.email.SMTPCreated).not.toBeCalled()
|
await saveSMTPConfig(smtpConf.config, smtpConf._id, smtpConf._rev)
|
||||||
expect(events.email.SMTPUpdated).toBeCalledTimes(1)
|
expect(events.email.SMTPCreated).not.toBeCalled()
|
||||||
await config.deleteConfig(Config.SMTP)
|
expect(events.email.SMTPUpdated).toBeCalledTimes(1)
|
||||||
|
await config.deleteConfig(Config.SMTP)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -211,65 +223,73 @@ describe("configs", () => {
|
||||||
|
|
||||||
describe("create", () => {
|
describe("create", () => {
|
||||||
it("should create settings config with default settings", async () => {
|
it("should create settings config with default settings", async () => {
|
||||||
await config.deleteConfig(Config.SETTINGS)
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
|
await config.deleteConfig(Config.SETTINGS)
|
||||||
|
|
||||||
await saveSettingsConfig()
|
await saveSettingsConfig()
|
||||||
|
|
||||||
expect(events.org.nameUpdated).not.toBeCalled()
|
expect(events.org.nameUpdated).not.toBeCalled()
|
||||||
expect(events.org.logoUpdated).not.toBeCalled()
|
expect(events.org.logoUpdated).not.toBeCalled()
|
||||||
expect(events.org.platformURLUpdated).not.toBeCalled()
|
expect(events.org.platformURLUpdated).not.toBeCalled()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should create settings config with non-default settings", async () => {
|
it("should create settings config with non-default settings", async () => {
|
||||||
config.modeSelf()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
await config.deleteConfig(Config.SETTINGS)
|
config.modeSelf()
|
||||||
const conf = {
|
await config.deleteConfig(Config.SETTINGS)
|
||||||
company: "acme",
|
const conf = {
|
||||||
logoUrl: "http://example.com",
|
company: "acme",
|
||||||
platformUrl: "http://example.com",
|
logoUrl: "http://example.com",
|
||||||
}
|
platformUrl: "http://example.com",
|
||||||
|
}
|
||||||
|
|
||||||
await saveSettingsConfig(conf)
|
await saveSettingsConfig(conf)
|
||||||
|
|
||||||
expect(events.org.nameUpdated).toBeCalledTimes(1)
|
expect(events.org.nameUpdated).toBeCalledTimes(1)
|
||||||
expect(events.org.logoUpdated).toBeCalledTimes(1)
|
expect(events.org.logoUpdated).toBeCalledTimes(1)
|
||||||
expect(events.org.platformURLUpdated).toBeCalledTimes(1)
|
expect(events.org.platformURLUpdated).toBeCalledTimes(1)
|
||||||
config.modeCloud()
|
config.modeCloud()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("update", () => {
|
describe("update", () => {
|
||||||
it("should update settings config", async () => {
|
it("should update settings config", async () => {
|
||||||
config.modeSelf()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
await config.deleteConfig(Config.SETTINGS)
|
config.modeSelf()
|
||||||
const settingsConfig = await saveSettingsConfig()
|
await config.deleteConfig(Config.SETTINGS)
|
||||||
settingsConfig.config.company = "acme"
|
const settingsConfig = await saveSettingsConfig()
|
||||||
settingsConfig.config.logoUrl = "http://example.com"
|
settingsConfig.config.company = "acme"
|
||||||
settingsConfig.config.platformUrl = "http://example.com"
|
settingsConfig.config.logoUrl = "http://example.com"
|
||||||
|
settingsConfig.config.platformUrl = "http://example.com"
|
||||||
|
|
||||||
await saveSettingsConfig(
|
await saveSettingsConfig(
|
||||||
settingsConfig.config,
|
settingsConfig.config,
|
||||||
settingsConfig._id,
|
settingsConfig._id,
|
||||||
settingsConfig._rev
|
settingsConfig._rev
|
||||||
)
|
)
|
||||||
|
|
||||||
expect(events.org.nameUpdated).toBeCalledTimes(1)
|
expect(events.org.nameUpdated).toBeCalledTimes(1)
|
||||||
expect(events.org.logoUpdated).toBeCalledTimes(1)
|
expect(events.org.logoUpdated).toBeCalledTimes(1)
|
||||||
expect(events.org.platformURLUpdated).toBeCalledTimes(1)
|
expect(events.org.platformURLUpdated).toBeCalledTimes(1)
|
||||||
config.modeCloud()
|
config.modeCloud()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should return the correct checklist status based on the state of the budibase installation", async () => {
|
it("should return the correct checklist status based on the state of the budibase installation", async () => {
|
||||||
await config.saveSmtpConfig()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
|
await config.saveSmtpConfig()
|
||||||
|
|
||||||
const res = await config.api.configs.getConfigChecklist()
|
const res = await config.api.configs.getConfigChecklist()
|
||||||
const checklist = res.body
|
const checklist = res.body
|
||||||
|
|
||||||
expect(checklist.apps.checked).toBeFalsy()
|
expect(checklist.apps.checked).toBeFalsy()
|
||||||
expect(checklist.smtp.checked).toBeTruthy()
|
expect(checklist.smtp.checked).toBeTruthy()
|
||||||
expect(checklist.adminUser.checked).toBeTruthy()
|
expect(checklist.adminUser.checked).toBeTruthy()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { structures, TestConfiguration } from "../../../../tests"
|
import { structures, TestConfiguration } from "../../../../tests"
|
||||||
import { context, db, permissions, roles } from "@budibase/backend-core"
|
import { context, db, permissions, roles } from "@budibase/backend-core"
|
||||||
import { Mock } from "jest-mock"
|
import { Mock } from "jest-mock"
|
||||||
|
import { Database } from "@budibase/types"
|
||||||
|
|
||||||
jest.mock("@budibase/backend-core", () => {
|
jest.mock("@budibase/backend-core", () => {
|
||||||
const core = jest.requireActual("@budibase/backend-core")
|
const core = jest.requireActual("@budibase/backend-core")
|
||||||
|
@ -16,14 +17,13 @@ jest.mock("@budibase/backend-core", () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const appDb = db.getDB("app_test")
|
let appId: string
|
||||||
const mockAppDB = context.getAppDB as Mock
|
let appDb: Database
|
||||||
mockAppDB.mockReturnValue(appDb)
|
|
||||||
|
|
||||||
async function addAppMetadata() {
|
async function addAppMetadata() {
|
||||||
await appDb.put({
|
await appDb.put({
|
||||||
_id: "app_metadata",
|
_id: "app_metadata",
|
||||||
appId: "app_test",
|
appId: appId,
|
||||||
name: "New App",
|
name: "New App",
|
||||||
version: "version",
|
version: "version",
|
||||||
url: "url",
|
url: "url",
|
||||||
|
@ -39,12 +39,19 @@ describe("/api/global/roles", () => {
|
||||||
)
|
)
|
||||||
|
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
console.debug(role)
|
|
||||||
appDb.put(role)
|
|
||||||
await addAppMetadata()
|
|
||||||
await config.beforeAll()
|
await config.beforeAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
appId = db.generateAppID()
|
||||||
|
appDb = db.getDB(appId)
|
||||||
|
const mockAppDB = context.getAppDB as Mock
|
||||||
|
mockAppDB.mockReturnValue(appDb)
|
||||||
|
|
||||||
|
await addAppMetadata()
|
||||||
|
appDb.put(role)
|
||||||
|
})
|
||||||
|
|
||||||
afterAll(async () => {
|
afterAll(async () => {
|
||||||
await config.afterAll()
|
await config.afterAll()
|
||||||
})
|
})
|
||||||
|
@ -57,16 +64,14 @@ describe("/api/global/roles", () => {
|
||||||
it("retrieves roles", async () => {
|
it("retrieves roles", async () => {
|
||||||
const res = await config.api.roles.get()
|
const res = await config.api.roles.get()
|
||||||
expect(res.body).toBeDefined()
|
expect(res.body).toBeDefined()
|
||||||
expect(res.body["app_test"].roles.length).toEqual(5)
|
expect(res.body[appId].roles.length).toEqual(5)
|
||||||
expect(res.body["app_test"].roles.map((r: any) => r._id)).toContain(
|
expect(res.body[appId].roles.map((r: any) => r._id)).toContain(role._id)
|
||||||
role._id
|
|
||||||
)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("GET api/global/roles/:appId", () => {
|
describe("GET api/global/roles/:appId", () => {
|
||||||
it("finds a role by appId", async () => {
|
it("finds a role by appId", async () => {
|
||||||
const res = await config.api.roles.find("app_test")
|
const res = await config.api.roles.find(appId)
|
||||||
expect(res.body).toBeDefined()
|
expect(res.body).toBeDefined()
|
||||||
expect(res.body.name).toEqual("New App")
|
expect(res.body.name).toEqual("New App")
|
||||||
})
|
})
|
||||||
|
@ -79,9 +84,9 @@ describe("/api/global/roles", () => {
|
||||||
app_test: "role1",
|
app_test: "role1",
|
||||||
}
|
}
|
||||||
const userResponse = await config.createUser(user)
|
const userResponse = await config.createUser(user)
|
||||||
const res = await config.api.roles.remove("app_test")
|
const res = await config.api.roles.remove(appId)
|
||||||
const updatedUser = await config.api.users.getUser(userResponse._id!)
|
const updatedUser = await config.api.users.getUser(userResponse._id!)
|
||||||
expect(updatedUser.body.roles).not.toHaveProperty("app_test")
|
expect(updatedUser.body.roles).not.toHaveProperty(appId)
|
||||||
expect(res.body.message).toEqual("App role removed from all users")
|
expect(res.body.message).toEqual("App role removed from all users")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
import { InviteUsersResponse, User } from "@budibase/types"
|
import { InviteUsersResponse, User } from "@budibase/types"
|
||||||
|
|
||||||
jest.mock("nodemailer")
|
jest.mock("nodemailer")
|
||||||
import {
|
import { TestConfiguration, mocks, structures } from "../../../../tests"
|
||||||
TestConfiguration,
|
|
||||||
mocks,
|
|
||||||
structures,
|
|
||||||
TENANT_1,
|
|
||||||
} from "../../../../tests"
|
|
||||||
const sendMailMock = mocks.email.mock()
|
const sendMailMock = mocks.email.mock()
|
||||||
import { events, tenancy } from "@budibase/backend-core"
|
import { context, events, tenancy, utils } from "@budibase/backend-core"
|
||||||
|
|
||||||
describe("/api/global/users", () => {
|
describe("/api/global/users", () => {
|
||||||
const config = new TestConfiguration()
|
const config = new TestConfiguration()
|
||||||
|
@ -27,16 +22,18 @@ describe("/api/global/users", () => {
|
||||||
|
|
||||||
describe("invite", () => {
|
describe("invite", () => {
|
||||||
it("should be able to generate an invitation", async () => {
|
it("should be able to generate an invitation", async () => {
|
||||||
const email = structures.users.newEmail()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
const { code, res } = await config.api.users.sendUserInvite(
|
const email = structures.users.newEmail()
|
||||||
sendMailMock,
|
const { code, res } = await config.api.users.sendUserInvite(
|
||||||
email
|
sendMailMock,
|
||||||
)
|
email
|
||||||
|
)
|
||||||
|
|
||||||
expect(res.body).toEqual({ message: "Invitation has been sent." })
|
expect(res.body).toEqual({ message: "Invitation has been sent." })
|
||||||
expect(sendMailMock).toHaveBeenCalled()
|
expect(sendMailMock).toHaveBeenCalled()
|
||||||
expect(code).toBeDefined()
|
expect(code).toBeDefined()
|
||||||
expect(events.user.invited).toBeCalledTimes(1)
|
expect(events.user.invited).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should not be able to generate an invitation for existing user", async () => {
|
it("should not be able to generate an invitation for existing user", async () => {
|
||||||
|
@ -53,20 +50,22 @@ describe("/api/global/users", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should be able to create new user from invite", async () => {
|
it("should be able to create new user from invite", async () => {
|
||||||
const email = structures.users.newEmail()
|
await context.doInTenant(config.tenant1User!.tenantId, async () => {
|
||||||
const { code } = await config.api.users.sendUserInvite(
|
const email = structures.users.newEmail()
|
||||||
sendMailMock,
|
const { code } = await config.api.users.sendUserInvite(
|
||||||
email
|
sendMailMock,
|
||||||
)
|
email
|
||||||
|
)
|
||||||
|
|
||||||
const res = await config.api.users.acceptInvite(code)
|
const res = await config.api.users.acceptInvite(code)
|
||||||
|
|
||||||
expect(res.body._id).toBeDefined()
|
expect(res.body._id).toBeDefined()
|
||||||
const user = await config.getUser(email)
|
const user = await config.getUser(email)
|
||||||
expect(user).toBeDefined()
|
expect(user).toBeDefined()
|
||||||
expect(user._id).toEqual(res.body._id)
|
expect(user._id).toEqual(res.body._id)
|
||||||
expect(events.user.inviteAccepted).toBeCalledTimes(1)
|
expect(events.user.inviteAccepted).toBeCalledTimes(1)
|
||||||
expect(events.user.inviteAccepted).toBeCalledWith(user)
|
expect(events.user.inviteAccepted).toBeCalledWith(user)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -118,7 +117,7 @@ describe("/api/global/users", () => {
|
||||||
const user = await config.createUser()
|
const user = await config.createUser()
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
|
|
||||||
await tenancy.doInTenant(TENANT_1, async () => {
|
await tenancy.doInTenant(config.getTenantId(), async () => {
|
||||||
const response = await config.api.users.bulkCreateUsers([user])
|
const response = await config.api.users.bulkCreateUsers([user])
|
||||||
|
|
||||||
expect(response.created?.successful.length).toBe(0)
|
expect(response.created?.successful.length).toBe(0)
|
||||||
|
@ -231,7 +230,7 @@ describe("/api/global/users", () => {
|
||||||
const user = await config.createUser()
|
const user = await config.createUser()
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
|
|
||||||
await tenancy.doInTenant(TENANT_1, async () => {
|
await tenancy.doInTenant(config.getTenantId(), async () => {
|
||||||
delete user._id
|
delete user._id
|
||||||
const response = await config.api.users.saveUser(user, 400)
|
const response = await config.api.users.saveUser(user, 400)
|
||||||
|
|
||||||
|
@ -444,7 +443,7 @@ describe("/api/global/users", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
it("should not be able to update email address", async () => {
|
it("should not be able to update email address", async () => {
|
||||||
const email = "email@test.com"
|
const email = `${utils.newid()}@test.com`
|
||||||
const user = await config.createUser(structures.users.user({ email }))
|
const user = await config.createUser(structures.users.user({ email }))
|
||||||
user.email = "new@test.com"
|
user.email = "new@test.com"
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,11 @@ import {
|
||||||
auth,
|
auth,
|
||||||
constants,
|
constants,
|
||||||
env as coreEnv,
|
env as coreEnv,
|
||||||
|
context,
|
||||||
|
utils,
|
||||||
|
DEFAULT_TENANT_ID,
|
||||||
} from "@budibase/backend-core"
|
} from "@budibase/backend-core"
|
||||||
import structures, { TENANT_ID, TENANT_1, CSRF_TOKEN } from "./structures"
|
import structures, { TENANT_ID, CSRF_TOKEN } from "./structures"
|
||||||
import { CreateUserResponse, User, AuthToken } from "@budibase/types"
|
import { CreateUserResponse, User, AuthToken } from "@budibase/types"
|
||||||
import API from "./api"
|
import API from "./api"
|
||||||
|
|
||||||
|
@ -36,6 +39,7 @@ class TestConfiguration {
|
||||||
api: API
|
api: API
|
||||||
defaultUser?: User
|
defaultUser?: User
|
||||||
tenant1User?: User
|
tenant1User?: User
|
||||||
|
#tenantId?: string
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
opts: { openServer: boolean; mode: Mode } = {
|
opts: { openServer: boolean; mode: Mode } = {
|
||||||
|
@ -112,10 +116,12 @@ class TestConfiguration {
|
||||||
// SETUP / TEARDOWN
|
// SETUP / TEARDOWN
|
||||||
|
|
||||||
async beforeAll() {
|
async beforeAll() {
|
||||||
|
this.#tenantId = `tenant-${utils.newid()}`
|
||||||
|
|
||||||
await this.createDefaultUser()
|
await this.createDefaultUser()
|
||||||
await this.createSession(this.defaultUser!)
|
await this.createSession(this.defaultUser!)
|
||||||
|
|
||||||
await tenancy.doInTenant(TENANT_1, async () => {
|
await tenancy.doInTenant(this.#tenantId, async () => {
|
||||||
await this.createTenant1User()
|
await this.createTenant1User()
|
||||||
await this.createSession(this.tenant1User!)
|
await this.createSession(this.tenant1User!)
|
||||||
})
|
})
|
||||||
|
@ -152,7 +158,7 @@ class TestConfiguration {
|
||||||
try {
|
try {
|
||||||
return tenancy.getTenantId()
|
return tenancy.getTenantId()
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
return TENANT_ID
|
return DEFAULT_TENANT_ID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +209,7 @@ class TestConfiguration {
|
||||||
const tenantId = this.getTenantId()
|
const tenantId = this.getTenantId()
|
||||||
if (tenantId === TENANT_ID) {
|
if (tenantId === TENANT_ID) {
|
||||||
return this.authHeaders(this.defaultUser!)
|
return this.authHeaders(this.defaultUser!)
|
||||||
} else if (tenantId === TENANT_1) {
|
} else if (tenantId === this.getTenantId()) {
|
||||||
return this.authHeaders(this.tenant1User!)
|
return this.authHeaders(this.tenant1User!)
|
||||||
} else {
|
} else {
|
||||||
throw new Error("could not determine auth headers to use")
|
throw new Error("could not determine auth headers to use")
|
||||||
|
@ -222,7 +228,6 @@ class TestConfiguration {
|
||||||
|
|
||||||
async createDefaultUser() {
|
async createDefaultUser() {
|
||||||
const user = structures.users.adminUser({
|
const user = structures.users.adminUser({
|
||||||
email: "test@test.com",
|
|
||||||
password: "test",
|
password: "test",
|
||||||
})
|
})
|
||||||
this.defaultUser = await this.createUser(user)
|
this.defaultUser = await this.createUser(user)
|
||||||
|
@ -230,7 +235,6 @@ class TestConfiguration {
|
||||||
|
|
||||||
async createTenant1User() {
|
async createTenant1User() {
|
||||||
const user = structures.users.adminUser({
|
const user = structures.users.adminUser({
|
||||||
email: "tenant1@test.com",
|
|
||||||
password: "test",
|
password: "test",
|
||||||
})
|
})
|
||||||
this.tenant1User = await this.createUser(user)
|
this.tenant1User = await this.createUser(user)
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import structures from "../structures"
|
||||||
import TestConfiguration from "../TestConfiguration"
|
import TestConfiguration from "../TestConfiguration"
|
||||||
import { TestAPI } from "./base"
|
import { TestAPI } from "./base"
|
||||||
|
|
||||||
|
@ -24,14 +25,17 @@ export class AuthAPI extends TestAPI {
|
||||||
.expect(200)
|
.expect(200)
|
||||||
}
|
}
|
||||||
|
|
||||||
requestPasswordReset = async (sendMailMock: any) => {
|
requestPasswordReset = async (sendMailMock: any, userEmail: string) => {
|
||||||
await this.config.saveSmtpConfig()
|
await this.config.saveSmtpConfig()
|
||||||
await this.config.saveSettingsConfig()
|
await this.config.saveSettingsConfig()
|
||||||
await this.config.createUser()
|
await this.config.createUser({
|
||||||
|
...structures.users.user(),
|
||||||
|
email: userEmail,
|
||||||
|
})
|
||||||
const res = await this.request
|
const res = await this.request
|
||||||
.post(`/api/global/auth/${this.config.getTenantId()}/reset`)
|
.post(`/api/global/auth/${this.config.getTenantId()}/reset`)
|
||||||
.send({
|
.send({
|
||||||
email: "test@test.com",
|
email: userEmail,
|
||||||
})
|
})
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
|
|
@ -10,8 +10,8 @@ export class ConfigAPI extends TestAPI {
|
||||||
return this.request
|
return this.request
|
||||||
.get(`/api/global/configs/checklist`)
|
.get(`/api/global/configs/checklist`)
|
||||||
.set(this.config.defaultHeaders())
|
.set(this.config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
}
|
}
|
||||||
|
|
||||||
saveConfig = (data: any) => {
|
saveConfig = (data: any) => {
|
||||||
|
@ -19,8 +19,8 @@ export class ConfigAPI extends TestAPI {
|
||||||
.post(`/api/global/configs`)
|
.post(`/api/global/configs`)
|
||||||
.send(data)
|
.send(data)
|
||||||
.set(this.config.defaultHeaders())
|
.set(this.config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
|
||||||
.expect(200)
|
.expect(200)
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
}
|
}
|
||||||
|
|
||||||
OIDCCallback = (configId: string, preAuthRes: any) => {
|
OIDCCallback = (configId: string, preAuthRes: any) => {
|
||||||
|
|
|
@ -26,8 +26,8 @@ export class UserAPI extends TestAPI {
|
||||||
email,
|
email,
|
||||||
})
|
})
|
||||||
.set(this.config.defaultHeaders())
|
.set(this.config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
|
||||||
.expect(status)
|
.expect(status)
|
||||||
|
.expect("Content-Type", /json/)
|
||||||
|
|
||||||
if (status !== 200) {
|
if (status !== 200) {
|
||||||
return { code: undefined, res }
|
return { code: undefined, res }
|
||||||
|
@ -99,7 +99,7 @@ export class UserAPI extends TestAPI {
|
||||||
request = {
|
request = {
|
||||||
email: structures.email(),
|
email: structures.email(),
|
||||||
password: generator.string(),
|
password: generator.string(),
|
||||||
tenantId: structures.uuid(),
|
tenantId: `tenant-${structures.uuid()}`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const res = await this.request
|
const res = await this.request
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
import env from "../environment"
|
process.env.SELF_HOSTED = "0"
|
||||||
import { env as coreEnv } from "@budibase/backend-core"
|
process.env.NODE_ENV = "jest"
|
||||||
|
process.env.JWT_SECRET = "test-jwtsecret"
|
||||||
env._set("SELF_HOSTED", "0")
|
process.env.LOG_LEVEL = "silent"
|
||||||
env._set("NODE_ENV", "jest")
|
process.env.MULTI_TENANCY = "1"
|
||||||
env._set("JWT_SECRET", "test-jwtsecret")
|
process.env.MINIO_URL = "http://localhost"
|
||||||
env._set("LOG_LEVEL", "silent")
|
process.env.MINIO_ACCESS_KEY = "test"
|
||||||
env._set("MULTI_TENANCY", "1")
|
process.env.MINIO_SECRET_KEY = "test"
|
||||||
env._set("MINIO_URL", "http://localhost")
|
process.env.PLATFORM_URL = "http://localhost:10000"
|
||||||
env._set("MINIO_ACCESS_KEY", "test")
|
process.env.INTERNAL_API_KEY = "tet"
|
||||||
env._set("MINIO_SECRET_KEY", "test")
|
process.env.DISABLE_ACCOUNT_PORTAL = "0"
|
||||||
env._set("PLATFORM_URL", "http://localhost:10000")
|
|
||||||
env._set("INTERNAL_API_KEY", "test")
|
|
||||||
env._set("DISABLE_ACCOUNT_PORTAL", "0")
|
|
||||||
coreEnv._set("COUCH_DB_USER", "budibase")
|
|
||||||
coreEnv._set("COUCH_DB_PASSWORD", "budibase")
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { mocks } from "@budibase/backend-core/tests"
|
import { mocks } from "@budibase/backend-core/tests"
|
||||||
|
|
||||||
|
import env from "../environment"
|
||||||
|
import { env as coreEnv } from "@budibase/backend-core"
|
||||||
|
|
||||||
// must explicitly enable fetch mock
|
// must explicitly enable fetch mock
|
||||||
mocks.fetch.enable()
|
mocks.fetch.enable()
|
||||||
|
|
||||||
|
@ -17,3 +20,24 @@ if (!process.env.CI) {
|
||||||
// 100 seconds
|
// 100 seconds
|
||||||
jest.setTimeout(100000)
|
jest.setTimeout(100000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function overrideConfigValue(key: string, value: string) {
|
||||||
|
env._set(key, value)
|
||||||
|
coreEnv._set(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const globalSafe = global as any
|
||||||
|
|
||||||
|
overrideConfigValue(
|
||||||
|
"COUCH_DB_PORT",
|
||||||
|
globalSafe.__TESTCONTAINERS_DEVENV_PORT_5984__
|
||||||
|
)
|
||||||
|
overrideConfigValue(
|
||||||
|
"COUCH_DB_URL",
|
||||||
|
`http://${globalSafe.__TESTCONTAINERS_DEVENV_IP__}:${globalSafe.__TESTCONTAINERS_DEVENV_PORT_5984__}`
|
||||||
|
)
|
||||||
|
|
||||||
|
overrideConfigValue(
|
||||||
|
"MINIO_URL",
|
||||||
|
`http://${globalSafe.__TESTCONTAINERS_DEVENV_IP__}:${globalSafe.__TESTCONTAINERS_DEVENV_PORT_9000__}`
|
||||||
|
)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import * as groups from "./groups"
|
||||||
import { v4 as uuid } from "uuid"
|
import { v4 as uuid } from "uuid"
|
||||||
|
|
||||||
export const TENANT_ID = "default"
|
export const TENANT_ID = "default"
|
||||||
export const TENANT_1 = "tenant1"
|
|
||||||
export const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
|
export const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
|
||||||
|
|
||||||
const pkg = {
|
const pkg = {
|
||||||
|
@ -14,7 +13,6 @@ const pkg = {
|
||||||
configs,
|
configs,
|
||||||
users,
|
users,
|
||||||
TENANT_ID,
|
TENANT_ID,
|
||||||
TENANT_1,
|
|
||||||
CSRF_TOKEN,
|
CSRF_TOKEN,
|
||||||
groups,
|
groups,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue