Test fixes

This commit is contained in:
Rory Powell 2022-11-11 15:43:41 +00:00
parent 0bad2dd9ae
commit 80b823f6cf
33 changed files with 285 additions and 189 deletions

View File

@ -21,7 +21,6 @@ export const buildMatcherRegex = (
const suffix = match.endsWith("/") ? "/" : "" const suffix = match.endsWith("/") ? "/" : ""
const pattern = "/.*" + suffix const pattern = "/.*" + suffix
route = route.replace(match, pattern) route = route.replace(match, pattern)
console.log(route)
} }
} }

View File

@ -225,6 +225,7 @@ export const getTenantIDFromCtx = (
} }
} }
// path
if (isAllowed(TenantResolutionStrategy.PATH)) { if (isAllowed(TenantResolutionStrategy.PATH)) {
// params - have to parse manually due to koa-router not run yet // params - have to parse manually due to koa-router not run yet
const match = ctx.matched.find( const match = ctx.matched.find(

View File

@ -1 +1,7 @@
import { v4 as uuid } from "uuid"
export { v4 as uuid } from "uuid" export { v4 as uuid } from "uuid"
export const email = () => {
return `${uuid()}@test.com`
}

View File

@ -51,3 +51,9 @@ export interface SearchUsersRequest {
appId?: string appId?: string
userIds?: string[] userIds?: string[]
} }
export interface CreateAdminUserRequest {
email: string
password: string
tenantId: string
}

View File

@ -5,6 +5,7 @@ import {
BulkUserRequest, BulkUserRequest,
BulkUserResponse, BulkUserResponse,
CloudAccount, CloudAccount,
CreateAdminUserRequest,
InviteUserRequest, InviteUserRequest,
InviteUsersRequest, InviteUsersRequest,
SearchUsersRequest, SearchUsersRequest,
@ -67,7 +68,8 @@ const parseBooleanParam = (param: any) => {
} }
export const adminUser = async (ctx: any) => { export const adminUser = async (ctx: any) => {
const { email, password, tenantId } = ctx.request.body const { email, password, tenantId } = ctx.request
.body as CreateAdminUserRequest
await tenancy.doInTenant(tenantId, async () => { await tenancy.doInTenant(tenantId, async () => {
// account portal sends a pre-hashed password - honour param to prevent double hashing // account portal sends a pre-hashed password - honour param to prevent double hashing
const hashPassword = parseBooleanParam(ctx.request.query.hashPassword) const hashPassword = parseBooleanParam(ctx.request.query.hashPassword)

View File

@ -11,8 +11,8 @@ const _delete = async (ctx: BBContext) => {
} }
try { try {
await deprovisioning.deleteTenant(tenantId)
await quotas.bustCache() await quotas.bustCache()
await deprovisioning.deleteTenant(tenantId)
ctx.status = 204 ctx.status = 204
} catch (err) { } catch (err) {
ctx.log.error(err) ctx.log.error(err)

View File

@ -1,11 +1,10 @@
jest.mock("nodemailer") jest.mock("nodemailer")
import { TestConfiguration, mocks, API } 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 } from "@budibase/backend-core"
describe("/api/global/auth", () => { describe("/api/global/auth", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -20,12 +19,14 @@ describe("/api/global/auth", () => {
}) })
it("should logout", async () => { it("should logout", async () => {
await api.auth.logout() await config.api.auth.logout()
expect(events.auth.logout).toBeCalledTimes(1) expect(events.auth.logout).toBeCalledTimes(1)
}) })
it("should be able to generate password reset email", async () => { it("should be able to generate password reset email", async () => {
const { res, code } = await api.auth.requestPasswordReset(sendMailMock) const { res, code } = await config.api.auth.requestPasswordReset(
sendMailMock
)
const user = await config.getUser("test@test.com") const user = await config.getUser("test@test.com")
expect(res.body).toEqual({ expect(res.body).toEqual({
@ -39,11 +40,11 @@ describe("/api/global/auth", () => {
}) })
it("should allow resetting user password with code", async () => { it("should allow resetting user password with code", async () => {
const { code } = await api.auth.requestPasswordReset(sendMailMock) const { code } = await config.api.auth.requestPasswordReset(sendMailMock)
const user = await config.getUser("test@test.com") const user = await config.getUser("test@test.com")
delete user.password delete user.password
const res = await api.auth.updatePassword(code) const res = await config.api.auth.updatePassword(code)
expect(res.body).toEqual({ message: "password reset successfully." }) expect(res.body).toEqual({ message: "password reset successfully." })
expect(events.user.passwordReset).toBeCalledTimes(1) expect(events.user.passwordReset).toBeCalledTimes(1)
@ -80,7 +81,7 @@ describe("/api/global/auth", () => {
describe("oidc configs", () => { describe("oidc configs", () => {
it("should load strategy and delegate to passport", async () => { it("should load strategy and delegate to passport", async () => {
await api.configs.getOIDCConfig(configId) await config.api.configs.getOIDCConfig(configId)
expect(passportSpy).toBeCalledWith(mockStrategyReturn, { expect(passportSpy).toBeCalledWith(mockStrategyReturn, {
scope: ["profile", "email", "offline_access"], scope: ["profile", "email", "offline_access"],
@ -91,7 +92,7 @@ describe("/api/global/auth", () => {
describe("oidc callback", () => { describe("oidc callback", () => {
it("should load strategy and delegate to passport", async () => { it("should load strategy and delegate to passport", async () => {
await api.configs.OIDCCallback(configId) await config.api.configs.OIDCCallback(configId)
expect(passportSpy).toBeCalledWith( expect(passportSpy).toBeCalledWith(
mockStrategyReturn, mockStrategyReturn,

View File

@ -1,12 +1,11 @@
// mock the email system // mock the email system
jest.mock("nodemailer") jest.mock("nodemailer")
import { TestConfiguration, structures, mocks, API } from "../../../../tests" import { TestConfiguration, structures, mocks } from "../../../../tests"
mocks.email.mock() mocks.email.mock()
import { Configs, events } from "@budibase/backend-core" import { Configs, events } from "@budibase/backend-core"
describe("configs", () => { describe("configs", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -28,7 +27,7 @@ describe("configs", () => {
_rev, _rev,
} }
const res = await api.configs.saveConfig(data) const res = await config.api.configs.saveConfig(data)
return { return {
...data, ...data,
@ -266,7 +265,7 @@ describe("configs", () => {
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 config.saveSmtpConfig()
const res = await 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()

View File

@ -1,11 +1,10 @@
jest.mock("nodemailer") jest.mock("nodemailer")
import { TestConfiguration, mocks, API } from "../../../../tests" import { TestConfiguration, mocks } from "../../../../tests"
const sendMailMock = mocks.email.mock() const sendMailMock = mocks.email.mock()
import { EmailTemplatePurpose } from "../../../../constants" import { EmailTemplatePurpose } from "../../../../constants"
describe("/api/global/email", () => { describe("/api/global/email", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -20,7 +19,9 @@ describe("/api/global/email", () => {
await config.saveSmtpConfig() await config.saveSmtpConfig()
await config.saveSettingsConfig() await config.saveSettingsConfig()
const res = await api.emails.sendEmail(EmailTemplatePurpose.INVITATION) const res = await config.api.emails.sendEmail(
EmailTemplatePurpose.INVITATION
)
expect(res.body.message).toBeDefined() expect(res.body.message).toBeDefined()
expect(sendMailMock).toHaveBeenCalled() expect(sendMailMock).toHaveBeenCalled()

View File

@ -1,8 +1,9 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
// TODO
describe("/api/global/license", () => { describe("/api/global/license", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -16,7 +17,9 @@ describe("/api/global/license", () => {
jest.clearAllMocks() jest.clearAllMocks()
}) })
describe("POST /api/global/license/activate", () => {}) describe("POST /api/global/license/activate", () => {
it("activates license", () => {})
})
describe("POST /api/global/license/refresh", () => {}) describe("POST /api/global/license/refresh", () => {})

View File

@ -1,4 +1,4 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
import { EmailTemplatePurpose } from "../../../../constants" import { EmailTemplatePurpose } from "../../../../constants"
const nodemailer = require("nodemailer") const nodemailer = require("nodemailer")
const fetch = require("node-fetch") const fetch = require("node-fetch")
@ -8,7 +8,6 @@ jest.setTimeout(30000)
describe("/api/global/email", () => { describe("/api/global/email", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -35,7 +34,7 @@ describe("/api/global/email", () => {
await Promise.race([config.saveEtherealSmtpConfig(), timeout()]) await Promise.race([config.saveEtherealSmtpConfig(), timeout()])
await Promise.race([config.saveSettingsConfig(), timeout()]) await Promise.race([config.saveSettingsConfig(), timeout()])
const res = await api.emails.sendEmail(purpose).timeout(20000) const res = await config.api.emails.sendEmail(purpose).timeout(20000)
// ethereal hiccup, can't test right now // ethereal hiccup, can't test right now
if (res.status >= 300) { if (res.status >= 300) {
return return

View File

@ -1,8 +1,9 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
// TODO
describe("/api/global/roles", () => { describe("/api/global/roles", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -16,7 +17,9 @@ describe("/api/global/roles", () => {
jest.clearAllMocks() jest.clearAllMocks()
}) })
describe("GET /api/global/roles", () => {}) describe("GET /api/global/roles", () => {
it("retrieves roles", () => {})
})
describe("GET /api/global/roles/:appId", () => {}) describe("GET /api/global/roles/:appId", () => {})

View File

@ -1,10 +1,9 @@
jest.mock("nodemailer") jest.mock("nodemailer")
import { TestConfiguration, API, mocks } from "../../../../tests" import { TestConfiguration, mocks } from "../../../../tests"
import { events } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
describe("/api/global/self", () => { describe("/api/global/self", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -24,7 +23,7 @@ describe("/api/global/self", () => {
await config.createSession(user) await config.createSession(user)
delete user.password delete user.password
const res = await api.self.updateSelf(user) const res = await config.api.self.updateSelf(user)
const dbUser = await config.getUser(user.email) const dbUser = await config.getUser(user.email)
user._rev = dbUser._rev user._rev = dbUser._rev
@ -40,7 +39,7 @@ describe("/api/global/self", () => {
await config.createSession(user) await config.createSession(user)
user.password = "newPassword" user.password = "newPassword"
const res = await api.self.updateSelf(user) const res = await config.api.self.updateSelf(user)
const dbUser = await config.getUser(user.email) const dbUser = await config.getUser(user.email)
user._rev = dbUser._rev user._rev = dbUser._rev

View File

@ -1,8 +1,9 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
// TODO
describe("/api/global/template", () => { describe("/api/global/template", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -16,7 +17,9 @@ describe("/api/global/template", () => {
jest.clearAllMocks() jest.clearAllMocks()
}) })
describe("GET /api/global/template/definitions", () => {}) describe("GET /api/global/template/definitions", () => {
it("retrieves definitions", () => {})
})
describe("POST /api/global/template", () => {}) describe("POST /api/global/template", () => {})

View File

@ -6,14 +6,12 @@ import {
mocks, mocks,
structures, structures,
TENANT_1, TENANT_1,
API,
} from "../../../../tests" } from "../../../../tests"
const sendMailMock = mocks.email.mock() const sendMailMock = mocks.email.mock()
import { events, tenancy } from "@budibase/backend-core" import { events, tenancy } from "@budibase/backend-core"
describe("/api/global/users", () => { describe("/api/global/users", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -30,7 +28,10 @@ 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() const email = structures.users.newEmail()
const { code, res } = await api.users.sendUserInvite(sendMailMock, email) const { code, res } = await config.api.users.sendUserInvite(
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()
@ -39,7 +40,7 @@ describe("/api/global/users", () => {
}) })
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 () => {
const { code, res } = await api.users.sendUserInvite( const { code, res } = await config.api.users.sendUserInvite(
sendMailMock, sendMailMock,
config.defaultUser!.email, config.defaultUser!.email,
400 400
@ -53,9 +54,12 @@ 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() const email = structures.users.newEmail()
const { code } = await api.users.sendUserInvite(sendMailMock, email) const { code } = await config.api.users.sendUserInvite(
sendMailMock,
email
)
const res = await 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)
@ -74,7 +78,7 @@ describe("/api/global/users", () => {
}) })
const request = [newUserInvite(), newUserInvite()] const request = [newUserInvite(), newUserInvite()]
const res = await api.users.sendMultiUserInvite(request) const res = await config.api.users.sendMultiUserInvite(request)
const body = res.body as InviteUsersResponse const body = res.body as InviteUsersResponse
expect(body.successful.length).toBe(2) expect(body.successful.length).toBe(2)
@ -86,7 +90,7 @@ describe("/api/global/users", () => {
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 () => {
const request = [{ email: config.defaultUser!.email, userInfo: {} }] const request = [{ email: config.defaultUser!.email, userInfo: {} }]
const res = await api.users.sendMultiUserInvite(request) const res = await config.api.users.sendMultiUserInvite(request)
const body = res.body as InviteUsersResponse const body = res.body as InviteUsersResponse
expect(body.successful.length).toBe(0) expect(body.successful.length).toBe(0)
@ -102,7 +106,7 @@ describe("/api/global/users", () => {
const user = await config.createUser() const user = await config.createUser()
jest.clearAllMocks() jest.clearAllMocks()
const response = await 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)
expect(response.created?.unsuccessful.length).toBe(1) expect(response.created?.unsuccessful.length).toBe(1)
@ -115,7 +119,7 @@ describe("/api/global/users", () => {
jest.resetAllMocks() jest.resetAllMocks()
await tenancy.doInTenant(TENANT_1, async () => { await tenancy.doInTenant(TENANT_1, async () => {
const response = await 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)
expect(response.created?.unsuccessful.length).toBe(1) expect(response.created?.unsuccessful.length).toBe(1)
@ -126,11 +130,11 @@ describe("/api/global/users", () => {
it("should ignore accounts using the same email", async () => { it("should ignore accounts using the same email", async () => {
const account = structures.accounts.account() const account = structures.accounts.account()
const resp = await api.accounts.saveMetadata(account) const resp = await config.api.accounts.saveMetadata(account)
const user = structures.users.user({ email: resp.email }) const user = structures.users.user({ email: resp.email })
jest.clearAllMocks() jest.clearAllMocks()
const response = await 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)
expect(response.created?.unsuccessful.length).toBe(1) expect(response.created?.unsuccessful.length).toBe(1)
@ -143,7 +147,11 @@ describe("/api/global/users", () => {
const admin = structures.users.adminUser() const admin = structures.users.adminUser()
const user = structures.users.user() const user = structures.users.user()
const response = await api.users.bulkCreateUsers([builder, admin, user]) const response = await config.api.users.bulkCreateUsers([
builder,
admin,
user,
])
expect(response.created?.successful.length).toBe(3) expect(response.created?.successful.length).toBe(3)
expect(response.created?.successful[0].email).toBe(builder.email) expect(response.created?.successful[0].email).toBe(builder.email)
@ -160,7 +168,7 @@ describe("/api/global/users", () => {
it("should be able to create a basic user", async () => { it("should be able to create a basic user", async () => {
const user = structures.users.user() const user = structures.users.user()
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).toBeCalledTimes(1) expect(events.user.created).toBeCalledTimes(1)
expect(events.user.updated).not.toBeCalled() expect(events.user.updated).not.toBeCalled()
@ -171,7 +179,7 @@ describe("/api/global/users", () => {
it("should be able to create an admin user", async () => { it("should be able to create an admin user", async () => {
const user = structures.users.adminUser() const user = structures.users.adminUser()
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).toBeCalledTimes(1) expect(events.user.created).toBeCalledTimes(1)
expect(events.user.updated).not.toBeCalled() expect(events.user.updated).not.toBeCalled()
@ -182,7 +190,7 @@ describe("/api/global/users", () => {
it("should be able to create a builder user", async () => { it("should be able to create a builder user", async () => {
const user = structures.users.builderUser() const user = structures.users.builderUser()
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).toBeCalledTimes(1) expect(events.user.created).toBeCalledTimes(1)
expect(events.user.updated).not.toBeCalled() expect(events.user.updated).not.toBeCalled()
@ -197,7 +205,7 @@ describe("/api/global/users", () => {
app_456: "role2", app_456: "role2",
} }
await api.users.saveUser(user) await config.api.users.saveUser(user)
const savedUser = await config.getUser(user.email) const savedUser = await config.getUser(user.email)
expect(events.user.created).toBeCalledTimes(1) expect(events.user.created).toBeCalledTimes(1)
@ -213,7 +221,7 @@ describe("/api/global/users", () => {
delete user._id delete user._id
delete user._rev delete user._rev
const response = await api.users.saveUser(user, 400) const response = await config.api.users.saveUser(user, 400)
expect(response.body.message).toBe(`Unavailable`) expect(response.body.message).toBe(`Unavailable`)
expect(events.user.created).toBeCalledTimes(0) expect(events.user.created).toBeCalledTimes(0)
@ -225,7 +233,7 @@ describe("/api/global/users", () => {
await tenancy.doInTenant(TENANT_1, async () => { await tenancy.doInTenant(TENANT_1, async () => {
delete user._id delete user._id
const response = await api.users.saveUser(user, 400) const response = await config.api.users.saveUser(user, 400)
expect(response.body.message).toBe(`Unavailable`) expect(response.body.message).toBe(`Unavailable`)
expect(events.user.created).toBeCalledTimes(0) expect(events.user.created).toBeCalledTimes(0)
@ -237,7 +245,7 @@ describe("/api/global/users", () => {
const account = structures.accounts.cloudAccount() const account = structures.accounts.cloudAccount()
mocks.accounts.getAccount.mockReturnValueOnce(account) mocks.accounts.getAccount.mockReturnValueOnce(account)
const response = await api.users.saveUser(user, 400) const response = await config.api.users.saveUser(user, 400)
expect(response.body.message).toBe(`Unavailable`) expect(response.body.message).toBe(`Unavailable`)
expect(events.user.created).toBeCalledTimes(0) expect(events.user.created).toBeCalledTimes(0)
@ -245,20 +253,20 @@ describe("/api/global/users", () => {
it("should not be able to create a user with the same email and different casing", async () => { it("should not be able to create a user with the same email and different casing", async () => {
const user = structures.users.user() const user = structures.users.user()
await api.users.saveUser(user) await config.api.users.saveUser(user)
user.email = user.email.toUpperCase() user.email = user.email.toUpperCase()
await api.users.saveUser(user, 400) await config.api.users.saveUser(user, 400)
expect(events.user.created).toBeCalledTimes(1) expect(events.user.created).toBeCalledTimes(1)
}) })
it("should not be able to bulk create a user with the same email and different casing", async () => { it("should not be able to bulk create a user with the same email and different casing", async () => {
const user = structures.users.user() const user = structures.users.user()
await api.users.saveUser(user) await config.api.users.saveUser(user)
user.email = user.email.toUpperCase() user.email = user.email.toUpperCase()
await api.users.bulkCreateUsers([user]) await config.api.users.bulkCreateUsers([user])
expect(events.user.created).toBeCalledTimes(1) expect(events.user.created).toBeCalledTimes(1)
}) })
@ -269,7 +277,7 @@ describe("/api/global/users", () => {
const user = await config.createUser() const user = await config.createUser()
jest.clearAllMocks() jest.clearAllMocks()
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
expect(events.user.updated).toBeCalledTimes(1) expect(events.user.updated).toBeCalledTimes(1)
@ -284,7 +292,7 @@ describe("/api/global/users", () => {
user.forceResetPassword = true user.forceResetPassword = true
user.password = "tempPassword" user.password = "tempPassword"
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
expect(events.user.updated).toBeCalledTimes(1) expect(events.user.updated).toBeCalledTimes(1)
@ -297,7 +305,7 @@ describe("/api/global/users", () => {
const user = await config.createUser() const user = await config.createUser()
jest.clearAllMocks() jest.clearAllMocks()
await api.users.saveUser(structures.users.adminUser(user)) await config.api.users.saveUser(structures.users.adminUser(user))
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
expect(events.user.updated).toBeCalledTimes(1) expect(events.user.updated).toBeCalledTimes(1)
@ -309,7 +317,7 @@ describe("/api/global/users", () => {
const user = await config.createUser() const user = await config.createUser()
jest.clearAllMocks() jest.clearAllMocks()
await api.users.saveUser(structures.users.builderUser(user)) await config.api.users.saveUser(structures.users.builderUser(user))
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
expect(events.user.updated).toBeCalledTimes(1) expect(events.user.updated).toBeCalledTimes(1)
@ -323,7 +331,7 @@ describe("/api/global/users", () => {
user.admin!.global = false user.admin!.global = false
user.builder!.global = false user.builder!.global = false
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
expect(events.user.updated).toBeCalledTimes(1) expect(events.user.updated).toBeCalledTimes(1)
@ -336,7 +344,7 @@ describe("/api/global/users", () => {
jest.clearAllMocks() jest.clearAllMocks()
user.builder!.global = false user.builder!.global = false
await api.users.saveUser(user) await config.api.users.saveUser(user)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
expect(events.user.updated).toBeCalledTimes(1) expect(events.user.updated).toBeCalledTimes(1)
@ -352,7 +360,7 @@ describe("/api/global/users", () => {
app_456: "role2", app_456: "role2",
} }
await api.users.saveUser(user) await config.api.users.saveUser(user)
const savedUser = await config.getUser(user.email) const savedUser = await config.getUser(user.email)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
@ -372,7 +380,7 @@ describe("/api/global/users", () => {
jest.clearAllMocks() jest.clearAllMocks()
user.roles = {} user.roles = {}
await api.users.saveUser(user) await config.api.users.saveUser(user)
const savedUser = await config.getUser(user.email) const savedUser = await config.getUser(user.email)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
@ -395,7 +403,7 @@ describe("/api/global/users", () => {
app_456: "role2-edit", app_456: "role2-edit",
} }
await api.users.saveUser(user) await config.api.users.saveUser(user)
const savedUser = await config.getUser(user.email) const savedUser = await config.getUser(user.email)
expect(events.user.created).not.toBeCalled() expect(events.user.created).not.toBeCalled()
@ -411,7 +419,7 @@ describe("/api/global/users", () => {
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"
const response = await api.users.saveUser(user, 400) const response = await config.api.users.saveUser(user, 400)
const dbUser = await config.getUser(email) const dbUser = await config.getUser(email)
user.email = email user.email = email
@ -424,7 +432,7 @@ describe("/api/global/users", () => {
it("should not be able to bulk delete current user", async () => { it("should not be able to bulk delete current user", async () => {
const user = await config.defaultUser! const user = await config.defaultUser!
const response = await api.users.bulkDeleteUsers([user._id!], 400) const response = await config.api.users.bulkDeleteUsers([user._id!], 400)
expect(response.message).toBe("Unable to delete self.") expect(response.message).toBe("Unable to delete self.")
expect(events.user.deleted).not.toBeCalled() expect(events.user.deleted).not.toBeCalled()
@ -436,7 +444,7 @@ describe("/api/global/users", () => {
account.budibaseUserId = user._id! account.budibaseUserId = user._id!
mocks.accounts.getAccountByTenantId.mockReturnValue(account) mocks.accounts.getAccountByTenantId.mockReturnValue(account)
const response = await api.users.bulkDeleteUsers([user._id!]) const response = await config.api.users.bulkDeleteUsers([user._id!])
expect(response.deleted?.successful.length).toBe(0) expect(response.deleted?.successful.length).toBe(0)
expect(response.deleted?.unsuccessful.length).toBe(1) expect(response.deleted?.unsuccessful.length).toBe(1)
@ -454,7 +462,7 @@ describe("/api/global/users", () => {
const builder = structures.users.builderUser() const builder = structures.users.builderUser()
const admin = structures.users.adminUser() const admin = structures.users.adminUser()
const user = structures.users.user() const user = structures.users.user()
const createdUsers = await api.users.bulkCreateUsers([ const createdUsers = await config.api.users.bulkCreateUsers([
builder, builder,
admin, admin,
user, user,
@ -463,7 +471,7 @@ describe("/api/global/users", () => {
const toDelete = createdUsers.created?.successful.map( const toDelete = createdUsers.created?.successful.map(
u => u._id! u => u._id!
) as string[] ) as string[]
const response = await api.users.bulkDeleteUsers(toDelete) const response = await config.api.users.bulkDeleteUsers(toDelete)
expect(response.deleted?.successful.length).toBe(3) expect(response.deleted?.successful.length).toBe(3)
expect(response.deleted?.unsuccessful.length).toBe(0) expect(response.deleted?.unsuccessful.length).toBe(0)
@ -478,7 +486,7 @@ describe("/api/global/users", () => {
const user = await config.createUser() const user = await config.createUser()
jest.clearAllMocks() jest.clearAllMocks()
await api.users.deleteUser(user._id!) await config.api.users.deleteUser(user._id!)
expect(events.user.deleted).toBeCalledTimes(1) expect(events.user.deleted).toBeCalledTimes(1)
expect(events.user.permissionBuilderRemoved).not.toBeCalled() expect(events.user.permissionBuilderRemoved).not.toBeCalled()
@ -489,7 +497,7 @@ describe("/api/global/users", () => {
const user = await config.createUser(structures.users.adminUser()) const user = await config.createUser(structures.users.adminUser())
jest.clearAllMocks() jest.clearAllMocks()
await api.users.deleteUser(user._id!) await config.api.users.deleteUser(user._id!)
expect(events.user.deleted).toBeCalledTimes(1) expect(events.user.deleted).toBeCalledTimes(1)
expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1) expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
@ -500,7 +508,7 @@ describe("/api/global/users", () => {
const user = await config.createUser(structures.users.builderUser()) const user = await config.createUser(structures.users.builderUser())
jest.clearAllMocks() jest.clearAllMocks()
await api.users.deleteUser(user._id!) await config.api.users.deleteUser(user._id!)
expect(events.user.deleted).toBeCalledTimes(1) expect(events.user.deleted).toBeCalledTimes(1)
expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1) expect(events.user.permissionBuilderRemoved).toBeCalledTimes(1)
@ -512,7 +520,7 @@ describe("/api/global/users", () => {
const account = structures.accounts.cloudAccount() const account = structures.accounts.cloudAccount()
mocks.accounts.getAccount.mockReturnValueOnce(account) mocks.accounts.getAccount.mockReturnValueOnce(account)
const response = await api.users.deleteUser(user._id!, 400) const response = await config.api.users.deleteUser(user._id!, 400)
expect(response.body.message).toBe("Account holder cannot be deleted") expect(response.body.message).toBe("Account holder cannot be deleted")
}) })
@ -523,7 +531,7 @@ describe("/api/global/users", () => {
account.email = user.email account.email = user.email
mocks.accounts.getAccount.mockReturnValueOnce(account) mocks.accounts.getAccount.mockReturnValueOnce(account)
const response = await api.users.deleteUser(user._id!, 400) const response = await config.api.users.deleteUser(user._id!, 400)
expect(response.body.message).toBe("Unable to delete self.") expect(response.body.message).toBe("Unable to delete self.")
}) })

View File

@ -1,8 +1,9 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
// TODO
describe("/api/global/workspaces", () => { describe("/api/global/workspaces", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -16,7 +17,9 @@ describe("/api/global/workspaces", () => {
jest.clearAllMocks() jest.clearAllMocks()
}) })
describe("GET /api/global/workspaces", () => {}) describe("GET /api/global/workspaces", () => {
it("retrieves workspaces", () => {})
})
describe("DELETE /api/global/workspaces/:id", () => {}) describe("DELETE /api/global/workspaces/:id", () => {})

View File

@ -1,10 +1,9 @@
import sdk from "../../../../sdk" import sdk from "../../../../sdk"
import { TestConfiguration, structures, API } from "../../../../tests" import { TestConfiguration, structures } from "../../../../tests"
import { v4 as uuid } from "uuid" import { v4 as uuid } from "uuid"
describe("accounts", () => { describe("accounts", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -23,7 +22,7 @@ describe("accounts", () => {
it("saves account metadata", async () => { it("saves account metadata", async () => {
let account = structures.accounts.account() let account = structures.accounts.account()
const response = await api.accounts.saveMetadata(account) const response = await config.api.accounts.saveMetadata(account)
const id = sdk.accounts.formatAccountMetadataId(account.accountId) const id = sdk.accounts.formatAccountMetadataId(account.accountId)
const metadata = await sdk.accounts.getMetadata(id) const metadata = await sdk.accounts.getMetadata(id)
@ -34,9 +33,9 @@ describe("accounts", () => {
describe("destroyMetadata", () => { describe("destroyMetadata", () => {
it("destroys account metadata", async () => { it("destroys account metadata", async () => {
const account = structures.accounts.account() const account = structures.accounts.account()
await api.accounts.saveMetadata(account) await config.api.accounts.saveMetadata(account)
await api.accounts.destroyMetadata(account.accountId) await config.api.accounts.destroyMetadata(account.accountId)
const deleted = await sdk.accounts.getMetadata(account.accountId) const deleted = await sdk.accounts.getMetadata(account.accountId)
expect(deleted).toBe(undefined) expect(deleted).toBe(undefined)
@ -45,7 +44,7 @@ describe("accounts", () => {
it("destroys account metadata that does not exist", async () => { it("destroys account metadata that does not exist", async () => {
const id = uuid() const id = uuid()
const response = await api.accounts.destroyMetadata(id) const response = await config.api.accounts.destroyMetadata(id)
expect(response.status).toBe(204) expect(response.status).toBe(204)
}) })

View File

@ -1,8 +1,7 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
describe("/api/system/environment", () => { describe("/api/system/environment", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -18,7 +17,7 @@ describe("/api/system/environment", () => {
describe("GET /api/system/environment", () => { describe("GET /api/system/environment", () => {
it("returns the expected environment", async () => { it("returns the expected environment", async () => {
const env = await api.environment.getEnvironment() const env = await config.api.environment.getEnvironment()
expect(env.body).toEqual({ expect(env.body).toEqual({
cloud: true, cloud: true,
disableAccountPortal: false, disableAccountPortal: false,

View File

@ -1,6 +1,6 @@
const migrateFn = jest.fn() const migrateFn = jest.fn()
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
jest.mock("../../../../migrations", () => { jest.mock("../../../../migrations", () => {
return { return {
@ -11,7 +11,6 @@ jest.mock("../../../../migrations", () => {
describe("/api/system/migrations", () => { describe("/api/system/migrations", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -27,7 +26,7 @@ describe("/api/system/migrations", () => {
describe("POST /api/system/migrations/run", () => { describe("POST /api/system/migrations/run", () => {
it("fails with no internal api key", async () => { it("fails with no internal api key", async () => {
const res = await api.migrations.runMigrations({ const res = await config.api.migrations.runMigrations({
headers: {}, headers: {},
status: 403, status: 403,
}) })
@ -36,7 +35,7 @@ describe("/api/system/migrations", () => {
}) })
it("runs migrations", async () => { it("runs migrations", async () => {
const res = await api.migrations.runMigrations() const res = await config.api.migrations.runMigrations()
expect(res.text).toBe("OK") expect(res.text).toBe("OK")
expect(migrateFn).toBeCalledTimes(1) expect(migrateFn).toBeCalledTimes(1)
}) })
@ -44,7 +43,7 @@ describe("/api/system/migrations", () => {
describe("DELETE /api/system/migrations/definitions", () => { describe("DELETE /api/system/migrations/definitions", () => {
it("fails with no internal api key", async () => { it("fails with no internal api key", async () => {
const res = await api.migrations.getMigrationDefinitions({ const res = await config.api.migrations.getMigrationDefinitions({
headers: {}, headers: {},
status: 403, status: 403,
}) })
@ -52,7 +51,7 @@ describe("/api/system/migrations", () => {
}) })
it("returns definitions", async () => { it("returns definitions", async () => {
const res = await api.migrations.getMigrationDefinitions() const res = await config.api.migrations.getMigrationDefinitions()
expect(res.body).toEqual([ expect(res.body).toEqual([
{ {
name: "global_info_sync_users", name: "global_info_sync_users",

View File

@ -1,8 +1,7 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
describe("/api/system/restore", () => { describe("/api/system/restore", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -18,7 +17,7 @@ describe("/api/system/restore", () => {
describe("POST /api/global/restore", () => { describe("POST /api/global/restore", () => {
it("doesn't allow restore in cloud", async () => { it("doesn't allow restore in cloud", async () => {
const res = await api.restore.restored({ status: 405 }) const res = await config.api.restore.restored({ status: 405 })
expect(res.body).toEqual({ expect(res.body).toEqual({
message: "This operation is not allowed in cloud.", message: "This operation is not allowed in cloud.",
status: 405, status: 405,
@ -27,7 +26,7 @@ describe("/api/system/restore", () => {
it("restores in self host", async () => { it("restores in self host", async () => {
config.modeSelf() config.modeSelf()
const res = await api.restore.restored() const res = await config.api.restore.restored()
expect(res.body).toEqual({ expect(res.body).toEqual({
message: "System prepared after restore.", message: "System prepared after restore.",
}) })

View File

@ -1,10 +1,9 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
import { accounts } from "@budibase/backend-core" import { accounts } from "@budibase/backend-core"
import { mocks } from "@budibase/backend-core/tests" import { mocks } from "@budibase/backend-core/tests"
describe("/api/system/status", () => { describe("/api/system/status", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -21,7 +20,7 @@ describe("/api/system/status", () => {
describe("GET /api/system/status", () => { describe("GET /api/system/status", () => {
it("returns status in self host", async () => { it("returns status in self host", async () => {
config.modeSelf() config.modeSelf()
const res = await api.status.getStatus() const res = await config.api.status.getStatus()
expect(res.body).toEqual({ expect(res.body).toEqual({
health: { health: {
passing: true, passing: true,
@ -40,7 +39,7 @@ describe("/api/system/status", () => {
mocks.accounts.getStatus.mockReturnValueOnce(value) mocks.accounts.getStatus.mockReturnValueOnce(value)
const res = await api.status.getStatus() const res = await config.api.status.getStatus()
expect(accounts.getStatus).toBeCalledTimes(1) expect(accounts.getStatus).toBeCalledTimes(1)
expect(res.body).toEqual(value) expect(res.body).toEqual(value)

View File

@ -1,8 +1,8 @@
import { TestConfiguration, API } from "../../../../tests" import { TestConfiguration } from "../../../../tests"
import { tenancy } from "@budibase/backend-core"
describe("/api/global/workspaces", () => { describe("/api/global/workspaces", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -19,14 +19,43 @@ describe("/api/global/workspaces", () => {
describe("DELETE /api/system/tenants/:tenantId", () => { describe("DELETE /api/system/tenants/:tenantId", () => {
it("allows deleting the current tenant", async () => { it("allows deleting the current tenant", async () => {
const user = await config.createTenant() const user = await config.createTenant()
await config.createSession(user)
const res = await api.tenants.delete(user.tenantId, { await config.api.tenants.delete(user.tenantId, {
headers: config.authHeaders(user), headers: config.authHeaders(user),
}) })
}) })
it("rejects deleting another tenant", () => {}) it("rejects deleting another tenant", async () => {
const user1 = await config.createTenant()
// create a second user in another tenant
const user2 = await config.createTenant()
it("requires admin", () => {}) const status = 403
const res = await config.api.tenants.delete(user1.tenantId, {
status,
headers: config.authHeaders(user2),
})
expect(res.body).toEqual({
message: "Tenant ID does not match current user",
status,
})
})
it("rejects non-admin", async () => {
const user1 = await config.createTenant()
// create an internal non-admin user
const user2 = await tenancy.doInTenant(user1.tenantId, () => {
return config.createUser()
})
await config.createSession(user2)
const res = await config.api.tenants.delete(user1.tenantId, {
status: 403,
headers: config.authHeaders(user2),
})
expect(res.body).toEqual(config.adminOnlyResponse())
})
}) })
}) })

View File

@ -1,9 +1,8 @@
import { TestConfiguration, API, structures } from "../../tests" import { TestConfiguration, structures } from "../../tests"
import { constants } from "@budibase/backend-core" import { constants } from "@budibase/backend-core"
describe("tenancy middleware", () => { describe("tenancy middleware", () => {
const config = new TestConfiguration() const config = new TestConfiguration()
const api = new API(config)
beforeAll(async () => { beforeAll(async () => {
await config.beforeAll() await config.beforeAll()
@ -20,7 +19,7 @@ describe("tenancy middleware", () => {
it("should get tenant id from user", async () => { it("should get tenant id from user", async () => {
const user = await config.createTenant() const user = await config.createTenant()
await config.createSession(user) await config.createSession(user)
const res = await api.self.getSelf(user) const res = await config.api.self.getSelf(user)
expect(res.headers[constants.Headers.TENANT_ID]).toBe(user.tenantId) expect(res.headers[constants.Headers.TENANT_ID]).toBe(user.tenantId)
}) })

View File

@ -2,7 +2,6 @@ import "./mocks"
import dbConfig from "../db" import dbConfig from "../db"
dbConfig.init() dbConfig.init()
import env from "../environment" import env from "../environment"
import { env as coreEnv } from "@budibase/backend-core"
import controllers from "./controllers" import controllers from "./controllers"
const supertest = require("supertest") const supertest = require("supertest")
import { Configs } from "../constants" import { Configs } from "../constants"
@ -14,9 +13,11 @@ import {
sessions, sessions,
auth, auth,
constants, constants,
env as coreEnv,
} from "@budibase/backend-core" } from "@budibase/backend-core"
import structures, { TENANT_ID, TENANT_1, CSRF_TOKEN } from "./structures" import structures, { TENANT_ID, TENANT_1, CSRF_TOKEN } from "./structures"
import { CreateUserResponse, User, AuthToken } from "@budibase/types" import { CreateUserResponse, User, AuthToken } from "@budibase/types"
import API from "./api"
enum Mode { enum Mode {
CLOUD = "cloud", CLOUD = "cloud",
@ -26,6 +27,7 @@ enum Mode {
class TestConfiguration { class TestConfiguration {
server: any server: any
request: any request: any
api: API
defaultUser?: User defaultUser?: User
tenant1User?: User tenant1User?: User
@ -47,6 +49,8 @@ class TestConfiguration {
// we need the request for logging in, involves cookies, hard to fake // we need the request for logging in, involves cookies, hard to fake
this.request = supertest(this.server) this.request = supertest(this.server)
} }
this.api = new API(this)
} }
getRequest() { getRequest() {
@ -119,14 +123,23 @@ class TestConfiguration {
// TENANCY // TENANCY
createTenant = async (tenantId?: string): Promise<User> => { createTenant = async (): Promise<User> => {
// create user / new tenant // create user / new tenant
if (!tenantId) { const res = await this.api.users.createAdminUser()
tenantId = structures.uuid()
} // return the created user
return tenancy.doInTenant(tenantId, async () => { const userRes = await this.api.users.getUser(res.userId, {
return this.createUser() headers: {
...this.internalAPIHeaders(),
[constants.Headers.TENANT_ID]: res.tenantId,
},
}) })
// create a session for the new user
const user = userRes.body
await this.createSession(user)
return user
} }
getTenantId() { getTenantId() {
@ -137,30 +150,24 @@ class TestConfiguration {
} }
} }
// USER / AUTH // AUTH
async createDefaultUser() { async _createSession({
const user = structures.users.adminUser({ userId,
email: "test@test.com", tenantId,
password: "test", }: {
userId: string
tenantId: string
}) {
await sessions.createASession(userId!, {
sessionId: "sessionid",
tenantId: tenantId,
csrfToken: CSRF_TOKEN,
}) })
this.defaultUser = await this.createUser(user)
}
async createTenant1User() {
const user = structures.users.adminUser({
email: "tenant1@test.com",
password: "test",
})
this.tenant1User = await this.createUser(user)
} }
async createSession(user: User) { async createSession(user: User) {
await sessions.createASession(user._id!, { return this._createSession({ userId: user._id!, tenantId: user.tenantId })
sessionId: "sessionid",
tenantId: user.tenantId,
csrfToken: CSRF_TOKEN,
})
} }
cookieHeader(cookies: any) { cookieHeader(cookies: any) {
@ -198,6 +205,28 @@ class TestConfiguration {
return { [constants.Headers.API_KEY]: env.INTERNAL_API_KEY } return { [constants.Headers.API_KEY]: env.INTERNAL_API_KEY }
} }
adminOnlyResponse = () => {
return { message: "Admin user only endpoint.", status: 403 }
}
// USERS
async createDefaultUser() {
const user = structures.users.adminUser({
email: "test@test.com",
password: "test",
})
this.defaultUser = await this.createUser(user)
}
async createTenant1User() {
const user = structures.users.adminUser({
email: "tenant1@test.com",
password: "test",
})
this.tenant1User = await this.createUser(user)
}
async getUser(email: string): Promise<User> { async getUser(email: string): Promise<User> {
return tenancy.doInTenant(this.getTenantId(), () => { return tenancy.doInTenant(this.getTenantId(), () => {
return users.getGlobalUserByEmail(email) return users.getGlobalUserByEmail(email)

View File

@ -1,20 +1,17 @@
import { Account, AccountMetadata } from "@budibase/types" import { Account, AccountMetadata } from "@budibase/types"
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class AccountAPI { export class AccountAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
saveMetadata = async (account: Account) => { saveMetadata = async (account: Account) => {
const res = await this.request const res = await this.request
.put(`/api/system/accounts/${account.accountId}/metadata`) .put(`/api/system/accounts/${account.accountId}/metadata`)
.send(account) .send(account)
.set(this.config.defaultHeaders()) .set(this.config.internalAPIHeaders())
.expect("Content-Type", /json/) .expect("Content-Type", /json/)
.expect(200) .expect(200)
return res.body as AccountMetadata return res.body as AccountMetadata
@ -23,6 +20,6 @@ export class AccountAPI {
destroyMetadata = (accountId: string) => { destroyMetadata = (accountId: string) => {
return this.request return this.request
.del(`/api/system/accounts/${accountId}/metadata`) .del(`/api/system/accounts/${accountId}/metadata`)
.set(this.config.defaultHeaders()) .set(this.config.internalAPIHeaders())
} }
} }

View File

@ -1,12 +1,9 @@
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class AuthAPI { export class AuthAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
updatePassword = (code: string) => { updatePassword = (code: string) => {

View File

@ -1,12 +1,9 @@
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class ConfigAPI { export class ConfigAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
getConfigChecklist = () => { getConfigChecklist = () => {

View File

@ -1,12 +1,9 @@
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class EmailAPI { export class EmailAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
sendEmail = (purpose: string) => { sendEmail = (purpose: string) => {

View File

@ -1,12 +1,9 @@
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class EnvironmentAPI { export class EnvironmentAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
getEnvironment = () => { getEnvironment = () => {

View File

@ -1,13 +1,10 @@
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { User } from "@budibase/types" import { User } from "@budibase/types"
import { TestAPI } from "./base"
export class SelfAPI { export class SelfAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
updateSelf = (user: User) => { updateSelf = (user: User) => {

View File

@ -1,12 +1,9 @@
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI } from "./base"
export class StatusAPI { export class StatusAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
getStatus = () => { getStatus = () => {

View File

@ -10,6 +10,6 @@ export class TenantAPI extends TestAPI {
return this.request return this.request
.delete(`/api/system/tenants/${tenantId}`) .delete(`/api/system/tenants/${tenantId}`)
.set(opts?.headers) .set(opts?.headers)
.expect(opts?.status ? opts.status : 200) .expect(opts?.status ? opts.status : 204)
} }
} }

View File

@ -3,16 +3,16 @@ import {
BulkUserRequest, BulkUserRequest,
InviteUsersRequest, InviteUsersRequest,
User, User,
CreateAdminUserRequest,
} from "@budibase/types" } from "@budibase/types"
import * as structures from "../structures"
import { generator } from "@budibase/backend-core/tests"
import TestConfiguration from "../TestConfiguration" import TestConfiguration from "../TestConfiguration"
import { TestAPI, TestAPIOpts } from "./base"
export class UserAPI { export class UserAPI extends TestAPI {
config: TestConfiguration
request: any
constructor(config: TestConfiguration) { constructor(config: TestConfiguration) {
this.config = config super(config)
this.request = config.request
} }
// INVITE // INVITE
@ -91,6 +91,30 @@ export class UserAPI {
// USER // USER
createAdminUser = async (
request?: CreateAdminUserRequest,
opts?: TestAPIOpts
) => {
if (!request) {
request = {
email: structures.email(),
password: generator.string(),
tenantId: structures.uuid(),
}
}
const res = await this.request
.post(`/api/global/users/init`)
.send(request)
.set(this.config.internalAPIHeaders())
.expect("Content-Type", /json/)
.expect(opts?.status ? opts.status : 200)
return {
...request,
userId: res.body._id,
}
}
saveUser = (user: User, status?: number) => { saveUser = (user: User, status?: number) => {
return this.request return this.request
.post(`/api/global/users`) .post(`/api/global/users`)
@ -107,4 +131,12 @@ export class UserAPI {
.expect("Content-Type", /json/) .expect("Content-Type", /json/)
.expect(status ? status : 200) .expect(status ? status : 200)
} }
getUser = (userId: string, opts?: TestAPIOpts) => {
return this.request
.get(`/api/global/users/${userId}`)
.set(opts?.headers ? opts.headers : this.config.defaultHeaders())
.expect("Content-Type", /json/)
.expect(opts?.status ? opts.status : 200)
}
} }