lint
This commit is contained in:
parent
7eb65ed347
commit
ecf75a9685
|
@ -19,4 +19,4 @@ export interface SearchAccountsRequest {
|
||||||
tenantId?: string
|
tenantId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SearchAccountsResponse = Account[]
|
export type SearchAccountsResponse = Account[]
|
||||||
|
|
|
@ -13,7 +13,7 @@ function init() {
|
||||||
BB_ADMIN_USER_PASSWORD: "admin",
|
BB_ADMIN_USER_PASSWORD: "admin",
|
||||||
LOG_LEVEL: "info",
|
LOG_LEVEL: "info",
|
||||||
JEST_TIMEOUT: "60000",
|
JEST_TIMEOUT: "60000",
|
||||||
DISABLE_PINO_LOGGER: "1"
|
DISABLE_PINO_LOGGER: "1",
|
||||||
}
|
}
|
||||||
let envFile = ""
|
let envFile = ""
|
||||||
Object.keys(envFileJson).forEach(key => {
|
Object.keys(envFileJson).forEach(key => {
|
||||||
|
|
|
@ -48,7 +48,7 @@ export default class AccountInternalAPIClient {
|
||||||
if (options.internal) {
|
if (options.internal) {
|
||||||
requestOptions.headers = {
|
requestOptions.headers = {
|
||||||
...requestOptions.headers,
|
...requestOptions.headers,
|
||||||
...{ [Header.API_KEY] : env.ACCOUNT_PORTAL_API_KEY },
|
...{ [Header.API_KEY]: env.ACCOUNT_PORTAL_API_KEY },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
import { Response } from "node-fetch"
|
import { Response } from "node-fetch"
|
||||||
import { Account, CreateAccountRequest, SearchAccountsRequest, SearchAccountsResponse } from "@budibase/types"
|
import {
|
||||||
|
Account,
|
||||||
|
CreateAccountRequest,
|
||||||
|
SearchAccountsRequest,
|
||||||
|
SearchAccountsResponse,
|
||||||
|
} from "@budibase/types"
|
||||||
import AccountInternalAPIClient from "../AccountInternalAPIClient"
|
import AccountInternalAPIClient from "../AccountInternalAPIClient"
|
||||||
import { APIRequestOpts } from "../../../types"
|
import { APIRequestOpts } from "../../../types"
|
||||||
import { Header } from "@budibase/backend-core"
|
import { Header } from "@budibase/backend-core"
|
||||||
|
@ -13,17 +18,11 @@ export default class AccountAPI extends BaseAPI {
|
||||||
this.client = client
|
this.client = client
|
||||||
}
|
}
|
||||||
|
|
||||||
async validateEmail(
|
async validateEmail(email: string, opts: APIRequestOpts = { status: 200 }) {
|
||||||
email: string,
|
|
||||||
opts: APIRequestOpts = { status: 200 }
|
|
||||||
) {
|
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.post(
|
return this.client.post(`/api/accounts/validate/email`, {
|
||||||
`/api/accounts/validate/email`,
|
body: { email },
|
||||||
{
|
})
|
||||||
body: { email },
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,22 +31,22 @@ export default class AccountAPI extends BaseAPI {
|
||||||
opts: APIRequestOpts = { status: 200 }
|
opts: APIRequestOpts = { status: 200 }
|
||||||
) {
|
) {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.post(
|
return this.client.post(`/api/accounts/validate/tenantId`, {
|
||||||
`/api/accounts/validate/tenantId`,
|
body: { tenantId },
|
||||||
{
|
})
|
||||||
body: { tenantId },
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(
|
async create(
|
||||||
body: CreateAccountRequest,
|
body: CreateAccountRequest,
|
||||||
opts: APIRequestOpts & { autoVerify: boolean } = { status: 201, autoVerify: false }
|
opts: APIRequestOpts & { autoVerify: boolean } = {
|
||||||
|
status: 201,
|
||||||
|
autoVerify: false,
|
||||||
|
}
|
||||||
): Promise<[Response, Account]> {
|
): Promise<[Response, Account]> {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
const headers = {
|
const headers = {
|
||||||
"no-verify": opts.autoVerify ? "1" : "0"
|
"no-verify": opts.autoVerify ? "1" : "0",
|
||||||
}
|
}
|
||||||
return this.client.post(`/api/accounts`, {
|
return this.client.post(`/api/accounts`, {
|
||||||
body,
|
body,
|
||||||
|
@ -56,81 +55,63 @@ export default class AccountAPI extends BaseAPI {
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(
|
async delete(accountID: string, opts: APIRequestOpts = { status: 204 }) {
|
||||||
accountID: string,
|
|
||||||
opts: APIRequestOpts = { status: 204 }) {
|
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.del(
|
return this.client.del(`/api/accounts/${accountID}`, {
|
||||||
`/api/accounts/${accountID}`,
|
internal: true,
|
||||||
{
|
})
|
||||||
internal: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteCurrentAccount(
|
async deleteCurrentAccount(opts: APIRequestOpts = { status: 204 }) {
|
||||||
opts: APIRequestOpts = { status: 204 }
|
|
||||||
) {
|
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.del(
|
return this.client.del(`/api/accounts`)
|
||||||
`/api/accounts`
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async verifyAccount(
|
async verifyAccount(
|
||||||
verificationCode: string,
|
verificationCode: string,
|
||||||
opts: APIRequestOpts = { status: 200 }
|
opts: APIRequestOpts = { status: 200 }
|
||||||
){
|
) {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.post(
|
return this.client.post(`/api/accounts/verify`, {
|
||||||
`/api/accounts/verify`,
|
body: { verificationCode },
|
||||||
{
|
})
|
||||||
body: { verificationCode },
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async sendVerificationEmail(
|
async sendVerificationEmail(
|
||||||
email: string,
|
email: string,
|
||||||
opts: APIRequestOpts = { status: 200 }
|
opts: APIRequestOpts = { status: 200 }
|
||||||
): Promise<[Response, string]> {
|
): Promise<[Response, string]> {
|
||||||
return this.doRequest(async () => {
|
return this.doRequest(async () => {
|
||||||
const [response] = await this.client.post(
|
const [response] = await this.client.post(`/api/accounts/verify/send`, {
|
||||||
`/api/accounts/verify/send`,
|
body: { email },
|
||||||
{
|
headers: {
|
||||||
body: { email },
|
[Header.RETURN_VERIFICATION_CODE]: "1",
|
||||||
headers: {
|
},
|
||||||
[Header.RETURN_VERIFICATION_CODE]: "1"
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const code = response.headers.get(Header.VERIFICATION_CODE)
|
const code = response.headers.get(Header.VERIFICATION_CODE)
|
||||||
return [response, code]
|
return [response, code]
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async search(
|
async search(
|
||||||
searchType: string,
|
searchType: string,
|
||||||
search: 'email' | 'tenantId',
|
search: "email" | "tenantId",
|
||||||
opts: APIRequestOpts = { status: 200 }
|
opts: APIRequestOpts = { status: 200 }
|
||||||
): Promise<[Response, SearchAccountsResponse]> {
|
): Promise<[Response, SearchAccountsResponse]> {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
let body: SearchAccountsRequest = {}
|
let body: SearchAccountsRequest = {}
|
||||||
if (search === 'email') {
|
if (search === "email") {
|
||||||
body.email = searchType
|
body.email = searchType
|
||||||
} else if (search === 'tenantId') {
|
} else if (search === "tenantId") {
|
||||||
body.tenantId = searchType
|
body.tenantId = searchType
|
||||||
}
|
}
|
||||||
return this.client.post(
|
return this.client.post(`/api/accounts/search`, {
|
||||||
`/api/accounts/search`,
|
body,
|
||||||
{
|
internal: true,
|
||||||
body,
|
})
|
||||||
internal: true
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,15 +17,12 @@ export default class AuthAPI extends BaseAPI {
|
||||||
opts: APIRequestOpts = { doExpect: true, status: 200 }
|
opts: APIRequestOpts = { doExpect: true, status: 200 }
|
||||||
): Promise<[Response, string]> {
|
): Promise<[Response, string]> {
|
||||||
return this.doRequest(async () => {
|
return this.doRequest(async () => {
|
||||||
const [res] = await this.client.post(
|
const [res] = await this.client.post(`/api/auth/login`, {
|
||||||
`/api/auth/login`,
|
body: {
|
||||||
{
|
email: email,
|
||||||
body: {
|
password: password,
|
||||||
email: email,
|
},
|
||||||
password: password,
|
})
|
||||||
},
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const cookie = res.headers.get("set-cookie")
|
const cookie = res.headers.get("set-cookie")
|
||||||
return [res, cookie]
|
return [res, cookie]
|
||||||
}, opts)
|
}, opts)
|
||||||
|
|
|
@ -4,10 +4,10 @@ import { APIRequestOpts } from "../../../types"
|
||||||
// TODO: Add to LicenseAPI
|
// TODO: Add to LicenseAPI
|
||||||
|
|
||||||
export default class BaseAPI {
|
export default class BaseAPI {
|
||||||
|
|
||||||
async doRequest(
|
async doRequest(
|
||||||
request: () => Promise<[Response, any]>,
|
request: () => Promise<[Response, any]>,
|
||||||
opts: APIRequestOpts): Promise<[Response, any]> {
|
opts: APIRequestOpts
|
||||||
|
): Promise<[Response, any]> {
|
||||||
const [response, body] = await request()
|
const [response, body] = await request()
|
||||||
|
|
||||||
// do expect on by default
|
// do expect on by default
|
||||||
|
@ -19,4 +19,4 @@ export default class BaseAPI {
|
||||||
}
|
}
|
||||||
return [response, body]
|
return [response, body]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,10 @@ export default class LicenseAPI extends BaseAPI {
|
||||||
opts: APIRequestOpts = { status: 200 }
|
opts: APIRequestOpts = { status: 200 }
|
||||||
): Promise<[Response, Account]> {
|
): Promise<[Response, Account]> {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.put(
|
return this.client.put(`/api/accounts/${accountId}/license`, {
|
||||||
`/api/accounts/${accountId}/license`,
|
body,
|
||||||
{
|
internal: true,
|
||||||
body,
|
})
|
||||||
internal: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,28 @@ import { AccountInternalAPI } from "../api"
|
||||||
import { BudibaseTestConfiguration } from "../../shared"
|
import { BudibaseTestConfiguration } from "../../shared"
|
||||||
|
|
||||||
export default class TestConfiguration<T> extends BudibaseTestConfiguration {
|
export default class TestConfiguration<T> extends BudibaseTestConfiguration {
|
||||||
// apis
|
// apis
|
||||||
api: AccountInternalAPI
|
api: AccountInternalAPI
|
||||||
|
|
||||||
context: T
|
context: T
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.api = new AccountInternalAPI(this.state)
|
this.api = new AccountInternalAPI(this.state)
|
||||||
this.context = <T>{}
|
this.context = <T>{}
|
||||||
}
|
}
|
||||||
|
|
||||||
async beforeAll() {
|
async beforeAll() {
|
||||||
await super.beforeAll()
|
await super.beforeAll()
|
||||||
await this.setApiKey()
|
await this.setApiKey()
|
||||||
}
|
}
|
||||||
|
|
||||||
async afterAll() {
|
async afterAll() {
|
||||||
await super.afterAll()
|
await super.afterAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
async setApiKey() {
|
async setApiKey() {
|
||||||
const apiKeyResponse = await this.internalApi.self.getApiKey()
|
const apiKeyResponse = await this.internalApi.self.getApiKey()
|
||||||
this.state.apiKey = apiKeyResponse.apiKey
|
this.state.apiKey = apiKeyResponse.apiKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,19 @@ import { Hosting, CreateAccountRequest } from "@budibase/types"
|
||||||
|
|
||||||
// TODO: Refactor me to central location
|
// TODO: Refactor me to central location
|
||||||
export const generateAccount = (): CreateAccountRequest => {
|
export const generateAccount = (): CreateAccountRequest => {
|
||||||
const uuid = generator.guid()
|
const uuid = generator.guid()
|
||||||
|
|
||||||
const email = `${uuid}@budibase.com`
|
const email = `${uuid}@budibase.com`
|
||||||
const tenant = `tenant${uuid.replace(/-/g, "")}`
|
const tenant = `tenant${uuid.replace(/-/g, "")}`
|
||||||
|
|
||||||
return {
|
return {
|
||||||
email,
|
email,
|
||||||
hosting: Hosting.CLOUD,
|
hosting: Hosting.CLOUD,
|
||||||
name: email,
|
name: email,
|
||||||
password: uuid,
|
password: uuid,
|
||||||
profession: "software_engineer",
|
profession: "software_engineer",
|
||||||
size: "10+",
|
size: "10+",
|
||||||
tenantId: tenant,
|
tenantId: tenant,
|
||||||
tenantName: tenant,
|
tenantName: tenant,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
export * as accounts from "./accounts"
|
export * as accounts from "./accounts"
|
||||||
|
|
|
@ -35,7 +35,9 @@ describe("Accounts", () => {
|
||||||
await config.loginAsAccount(createAccountRequest, { status: 400 })
|
await config.loginAsAccount(createAccountRequest, { status: 400 })
|
||||||
|
|
||||||
// Re-send verification email to get access to code
|
// Re-send verification email to get access to code
|
||||||
const [_, code] = await config.accountsApi.accounts.sendVerificationEmail(email)
|
const [_, code] = await config.accountsApi.accounts.sendVerificationEmail(
|
||||||
|
email
|
||||||
|
)
|
||||||
|
|
||||||
// Send the verification request
|
// Send the verification request
|
||||||
await config.accountsApi.accounts.verifyAccount(code!)
|
await config.accountsApi.accounts.verifyAccount(code!)
|
||||||
|
@ -56,11 +58,17 @@ describe("Accounts", () => {
|
||||||
const tenantId = generator.string()
|
const tenantId = generator.string()
|
||||||
|
|
||||||
// Empty result
|
// Empty result
|
||||||
const [_, emptyBody] = await config.api.accounts.search(tenantId, "tenantId")
|
const [_, emptyBody] = await config.api.accounts.search(
|
||||||
|
tenantId,
|
||||||
|
"tenantId"
|
||||||
|
)
|
||||||
expect(emptyBody.length).toBe(0)
|
expect(emptyBody.length).toBe(0)
|
||||||
|
|
||||||
// Hit result
|
// Hit result
|
||||||
const [hitRes, hitBody] = await config.api.accounts.search(config.state.tenantId!, "tenantId")
|
const [hitRes, hitBody] = await config.api.accounts.search(
|
||||||
|
config.state.tenantId!,
|
||||||
|
"tenantId"
|
||||||
|
)
|
||||||
expect(hitBody.length).toBe(1)
|
expect(hitBody.length).toBe(1)
|
||||||
expect(hitBody[0].tenantId).toBe(config.state.tenantId)
|
expect(hitBody[0].tenantId).toBe(config.state.tenantId)
|
||||||
})
|
})
|
||||||
|
@ -73,7 +81,10 @@ describe("Accounts", () => {
|
||||||
expect(emptyBody.length).toBe(0)
|
expect(emptyBody.length).toBe(0)
|
||||||
|
|
||||||
// Hit result
|
// Hit result
|
||||||
const [hitRes, hitBody] = await config.api.accounts.search(config.state.email!, "email")
|
const [hitRes, hitBody] = await config.api.accounts.search(
|
||||||
|
config.state.email!,
|
||||||
|
"email"
|
||||||
|
)
|
||||||
expect(hitBody.length).toBe(1)
|
expect(hitBody.length).toBe(1)
|
||||||
expect(hitBody[0].email).toBe(config.state.email)
|
expect(hitBody[0].email).toBe(config.state.email)
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { APIRequestOpts } from "../types"
|
||||||
const accountsApi = new AccountInternalAPI({})
|
const accountsApi = new AccountInternalAPI({})
|
||||||
const internalApi = new BudibaseInternalAPI({})
|
const internalApi = new BudibaseInternalAPI({})
|
||||||
|
|
||||||
const API_OPTS: APIRequestOpts = { doExpect: false}
|
const API_OPTS: APIRequestOpts = { doExpect: false }
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
global.qa = {}
|
global.qa = {}
|
||||||
|
@ -18,8 +18,10 @@ async function createAccount(): Promise<[CreateAccountRequest, Account]> {
|
||||||
const account = fixtures.accounts.generateAccount()
|
const account = fixtures.accounts.generateAccount()
|
||||||
await accountsApi.accounts.validateEmail(account.email, API_OPTS)
|
await accountsApi.accounts.validateEmail(account.email, API_OPTS)
|
||||||
await accountsApi.accounts.validateTenantId(account.tenantId, API_OPTS)
|
await accountsApi.accounts.validateTenantId(account.tenantId, API_OPTS)
|
||||||
const [res, newAccount] = await accountsApi.accounts.create(
|
const [res, newAccount] = await accountsApi.accounts.create(account, {
|
||||||
account, {...API_OPTS, autoVerify: true })
|
...API_OPTS,
|
||||||
|
autoVerify: true,
|
||||||
|
})
|
||||||
await updateLicense(newAccount.accountId)
|
await updateLicense(newAccount.accountId)
|
||||||
return [account, newAccount]
|
return [account, newAccount]
|
||||||
}
|
}
|
||||||
|
@ -27,25 +29,29 @@ async function createAccount(): Promise<[CreateAccountRequest, Account]> {
|
||||||
const UNLIMITED = { value: -1 }
|
const UNLIMITED = { value: -1 }
|
||||||
|
|
||||||
async function updateLicense(accountId: string) {
|
async function updateLicense(accountId: string) {
|
||||||
const [response] = await accountsApi.licenses.updateLicense(accountId, {
|
const [response] = await accountsApi.licenses.updateLicense(
|
||||||
overrides: {
|
accountId,
|
||||||
// add all features
|
{
|
||||||
features: Object.values(Feature),
|
overrides: {
|
||||||
quotas: {
|
// add all features
|
||||||
usage: {
|
features: Object.values(Feature),
|
||||||
monthly: {
|
quotas: {
|
||||||
automations: UNLIMITED,
|
usage: {
|
||||||
},
|
monthly: {
|
||||||
static: {
|
automations: UNLIMITED,
|
||||||
rows: UNLIMITED,
|
},
|
||||||
users: UNLIMITED,
|
static: {
|
||||||
userGroups: UNLIMITED,
|
rows: UNLIMITED,
|
||||||
plugins: UNLIMITED,
|
users: UNLIMITED,
|
||||||
|
userGroups: UNLIMITED,
|
||||||
|
plugins: UNLIMITED,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, { doExpect: false })
|
{ doExpect: false }
|
||||||
|
)
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Could not update license for accountId=${accountId}: ${response.status}`
|
`Could not update license for accountId=${accountId}: ${response.status}`
|
||||||
|
|
|
@ -11,7 +11,9 @@ async function deleteAccount() {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const accountID = global.qa.accountId
|
const accountID = global.qa.accountId
|
||||||
|
|
||||||
const [response] = await accountsApi.accounts.delete(accountID, { doExpect: false })
|
const [response] = await accountsApi.accounts.delete(accountID, {
|
||||||
|
doExpect: false,
|
||||||
|
})
|
||||||
if (response.status !== 204) {
|
if (response.status !== 204) {
|
||||||
throw new Error(`status: ${response.status} not equal to expected: 201`)
|
throw new Error(`status: ${response.status} not equal to expected: 201`)
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,7 +69,10 @@ export default class BudibaseTestConfiguration {
|
||||||
this.state.email = original.email
|
this.state.email = original.email
|
||||||
}
|
}
|
||||||
|
|
||||||
async loginAsAccount(account: CreateAccountRequest, opts: APIRequestOpts = {}) {
|
async loginAsAccount(
|
||||||
|
account: CreateAccountRequest,
|
||||||
|
opts: APIRequestOpts = {}
|
||||||
|
) {
|
||||||
const [_, cookie] = await this.accountsApi.auth.login(
|
const [_, cookie] = await this.accountsApi.auth.login(
|
||||||
account.email,
|
account.email,
|
||||||
account.password,
|
account.password,
|
||||||
|
|
Loading…
Reference in New Issue