diff --git a/packages/server/src/api/routes/row.ts b/packages/server/src/api/routes/row.ts index 6b393051c6..e5969fc4a2 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 /** @@ -147,7 +147,7 @@ router rowController.search ) .get( - "/api/views/v2/:viewId/search", + "/api/v2/views/:viewId/search", authorized(PermissionType.VIEW, PermissionLevel.READ), rowController.searchView ) @@ -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 8b965570a3..f388782d2d 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) - } + ); + 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]) + await createRow(ids[i]); } - await assertRowUsage(rowUsage + ids.length) - await assertQueryUsage(queryUsage + ids.length) - }) + 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/views/v2/${createViewResponse._id}/search`) + .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)), - }) - }) - }) -}) + }); + }); + }); +});