Convert BackupAPI.
This commit is contained in:
parent
6b306266b5
commit
5163434b08
|
@ -19,11 +19,8 @@ describe("/backups", () => {
|
||||||
|
|
||||||
describe("/api/backups/export", () => {
|
describe("/api/backups/export", () => {
|
||||||
it("should be able to export app", async () => {
|
it("should be able to export app", async () => {
|
||||||
const { body, headers } = await config.api.backup.exportBasicBackup(
|
const body = await config.api.backup.exportBasicBackup(config.getAppId()!)
|
||||||
config.getAppId()!
|
|
||||||
)
|
|
||||||
expect(body instanceof Buffer).toBe(true)
|
expect(body instanceof Buffer).toBe(true)
|
||||||
expect(headers["content-type"]).toEqual("application/gzip")
|
|
||||||
expect(events.app.exported).toBeCalledTimes(1)
|
expect(events.app.exported).toBeCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -38,15 +35,13 @@ describe("/backups", () => {
|
||||||
it("should infer the app name from the app", async () => {
|
it("should infer the app name from the app", async () => {
|
||||||
tk.freeze(mocks.date.MOCK_DATE)
|
tk.freeze(mocks.date.MOCK_DATE)
|
||||||
|
|
||||||
const { headers } = await config.api.backup.exportBasicBackup(
|
await config.api.backup.exportBasicBackup(config.getAppId()!, {
|
||||||
config.getAppId()!
|
headers: {
|
||||||
)
|
"content-disposition": `attachment; filename="${
|
||||||
|
|
||||||
expect(headers["content-disposition"]).toEqual(
|
|
||||||
`attachment; filename="${
|
|
||||||
config.getApp().name
|
config.getApp().name
|
||||||
}-export-${mocks.date.MOCK_DATE.getTime()}.tar.gz"`
|
}-export-${mocks.date.MOCK_DATE.getTime()}.tar.gz"`,
|
||||||
)
|
},
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -2,42 +2,38 @@ import {
|
||||||
CreateAppBackupResponse,
|
CreateAppBackupResponse,
|
||||||
ImportAppBackupResponse,
|
ImportAppBackupResponse,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import TestConfiguration from "../TestConfiguration"
|
import { Expectations, TestAPI } from "./base"
|
||||||
import { TestAPI } from "./base"
|
|
||||||
|
|
||||||
export class BackupAPI extends TestAPI {
|
export class BackupAPI extends TestAPI {
|
||||||
constructor(config: TestConfiguration) {
|
exportBasicBackup = async (appId: string, expectations?: Expectations) => {
|
||||||
super(config)
|
const exp = {
|
||||||
|
...expectations,
|
||||||
|
headers: {
|
||||||
|
...expectations?.headers,
|
||||||
|
"Content-Type": "application/gzip",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return await this._post<Buffer>(`/api/backups/export`, {
|
||||||
|
query: { appId },
|
||||||
|
expectations: exp,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exportBasicBackup = async (appId: string) => {
|
createBackup = async (appId: string, expectations?: Expectations) => {
|
||||||
const result = await this.request
|
return await this._post<CreateAppBackupResponse>(
|
||||||
.post(`/api/backups/export?appId=${appId}`)
|
`/api/apps/${appId}/backups`,
|
||||||
.set(this.config.defaultHeaders())
|
{ expectations }
|
||||||
.expect("Content-Type", /application\/gzip/)
|
)
|
||||||
.expect(200)
|
|
||||||
return {
|
|
||||||
body: result.body as Buffer,
|
|
||||||
headers: result.headers,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
createBackup = async (appId: string) => {
|
|
||||||
const result = await this.request
|
|
||||||
.post(`/api/apps/${appId}/backups`)
|
|
||||||
.set(this.config.defaultHeaders())
|
|
||||||
.expect("Content-Type", /json/)
|
|
||||||
.expect(200)
|
|
||||||
return result.body as CreateAppBackupResponse
|
|
||||||
}
|
}
|
||||||
|
|
||||||
waitForBackupToComplete = async (appId: string, backupId: string) => {
|
waitForBackupToComplete = async (appId: string, backupId: string) => {
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
const result = await this.request
|
const response = await this._requestRaw(
|
||||||
.get(`/api/apps/${appId}/backups/${backupId}/file`)
|
"get",
|
||||||
.set(this.config.defaultHeaders())
|
`/api/apps/${appId}/backups/${backupId}/file`
|
||||||
if (result.status === 200) {
|
)
|
||||||
|
if (response.status === 200) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,13 +42,12 @@ export class BackupAPI extends TestAPI {
|
||||||
|
|
||||||
importBackup = async (
|
importBackup = async (
|
||||||
appId: string,
|
appId: string,
|
||||||
backupId: string
|
backupId: string,
|
||||||
|
expectations?: Expectations
|
||||||
): Promise<ImportAppBackupResponse> => {
|
): Promise<ImportAppBackupResponse> => {
|
||||||
const result = await this.request
|
return await this._post<ImportAppBackupResponse>(
|
||||||
.post(`/api/apps/${appId}/backups/${backupId}/import`)
|
`/api/apps/${appId}/backups/${backupId}/import`,
|
||||||
.set(this.config.defaultHeaders())
|
{ expectations }
|
||||||
.expect("Content-Type", /json/)
|
)
|
||||||
.expect(200)
|
|
||||||
return result.body as ImportAppBackupResponse
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import TestConfiguration from "../TestConfiguration"
|
import TestConfiguration from "../TestConfiguration"
|
||||||
import { SuperTest, Test } from "supertest"
|
import { SuperTest, Test, Response } from "supertest"
|
||||||
import { ReadStream } from "fs"
|
import { ReadStream } from "fs"
|
||||||
|
|
||||||
type Headers = Record<string, string | string[] | undefined>
|
type Headers = Record<string, string | string[] | undefined>
|
||||||
|
@ -22,7 +22,6 @@ function isAttachedFile(file: any): file is AttachedFile {
|
||||||
|
|
||||||
export interface Expectations {
|
export interface Expectations {
|
||||||
status?: number
|
status?: number
|
||||||
contentType?: string | RegExp
|
|
||||||
headers?: Record<string, string | RegExp>
|
headers?: Record<string, string | RegExp>
|
||||||
headersNotPresent?: string[]
|
headersNotPresent?: string[]
|
||||||
}
|
}
|
||||||
|
@ -71,11 +70,11 @@ export abstract class TestAPI {
|
||||||
return await this._request<T>("delete", url, opts)
|
return await this._request<T>("delete", url, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected _request = async <T>(
|
protected _requestRaw = async (
|
||||||
method: "get" | "post" | "put" | "patch" | "delete",
|
method: "get" | "post" | "put" | "patch" | "delete",
|
||||||
url: string,
|
url: string,
|
||||||
opts?: RequestOpts
|
opts?: RequestOpts
|
||||||
): Promise<T> => {
|
): Promise<Response> => {
|
||||||
const {
|
const {
|
||||||
headers = {},
|
headers = {},
|
||||||
query = {},
|
query = {},
|
||||||
|
@ -84,7 +83,12 @@ export abstract class TestAPI {
|
||||||
files = {},
|
files = {},
|
||||||
expectations,
|
expectations,
|
||||||
} = opts || {}
|
} = opts || {}
|
||||||
const { status = 200, contentType = /json/ } = expectations || {}
|
const { status = 200 } = expectations || {}
|
||||||
|
const expectHeaders = expectations?.headers || {}
|
||||||
|
|
||||||
|
if (status !== 204 && !expectHeaders["Content-Type"]) {
|
||||||
|
expectHeaders["Content-Type"] = "application/json"
|
||||||
|
}
|
||||||
|
|
||||||
let queryParams = []
|
let queryParams = []
|
||||||
for (const [key, value] of Object.entries(query)) {
|
for (const [key, value] of Object.entries(query)) {
|
||||||
|
@ -118,16 +122,29 @@ export abstract class TestAPI {
|
||||||
request = request.attach(key, value as any)
|
request = request.attach(key, value as any)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (contentType && status !== 204) {
|
|
||||||
request = request.expect("Content-Type", contentType as any)
|
|
||||||
}
|
|
||||||
if (expectations?.headers) {
|
if (expectations?.headers) {
|
||||||
for (const [key, value] of Object.entries(expectations.headers)) {
|
for (const [key, value] of Object.entries(expectations.headers)) {
|
||||||
|
if (value === undefined) {
|
||||||
|
throw new Error(
|
||||||
|
`Got an undefined expected value for header "${key}", if you want to check for the absence of a header, use headersNotPresent`
|
||||||
|
)
|
||||||
|
}
|
||||||
request = request.expect(key, value as any)
|
request = request.expect(key, value as any)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await request
|
return await request
|
||||||
|
}
|
||||||
|
|
||||||
|
protected _request = async <T>(
|
||||||
|
method: "get" | "post" | "put" | "patch" | "delete",
|
||||||
|
url: string,
|
||||||
|
opts?: RequestOpts
|
||||||
|
): Promise<T> => {
|
||||||
|
const { expectations } = opts || {}
|
||||||
|
const { status = 200 } = expectations || {}
|
||||||
|
|
||||||
|
const response = await this._requestRaw(method, url, opts)
|
||||||
|
|
||||||
if (response.status !== status) {
|
if (response.status !== status) {
|
||||||
let message = `Expected status ${status} but got ${response.status}`
|
let message = `Expected status ${status} but got ${response.status}`
|
||||||
|
|
Loading…
Reference in New Issue