Merge pull request #8024 from Budibase/qa/internal-api-tests
Qa/internal api tests
This commit is contained in:
commit
7594873f49
|
@ -4,3 +4,4 @@ ENCRYPTED_TEST_PUBLIC_API_KEY=a65722f06bee5caeadc5d7ca2f543a43-d610e627344210c64
|
||||||
COUCH_DB_URL=http://budibase:budibase@localhost:4567
|
COUCH_DB_URL=http://budibase:budibase@localhost:4567
|
||||||
COUCH_DB_USER=budibase
|
COUCH_DB_USER=budibase
|
||||||
COUCH_DB_PASSWORD=budibase
|
COUCH_DB_PASSWORD=budibase
|
||||||
|
JWT_SECRET=test
|
|
@ -9,8 +9,8 @@
|
||||||
"url": "https://github.com/Budibase/budibase.git"
|
"url": "https://github.com/Budibase/budibase.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --runInBand",
|
"test": "env-cmd jest --runInBand",
|
||||||
"test:watch": "jest --watch",
|
"test:watch": "env-cmd jest --watch",
|
||||||
"test:debug": "DEBUG=1 jest",
|
"test:debug": "DEBUG=1 jest",
|
||||||
"docker:up": "docker-compose up -d",
|
"docker:up": "docker-compose up -d",
|
||||||
"docker:down": "docker-compose down",
|
"docker:down": "docker-compose down",
|
||||||
|
@ -24,7 +24,8 @@
|
||||||
"testEnvironment": "node",
|
"testEnvironment": "node",
|
||||||
"moduleNameMapper": {
|
"moduleNameMapper": {
|
||||||
"@budibase/types": "<rootDir>/../packages/types/src",
|
"@budibase/types": "<rootDir>/../packages/types/src",
|
||||||
"@budibase/server": "<rootDir>/../packages/server/src"
|
"@budibase/server": "<rootDir>/../packages/server/src",
|
||||||
|
"@budibase/backend-core": "<rootDir>/../packages/backend-core/src"
|
||||||
},
|
},
|
||||||
"setupFiles": [
|
"setupFiles": [
|
||||||
"./scripts/jestSetup.js"
|
"./scripts/jestSetup.js"
|
||||||
|
@ -49,6 +50,7 @@
|
||||||
"typescript": "4.7.3"
|
"typescript": "4.7.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@budibase/backend-core": "^2.0.5",
|
||||||
"node-fetch": "2"
|
"node-fetch": "2"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
import env from "../../../environment"
|
||||||
|
import fetch, { HeadersInit } from "node-fetch"
|
||||||
|
|
||||||
|
type APIMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE"
|
||||||
|
|
||||||
|
interface ApiOptions {
|
||||||
|
method?: APIMethod
|
||||||
|
body?: object
|
||||||
|
headers?: HeadersInit | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
class InternalAPIClient {
|
||||||
|
host: string
|
||||||
|
appId?: string
|
||||||
|
cookie?: string
|
||||||
|
|
||||||
|
constructor(appId?: string) {
|
||||||
|
if (!env.BUDIBASE_SERVER_URL) {
|
||||||
|
throw new Error(
|
||||||
|
"Must set BUDIBASE_SERVER_URL env var"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
this.host = `${env.BUDIBASE_SERVER_URL}/api`
|
||||||
|
this.appId = appId
|
||||||
|
}
|
||||||
|
|
||||||
|
apiCall =
|
||||||
|
(method: APIMethod) =>
|
||||||
|
async (url = "", options: ApiOptions = {}) => {
|
||||||
|
const requestOptions = {
|
||||||
|
method,
|
||||||
|
body: JSON.stringify(options.body),
|
||||||
|
headers: {
|
||||||
|
"x-budibase-app-id": this.appId,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "application/json",
|
||||||
|
cookie: this.cookie,
|
||||||
|
...options.headers,
|
||||||
|
},
|
||||||
|
credentials: "include",
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const response = await fetch(`${this.host}${url}`, requestOptions)
|
||||||
|
if (response.status !== 200) {
|
||||||
|
console.error(response)
|
||||||
|
}
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
post = this.apiCall("POST")
|
||||||
|
get = this.apiCall("GET")
|
||||||
|
patch = this.apiCall("PATCH")
|
||||||
|
del = this.apiCall("DELETE")
|
||||||
|
put = this.apiCall("PUT")
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InternalAPIClient
|
|
@ -0,0 +1,33 @@
|
||||||
|
import {
|
||||||
|
Application,
|
||||||
|
} from "@budibase/server/api/controllers/public/mapping/types"
|
||||||
|
import { Response } from "node-fetch"
|
||||||
|
import InternalAPIClient from "./InternalAPIClient"
|
||||||
|
|
||||||
|
export default class AppApi {
|
||||||
|
api: InternalAPIClient
|
||||||
|
|
||||||
|
constructor(apiClient: InternalAPIClient) {
|
||||||
|
this.api = apiClient
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetch(): Promise<[Response, Application[]]> {
|
||||||
|
const response = await this.api.get(`/applications?status=all`)
|
||||||
|
const json = await response.json()
|
||||||
|
return [response, json]
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(
|
||||||
|
body: any
|
||||||
|
): Promise<[Response, Application]> {
|
||||||
|
const response = await this.api.post(`/applications`, { body })
|
||||||
|
const json = await response.json()
|
||||||
|
return [response, json]
|
||||||
|
}
|
||||||
|
|
||||||
|
async read(id: string): Promise<[Response, Application]> {
|
||||||
|
const response = await this.api.get(`/applications/${id}`)
|
||||||
|
const json = await response.json()
|
||||||
|
return [response, json.data]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { Response } from "node-fetch"
|
||||||
|
import InternalAPIClient from "./InternalAPIClient"
|
||||||
|
|
||||||
|
export default class AuthApi {
|
||||||
|
api: InternalAPIClient
|
||||||
|
|
||||||
|
constructor(apiClient: InternalAPIClient) {
|
||||||
|
this.api = apiClient
|
||||||
|
}
|
||||||
|
|
||||||
|
async login(): Promise<[Response, any]> {
|
||||||
|
const response = await this.api.post(`/global/auth/default/login`, {
|
||||||
|
body: {
|
||||||
|
username: process.env.BB_ADMIN_USER_EMAIL,
|
||||||
|
password: process.env.BB_ADMIN_USER_PASSWORD
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const cookie = response.headers.get("set-cookie")
|
||||||
|
this.api.cookie = cookie as any
|
||||||
|
return [response, cookie]
|
||||||
|
}
|
||||||
|
|
||||||
|
async logout(): Promise<any> {
|
||||||
|
return this.api.post(`/global/auth/logout`)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
const Chance = require("chance")
|
||||||
|
|
||||||
|
export default new Chance()
|
|
@ -0,0 +1,21 @@
|
||||||
|
import ApplicationApi from "./applications"
|
||||||
|
import AuthApi from "./auth"
|
||||||
|
import InternalAPIClient from "./InternalAPIClient"
|
||||||
|
|
||||||
|
export default class TestConfiguration<T> {
|
||||||
|
applications: ApplicationApi
|
||||||
|
auth: AuthApi
|
||||||
|
context: T
|
||||||
|
|
||||||
|
constructor(apiClient: InternalAPIClient) {
|
||||||
|
this.applications = new ApplicationApi(apiClient)
|
||||||
|
this.auth = new AuthApi(apiClient)
|
||||||
|
this.context = <T>{}
|
||||||
|
}
|
||||||
|
|
||||||
|
async beforeAll() {}
|
||||||
|
|
||||||
|
async afterAll() {
|
||||||
|
this.context = <T>{}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
import generator from "../../generator"
|
||||||
|
import {
|
||||||
|
Application,
|
||||||
|
} from "@budibase/server/api/controllers/public/mapping/types"
|
||||||
|
|
||||||
|
|
||||||
|
const generate = (overrides: Partial<Application> = {}): Partial<Application> => ({
|
||||||
|
name: generator.word(),
|
||||||
|
url: `/${generator.word()}`,
|
||||||
|
...overrides,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default generate
|
|
@ -1,4 +1,4 @@
|
||||||
import generator from "../TestConfiguration/generator"
|
import generator from "../../generator"
|
||||||
import {
|
import {
|
||||||
Application,
|
Application,
|
||||||
CreateApplicationParams,
|
CreateApplicationParams,
|
||||||
|
|
|
@ -4,7 +4,7 @@ import {
|
||||||
Row,
|
Row,
|
||||||
Table,
|
Table,
|
||||||
} from "@budibase/server/api/controllers/public/mapping/types"
|
} from "@budibase/server/api/controllers/public/mapping/types"
|
||||||
import generator from "../TestConfiguration/generator"
|
import generator from "../../generator"
|
||||||
|
|
||||||
export const generateTable = (
|
export const generateTable = (
|
||||||
overrides: Partial<Table> = {}
|
overrides: Partial<Table> = {}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {
|
||||||
CreateUserParams,
|
CreateUserParams,
|
||||||
User,
|
User,
|
||||||
} from "@budibase/server/api/controllers/public/mapping/types"
|
} from "@budibase/server/api/controllers/public/mapping/types"
|
||||||
import generator from "../TestConfiguration/generator"
|
import generator from "../../generator"
|
||||||
|
|
||||||
const generate = (overrides: Partial<User> = {}): CreateUserParams => ({
|
const generate = (overrides: Partial<User> = {}): CreateUserParams => ({
|
||||||
email: generator.email(),
|
email: generator.email(),
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
import TestConfiguration from "../../../config/internal-api/TestConfiguration"
|
||||||
|
import { Application } from "@budibase/server/api/controllers/public/mapping/types"
|
||||||
|
import InternalAPIClient from "../../../config/internal-api/TestConfiguration/InternalAPIClient"
|
||||||
|
import generateApp from "../../../config/internal-api/fixtures/applications"
|
||||||
|
|
||||||
|
describe("Internal API - /applications endpoints", () => {
|
||||||
|
const api = new InternalAPIClient()
|
||||||
|
const config = new TestConfiguration<Application>(api)
|
||||||
|
|
||||||
|
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)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("GET - fetch applications", async () => {
|
||||||
|
await config.applications.create({
|
||||||
|
...generateApp(),
|
||||||
|
useTemplate: false
|
||||||
|
})
|
||||||
|
const [response, apps] = await config.applications.fetch()
|
||||||
|
expect(response).toHaveStatusCode(200)
|
||||||
|
expect(apps.length).toBeGreaterThan(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
it("POST - Create an application", async () => {
|
||||||
|
const [response, app] = await config.applications.create(generateApp())
|
||||||
|
expect(response).toHaveStatusCode(200)
|
||||||
|
expect(app._id).toBeDefined()
|
||||||
|
})
|
||||||
|
})
|
|
@ -14,6 +14,7 @@
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@budibase/types": ["../packages/types/src"],
|
"@budibase/types": ["../packages/types/src"],
|
||||||
|
"@budibase/backend-core": ["../packages/backend-core"],
|
||||||
"@budibase/server/*": ["../packages/server/src/*"],
|
"@budibase/server/*": ["../packages/server/src/*"],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
2051
qa-core/yarn.lock
2051
qa-core/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue