1
0
Fork 0
mirror of synced 2024-06-14 08:24:48 +12:00
budibase/packages/server/src/sdk/tests/rows/row.spec.ts
melohagan 37dc8ba6e4
Only export selected columns (#12438)
* Only export selected columns

* Refactor and unit test
2023-11-29 10:23:21 +00:00

133 lines
3.7 KiB
TypeScript

import { exportRows } from "../../app/rows/search/external"
import sdk from "../.."
import { ExternalRequest } from "../../../api/controllers/row/ExternalRequest"
import { ExportRowsParams } from "../../app/rows/search"
import { Format } from "../../../api/controllers/view/exporters"
import { HTTPError } from "@budibase/backend-core"
import { Operation } from "@budibase/types"
const mockDatasourcesGet = jest.fn()
const mockTableGet = jest.fn()
sdk.datasources.get = mockDatasourcesGet
sdk.tables.getTable = mockTableGet
jest.mock("../../../api/controllers/row/ExternalRequest")
jest.mock("../../../utilities/rowProcessor", () => ({
outputProcessing: jest.fn((_, rows) => rows),
}))
jest.mock("../../../api/controllers/view/exporters", () => ({
...jest.requireActual("../../../api/controllers/view/exporters"),
Format: {
CSV: "csv",
},
}))
jest.mock("../../../utilities/fileSystem")
describe("external row sdk", () => {
describe("exportRows", () => {
function getExportOptions(): ExportRowsParams {
return {
tableId: "datasource__tablename",
format: Format.CSV,
query: {},
}
}
const externalRequestCall = jest.fn()
beforeAll(() => {
jest
.spyOn(ExternalRequest.prototype, "run")
.mockImplementation(externalRequestCall.mockResolvedValue([]))
})
afterEach(() => {
jest.clearAllMocks()
})
it("should throw a 400 if no datasource entities are present", async () => {
const exportOptions = getExportOptions()
await expect(exportRows(exportOptions)).rejects.toThrowError(
new HTTPError("Datasource has not been configured for plus API.", 400)
)
})
it("should handle single quotes from a row ID", async () => {
mockDatasourcesGet.mockImplementation(async () => ({
entities: {
tablename: {
schema: {},
},
},
}))
const exportOptions = getExportOptions()
exportOptions.rowIds = ["['d001']"]
await exportRows(exportOptions)
expect(ExternalRequest).toBeCalledTimes(1)
expect(ExternalRequest).toBeCalledWith(
Operation.READ,
exportOptions.tableId,
undefined
)
expect(externalRequestCall).toBeCalledTimes(1)
expect(externalRequestCall).toBeCalledWith(
expect.objectContaining({
filters: {
oneOf: {
_id: ["d001"],
},
},
})
)
})
it("should throw a 400 if any composite keys are present", async () => {
const exportOptions = getExportOptions()
exportOptions.rowIds = ["[123]", "['d001'%2C'10111']"]
await expect(exportRows(exportOptions)).rejects.toThrowError(
new HTTPError("Export data does not support composite keys.", 400)
)
})
it("should throw a 400 if no table name was found", async () => {
const exportOptions = getExportOptions()
exportOptions.tableId = "datasource__"
exportOptions.rowIds = ["[123]"]
await expect(exportRows(exportOptions)).rejects.toThrowError(
new HTTPError("Could not find table name.", 400)
)
})
it("should only export specified columns", async () => {
mockDatasourcesGet.mockImplementation(async () => ({
entities: {
tablename: {
schema: {
name: {},
age: {},
dob: {},
},
},
},
}))
const headers = ["name", "dob"]
const result = await exportRows({
tableId: "datasource__tablename",
format: Format.CSV,
query: {},
columns: headers,
})
expect(result).toEqual({
fileName: "export.csv",
content: `"name","dob"`,
})
})
})
})