From 198ebcf5d1dbaa827f4d173a322fbeef5a791206 Mon Sep 17 00:00:00 2001 From: Denis Berezin <denis.berezin@metabase.com> Date: Thu, 18 Apr 2024 20:15:56 +0300 Subject: [PATCH] Fix Embedded dashboard parameters parse runtime error (#41545) * Fix parameters parse * Add e2e test * Add e2e test --- .../scenarios/sharing/public-dashboard.cy.spec.js | 12 ++++++++++++ frontend/src/metabase/lib/browser.js | 4 +++- frontend/src/metabase/lib/utils.ts | 13 +++++++++++++ .../PublicDashboard/PublicDashboard.unit.spec.tsx | 10 ++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/e2e/test/scenarios/sharing/public-dashboard.cy.spec.js b/e2e/test/scenarios/sharing/public-dashboard.cy.spec.js index a99eb9a389d..1e3d17cca03 100644 --- a/e2e/test/scenarios/sharing/public-dashboard.cy.spec.js +++ b/e2e/test/scenarios/sharing/public-dashboard.cy.spec.js @@ -245,4 +245,16 @@ describe("scenarios > public > dashboard", () => { assertDashboardFullWidth(); }); + + it("should render when a filter passed with value starting from '0' (metabase#41483)", () => { + cy.get("@dashboardId").then(id => { + visitPublicDashboard(id, { + params: { text: "002" }, + }); + }); + + cy.url().should("include", "text=002"); + + filterWidget().findByText("002").should("be.visible"); + }); }); diff --git a/frontend/src/metabase/lib/browser.js b/frontend/src/metabase/lib/browser.js index 94324621047..77a9cb778a7 100644 --- a/frontend/src/metabase/lib/browser.js +++ b/frontend/src/metabase/lib/browser.js @@ -1,5 +1,7 @@ import querystring from "querystring"; +import { safeJsonParse } from "metabase/lib/utils"; + function parseQueryStringOptions(s) { const options = querystring.parse(s); @@ -7,7 +9,7 @@ function parseQueryStringOptions(s) { if (options[name] === "") { options[name] = true; } else if (/^(true|false|-?\d+(\.\d+)?)$/.test(options[name])) { - options[name] = JSON.parse(options[name]); + options[name] = safeJsonParse(options[name]); } } diff --git a/frontend/src/metabase/lib/utils.ts b/frontend/src/metabase/lib/utils.ts index eef73460d82..a7dc02eb659 100644 --- a/frontend/src/metabase/lib/utils.ts +++ b/frontend/src/metabase/lib/utils.ts @@ -184,3 +184,16 @@ export function compareVersions( } export const isEEBuild = () => PLUGIN_IS_EE_BUILD.isEEBuild(); + +export const safeJsonParse = (value: string | null | undefined) => { + if (!value) { + return null; + } + + try { + return JSON.parse(value); + } catch (e) { + console.error("Unable to parse JSON: ", value, e); + return null; + } +}; diff --git a/frontend/src/metabase/public/containers/PublicDashboard/PublicDashboard.unit.spec.tsx b/frontend/src/metabase/public/containers/PublicDashboard/PublicDashboard.unit.spec.tsx index 9c1e8c125a8..30c5e9cfbe3 100644 --- a/frontend/src/metabase/public/containers/PublicDashboard/PublicDashboard.unit.spec.tsx +++ b/frontend/src/metabase/public/containers/PublicDashboard/PublicDashboard.unit.spec.tsx @@ -70,6 +70,16 @@ describe("PublicDashboard", () => { expect(firstTab).toHaveAttribute("aria-selected", "true"); }); + + it("should render when a filter passed with value starting from '0' (metabase#41483)", async () => { + // note: as all slugs this is ignored and we only use the id + await setup({ + queryString: "?my-filter-value=01", + }); + + // should not throw runtime error and render dashboard content + expect(screen.getByText(DASHBOARD_TITLE)).toBeInTheDocument(); + }); }); async function setup({ -- GitLab