From 15f2aaf950b15e15dcbae5fed8f04e3306018554 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 16 Dec 2024 16:55:38 +0100 Subject: [PATCH 1/3] Fix encodings --- packages/backend-core/src/sql/utils.ts | 4 ++++ packages/server/src/api/controllers/row/utils/utils.ts | 2 +- packages/server/src/db/utils.ts | 10 ++-------- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/backend-core/src/sql/utils.ts b/packages/backend-core/src/sql/utils.ts index 14127a189f..16b352995b 100644 --- a/packages/backend-core/src/sql/utils.ts +++ b/packages/backend-core/src/sql/utils.ts @@ -70,6 +70,10 @@ export function encodeTableId(tableId: string) { } } +export function encodeViewId(viewId: string) { + return encodeURIComponent(viewId) +} + export function breakExternalTableId(tableId: string) { const parts = tableId.split(DOUBLE_SEPARATOR) let datasourceId = parts.shift() diff --git a/packages/server/src/api/controllers/row/utils/utils.ts b/packages/server/src/api/controllers/row/utils/utils.ts index baa811fe90..86986b64e8 100644 --- a/packages/server/src/api/controllers/row/utils/utils.ts +++ b/packages/server/src/api/controllers/row/utils/utils.ts @@ -66,7 +66,7 @@ export function getSourceId(ctx: Ctx): { tableId: string; viewId?: string } { if (docIds.isViewId(sourceId)) { return { tableId: utils.extractViewInfoFromID(sourceId).tableId, - viewId: sourceId, + viewId: sql.utils.encodeViewId(sourceId), } } return { tableId: sql.utils.encodeTableId(ctx.params.sourceId) } diff --git a/packages/server/src/db/utils.ts b/packages/server/src/db/utils.ts index 70c69b3c60..6c1065e847 100644 --- a/packages/server/src/db/utils.ts +++ b/packages/server/src/db/utils.ts @@ -1,10 +1,4 @@ -import { - context, - db as dbCore, - docIds, - utils, - sql, -} from "@budibase/backend-core" +import { context, db as dbCore, docIds, utils } from "@budibase/backend-core" import { DatabaseQueryOpts, Datasource, @@ -334,7 +328,7 @@ export function extractViewInfoFromID(viewId: string) { const regex = new RegExp(`^(?.+)${SEPARATOR}([^${SEPARATOR}]+)$`) const res = regex.exec(viewId) return { - tableId: sql.utils.encodeTableId(res!.groups!["tableId"]), + tableId: res!.groups!["tableId"], } } From b538125d1faf0af2ecf67e6600e825ba29eb9a18 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 18 Dec 2024 10:40:12 +0100 Subject: [PATCH 2/3] Add failing test --- .../src/api/routes/tests/viewV2.spec.ts | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 244a0a23eb..632dbfec3a 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -55,7 +55,7 @@ if (descriptions.length) { let datasource: Datasource | undefined function saveTableRequest( - ...overrides: Partial>[] + ...overrides: Partial[] ): SaveTableRequest { const req: SaveTableRequest = { name: generator.guid().replaceAll("-", "").substring(0, 16), @@ -1898,6 +1898,36 @@ if (descriptions.length) { } expect(view.queryUI).toEqual(expected) }) + + it("tables and views can contain whitespaces", async () => { + const table = await config.api.table.save( + saveTableRequest({ + name: "table with spaces", + schema: { + name: { + type: FieldType.STRING, + name: "name", + }, + }, + }) + ) + + const view = await config.api.viewV2.create({ + tableId: table._id!, + name: `view name with spaces`, + schema: { + name: { visible: true }, + }, + }) + + expect(await getDelegate(view)).toEqual({ + ...view, + schema: { + id: { ...table.schema["id"], visible: false }, + name: { ...table.schema["name"], visible: true }, + }, + }) + }) }) describe("updating table schema", () => { From b81e43ed59855c15abce129894eeabf1637e7ba8 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Wed, 18 Dec 2024 10:55:32 +0100 Subject: [PATCH 3/3] Fix tests --- packages/server/src/api/routes/tests/viewV2.spec.ts | 2 +- packages/server/src/tests/utilities/api/viewV2.ts | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index 632dbfec3a..ba2ad422eb 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -1902,7 +1902,7 @@ if (descriptions.length) { it("tables and views can contain whitespaces", async () => { const table = await config.api.table.save( saveTableRequest({ - name: "table with spaces", + name: `table with spaces ${generator.hash()}`, schema: { name: { type: FieldType.STRING, diff --git a/packages/server/src/tests/utilities/api/viewV2.ts b/packages/server/src/tests/utilities/api/viewV2.ts index 7cc57673a0..d0350a5521 100644 --- a/packages/server/src/tests/utilities/api/viewV2.ts +++ b/packages/server/src/tests/utilities/api/viewV2.ts @@ -46,8 +46,11 @@ export class ViewV2API extends TestAPI { } get = async (viewId: string) => { - return (await this._get(`/api/v2/views/${viewId}`)) - .data + return ( + await this._get( + `/api/v2/views/${encodeURIComponent(viewId)}` + ) + ).data } fetch = async (expectations?: Expectations) => {