From 0fb6f8312a3e5a24242c5dad0617e4475ddf3a4b Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 14 Aug 2023 12:10:16 +0100 Subject: [PATCH 1/2] Fixing test and updating middleware to match requirements. --- .../src/middleware/tests/trimViewRowInfo.spec.ts | 12 +++++++++--- packages/server/src/middleware/trimViewRowInfo.ts | 13 +++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/server/src/middleware/tests/trimViewRowInfo.spec.ts b/packages/server/src/middleware/tests/trimViewRowInfo.spec.ts index 69d1272df9..17b4cc7b93 100644 --- a/packages/server/src/middleware/tests/trimViewRowInfo.spec.ts +++ b/packages/server/src/middleware/tests/trimViewRowInfo.spec.ts @@ -102,12 +102,13 @@ describe("trimViewRowInfo middleware", () => { address: generator.address(), }) - it("when no columns are defined, same data is returned", async () => { + it("when no columns are defined, don't allow anything", async () => { mockGetView.mockResolvedValue({ version: 2, id: viewId, name: generator.guid(), tableId: table._id!, + schema: {}, }) const data = getRandomData() @@ -116,7 +117,9 @@ describe("trimViewRowInfo middleware", () => { ...data, }) - expect(config.request?.body).toEqual(data) + expect(config.request?.body).toEqual({ + _id: data._id, + }) expect(config.params.sourceId).toEqual(table._id) expect(config.next).toBeCalledTimes(1) @@ -129,7 +132,10 @@ describe("trimViewRowInfo middleware", () => { id: viewId, name: generator.guid(), tableId: table._id!, - columns: ["name", "address"], + schema: { + name: {}, + address: {}, + }, }) const data = getRandomData() diff --git a/packages/server/src/middleware/trimViewRowInfo.ts b/packages/server/src/middleware/trimViewRowInfo.ts index 07e0a344fa..39587d1882 100644 --- a/packages/server/src/middleware/trimViewRowInfo.ts +++ b/packages/server/src/middleware/trimViewRowInfo.ts @@ -23,7 +23,7 @@ export default async (ctx: Ctx, next: Next) => { // don't need to trim delete requests if (ctx?.method?.toLowerCase() !== "delete") { - await trimViewFields(ctx.request.body, viewId, tableId) + await trimViewFields(ctx.request.body, viewId) } ctx.params.sourceId = tableId @@ -34,18 +34,11 @@ export default async (ctx: Ctx, next: Next) => { // have to mutate the koa context, can't return export async function trimViewFields( body: Row, - viewId: string, - tableId: string + viewId: string ): Promise { const view = await sdk.views.get(viewId) - if (!view?.schema || !Object.keys(view.schema).length) { - return - } - - const table = await sdk.tables.getTable(tableId) - const { schema } = sdk.views.enrichSchema(view!, table.schema) const allowedKeys = [ - ...Object.keys(schema), + ...Object.keys(view?.schema || {}), ...db.CONSTANT_EXTERNAL_ROW_COLS, ...db.CONSTANT_INTERNAL_ROW_COLS, ] From 4bbae677b2bdd0db43940bb8cf42de2255a666ed Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Mon, 14 Aug 2023 12:44:05 +0100 Subject: [PATCH 2/2] Updating tests/search to handle no schema means no data, rather than all data. --- .../server/src/api/controllers/row/views.ts | 10 +--------- .../server/src/api/routes/tests/row.spec.ts | 8 ++++++-- .../server/src/middleware/trimViewRowInfo.ts | 6 +----- packages/server/src/sdk/app/views/index.ts | 18 +++++++++++++++--- .../server/src/tests/utilities/api/viewV2.ts | 3 ++- 5 files changed, 25 insertions(+), 20 deletions(-) diff --git a/packages/server/src/api/controllers/row/views.ts b/packages/server/src/api/controllers/row/views.ts index d8835c4837..455a4c0aa2 100644 --- a/packages/server/src/api/controllers/row/views.ts +++ b/packages/server/src/api/controllers/row/views.ts @@ -24,15 +24,7 @@ export async function searchView( ctx.throw(400, `This method only supports viewsV2`) } - const table = await sdk.tables.getTable(view?.tableId) - - const viewFields = - (view.schema && - Object.entries(view.schema).length && - Object.keys(sdk.views.enrichSchema(view, table.schema).schema)) || - undefined - - ctx.status = 200 + const viewFields = Object.keys(view.schema || {}) const { body } = ctx.request const query = dataFilters.buildLuceneQuery(view.query || []) diff --git a/packages/server/src/api/routes/tests/row.spec.ts b/packages/server/src/api/routes/tests/row.spec.ts index cacdff317b..a9675e4a66 100644 --- a/packages/server/src/api/routes/tests/row.spec.ts +++ b/packages/server/src/api/routes/tests/row.spec.ts @@ -985,6 +985,7 @@ describe("/rows", () => { }) describe("view search", () => { + const viewSchema = { age: { visible: true }, name: { visible: true } } function userTable(): Table { return { name: "user", @@ -1041,6 +1042,7 @@ describe("/rows", () => { const createViewResponse = await config.api.viewV2.create({ query: [{ operator: "equal", field: "age", value: 40 }], + schema: viewSchema, }) const response = await config.api.viewV2.search(createViewResponse.id) @@ -1141,6 +1143,7 @@ describe("/rows", () => { const createViewResponse = await config.api.viewV2.create({ sort: sortParams, + schema: viewSchema, }) const response = await config.api.viewV2.search(createViewResponse.id) @@ -1175,6 +1178,7 @@ describe("/rows", () => { order: SortOrder.ASCENDING, type: SortType.STRING, }, + schema: viewSchema, }) const response = await config.api.viewV2.search( @@ -1207,7 +1211,7 @@ describe("/rows", () => { } const view = await config.api.viewV2.create({ - schema: { name: {} }, + schema: { name: { visible: true } }, }) const response = await config.api.viewV2.search(view.id) @@ -1224,7 +1228,7 @@ describe("/rows", () => { }) it("views without data can be returned", async () => { - const table = await config.createTable(userTable()) + await config.createTable(userTable()) const createViewResponse = await config.api.viewV2.create() const response = await config.api.viewV2.search(createViewResponse.id) diff --git a/packages/server/src/middleware/trimViewRowInfo.ts b/packages/server/src/middleware/trimViewRowInfo.ts index 39587d1882..cedcb31640 100644 --- a/packages/server/src/middleware/trimViewRowInfo.ts +++ b/packages/server/src/middleware/trimViewRowInfo.ts @@ -37,11 +37,7 @@ export async function trimViewFields( viewId: string ): Promise { const view = await sdk.views.get(viewId) - const allowedKeys = [ - ...Object.keys(view?.schema || {}), - ...db.CONSTANT_EXTERNAL_ROW_COLS, - ...db.CONSTANT_INTERNAL_ROW_COLS, - ] + const allowedKeys = sdk.views.allowedFields(view) // have to mutate the context, can't update reference const toBeRemoved = Object.keys(body).filter( key => !allowedKeys.includes(key) diff --git a/packages/server/src/sdk/app/views/index.ts b/packages/server/src/sdk/app/views/index.ts index 5f2a001ddc..03c8b6aef5 100644 --- a/packages/server/src/sdk/app/views/index.ts +++ b/packages/server/src/sdk/app/views/index.ts @@ -1,15 +1,19 @@ import { RenameColumn, TableSchema, View, ViewV2 } from "@budibase/types" -import { context, HTTPError } from "@budibase/backend-core" +import { context, db as dbCore, HTTPError } from "@budibase/backend-core" import { cloneDeep } from "lodash" import sdk from "../../../sdk" import * as utils from "../../../db/utils" -export async function get(viewId: string): Promise { +export async function get(viewId: string): Promise { const { tableId } = utils.extractViewInfoFromID(viewId) const table = await sdk.tables.getTable(tableId) const views = Object.values(table.views!) - return views.find(v => isV2(v) && v.id === viewId) as ViewV2 | undefined + const found = views.find(v => isV2(v) && v.id === viewId) + if (!found) { + throw new Error("No view found") + } + return found as ViewV2 } export async function create( @@ -68,6 +72,14 @@ export async function remove(viewId: string): Promise { return view } +export function allowedFields(view: View | ViewV2) { + return [ + ...Object.keys(view?.schema || {}), + ...dbCore.CONSTANT_EXTERNAL_ROW_COLS, + ...dbCore.CONSTANT_INTERNAL_ROW_COLS, + ] +} + export function enrichSchema(view: View | ViewV2, tableSchema: TableSchema) { if (!sdk.views.isV2(view)) { return view diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 1520154641..f3b15afd38 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -23,7 +23,8 @@ export class ViewV2API extends TestAPI { if (!tableId && !this.config.table) { throw "Test requires table to be configured." } - tableId = this.config.table!._id! + const table = this.config.table + tableId = table!._id! const view = { tableId, name: generator.guid(),