Final fixes after re-running all test suites.

This commit is contained in:
mike12345567 2022-11-28 19:12:23 +00:00
parent 482c130a2e
commit ab914bcca2
8 changed files with 108 additions and 77 deletions

View File

@ -85,7 +85,7 @@ for (let [key, value] of Object.entries(environment)) {
// handle the edge case of "0" to disable an environment variable // handle the edge case of "0" to disable an environment variable
if (value === "0") { if (value === "0") {
// @ts-ignore // @ts-ignore
env[key] = 0 environment[key] = 0
} }
} }

View File

@ -1,4 +1,4 @@
import setup from "./utilities" import * as setup from "./utilities"
import { events } from "@budibase/backend-core" import { events } from "@budibase/backend-core"
describe("/deployments", () => { describe("/deployments", () => {

View File

@ -271,7 +271,7 @@ describe("/tables", () => {
.expect(200) .expect(200)
expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`) expect(res.body.message).toEqual(`Table ${testTable._id} deleted.`)
expect(events.table.deleted).toBeCalledTimes(1) expect(events.table.deleted).toBeCalledTimes(1)
expect(events.table.deleted).toBeCalledWith(testTable) expect(events.table.deleted).toBeCalledWith({ ...testTable, tableId: testTable._id })
}) })
it("deletes linked references to the table after deletion", async () => { it("deletes linked references to the table after deletion", async () => {
@ -288,6 +288,7 @@ describe("/tables", () => {
}, },
TestTable: { TestTable: {
type: "link", type: "link",
fieldName: "TestTable",
tableId: testTable._id, tableId: testTable._id,
constraints: { constraints: {
type: "array" type: "array"

View File

@ -1,6 +1,6 @@
const TestConfig = require("../../../../tests/utilities/TestConfiguration") import TestConfig from "../../../../tests/utilities/TestConfiguration"
const structures = require("../../../../tests/utilities/structures") import env from "../../../../environment"
const env = require("../../../../environment") export * as structures from "../../../../tests/utilities/structures"
function user() { function user() {
return { return {
@ -40,16 +40,18 @@ jest.mock("../../../../utilities/workerRequests", () => ({
removeAppFromUserRoles: jest.fn(), removeAppFromUserRoles: jest.fn(),
})) }))
exports.delay = ms => new Promise(resolve => setTimeout(resolve, ms)) export function delay(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms))
}
let request, config let request: any, config: any
exports.beforeAll = () => { export function beforeAll() {
config = new TestConfig() config = new TestConfig()
request = config.getRequest() request = config.getRequest()
} }
exports.afterAll = () => { export function afterAll() {
if (config) { if (config) {
config.end() config.end()
} }
@ -59,21 +61,21 @@ exports.afterAll = () => {
config = null config = null
} }
exports.getRequest = () => { export function getRequest() {
if (!request) { if (!request) {
exports.beforeAll() exports.beforeAll()
} }
return request return request
} }
exports.getConfig = () => { export function getConfig() {
if (!config) { if (!config) {
exports.beforeAll() exports.beforeAll()
} }
return config return config
} }
exports.switchToSelfHosted = async func => { export async function switchToSelfHosted(func: any) {
// self hosted stops any attempts to Dynamo // self hosted stops any attempts to Dynamo
env._set("NODE_ENV", "production") env._set("NODE_ENV", "production")
env._set("SELF_HOSTED", true) env._set("SELF_HOSTED", true)
@ -90,5 +92,3 @@ exports.switchToSelfHosted = async func => {
throw error throw error
} }
} }
exports.structures = structures

View File

@ -1,23 +1,23 @@
const TestConfig = require("../../../tests/utilities/TestConfiguration") import TestConfig from "../../../tests/utilities/TestConfiguration"
const { context } = require("@budibase/backend-core") import { context } from "@budibase/backend-core"
const actions = require("../../actions") import { ACTION_DEFINITIONS, getAction } from "../../actions"
const emitter = require("../../../events/index") import emitter from "../../../events/index"
const env = require("../../../environment") import env from "../../../environment"
let config let config: any
exports.getConfig = () => { export function getConfig() {
if (!config) { if (!config) {
config = new TestConfig(false) config = new TestConfig(false)
} }
return config return config
} }
exports.afterAll = () => { export function afterAll() {
config.end() config.end()
} }
exports.runInProd = async fn => { export async function runInProd(fn: any) {
env._set("NODE_ENV", "production") env._set("NODE_ENV", "production")
let error let error
try { try {
@ -31,15 +31,19 @@ exports.runInProd = async fn => {
} }
} }
exports.runStep = async function runStep(stepId, inputs) { export async function runStep(stepId: string, inputs: any) {
async function run() { async function run() {
let step = await actions.getAction(stepId) let step = await getAction(stepId)
expect(step).toBeDefined() expect(step).toBeDefined()
if (!step) {
throw new Error("No step found")
}
return step({ return step({
context: {},
inputs, inputs,
appId: config ? config.getAppId() : null, appId: config ? config.getAppId() : null,
// don't really need an API key, mocked out usage quota, not being tested here // don't really need an API key, mocked out usage quota, not being tested here
apiKey: exports.apiKey, apiKey,
emitter, emitter,
}) })
} }
@ -52,6 +56,5 @@ exports.runStep = async function runStep(stepId, inputs) {
} }
} }
exports.apiKey = "test" export const apiKey = "test"
export const actions = ACTION_DEFINITIONS
exports.actions = actions.ACTION_DEFINITIONS

View File

@ -1,6 +1,7 @@
require("../../db").init() import { init as dbInit } from "../../db"
const env = require("../../environment") dbInit()
const { import env from "../../environment"
import {
basicTable, basicTable,
basicRow, basicRow,
basicRole, basicRole,
@ -11,24 +12,24 @@ const {
basicLayout, basicLayout,
basicWebhook, basicWebhook,
TENANT_ID, TENANT_ID,
} = require("./structures") } from "./structures"
const { import {
constants, constants,
tenancy, tenancy,
sessions, sessions,
cache, cache,
context, context,
db: dbCore, db as dbCore,
encryption, encryption,
auth, auth,
roles, roles,
} = require("@budibase/backend-core") } from "@budibase/backend-core"
const controllers = require("./controllers") import * as controllers from "./controllers"
import { cleanup } from "../../utilities/fileSystem"
import newid from "../../db/newid"
import { generateUserMetadataID } from "../../db/utils"
import { startup } from "../../startup"
const supertest = require("supertest") const supertest = require("supertest")
const { cleanup } = require("../../utilities/fileSystem")
const newid = require("../../db/newid")
const { generateUserMetadataID } = require("../../db/utils")
const { startup } = require("../../startup")
const GLOBAL_USER_ID = "us_uuid1" const GLOBAL_USER_ID = "us_uuid1"
const EMAIL = "babs@babs.com" const EMAIL = "babs@babs.com"
@ -37,10 +38,26 @@ const LASTNAME = "Barbington"
const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306" const CSRF_TOKEN = "e3727778-7af0-4226-b5eb-f43cbe60a306"
class TestConfiguration { class TestConfiguration {
server: any
request: any
started: boolean
appId: string | null
allApps: any[]
app: any
prodApp: any
prodAppId: any
user: any
globalUserId: any
userMetadataId: any
table: any
linkedTable: any
automation: any
datasource: any
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
env.PORT = 0 env.PORT = "0"
this.server = require("../../app") this.server = require("../../app")
// 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)
@ -81,7 +98,7 @@ class TestConfiguration {
} }
} }
async doInContext(appId, task) { async doInContext(appId: string | null, task: any) {
if (!appId) { if (!appId) {
appId = this.appId appId = this.appId
} }
@ -125,9 +142,9 @@ class TestConfiguration {
// UTILS // UTILS
async _req(body, params, controlFunc) { async _req(body: any, params: any, controlFunc: any) {
// create a fake request ctx // create a fake request ctx
const request = {} const request: any = {}
const appId = this.appId const appId = this.appId
request.appId = appId request.appId = appId
// fake cookies, we don't need them // fake cookies, we don't need them
@ -156,8 +173,8 @@ class TestConfiguration {
admin = false, admin = false,
email = EMAIL, email = EMAIL,
roles, roles,
} = {}) { }: any = {}) {
return tenancy.doWithGlobalDB(TENANT_ID, async db => { return tenancy.doWithGlobalDB(TENANT_ID, async (db: any) => {
let existing let existing
try { try {
existing = await db.get(id) existing = await db.get(id)
@ -221,7 +238,7 @@ class TestConfiguration {
} }
} }
async login({ roleId, userId, builder, prodApp = false } = {}) { async login({ roleId, userId, builder, prodApp = false }: any = {}) {
const appId = prodApp ? this.prodAppId : this.appId const appId = prodApp ? this.prodAppId : this.appId
return context.doInAppContext(appId, async () => { return context.doInAppContext(appId, async () => {
userId = !userId ? `us_uuid1` : userId userId = !userId ? `us_uuid1` : userId
@ -278,7 +295,7 @@ class TestConfiguration {
} }
const authToken = auth.jwt.sign(authObj, env.JWT_SECRET) const authToken = auth.jwt.sign(authObj, env.JWT_SECRET)
const appToken = auth.jwt.sign(app, env.JWT_SECRET) const appToken = auth.jwt.sign(app, env.JWT_SECRET)
const headers = { const headers: any = {
Accept: "application/json", Accept: "application/json",
Cookie: [ Cookie: [
`${constants.Cookie.Auth}=${authToken}`, `${constants.Cookie.Auth}=${authToken}`,
@ -296,7 +313,7 @@ class TestConfiguration {
publicHeaders({ prodApp = true } = {}) { publicHeaders({ prodApp = true } = {}) {
const appId = prodApp ? this.prodAppId : this.appId const appId = prodApp ? this.prodAppId : this.appId
const headers = { const headers: any = {
Accept: "application/json", Accept: "application/json",
} }
if (appId) { if (appId) {
@ -317,7 +334,7 @@ class TestConfiguration {
// API // API
async generateApiKey(userId = GLOBAL_USER_ID) { async generateApiKey(userId = GLOBAL_USER_ID) {
return tenancy.doWithGlobalDB(TENANT_ID, async db => { return tenancy.doWithGlobalDB(TENANT_ID, async (db: any) => {
const id = dbCore.generateDevInfoID(userId) const id = dbCore.generateDevInfoID(userId)
let devInfo let devInfo
try { try {
@ -335,13 +352,15 @@ class TestConfiguration {
// APP // APP
async createApp(appName) { async createApp(appName: string) {
// create dev app // create dev app
// clear any old app // clear any old app
this.appId = null this.appId = null
// @ts-ignore
await context.updateAppId(null) await context.updateAppId(null)
this.app = await this._req({ name: appName }, null, controllers.app.create) this.app = await this._req({ name: appName }, null, controllers.app.create)
this.appId = this.app.appId this.appId = this.app.appId
// @ts-ignore
await context.updateAppId(this.appId) await context.updateAppId(this.appId)
// create production app // create production app
@ -355,6 +374,7 @@ class TestConfiguration {
async deploy() { async deploy() {
await this._req(null, null, controllers.deploy.deployApp) await this._req(null, null, controllers.deploy.deployApp)
// @ts-ignore
const prodAppId = this.getAppId().replace("_dev", "") const prodAppId = this.getAppId().replace("_dev", "")
this.prodAppId = prodAppId this.prodAppId = prodAppId
@ -366,29 +386,29 @@ class TestConfiguration {
// TABLE // TABLE
async updateTable(config = null) { async updateTable(config?: any) {
config = config || basicTable() config = config || basicTable()
this.table = await this._req(config, null, controllers.table.save) this.table = await this._req(config, null, controllers.table.save)
return this.table return this.table
} }
async createTable(config = null) { async createTable(config?: any) {
if (config != null && config._id) { if (config != null && config._id) {
delete config._id delete config._id
} }
return this.updateTable(config) return this.updateTable(config)
} }
async getTable(tableId = null) { async getTable(tableId?: string) {
tableId = tableId || this.table._id tableId = tableId || this.table._id
return this._req(null, { tableId }, controllers.table.find) return this._req(null, { tableId }, controllers.table.find)
} }
async createLinkedTable(relationshipType = null, links = ["link"]) { async createLinkedTable(relationshipType?: string, links: any = ["link"]) {
if (!this.table) { if (!this.table) {
throw "Must have created a table first." throw "Must have created a table first."
} }
const tableConfig = basicTable() const tableConfig: any = basicTable()
tableConfig.primaryDisplay = "name" tableConfig.primaryDisplay = "name"
for (let link of links) { for (let link of links) {
tableConfig.schema[link] = { tableConfig.schema[link] = {
@ -407,7 +427,7 @@ class TestConfiguration {
} }
async createAttachmentTable() { async createAttachmentTable() {
const table = basicTable() const table: any = basicTable()
table.schema.attachment = { table.schema.attachment = {
type: "attachment", type: "attachment",
} }
@ -416,7 +436,7 @@ class TestConfiguration {
// ROW // ROW
async createRow(config = null) { async createRow(config: any = null) {
if (!this.table) { if (!this.table) {
throw "Test requires table to be configured." throw "Test requires table to be configured."
} }
@ -425,11 +445,11 @@ class TestConfiguration {
return this._req(config, { tableId }, controllers.row.save) return this._req(config, { tableId }, controllers.row.save)
} }
async getRow(tableId, rowId) { async getRow(tableId: string, rowId: string) {
return this._req(null, { tableId, rowId }, controllers.row.find) return this._req(null, { tableId, rowId }, controllers.row.find)
} }
async getRows(tableId) { async getRows(tableId: string) {
if (!tableId && this.table) { if (!tableId && this.table) {
tableId = this.table._id tableId = this.table._id
} }
@ -438,12 +458,12 @@ class TestConfiguration {
// ROLE // ROLE
async createRole(config = null) { async createRole(config?: any) {
config = config || basicRole() config = config || basicRole()
return this._req(config, null, controllers.role.save) return this._req(config, null, controllers.role.save)
} }
async addPermission(roleId, resourceId, level = "read") { async addPermission(roleId: string, resourceId: string, level = "read") {
return this._req( return this._req(
null, null,
{ {
@ -457,7 +477,7 @@ class TestConfiguration {
// VIEW // VIEW
async createView(config) { async createView(config?: any) {
if (!this.table) { if (!this.table) {
throw "Test requires table to be configured." throw "Test requires table to be configured."
} }
@ -470,7 +490,7 @@ class TestConfiguration {
// AUTOMATION // AUTOMATION
async createAutomation(config) { async createAutomation(config?: any) {
config = config || basicAutomation() config = config || basicAutomation()
if (config._rev) { if (config._rev) {
delete config._rev delete config._rev
@ -485,7 +505,7 @@ class TestConfiguration {
return this._req(null, null, controllers.automation.fetch) return this._req(null, null, controllers.automation.fetch)
} }
async deleteAutomation(automation = null) { async deleteAutomation(automation?: any) {
automation = automation || this.automation automation = automation || this.automation
if (!automation) { if (!automation) {
return return
@ -497,7 +517,7 @@ class TestConfiguration {
) )
} }
async createWebhook(config = null) { async createWebhook(config?: any) {
if (!this.automation) { if (!this.automation) {
throw "Must create an automation before creating webhook." throw "Must create an automation before creating webhook."
} }
@ -507,14 +527,14 @@ class TestConfiguration {
// DATASOURCE // DATASOURCE
async createDatasource(config = null) { async createDatasource(config?: any) {
config = config || basicDatasource() config = config || basicDatasource()
const response = await this._req(config, null, controllers.datasource.save) const response = await this._req(config, null, controllers.datasource.save)
this.datasource = response.datasource this.datasource = response.datasource
return this.datasource return this.datasource
} }
async updateDatasource(datasource) { async updateDatasource(datasource: any) {
const response = await this._req( const response = await this._req(
datasource, datasource,
{ datasourceId: datasource._id }, { datasourceId: datasource._id },
@ -524,7 +544,7 @@ class TestConfiguration {
return this.datasource return this.datasource
} }
async restDatasource(cfg) { async restDatasource(cfg?: any) {
return this.createDatasource({ return this.createDatasource({
datasource: { datasource: {
...basicDatasource().datasource, ...basicDatasource().datasource,
@ -559,7 +579,14 @@ class TestConfiguration {
// QUERY // QUERY
async previewQuery(request, config, datasource, fields, params, verb) { async previewQuery(
request: any,
config: any,
datasource: any,
fields: any,
params: any,
verb: string
) {
return request return request
.post(`/api/queries/preview`) .post(`/api/queries/preview`)
.send({ .send({
@ -574,7 +601,7 @@ class TestConfiguration {
.expect(200) .expect(200)
} }
async createQuery(config = null) { async createQuery(config?: any) {
if (!this.datasource && !config) { if (!this.datasource && !config) {
throw "No datasource created for query." throw "No datasource created for query."
} }
@ -584,17 +611,17 @@ class TestConfiguration {
// SCREEN // SCREEN
async createScreen(config = null) { async createScreen(config?: any) {
config = config || basicScreen() config = config || basicScreen()
return this._req(config, null, controllers.screen.save) return this._req(config, null, controllers.screen.save)
} }
// LAYOUT // LAYOUT
async createLayout(config = null) { async createLayout(config?: any) {
config = config || basicLayout() config = config || basicLayout()
return await this._req(config, null, controllers.layout.save) return await this._req(config, null, controllers.layout.save)
} }
} }
module.exports = TestConfiguration export = TestConfiguration

View File

@ -1,7 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es6", "target": "es6",
"allowJs": true,
"module": "commonjs", "module": "commonjs",
"lib": ["es2020"], "lib": ["es2020"],
"strict": true, "strict": true,

View File

@ -115,4 +115,5 @@ export type AutomationStepInput = {
context: Record<string, any> context: Record<string, any>
emitter: EventEmitter emitter: EventEmitter
appId: string appId: string
apiKey?: string
} }