From a0025d0df9f875cc7277d5fc77811f229823ef0a Mon Sep 17 00:00:00 2001 From: Alexander Polyankin <alexander.polyankin@metabase.com> Date: Tue, 22 Oct 2024 14:06:47 -0400 Subject: [PATCH] Fix native query preview for mongo (#48960) * Fix native query preview for mongo * Add tests * Add tests * Do not rely on join identity --- .../reproductions.cy.spec.ts | 64 +++++++++++++++++++ frontend/src/metabase/lib/engine.ts | 4 +- frontend/src/metabase/lib/engine.unit.spec.ts | 5 +- 3 files changed, 67 insertions(+), 6 deletions(-) diff --git a/e2e/test/scenarios/question-reproductions/reproductions.cy.spec.ts b/e2e/test/scenarios/question-reproductions/reproductions.cy.spec.ts index fbe1d06a017..3f95fec3d3b 100644 --- a/e2e/test/scenarios/question-reproductions/reproductions.cy.spec.ts +++ b/e2e/test/scenarios/question-reproductions/reproductions.cy.spec.ts @@ -1,5 +1,7 @@ import { SAMPLE_DATABASE } from "e2e/support/cypress_sample_database"; import { + type NativeQuestionDetails, + createNativeQuestion, createQuestion, getNotebookStep, modal, @@ -229,3 +231,65 @@ describe("issue 39487", () => { return popover().get("button[data-previous]"); } }); + +const MONGO_DB_ID = 2; + +describe("issue 47793", () => { + const questionDetails: NativeQuestionDetails = { + database: MONGO_DB_ID, + native: { + query: `[ + { $match: { quantity: {{quantity}} }}, + { + "$project": { + "_id": "$_id", + "id": "$id", + "user_id": "$user_id", + "product_id": "$product_id", + "subtotal": "$subtotal", + "tax": "$tax", + "total": "$total", + "created_at": "$created_at", + "quantity": "$quantity", + "discount": "$discount" + } + }, + { + "$limit": 1048575 + } +]`, + "template-tags": { + quantity: { + type: "number", + name: "quantity", + id: "754ae827-661c-4fc9-b511-c0fb7b6bae2b", + "display-name": "Quantity", + default: "10", + }, + }, + collection: "orders", + }, + }; + + beforeEach(() => { + restore("mongo-5"); + cy.signInAsAdmin(); + }); + + it( + "should be able to preview queries for mongodb (metabase#47793)", + { tags: ["@external", "@mongo"] }, + () => { + createNativeQuestion(questionDetails, { visitQuestion: true }); + cy.findByTestId("visibility-toggler") + .findByText(/open editor/i) + .click(); + cy.findByTestId("native-query-editor-container") + .findByLabelText("Preview the query") + .click(); + modal() + .should("contain.text", "$project") + .and("contain.text", "quantity: 10"); + }, + ); +}); diff --git a/frontend/src/metabase/lib/engine.ts b/frontend/src/metabase/lib/engine.ts index 9dccf38c740..db145d3fb1c 100644 --- a/frontend/src/metabase/lib/engine.ts +++ b/frontend/src/metabase/lib/engine.ts @@ -41,8 +41,8 @@ export function formatNativeQuery(query?: string | JSONQuery, engine?: string) { return formatSQL(query); } - if (typeof query === "object" && engineType === "json") { - return formatJsonQuery(query); + if (engineType === "json") { + return typeof query === "object" ? formatJsonQuery(query) : query; } return undefined; diff --git a/frontend/src/metabase/lib/engine.unit.spec.ts b/frontend/src/metabase/lib/engine.unit.spec.ts index 66ac03c107e..1ac7292ee6d 100644 --- a/frontend/src/metabase/lib/engine.unit.spec.ts +++ b/frontend/src/metabase/lib/engine.unit.spec.ts @@ -85,10 +85,6 @@ describe("formatNativeQuery", () => { }); it("should return `undefined` when the query and the engine don't match", () => { - expect(formatNativeQuery("select 1", "mongo")).toBeUndefined(); - expect(formatNativeQuery("foo bar baz", "mongo")).toBeUndefined(); - expect(formatNativeQuery("", "mongo")).toBeUndefined(); - expect(formatNativeQuery({}, "postgres")).toBeUndefined(); expect(formatNativeQuery([], "postgres")).toBeUndefined(); expect(formatNativeQuery([{}], "postgres")).toBeUndefined(); @@ -117,6 +113,7 @@ describe("formatNativeQuery", () => { expect(formatNativeQuery([], "mongo")).toEqual("[]"); expect(formatNativeQuery(["foo"], "mongo")).toEqual('[\n "foo"\n]'); expect(formatNativeQuery({ a: 1 }, "mongo")).toEqual('{\n "a": 1\n}'); + expect(formatNativeQuery('["foo"]', "mongo")).toEqual('["foo"]'); }); }); -- GitLab