Convert BackupAPI.

This commit is contained in:
Sam Rose 2024-02-29 14:33:09 +00:00
parent 6b306266b5
commit 5163434b08
No known key found for this signature in database
3 changed files with 62 additions and 55 deletions

View File

@ -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"`,
) },
})
}) })
}) })

View File

@ -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
} }
} }

View File

@ -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}`