From 4826248e1351fc2da8871dff784060b308f1f68c Mon Sep 17 00:00:00 2001
From: Nemanja Glumac <31325167+nemanjaglumac@users.noreply.github.com>
Date: Fri, 27 Aug 2021 21:59:47 +0200
Subject: [PATCH] [Dashboard filters coverage] Add test for required and
 default values set on dashboard SQL filters (#17628)

* Add test for required and default values set on dashboard SQL field filters

* Add test for required and default values set on dashboard SQL simple filter
---
 ...lters-sql-required-field-filter.cy.spec.js | 110 +++++++++++++++
 ...ters-sql-required-simple-filter.cy.spec.js | 132 ++++++++++++++++++
 2 files changed, 242 insertions(+)
 create mode 100644 frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-field-filter.cy.spec.js
 create mode 100644 frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-simple-filter.cy.spec.js

diff --git a/frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-field-filter.cy.spec.js b/frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-field-filter.cy.spec.js
new file mode 100644
index 00000000000..0d8d80b45cb
--- /dev/null
+++ b/frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-field-filter.cy.spec.js
@@ -0,0 +1,110 @@
+import { restore, filterWidget } from "__support__/e2e/cypress";
+import { SAMPLE_DATASET } from "__support__/e2e/cypress_sample_dataset";
+
+const { PRODUCTS } = SAMPLE_DATASET;
+
+const questionDetails = {
+  name: "SQL products category, required, 2 selections",
+  native: {
+    query: "select * from PRODUCTS where {{filter}}",
+    "template-tags": {
+      filter: {
+        id: "e33dc805-6b71-99a5-ee14-128383953986",
+        name: "filter",
+        "display-name": "Filter",
+        type: "dimension",
+        dimension: ["field", PRODUCTS.CATEGORY, null],
+        "widget-type": "category",
+        default: ["Gizmo", "Gadget"],
+        required: true,
+      },
+    },
+  },
+};
+
+const filter = {
+  name: "Category",
+  slug: "category",
+  id: "49fcc65c",
+  type: "category",
+  default: "Widget",
+};
+
+const dashboardDetails = {
+  name: "Required Filters Dashboard",
+  parameters: [filter],
+};
+
+describe("scenarios > dashboard > filters > SQL > field filter > required ", () => {
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createNativeQuestionAndDashboard({
+      questionDetails,
+      dashboardDetails,
+    }).then(({ body: dashboardCard }) => {
+      const { card_id, dashboard_id } = dashboardCard;
+
+      const mapFilterToCard = {
+        parameter_mappings: [
+          {
+            parameter_id: filter.id,
+            card_id,
+            target: ["dimension", ["template-tag", "filter"]],
+          },
+        ],
+      };
+
+      cy.editDashboardCard(dashboardCard, mapFilterToCard);
+
+      cy.visit(`/dashboard/${dashboard_id}`);
+    });
+  });
+
+  it("should respect default filter precedence (dashboard filter, then SQL field filters)", () => {
+    // Default dashboard filter
+    cy.location("search").should("eq", "?category=Widget");
+
+    cy.get(".Card")
+      .as("dashboardCard")
+      .contains("Widget");
+
+    filterWidget().contains("Widget");
+
+    removeWidgetFilterValue();
+
+    cy.location("search").should("eq", "?category=");
+
+    // SQL question defaults
+    cy.get("@dashboardCard").within(() => {
+      cy.findAllByText("Gizmo");
+      cy.findAllByText("Gadget");
+    });
+
+    // The empty filter widget
+    filterWidget().contains("Category");
+
+    cy.reload();
+
+    // This part confirms that the issue metabase#13960 has been fixed
+    cy.location("search").should("eq", "?category=");
+
+    cy.get("@dashboardCard").within(() => {
+      cy.findAllByText("Gizmo");
+      cy.findAllByText("Gadget");
+    });
+
+    // Let's make sure the default dashboard filter is respected upon a subsequent visit from the root
+    cy.visit("/collection/root");
+    cy.findByText("Required Filters Dashboard").click();
+
+    cy.location("search").should("eq", "?category=Widget");
+  });
+});
+
+function removeWidgetFilterValue() {
+  filterWidget()
+    .find(".Icon-close")
+    .click();
+}
diff --git a/frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-simple-filter.cy.spec.js b/frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-simple-filter.cy.spec.js
new file mode 100644
index 00000000000..ed98a37933c
--- /dev/null
+++ b/frontend/test/metabase/scenarios/dashboard-filters/dashboard-filters-sql-required-simple-filter.cy.spec.js
@@ -0,0 +1,132 @@
+import {
+  restore,
+  filterWidget,
+  sidebar,
+  editDashboard,
+  saveDashboard,
+} from "__support__/e2e/cypress";
+
+const questionDetails = {
+  name: "Return input value",
+  native: {
+    query: "select {{filter}}",
+    "template-tags": {
+      filter: {
+        id: "7182a24e-163a-099c-b085-156f0879aaec",
+        name: "filter",
+        "display-name": "Filter",
+        type: "text",
+        required: true,
+        default: "Foo",
+      },
+    },
+  },
+  display: "scalar",
+};
+
+const filter = {
+  name: "Text",
+  slug: "text",
+  id: "904aa8b7",
+  type: "string/=",
+  sectionId: "string",
+  default: "Bar",
+};
+
+const dashboardDetails = {
+  name: "Required Filters Dashboard",
+  parameters: [filter],
+};
+
+describe("scenarios > dashboard > filters > SQL > simple filter > required ", () => {
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+
+    cy.createNativeQuestionAndDashboard({
+      questionDetails,
+      dashboardDetails,
+    }).then(({ body: dashboardCard }) => {
+      const { card_id, dashboard_id } = dashboardCard;
+
+      const mapFilterToCard = {
+        parameter_mappings: [
+          {
+            parameter_id: filter.id,
+            card_id,
+            target: ["variable", ["template-tag", "filter"]],
+          },
+        ],
+      };
+
+      cy.editDashboardCard(dashboardCard, mapFilterToCard);
+
+      cy.visit(`/dashboard/${dashboard_id}`);
+    });
+  });
+
+  it("should respect default filter precedence while properly updating the url for each step of the flow", () => {
+    // Default dashboard filter
+    cy.location("search").should("eq", "?text=Bar");
+
+    cy.get(".Card").contains("Bar");
+
+    cy.findByDisplayValue("Bar");
+
+    removeWidgetFilterValue();
+
+    cy.location("search").should("eq", "?text=");
+
+    // SQL question defaults
+    cy.findByText("Foo");
+
+    // The empty filter widget
+    cy.findByPlaceholderText("Text");
+
+    cy.reload();
+
+    // This part confirms that the issue metabase#13960 has been fixed
+    cy.location("search").should("eq", "?text=");
+
+    cy.findByText("Foo");
+
+    // Let's make sure the default dashboard filter is respected upon a subsequent visit from the root
+    cy.visit("/collection/root");
+    cy.findByText("Required Filters Dashboard").click();
+
+    cy.location("search").should("eq", "?text=Bar");
+
+    // Finally, when we remove dashboard filter's default value, the url should reflect that by removing the placeholder
+    editDashboard();
+
+    openFilterOptions("Text");
+
+    sidebar().within(() => {
+      removeDefaultFilterValue("Bar");
+    });
+
+    saveDashboard();
+
+    cy.url().should("not.include", "?text=");
+  });
+});
+
+function removeWidgetFilterValue() {
+  filterWidget()
+    .find(".Icon-close")
+    .click();
+}
+
+function openFilterOptions(filterDisplayName) {
+  cy.findByText(filterDisplayName)
+    .parent()
+    .find(".Icon-gear")
+    .click();
+}
+
+function removeDefaultFilterValue(value) {
+  cy.findByDisplayValue(value)
+    .parent()
+    .find(".Icon-close")
+    .click();
+}
-- 
GitLab