Working on typing TestConfiguration.ts.
This commit is contained in:
parent
6e4c2b7242
commit
7ac2449201
|
@ -248,4 +248,10 @@ describe("/applications", () => {
|
||||||
expect(devLogs.data.length).toBe(0)
|
expect(devLogs.data.length).toBe(0)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("permissions", () => {
|
||||||
|
it("should return the list of apps the user has access to", async () => {
|
||||||
|
const user = config.user
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -29,6 +29,6 @@ start().catch(err => {
|
||||||
throw err
|
throw err
|
||||||
})
|
})
|
||||||
|
|
||||||
export function getServer() {
|
export function getServer(): Server {
|
||||||
return server
|
return server
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ import {
|
||||||
AuthToken,
|
AuthToken,
|
||||||
Automation,
|
Automation,
|
||||||
CreateViewRequest,
|
CreateViewRequest,
|
||||||
|
Ctx,
|
||||||
Datasource,
|
Datasource,
|
||||||
FieldType,
|
FieldType,
|
||||||
INTERNAL_TABLE_SOURCE_ID,
|
INTERNAL_TABLE_SOURCE_ID,
|
||||||
|
@ -68,6 +69,8 @@ import {
|
||||||
import API from "./api"
|
import API from "./api"
|
||||||
import { cloneDeep } from "lodash"
|
import { cloneDeep } from "lodash"
|
||||||
import jwt, { Secret } from "jsonwebtoken"
|
import jwt, { Secret } from "jsonwebtoken"
|
||||||
|
import { Server } from "http"
|
||||||
|
import { userDetailListType } from "aws-sdk/clients/iam"
|
||||||
|
|
||||||
mocks.licenses.init(pro)
|
mocks.licenses.init(pro)
|
||||||
|
|
||||||
|
@ -82,16 +85,16 @@ export interface TableToBuild extends Omit<Table, "sourceId" | "sourceType"> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TestConfiguration {
|
export default class TestConfiguration {
|
||||||
server: any
|
server?: Server
|
||||||
request: supertest.SuperTest<supertest.Test> | undefined
|
request?: supertest.SuperTest<supertest.Test>
|
||||||
started: boolean
|
started: boolean
|
||||||
appId: string | null
|
appId?: string
|
||||||
allApps: any[]
|
allApps: any[]
|
||||||
app?: App
|
app?: App
|
||||||
prodApp: any
|
prodApp?: App
|
||||||
prodAppId: any
|
prodAppId?: string
|
||||||
user: any
|
user?: User
|
||||||
userMetadataId: any
|
userMetadataId?: string
|
||||||
table?: Table
|
table?: Table
|
||||||
automation: any
|
automation: any
|
||||||
datasource?: Datasource
|
datasource?: Datasource
|
||||||
|
@ -99,10 +102,6 @@ export default class TestConfiguration {
|
||||||
api: API
|
api: API
|
||||||
csrfToken?: string
|
csrfToken?: string
|
||||||
|
|
||||||
private get globalUserId() {
|
|
||||||
return this.user._id
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(openServer = true) {
|
constructor(openServer = true) {
|
||||||
if (openServer) {
|
if (openServer) {
|
||||||
// use a random port because it doesn't matter
|
// use a random port because it doesn't matter
|
||||||
|
@ -114,7 +113,7 @@ export default class TestConfiguration {
|
||||||
} else {
|
} else {
|
||||||
this.started = false
|
this.started = false
|
||||||
}
|
}
|
||||||
this.appId = null
|
this.appId = undefined
|
||||||
this.allApps = []
|
this.allApps = []
|
||||||
|
|
||||||
this.api = new API(this)
|
this.api = new API(this)
|
||||||
|
@ -134,37 +133,49 @@ export default class TestConfiguration {
|
||||||
|
|
||||||
getAppId() {
|
getAppId() {
|
||||||
if (!this.appId) {
|
if (!this.appId) {
|
||||||
throw "appId has not been initialised properly"
|
throw new Error("appId has not been initialised properly")
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.appId
|
return this.appId
|
||||||
}
|
}
|
||||||
|
|
||||||
getProdAppId() {
|
getProdAppId() {
|
||||||
|
if (!this.prodAppId) {
|
||||||
|
throw new Error(
|
||||||
|
"prodAppId has not been initialised, call config.init() first"
|
||||||
|
)
|
||||||
|
}
|
||||||
return this.prodAppId
|
return this.prodAppId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUser(): User {
|
||||||
|
if (!this.user) {
|
||||||
|
throw new Error("User has not been initialised, call config.init() first")
|
||||||
|
}
|
||||||
|
return this.user
|
||||||
|
}
|
||||||
|
|
||||||
getUserDetails() {
|
getUserDetails() {
|
||||||
|
const user = this.getUser()
|
||||||
return {
|
return {
|
||||||
globalId: this.globalUserId,
|
globalId: user._id!,
|
||||||
email: this.user.email,
|
email: user.email,
|
||||||
firstName: this.user.firstName,
|
firstName: user.firstName,
|
||||||
lastName: this.user.lastName,
|
lastName: user.lastName,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async doInContext<T>(
|
async doInContext<T>(
|
||||||
appId: string | null,
|
appId: string | undefined,
|
||||||
task: () => Promise<T>
|
task: () => Promise<T>
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
|
const tenant = this.getTenantId()
|
||||||
|
return tenancy.doInTenant(tenant, () => {
|
||||||
if (!appId) {
|
if (!appId) {
|
||||||
appId = this.appId
|
appId = this.appId
|
||||||
}
|
}
|
||||||
|
|
||||||
const tenant = this.getTenantId()
|
|
||||||
return tenancy.doInTenant(tenant, () => {
|
|
||||||
// check if already in a context
|
// check if already in a context
|
||||||
if (context.getAppId() == null && appId !== null) {
|
if (context.getAppId() == null && appId) {
|
||||||
return context.doInAppContext(appId, async () => {
|
return context.doInAppContext(appId, async () => {
|
||||||
return task()
|
return task()
|
||||||
})
|
})
|
||||||
|
@ -259,7 +270,11 @@ export default class TestConfiguration {
|
||||||
|
|
||||||
// UTILS
|
// UTILS
|
||||||
|
|
||||||
_req(body: any, params: any, controlFunc: any) {
|
_req<Req extends Record<string, any>, Res, Context extends Ctx<Req, Res>>(
|
||||||
|
handler: (ctx: Context) => Promise<void>,
|
||||||
|
body?: Req,
|
||||||
|
params?: Record<string, string>
|
||||||
|
) {
|
||||||
// create a fake request ctx
|
// create a fake request ctx
|
||||||
const request: any = {}
|
const request: any = {}
|
||||||
const appId = this.appId
|
const appId = this.appId
|
||||||
|
@ -278,29 +293,19 @@ export default class TestConfiguration {
|
||||||
throw new Error(`Error ${status} - ${message}`)
|
throw new Error(`Error ${status} - ${message}`)
|
||||||
}
|
}
|
||||||
return this.doInContext(appId, async () => {
|
return this.doInContext(appId, async () => {
|
||||||
await controlFunc(request)
|
await handler(request)
|
||||||
return request.body
|
return request.body
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// USER / AUTH
|
// USER / AUTH
|
||||||
async globalUser(
|
async globalUser(config: Partial<User> = {}): Promise<User> {
|
||||||
config: {
|
|
||||||
id?: string
|
|
||||||
firstName?: string
|
|
||||||
lastName?: string
|
|
||||||
builder?: boolean
|
|
||||||
admin?: boolean
|
|
||||||
email?: string
|
|
||||||
roles?: any
|
|
||||||
} = {}
|
|
||||||
): Promise<User> {
|
|
||||||
const {
|
const {
|
||||||
id = `us_${newid()}`,
|
_id = `us_${newid()}`,
|
||||||
firstName = generator.first(),
|
firstName = generator.first(),
|
||||||
lastName = generator.last(),
|
lastName = generator.last(),
|
||||||
builder = true,
|
builder = { global: true },
|
||||||
admin = false,
|
admin = { global: false },
|
||||||
email = generator.email(),
|
email = generator.email(),
|
||||||
roles,
|
roles,
|
||||||
} = config
|
} = config
|
||||||
|
@ -308,72 +313,30 @@ export default class TestConfiguration {
|
||||||
const db = tenancy.getTenantDB(this.getTenantId())
|
const db = tenancy.getTenantDB(this.getTenantId())
|
||||||
let existing
|
let existing
|
||||||
try {
|
try {
|
||||||
existing = await db.get<any>(id)
|
existing = await db.get<User>(_id)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
existing = { email }
|
existing = { email }
|
||||||
}
|
}
|
||||||
const user: User = {
|
const user: User = {
|
||||||
_id: id,
|
_id: _id,
|
||||||
...existing,
|
...existing,
|
||||||
roles: roles || {},
|
roles: roles || {},
|
||||||
tenantId: this.getTenantId(),
|
tenantId: this.getTenantId(),
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
}
|
}
|
||||||
await sessions.createASession(id, {
|
await sessions.createASession(_id, {
|
||||||
sessionId: "sessionid",
|
sessionId: "sessionid",
|
||||||
tenantId: this.getTenantId(),
|
tenantId: this.getTenantId(),
|
||||||
csrfToken: this.csrfToken,
|
csrfToken: this.csrfToken,
|
||||||
})
|
})
|
||||||
if (builder) {
|
|
||||||
user.builder = { global: true }
|
|
||||||
} else {
|
|
||||||
user.builder = { global: false }
|
|
||||||
}
|
|
||||||
if (admin) {
|
|
||||||
user.admin = { global: true }
|
|
||||||
} else {
|
|
||||||
user.admin = { global: false }
|
|
||||||
}
|
|
||||||
const resp = await db.put(user)
|
const resp = await db.put(user)
|
||||||
return {
|
return { _rev: resp.rev, ...user }
|
||||||
_rev: resp.rev,
|
|
||||||
...user,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createUser(
|
async createUser(user: Partial<User> = {}): Promise<User> {
|
||||||
user: {
|
const resp = await this.globalUser(user)
|
||||||
id?: string
|
await cache.user.invalidateUser(resp._id!)
|
||||||
firstName?: string
|
|
||||||
lastName?: string
|
|
||||||
email?: string
|
|
||||||
builder?: boolean
|
|
||||||
admin?: boolean
|
|
||||||
roles?: UserRoles
|
|
||||||
} = {}
|
|
||||||
): Promise<User> {
|
|
||||||
const {
|
|
||||||
id,
|
|
||||||
firstName = generator.first(),
|
|
||||||
lastName = generator.last(),
|
|
||||||
email = generator.email(),
|
|
||||||
builder = true,
|
|
||||||
admin,
|
|
||||||
roles,
|
|
||||||
} = user
|
|
||||||
|
|
||||||
const globalId = !id ? `us_${Math.random()}` : `us_${id}`
|
|
||||||
const resp = await this.globalUser({
|
|
||||||
id: globalId,
|
|
||||||
firstName,
|
|
||||||
lastName,
|
|
||||||
email,
|
|
||||||
builder,
|
|
||||||
admin,
|
|
||||||
roles: roles || {},
|
|
||||||
})
|
|
||||||
await cache.user.invalidateUser(globalId)
|
|
||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,7 +344,7 @@ export default class TestConfiguration {
|
||||||
return context.doInTenant(this.tenantId!, async () => {
|
return context.doInTenant(this.tenantId!, async () => {
|
||||||
const baseGroup = structures.userGroups.userGroup()
|
const baseGroup = structures.userGroups.userGroup()
|
||||||
baseGroup.roles = {
|
baseGroup.roles = {
|
||||||
[this.prodAppId]: roleId,
|
[this.getProdAppId()]: roleId,
|
||||||
}
|
}
|
||||||
const { id, rev } = await pro.sdk.groups.save(baseGroup)
|
const { id, rev } = await pro.sdk.groups.save(baseGroup)
|
||||||
return {
|
return {
|
||||||
|
@ -404,8 +367,18 @@ export default class TestConfiguration {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async login({ roleId, userId, builder, prodApp = false }: any = {}) {
|
async login({
|
||||||
const appId = prodApp ? this.prodAppId : this.appId
|
roleId,
|
||||||
|
userId,
|
||||||
|
builder,
|
||||||
|
prodApp,
|
||||||
|
}: {
|
||||||
|
roleId: string
|
||||||
|
userId: string
|
||||||
|
builder: boolean
|
||||||
|
prodApp: boolean
|
||||||
|
}) {
|
||||||
|
const appId = prodApp ? this.getProdAppId() : this.getAppId()
|
||||||
return context.doInAppContext(appId, async () => {
|
return context.doInAppContext(appId, async () => {
|
||||||
userId = !userId ? `us_uuid1` : userId
|
userId = !userId ? `us_uuid1` : userId
|
||||||
if (!this.request) {
|
if (!this.request) {
|
||||||
|
@ -414,9 +387,9 @@ export default class TestConfiguration {
|
||||||
// make sure the user exists in the global DB
|
// make sure the user exists in the global DB
|
||||||
if (roleId !== roles.BUILTIN_ROLE_IDS.PUBLIC) {
|
if (roleId !== roles.BUILTIN_ROLE_IDS.PUBLIC) {
|
||||||
await this.globalUser({
|
await this.globalUser({
|
||||||
id: userId,
|
_id: userId,
|
||||||
builder,
|
builder: { global: builder },
|
||||||
roles: { [this.prodAppId]: roleId },
|
roles: { [appId]: roleId },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
await sessions.createASession(userId, {
|
await sessions.createASession(userId, {
|
||||||
|
@ -445,8 +418,9 @@ export default class TestConfiguration {
|
||||||
|
|
||||||
defaultHeaders(extras = {}, prodApp = false) {
|
defaultHeaders(extras = {}, prodApp = false) {
|
||||||
const tenantId = this.getTenantId()
|
const tenantId = this.getTenantId()
|
||||||
|
const user = this.getUser()
|
||||||
const authObj: AuthToken = {
|
const authObj: AuthToken = {
|
||||||
userId: this.globalUserId,
|
userId: user._id!,
|
||||||
sessionId: "sessionid",
|
sessionId: "sessionid",
|
||||||
tenantId,
|
tenantId,
|
||||||
}
|
}
|
||||||
|
@ -498,7 +472,7 @@ export default class TestConfiguration {
|
||||||
builder = false,
|
builder = false,
|
||||||
prodApp = true,
|
prodApp = true,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
return this.login({ email, roleId, builder, prodApp })
|
return this.login({ userId: email, roleId, builder, prodApp })
|
||||||
}
|
}
|
||||||
|
|
||||||
// TENANCY
|
// TENANCY
|
||||||
|
@ -521,7 +495,7 @@ export default class TestConfiguration {
|
||||||
|
|
||||||
this.tenantId = structures.tenant.id()
|
this.tenantId = structures.tenant.id()
|
||||||
this.user = await this.globalUser()
|
this.user = await this.globalUser()
|
||||||
this.userMetadataId = generateUserMetadataID(this.user._id)
|
this.userMetadataId = generateUserMetadataID(this.user._id!)
|
||||||
|
|
||||||
return this.createApp(appName)
|
return this.createApp(appName)
|
||||||
}
|
}
|
||||||
|
@ -532,7 +506,11 @@ export default class TestConfiguration {
|
||||||
|
|
||||||
// API
|
// API
|
||||||
|
|
||||||
async generateApiKey(userId = this.user._id) {
|
async generateApiKey(userId?: string) {
|
||||||
|
const user = this.getUser()
|
||||||
|
if (!userId) {
|
||||||
|
userId = user._id!
|
||||||
|
}
|
||||||
const db = tenancy.getTenantDB(this.getTenantId())
|
const db = tenancy.getTenantDB(this.getTenantId())
|
||||||
const id = dbCore.generateDevInfoID(userId)
|
const id = dbCore.generateDevInfoID(userId)
|
||||||
let devInfo: any
|
let devInfo: any
|
||||||
|
@ -552,13 +530,15 @@ export default class TestConfiguration {
|
||||||
async createApp(appName: string): Promise<App> {
|
async createApp(appName: string): Promise<App> {
|
||||||
// create dev app
|
// create dev app
|
||||||
// clear any old app
|
// clear any old app
|
||||||
this.appId = null
|
this.appId = undefined
|
||||||
this.app = await context.doInTenant(this.tenantId!, async () => {
|
this.app = await context.doInTenant(this.tenantId!, async () => {
|
||||||
const app = await this._req({ name: appName }, null, appController.create)
|
const app = (await this._req(appController.create, {
|
||||||
|
name: appName,
|
||||||
|
})) as App
|
||||||
this.appId = app.appId!
|
this.appId = app.appId!
|
||||||
return app
|
return app
|
||||||
})
|
})
|
||||||
return await context.doInAppContext(this.getAppId(), async () => {
|
return await context.doInAppContext(this.app.appId!, async () => {
|
||||||
// create production app
|
// create production app
|
||||||
this.prodApp = await this.publish()
|
this.prodApp = await this.publish()
|
||||||
|
|
||||||
|
@ -570,7 +550,7 @@ export default class TestConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
async publish() {
|
async publish() {
|
||||||
await this._req(null, null, deployController.publishApp)
|
await this._req(deployController.publishApp)
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const prodAppId = this.getAppId().replace("_dev", "")
|
const prodAppId = this.getAppId().replace("_dev", "")
|
||||||
this.prodAppId = prodAppId
|
this.prodAppId = prodAppId
|
||||||
|
@ -582,13 +562,11 @@ export default class TestConfiguration {
|
||||||
}
|
}
|
||||||
|
|
||||||
async unpublish() {
|
async unpublish() {
|
||||||
const response = await this._req(
|
const response = await this._req(appController.unpublish, {
|
||||||
null,
|
appId: this.appId,
|
||||||
{ appId: this.appId },
|
})
|
||||||
appController.unpublish
|
this.prodAppId = undefined
|
||||||
)
|
this.prodApp = undefined
|
||||||
this.prodAppId = null
|
|
||||||
this.prodApp = null
|
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -716,8 +694,7 @@ export default class TestConfiguration {
|
||||||
// ROLE
|
// ROLE
|
||||||
|
|
||||||
async createRole(config?: any) {
|
async createRole(config?: any) {
|
||||||
config = config || basicRole()
|
return this._req(roleController.save, config || basicRole())
|
||||||
return this._req(config, null, roleController.save)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VIEW
|
// VIEW
|
||||||
|
@ -730,7 +707,7 @@ export default class TestConfiguration {
|
||||||
tableId: this.table!._id,
|
tableId: this.table!._id,
|
||||||
name: generator.guid(),
|
name: generator.guid(),
|
||||||
}
|
}
|
||||||
return this._req(view, null, viewController.v1.save)
|
return this._req(viewController.v1.save, view)
|
||||||
}
|
}
|
||||||
|
|
||||||
async createView(
|
async createView(
|
||||||
|
@ -760,13 +737,13 @@ export default class TestConfiguration {
|
||||||
delete config._rev
|
delete config._rev
|
||||||
}
|
}
|
||||||
this.automation = (
|
this.automation = (
|
||||||
await this._req(config, null, automationController.create)
|
await this._req(automationController.create, config)
|
||||||
).automation
|
).automation
|
||||||
return this.automation
|
return this.automation
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllAutomations() {
|
async getAllAutomations() {
|
||||||
return this._req(null, null, automationController.fetch)
|
return this._req(automationController.fetch)
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteAutomation(automation?: any) {
|
async deleteAutomation(automation?: any) {
|
||||||
|
@ -774,11 +751,10 @@ export default class TestConfiguration {
|
||||||
if (!automation) {
|
if (!automation) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return this._req(
|
return this._req(automationController.destroy, {
|
||||||
null,
|
id: automation._id,
|
||||||
{ id: automation._id, rev: automation._rev },
|
rev: automation._rev,
|
||||||
automationController.destroy
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async createWebhook(config?: any) {
|
async createWebhook(config?: any) {
|
||||||
|
@ -787,7 +763,7 @@ export default class TestConfiguration {
|
||||||
}
|
}
|
||||||
config = config || basicWebhook(this.automation._id)
|
config = config || basicWebhook(this.automation._id)
|
||||||
|
|
||||||
return (await this._req(config, null, webhookController.save)).webhook
|
return (await this._req(webhookController.save, config)).webhook
|
||||||
}
|
}
|
||||||
|
|
||||||
// DATASOURCE
|
// DATASOURCE
|
||||||
|
@ -871,21 +847,21 @@ export default class TestConfiguration {
|
||||||
throw "No datasource created for query."
|
throw "No datasource created for query."
|
||||||
}
|
}
|
||||||
config = config || basicQuery(this.datasource!._id!)
|
config = config || basicQuery(this.datasource!._id!)
|
||||||
return this._req(config, null, queryController.save)
|
return this._req(queryController.save, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SCREEN
|
// SCREEN
|
||||||
|
|
||||||
async createScreen(config?: any) {
|
async createScreen(config?: any) {
|
||||||
config = config || basicScreen()
|
config = config || basicScreen()
|
||||||
return this._req(config, null, screenController.save)
|
return this._req(screenController.save, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LAYOUT
|
// LAYOUT
|
||||||
|
|
||||||
async createLayout(config?: any) {
|
async createLayout(config?: any) {
|
||||||
config = config || basicLayout()
|
config = config || basicLayout()
|
||||||
return await this._req(config, null, layoutController.save)
|
return await this._req(layoutController.save, config)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue