diff --git a/packages/server/src/api/routes/row.ts b/packages/server/src/api/routes/row.ts index e5969fc4a2..5fdc02b7a7 100644 --- a/packages/server/src/api/routes/row.ts +++ b/packages/server/src/api/routes/row.ts @@ -1,12 +1,12 @@ -import Router from "@koa/router"; -import * as rowController from "../controllers/row"; -import authorized from "../../middleware/authorized"; -import { paramResource, paramSubResource } from "../../middleware/resourceId"; -import { permissions } from "@budibase/backend-core"; -import { internalSearchValidator } from "./utils/validators"; -const { PermissionType, PermissionLevel } = permissions; +import Router from "@koa/router" +import * as rowController from "../controllers/row" +import authorized from "../../middleware/authorized" +import { paramResource, paramSubResource } from "../../middleware/resourceId" +import { permissions } from "@budibase/backend-core" +import { internalSearchValidator } from "./utils/validators" +const { PermissionType, PermissionLevel } = permissions -const router: Router = new Router(); +const router: Router = new Router() router /** @@ -266,6 +266,6 @@ router paramResource("tableId"), authorized(PermissionType.TABLE, PermissionLevel.WRITE), rowController.exportRows - ); + ) -export default router; +export default router diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index f388782d2d..0a068f77b9 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -1,12 +1,12 @@ -import tk from "timekeeper"; -const timestamp = new Date("2023-01-26T11:48:57.597Z").toISOString(); -tk.freeze(timestamp); +import tk from "timekeeper" +const timestamp = new Date("2023-01-26T11:48:57.597Z").toISOString() +tk.freeze(timestamp) -import { outputProcessing } from "../../../utilities/rowProcessor"; -import * as setup from "./utilities"; -const { basicRow } = setup.structures; -import { context, tenancy } from "@budibase/backend-core"; -import { quotas } from "@budibase/pro"; +import { outputProcessing } from "../../../utilities/rowProcessor" +import * as setup from "./utilities" +const { basicRow } = setup.structures +import { context, tenancy } from "@budibase/backend-core" +import { quotas } from "@budibase/pro" import { QuotaUsageType, StaticQuotaName, @@ -14,39 +14,39 @@ import { Row, Table, FieldType, -} from "@budibase/types"; -import { structures } from "@budibase/backend-core/tests"; +} from "@budibase/types" +import { structures } from "@budibase/backend-core/tests" describe("/rows", () => { - let request = setup.getRequest(); - let config = setup.getConfig(); - let table: Table; - let row: Row; + let request = setup.getRequest() + let config = setup.getConfig() + let table: Table + let row: Row - afterAll(setup.afterAll); + afterAll(setup.afterAll) beforeAll(async () => { - await config.init(); - }); + await config.init() + }) beforeEach(async () => { - table = await config.createTable(); - row = basicRow(table._id!); - }); + table = await config.createTable() + row = basicRow(table._id!) + }) const loadRow = async (id: string, tbl_Id: string, status = 200) => await request .get(`/api/${tbl_Id}/rows/${id}`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(status); + .expect(status) const getRowUsage = async () => { const { total } = await config.doInContext(null, () => quotas.getCurrentUsageValues(QuotaUsageType.STATIC, StaticQuotaName.ROWS) - ); - return total; - }; + ) + return total + } const getQueryUsage = async () => { const { total } = await config.doInContext(null, () => @@ -54,43 +54,43 @@ describe("/rows", () => { QuotaUsageType.MONTHLY, MonthlyQuotaName.QUERIES ) - ); - return total; - }; + ) + return total + } const assertRowUsage = async (expected: number) => { - const usage = await getRowUsage(); - expect(usage).toBe(expected); - }; + const usage = await getRowUsage() + expect(usage).toBe(expected) + } const assertQueryUsage = async (expected: number) => { - const usage = await getQueryUsage(); - expect(usage).toBe(expected); - }; + const usage = await getQueryUsage() + expect(usage).toBe(expected) + } describe("save, load, update", () => { it("returns a success message when the row is created", async () => { - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .post(`/api/${row.tableId}/rows`) .send(row) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) expect((res as any).res.statusMessage).toEqual( `${table.name} saved successfully` - ); - expect(res.body.name).toEqual("Test Contact"); - expect(res.body._rev).toBeDefined(); - await assertRowUsage(rowUsage + 1); - await assertQueryUsage(queryUsage + 1); - }); + ) + expect(res.body.name).toEqual("Test Contact") + expect(res.body._rev).toBeDefined() + await assertRowUsage(rowUsage + 1) + await assertQueryUsage(queryUsage + 1) + }) it("Increment row autoId per create row request", async () => { - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const newTable = await config.createTable({ name: "TestTableAuto", @@ -113,9 +113,9 @@ describe("/rows", () => { }, }, }, - }); + }) - const ids = [1, 2, 3]; + const ids = [1, 2, 3] // Performing several create row requests should increment the autoID fields accordingly const createRow = async (id: number) => { @@ -126,27 +126,27 @@ describe("/rows", () => { }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) expect((res as any).res.statusMessage).toEqual( `${newTable.name} saved successfully` - ); - expect(res.body.name).toEqual("row_" + id); - expect(res.body._rev).toBeDefined(); - expect(res.body["Row ID"]).toEqual(id); - }; - - for (let i = 0; i < ids.length; i++) { - await createRow(ids[i]); + ) + expect(res.body.name).toEqual("row_" + id) + expect(res.body._rev).toBeDefined() + expect(res.body["Row ID"]).toEqual(id) } - await assertRowUsage(rowUsage + ids.length); - await assertQueryUsage(queryUsage + ids.length); - }); + for (let i = 0; i < ids.length; i++) { + await createRow(ids[i]) + } + + await assertRowUsage(rowUsage + ids.length) + await assertQueryUsage(queryUsage + ids.length) + }) it("updates a row successfully", async () => { - const existing = await config.createRow(); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const existing = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .post(`/api/${table._id}/rows`) @@ -158,25 +158,25 @@ describe("/rows", () => { }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) expect((res as any).res.statusMessage).toEqual( `${table.name} updated successfully.` - ); - expect(res.body.name).toEqual("Updated Name"); - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage + 1); - }); + ) + expect(res.body.name).toEqual("Updated Name") + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage + 1) + }) it("should load a row", async () => { - const existing = await config.createRow(); - const queryUsage = await getQueryUsage(); + const existing = await config.createRow() + const queryUsage = await getQueryUsage() const res = await request .get(`/api/${table._id}/rows/${existing._id}`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) expect(res.body).toEqual({ ...row, @@ -185,65 +185,65 @@ describe("/rows", () => { type: "row", createdAt: timestamp, updatedAt: timestamp, - }); - await assertQueryUsage(queryUsage + 1); - }); + }) + await assertQueryUsage(queryUsage + 1) + }) it("should list all rows for given tableId", async () => { const newRow = { tableId: table._id, name: "Second Contact", status: "new", - }; - await config.createRow(); - await config.createRow(newRow); - const queryUsage = await getQueryUsage(); + } + await config.createRow() + await config.createRow(newRow) + const queryUsage = await getQueryUsage() const res = await request .get(`/api/${table._id}/rows`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) - expect(res.body.length).toBe(2); - expect(res.body.find((r: Row) => r.name === newRow.name)).toBeDefined(); - expect(res.body.find((r: Row) => r.name === row.name)).toBeDefined(); - await assertQueryUsage(queryUsage + 1); - }); + expect(res.body.length).toBe(2) + expect(res.body.find((r: Row) => r.name === newRow.name)).toBeDefined() + expect(res.body.find((r: Row) => r.name === row.name)).toBeDefined() + await assertQueryUsage(queryUsage + 1) + }) it("load should return 404 when row does not exist", async () => { - await config.createRow(); - const queryUsage = await getQueryUsage(); + await config.createRow() + const queryUsage = await getQueryUsage() await request .get(`/api/${table._id}/rows/not-a-valid-id`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(404); - await assertQueryUsage(queryUsage); // no change - }); + .expect(404) + await assertQueryUsage(queryUsage) // no change + }) it("row values are coerced", async () => { const str = { type: FieldType.STRING, name: "str", constraints: { type: "string", presence: false }, - }; + } const attachment = { type: FieldType.ATTACHMENT, name: "attachment", constraints: { type: "array", presence: false }, - }; + } const bool = { type: FieldType.BOOLEAN, name: "boolean", constraints: { type: "boolean", presence: false }, - }; + } const number = { type: FieldType.NUMBER, name: "str", constraints: { type: "number", presence: false }, - }; + } const datetime = { type: FieldType.DATETIME, name: "datetime", @@ -252,7 +252,7 @@ describe("/rows", () => { presence: false, datetime: { earliest: "", latest: "" }, }, - }; + } const arrayField = { type: FieldType.ARRAY, constraints: { @@ -262,7 +262,7 @@ describe("/rows", () => { }, name: "Sample Tags", sortable: false, - }; + } const optsField = { fieldName: "Sample Opts", name: "Sample Opts", @@ -309,7 +309,7 @@ describe("/rows", () => { optsFieldNull: optsField, optsFieldStrKnown: optsField, }, - }); + }) row = { name: "Test Row", @@ -344,54 +344,54 @@ describe("/rows", () => { optsFieldUndefined: undefined, optsFieldNull: null, optsFieldStrKnown: "Alpha", - }; + } - const createdRow = await config.createRow(row); - const id = createdRow._id!; + const createdRow = await config.createRow(row) + const id = createdRow._id! - const saved = (await loadRow(id, table._id!)).body; + const saved = (await loadRow(id, table._id!)).body - expect(saved.stringUndefined).toBe(undefined); - expect(saved.stringNull).toBe(""); - expect(saved.stringString).toBe("i am a string"); - expect(saved.numberEmptyString).toBe(null); - expect(saved.numberNull).toBe(null); - expect(saved.numberUndefined).toBe(undefined); - expect(saved.numberString).toBe(123); - expect(saved.numberNumber).toBe(123); - expect(saved.datetimeEmptyString).toBe(null); - expect(saved.datetimeNull).toBe(null); - expect(saved.datetimeUndefined).toBe(undefined); + expect(saved.stringUndefined).toBe(undefined) + expect(saved.stringNull).toBe("") + expect(saved.stringString).toBe("i am a string") + expect(saved.numberEmptyString).toBe(null) + expect(saved.numberNull).toBe(null) + expect(saved.numberUndefined).toBe(undefined) + expect(saved.numberString).toBe(123) + expect(saved.numberNumber).toBe(123) + expect(saved.datetimeEmptyString).toBe(null) + expect(saved.datetimeNull).toBe(null) + expect(saved.datetimeUndefined).toBe(undefined) expect(saved.datetimeString).toBe( new Date(row.datetimeString).toISOString() - ); - expect(saved.datetimeDate).toBe(row.datetimeDate.toISOString()); - expect(saved.boolNull).toBe(null); - expect(saved.boolEmpty).toBe(null); - expect(saved.boolUndefined).toBe(undefined); - expect(saved.boolString).toBe(true); - expect(saved.boolBool).toBe(true); - expect(saved.attachmentNull).toEqual([]); - expect(saved.attachmentUndefined).toBe(undefined); - expect(saved.attachmentEmpty).toEqual([]); - expect(saved.attachmentEmptyArrayStr).toEqual([]); - expect(saved.arrayFieldEmptyArrayStr).toEqual([]); - expect(saved.arrayFieldNull).toEqual([]); - expect(saved.arrayFieldUndefined).toEqual(undefined); - expect(saved.optsFieldEmptyStr).toEqual(null); - expect(saved.optsFieldUndefined).toEqual(undefined); - expect(saved.optsFieldNull).toEqual(null); - expect(saved.arrayFieldArrayStrKnown).toEqual(["One"]); - expect(saved.optsFieldStrKnown).toEqual("Alpha"); - }); - }); + ) + expect(saved.datetimeDate).toBe(row.datetimeDate.toISOString()) + expect(saved.boolNull).toBe(null) + expect(saved.boolEmpty).toBe(null) + expect(saved.boolUndefined).toBe(undefined) + expect(saved.boolString).toBe(true) + expect(saved.boolBool).toBe(true) + expect(saved.attachmentNull).toEqual([]) + expect(saved.attachmentUndefined).toBe(undefined) + expect(saved.attachmentEmpty).toEqual([]) + expect(saved.attachmentEmptyArrayStr).toEqual([]) + expect(saved.arrayFieldEmptyArrayStr).toEqual([]) + expect(saved.arrayFieldNull).toEqual([]) + expect(saved.arrayFieldUndefined).toEqual(undefined) + expect(saved.optsFieldEmptyStr).toEqual(null) + expect(saved.optsFieldUndefined).toEqual(undefined) + expect(saved.optsFieldNull).toEqual(null) + expect(saved.arrayFieldArrayStrKnown).toEqual(["One"]) + expect(saved.optsFieldStrKnown).toEqual("Alpha") + }) + }) describe("patch", () => { it("should update only the fields that are supplied", async () => { - const existing = await config.createRow(); + const existing = await config.createRow() - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .patch(`/api/${table._id}/rows`) @@ -403,26 +403,26 @@ describe("/rows", () => { }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) expect((res as any).res.statusMessage).toEqual( `${table.name} updated successfully.` - ); - expect(res.body.name).toEqual("Updated Name"); - expect(res.body.description).toEqual(existing.description); + ) + expect(res.body.name).toEqual("Updated Name") + expect(res.body.description).toEqual(existing.description) - const savedRow = await loadRow(res.body._id, table._id!); + const savedRow = await loadRow(res.body._id, table._id!) - expect(savedRow.body.description).toEqual(existing.description); - expect(savedRow.body.name).toEqual("Updated Name"); - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage + 2); // account for the second load - }); + expect(savedRow.body.description).toEqual(existing.description) + expect(savedRow.body.name).toEqual("Updated Name") + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage + 2) // account for the second load + }) it("should throw an error when given improper types", async () => { - const existing = await config.createRow(); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const existing = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() await request .patch(`/api/${table._id}/rows`) @@ -433,18 +433,18 @@ describe("/rows", () => { name: 1, }) .set(config.defaultHeaders()) - .expect(400); + .expect(400) - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage); - }); - }); + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage) + }) + }) describe("destroy", () => { it("should be able to delete a row", async () => { - const createdRow = await config.createRow(row); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const createdRow = await config.createRow(row) + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .delete(`/api/${table._id}/rows`) @@ -453,55 +453,55 @@ describe("/rows", () => { }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); - expect(res.body[0]._id).toEqual(createdRow._id); - await assertRowUsage(rowUsage - 1); - await assertQueryUsage(queryUsage + 1); - }); - }); + .expect(200) + expect(res.body[0]._id).toEqual(createdRow._id) + await assertRowUsage(rowUsage - 1) + await assertQueryUsage(queryUsage + 1) + }) + }) describe("validate", () => { it("should return no errors on valid row", async () => { - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .post(`/api/${table._id}/rows/validate`) .send({ name: "ivan" }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) - expect(res.body.valid).toBe(true); - expect(Object.keys(res.body.errors)).toEqual([]); - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage); - }); + expect(res.body.valid).toBe(true) + expect(Object.keys(res.body.errors)).toEqual([]) + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage) + }) it("should errors on invalid row", async () => { - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .post(`/api/${table._id}/rows/validate`) .send({ name: 1 }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) - expect(res.body.valid).toBe(false); - expect(Object.keys(res.body.errors)).toEqual(["name"]); - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage); - }); - }); + expect(res.body.valid).toBe(false) + expect(Object.keys(res.body.errors)).toEqual(["name"]) + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage) + }) + }) describe("bulkDelete", () => { it("should be able to delete a bulk set of rows", async () => { - const row1 = await config.createRow(); - const row2 = await config.createRow(); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const row1 = await config.createRow() + const row2 = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .delete(`/api/${table._id}/rows`) @@ -510,115 +510,115 @@ describe("/rows", () => { }) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) - expect(res.body.length).toEqual(2); - await loadRow(row1._id!, table._id!, 404); - await assertRowUsage(rowUsage - 2); - await assertQueryUsage(queryUsage + 1); - }); - }); + expect(res.body.length).toEqual(2) + await loadRow(row1._id!, table._id!, 404) + await assertRowUsage(rowUsage - 2) + await assertQueryUsage(queryUsage + 1) + }) + }) describe("fetchView", () => { it("should be able to fetch tables contents via 'view'", async () => { - const row = await config.createRow(); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const row = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .get(`/api/views/${table._id}`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); - expect(res.body.length).toEqual(1); - expect(res.body[0]._id).toEqual(row._id); - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage + 1); - }); + .expect(200) + expect(res.body.length).toEqual(1) + expect(res.body[0]._id).toEqual(row._id) + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage + 1) + }) it("should throw an error if view doesn't exist", async () => { - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() await request .get(`/api/views/derp`) .set(config.defaultHeaders()) - .expect(404); + .expect(404) - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage); - }); + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage) + }) it("should be able to run on a view", async () => { - const view = await config.createView(); - const row = await config.createRow(); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + const view = await config.createView() + const row = await config.createRow() + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() const res = await request .get(`/api/views/${view.name}`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); - expect(res.body.length).toEqual(1); - expect(res.body[0]._id).toEqual(row._id); + .expect(200) + expect(res.body.length).toEqual(1) + expect(res.body[0]._id).toEqual(row._id) - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage + 1); - }); - }); + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage + 1) + }) + }) describe("fetchEnrichedRows", () => { it("should allow enriching some linked rows", async () => { const { table, firstRow, secondRow } = await tenancy.doInTenant( config.getTenantId(), async () => { - const table = await config.createLinkedTable(); + const table = await config.createLinkedTable() const firstRow = await config.createRow({ name: "Test Contact", description: "original description", tableId: table._id, - }); + }) const secondRow = await config.createRow({ name: "Test 2", description: "og desc", link: [{ _id: firstRow._id }], tableId: table._id, - }); - return { table, firstRow, secondRow }; + }) + return { table, firstRow, secondRow } } - ); - const rowUsage = await getRowUsage(); - const queryUsage = await getQueryUsage(); + ) + const rowUsage = await getRowUsage() + const queryUsage = await getQueryUsage() // test basic enrichment const resBasic = await request .get(`/api/${table._id}/rows/${secondRow._id}`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); - expect(resBasic.body.link[0]._id).toBe(firstRow._id); - expect(resBasic.body.link[0].primaryDisplay).toBe("Test Contact"); + .expect(200) + expect(resBasic.body.link[0]._id).toBe(firstRow._id) + expect(resBasic.body.link[0].primaryDisplay).toBe("Test Contact") // test full enrichment const resEnriched = await request .get(`/api/${table._id}/${secondRow._id}/enrich`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); - expect(resEnriched.body.link.length).toBe(1); - expect(resEnriched.body.link[0]._id).toBe(firstRow._id); - expect(resEnriched.body.link[0].name).toBe("Test Contact"); - expect(resEnriched.body.link[0].description).toBe("original description"); - await assertRowUsage(rowUsage); - await assertQueryUsage(queryUsage + 2); - }); - }); + .expect(200) + expect(resEnriched.body.link.length).toBe(1) + expect(resEnriched.body.link[0]._id).toBe(firstRow._id) + expect(resEnriched.body.link[0].name).toBe("Test Contact") + expect(resEnriched.body.link[0].description).toBe("original description") + await assertRowUsage(rowUsage) + await assertQueryUsage(queryUsage + 2) + }) + }) describe("attachments", () => { it("should allow enriching attachment rows", async () => { - const table = await config.createAttachmentTable(); - const attachmentId = `${structures.uuid()}.csv`; + const table = await config.createAttachmentTable() + const attachmentId = `${structures.uuid()}.csv` const row = await config.createRow({ name: "test", description: "test", @@ -628,22 +628,22 @@ describe("/rows", () => { }, ], tableId: table._id, - }); + }) // the environment needs configured for this await setup.switchToSelfHosted(async () => { context.doInAppContext(config.getAppId(), async () => { - const enriched = await outputProcessing(table, [row]); + const enriched = await outputProcessing(table, [row]) expect((enriched as Row[])[0].attachment[0].url).toBe( `/files/signed/prod-budi-app-assets/${config.getProdAppId()}/attachments/${attachmentId}` - ); - }); - }); - }); - }); + ) + }) + }) + }) + }) describe("exportData", () => { it("should allow exporting all columns", async () => { - const existing = await config.createRow(); + const existing = await config.createRow() const res = await request .post(`/api/${table._id}/rows/exportRows?format=json`) .set(config.defaultHeaders()) @@ -651,22 +651,22 @@ describe("/rows", () => { rows: [existing._id], }) .expect("Content-Type", /json/) - .expect(200); - const results = JSON.parse(res.text); - expect(results.length).toEqual(1); - const row = results[0]; + .expect(200) + const results = JSON.parse(res.text) + expect(results.length).toEqual(1) + const row = results[0] // Ensure all original columns were exported expect(Object.keys(row).length).toBeGreaterThanOrEqual( Object.keys(existing).length - ); - Object.keys(existing).forEach((key) => { - expect(row[key]).toEqual(existing[key]); - }); - }); + ) + Object.keys(existing).forEach(key => { + expect(row[key]).toEqual(existing[key]) + }) + }) it("should allow exporting only certain columns", async () => { - const existing = await config.createRow(); + const existing = await config.createRow() const res = await request .post(`/api/${table._id}/rows/exportRows?format=json`) .set(config.defaultHeaders()) @@ -675,16 +675,16 @@ describe("/rows", () => { columns: ["_id"], }) .expect("Content-Type", /json/) - .expect(200); - const results = JSON.parse(res.text); - expect(results.length).toEqual(1); - const row = results[0]; + .expect(200) + const results = JSON.parse(res.text) + expect(results.length).toEqual(1) + const row = results[0] // Ensure only the _id column was exported - expect(Object.keys(row).length).toEqual(1); - expect(row._id).toEqual(existing._id); - }); - }); + expect(Object.keys(row).length).toEqual(1) + expect(row._id).toEqual(existing._id) + }) + }) describe("view search", () => { function priceTable(): Table { @@ -705,27 +705,27 @@ describe("/rows", () => { }, }, }, - }; + } } it("returns table rows from view", async () => { - const table = await config.createTable(priceTable()); - const rows = []; + const table = await config.createTable(priceTable()) + const rows = [] for (let i = 0; i < 10; i++) - rows.push(await config.createRow({ tableId: table._id })); + rows.push(await config.createRow({ tableId: table._id })) - const createViewResponse = await config.api.viewV2.create(); + const createViewResponse = await config.api.viewV2.create() const response = await request .get(`/api/v2/views/${createViewResponse._id}/search`) .set(config.defaultHeaders()) .expect("Content-Type", /json/) - .expect(200); + .expect(200) - expect(response.body.rows).toHaveLength(10); + expect(response.body.rows).toHaveLength(10) expect(response.body).toEqual({ rows: expect.arrayContaining(rows.map(expect.objectContaining)), - }); - }); - }); -}); + }) + }) + }) +})