Merge pull request #8080 from Budibase/qa/createaptests

/application endpoints API tests
This commit is contained in:
Martin McKeaveney 2022-10-03 10:06:18 +01:00 committed by GitHub
commit 54bd709052
8 changed files with 117 additions and 11 deletions

22
qa-core/README.md Normal file
View File

@ -0,0 +1,22 @@
# QA Core API Tests
The QA Core API tests are a jest suite that run directly against the budibase backend APIs.
## Auto Setup
You can run the whole test suite with one command, that spins up the budibase server and runs the jest tests:
`yarn api:test`
## Setup Server Only
You can also just stand up the budibase server alone.
`yarn api:server:setup`
## Run Tests
If you configured the server using the previous command, you can run the whole test suite by using:
`yarn test`
for watch mode, where the tests will run on every change:
`yarn test:watch`

View File

@ -25,7 +25,8 @@
"moduleNameMapper": {
"@budibase/types": "<rootDir>/../packages/types/src",
"@budibase/server": "<rootDir>/../packages/server/src",
"@budibase/backend-core": "<rootDir>/../packages/backend-core/src"
"@budibase/backend-core": "<rootDir>/../packages/backend-core/src",
"@budibase/backend-core/(.*)": "<rootDir>/../packages/backend-core/$1"
},
"setupFiles": [
"./scripts/jestSetup.js"
@ -51,6 +52,7 @@
},
"dependencies": {
"@budibase/backend-core": "^2.0.5",
"form-data": "^4.0.0",
"node-fetch": "2"
}
}

View File

@ -15,3 +15,5 @@ tk.freeze(MOCK_DATE)
if (!process.env.DEBUG) {
global.console.log = jest.fn() // console.log are ignored in tests
}
jest.setTimeout(10000)

View File

@ -1,8 +1,10 @@
import {
Application,
} from "@budibase/server/api/controllers/public/mapping/types"
import { App } from "@budibase/types"
import { Response } from "node-fetch"
import InternalAPIClient from "./InternalAPIClient"
import FormData from "form-data"
export default class AppApi {
api: InternalAPIClient
@ -17,9 +19,27 @@ export default class AppApi {
return [response, json]
}
async canRender(): Promise<[Response, boolean]> {
const response = await this.api.get("/routing/client")
const json = await response.json()
return [response, Object.keys(json.routes).length > 0]
}
async getAppPackage(appId: string): Promise<[Response, any]> {
const response = await this.api.get(`/applications/${appId}/appPackage`)
const json = await response.json()
return [response, json]
}
async publish(): Promise<[Response, string]> {
const response = await this.api.post("/deploy")
const json = await response.json()
return [response, json]
}
async create(
body: any
): Promise<[Response, Application]> {
): Promise<[Response, Partial<App>]> {
const response = await this.api.post(`/applications`, { body })
const json = await response.json()
return [response, json]

View File

@ -13,9 +13,12 @@ export default class TestConfiguration<T> {
this.context = <T>{}
}
async beforeAll() {}
async beforeAll() {
await this.auth.login()
}
async afterAll() {
this.context = <T>{}
await this.auth.logout()
}
}

View File

@ -1,7 +1,9 @@
import TestConfiguration from "../../../config/internal-api/TestConfiguration"
import { Application } from "@budibase/server/api/controllers/public/mapping/types"
import { db } from "@budibase/backend-core"
import InternalAPIClient from "../../../config/internal-api/TestConfiguration/InternalAPIClient"
import generateApp from "../../../config/internal-api/fixtures/applications"
import generator from "../../../config/generator"
describe("Internal API - /applications endpoints", () => {
const api = new InternalAPIClient()
@ -9,18 +11,22 @@ describe("Internal API - /applications endpoints", () => {
beforeAll(async () => {
await config.beforeAll()
await config.auth.login()
})
afterAll(async () => {
await config.afterAll()
await config.auth.logout()
})
it("POST - Can login", async () => {
const [response] = await config.auth.login()
expect(response).toHaveStatusCode(200)
async function createAppFromTemplate() {
return config.applications.create({
name: generator.word(),
url: `/${generator.word()}`,
useTemplate: "true",
templateName: "Near Miss Register",
templateKey: "app/near-miss-register",
templateFile: undefined
})
}
it("GET - fetch applications", async () => {
await config.applications.create({
@ -29,7 +35,7 @@ describe("Internal API - /applications endpoints", () => {
})
const [response, apps] = await config.applications.fetch()
expect(response).toHaveStatusCode(200)
expect(apps.length).toBeGreaterThan(1)
expect(apps.length).toBeGreaterThanOrEqual(1)
})
it("POST - Create an application", async () => {
@ -37,4 +43,44 @@ describe("Internal API - /applications endpoints", () => {
expect(response).toHaveStatusCode(200)
expect(app._id).toBeDefined()
})
it("POST - Publish application", async () => {
// create app
const [response, app] = await config.applications.create(generateApp())
expect(response).toHaveStatusCode(200)
expect(app.appId).toBeDefined()
// publish app
config.applications.api.appId = app.appId
const [publishResponse, publish] = await config.applications.publish()
expect(publishResponse).toHaveStatusCode(200)
expect(publish).toEqual({
_id: expect.any(String),
appUrl: app.url,
status: "SUCCESS"
})
})
it("POST - Create an application from a template, publish and check it renders", async () => {
// create the app
const appName = generator.word()
const [response, app] = await createAppFromTemplate()
expect(response).toHaveStatusCode(200)
expect(app.appId).toBeDefined()
config.applications.api.appId = app.appId
// check preview renders
const [previewResponse, previewRenders] = await config.applications.canRender()
expect(previewResponse).toHaveStatusCode(200)
expect(previewRenders).toBe(true)
// publish app
await config.applications.publish()
// check published app renders
config.applications.api.appId = db.getProdAppID(app.appId)
const [publishedAppResponse, publishedAppRenders] = await config.applications.canRender()
expect(publishedAppRenders).toBe(true)
})
})

View File

@ -14,7 +14,8 @@
"skipLibCheck": true,
"paths": {
"@budibase/types": ["../packages/types/src"],
"@budibase/backend-core": ["../packages/backend-core"],
"@budibase/backend-core": ["../packages/backend-core/src"],
"@budibase/backend-core/*": ["../packages/backend-core/*"],
"@budibase/server/*": ["../packages/server/src/*"],
}
},
@ -23,6 +24,7 @@
},
"references": [
{ "path": "../packages/types" },
{ "path": "../packages/backend-core" },
],
"include": [
"src/**/*",

View File

@ -1839,6 +1839,15 @@ form-data@^3.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@~2.3.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"