From 8f87659cb04aa3e1921218b017e9e7cd6b4a2d45 Mon Sep 17 00:00:00 2001
From: Denis Berezin <denis.berezin@metabase.com>
Date: Fri, 6 Oct 2023 21:14:18 +0300
Subject: [PATCH] [33482] Add more unit tests for all implemented drills
 (#33974)

* Add more drills tests, unify tests structure, add issues refs

* Add tests for fk-details drill apply

* Tests fixes after merge with master

* Code review fixes

* Comment failing tests after merging with master

* Restore sort drill tests
---
 frontend/src/metabase-lib/drills.unit.spec.ts | 2543 +++++++++++++----
 frontend/src/metabase-lib/test-helpers.ts     |    6 +
 frontend/src/metabase-lib/types.ts            |   21 +-
 .../api/mocks/presets/sample_database.ts      |  100 +
 frontend/src/metabase-types/api/query.ts      |    2 +-
 .../click-actions/Mode/constants.ts           |    1 +
 .../drills/mlv2/QuickFilterDrill.tsx          |  146 +
 .../drills/mlv2/SummarizeColumnDrill.ts       |   49 +
 .../ClickActionsPopover.unit.spec.tsx         |  117 +-
 9 files changed, 2401 insertions(+), 584 deletions(-)
 create mode 100644 frontend/src/metabase/visualizations/click-actions/drills/mlv2/QuickFilterDrill.tsx
 create mode 100644 frontend/src/metabase/visualizations/click-actions/drills/mlv2/SummarizeColumnDrill.ts

diff --git a/frontend/src/metabase-lib/drills.unit.spec.ts b/frontend/src/metabase-lib/drills.unit.spec.ts
index d39f65bd684..f0c90511654 100644
--- a/frontend/src/metabase-lib/drills.unit.spec.ts
+++ b/frontend/src/metabase-lib/drills.unit.spec.ts
@@ -9,8 +9,18 @@ import {
   createOrdersTaxDatasetColumn,
   createOrdersTotalDatasetColumn,
   createOrdersUserIdDatasetColumn,
+  createProductsCategoryDatasetColumn,
+  createProductsCreatedAtDatasetColumn,
+  createProductsEanDatasetColumn,
+  createProductsIdDatasetColumn,
+  createProductsPriceDatasetColumn,
+  createProductsRatingDatasetColumn,
+  createProductsTitleDatasetColumn,
+  createProductsVendorDatasetColumn,
   ORDERS,
   ORDERS_ID,
+  PRODUCTS,
+  PRODUCTS_ID,
   SAMPLE_DB_ID,
 } from "metabase-types/api/mocks/presets";
 import { createMockColumn } from "metabase-types/api/mocks";
@@ -20,35 +30,65 @@ import type {
   StructuredDatasetQuery,
 } from "metabase-types/api";
 import type { StructuredQuery as StructuredQueryApi } from "metabase-types/api/query";
-import type {
-  ColumnFilterDrillThruInfo,
-  DistributionDrillThruInfo,
-  DrillThru,
-  DrillThruDisplayInfo,
-  DrillThruType,
-  FKDetailsDrillThruInfo,
-  FKFilterDrillThruInfo,
-  Query,
-  QuickFilterDrillThruInfo,
-  SortDrillThruInfo,
-  SummarizeColumnByTimeDrillThruInfo,
-  SummarizeColumnDrillThruInfo,
-  UnderlyingRecordsDrillThruInfo,
-  ZoomDrillThruInfo,
-} from "metabase-lib/types";
 import type StructuredQuery from "metabase-lib/queries/StructuredQuery";
 import Question from "metabase-lib/Question";
-import { SAMPLE_METADATA } from "./test-helpers";
+import { columnFinder, SAMPLE_METADATA } from "./test-helpers";
 import { availableDrillThrus, drillThru } from "./drills";
 
+type TestCaseQueryType = "unaggregated" | "aggregated";
+
+type BaseTestCase = {
+  clickType: "cell" | "header";
+  customQuestion?: Question;
+} & (
+  | {
+      queryTable?: "ORDERS";
+      queryType: "unaggregated";
+      columnName: keyof typeof ORDERS_COLUMNS;
+    }
+  | {
+      queryTable?: "ORDERS";
+      queryType: "aggregated";
+      columnName: keyof typeof AGGREGATED_ORDERS_COLUMNS;
+    }
+  | {
+      queryTable: "PRODUCTS";
+      queryType: "unaggregated";
+      columnName: keyof typeof PRODUCTS_COLUMNS;
+    }
+  | {
+      queryTable: "PRODUCTS";
+      queryType: "aggregated";
+      columnName: keyof typeof AGGREGATED_PRODUCTS_COLUMNS;
+    }
+);
+
+type AvailableDrillsTestCase = BaseTestCase & {
+  expectedDrills: Lib.DrillThruDisplayInfo[];
+};
+
+type DrillDisplayInfoTestCase = BaseTestCase & {
+  drillType: Lib.DrillThruType;
+  expectedParameters: Lib.DrillThruDisplayInfo;
+};
+
+type ApplyDrillTestCase = BaseTestCase & {
+  drillType: Lib.DrillThruType;
+  drillArgs?: any[];
+  expectedQuery: StructuredQueryApi;
+};
+
+const ORDERS_DATASET_QUERY: StructuredDatasetQuery = {
+  database: SAMPLE_DB_ID,
+  type: "query",
+  query: {
+    "source-table": ORDERS_ID,
+  },
+};
 const ORDERS_QUESTION = Question.create({
-  databaseId: SAMPLE_DB_ID,
-  tableId: ORDERS_ID,
   metadata: SAMPLE_METADATA,
+  dataset_query: ORDERS_DATASET_QUERY,
 });
-
-type TestCaseConfig<T extends string> = [T, DrillThruDisplayInfo[]];
-
 const ORDERS_COLUMNS = {
   ID: createOrdersIdDatasetColumn(),
   USER_ID: createOrdersUserIdDatasetColumn(),
@@ -60,539 +100,1546 @@ const ORDERS_COLUMNS = {
   CREATED_AT: createOrdersCreatedAtDatasetColumn(),
   QUANTITY: createOrdersQuantityDatasetColumn(),
 };
-const ORDERS_ROW_VALUES: Record<keyof typeof ORDERS_COLUMNS, string | number> =
-  {
-    ID: "3",
-    USER_ID: "1",
-    PRODUCT_ID: "105",
-    SUBTOTAL: 52.723521442619514,
-    TAX: 2.9,
-    TOTAL: 49.206842233769756,
-    DISCOUNT: 6.416679208849759,
-    CREATED_AT: "2025-12-06T22:22:48.544+02:00",
-    QUANTITY: 2,
-  };
-describe("availableDrillThrus", () => {
-  describe("should return list of available drills", () => {
-    describe("unaggregated query", () => {
-      it.each<TestCaseConfig<keyof typeof ORDERS_COLUMNS>>([
-        [
-          "ID",
-          [
-            {
-              type: "drill-thru/zoom",
-              objectId: ORDERS_ROW_VALUES.ID,
-              "manyPks?": false,
-            } as ZoomDrillThruInfo,
-          ],
-        ],
+const ORDERS_ROW_VALUES: Record<keyof typeof ORDERS_COLUMNS, RowValue> = {
+  ID: "3",
+  USER_ID: "1",
+  PRODUCT_ID: "105",
+  SUBTOTAL: 52.723521442619514,
+  TAX: 2.9,
+  TOTAL: 49.206842233769756,
+  DISCOUNT: null,
+  CREATED_AT: "2025-12-06T22:22:48.544+02:00",
+  QUANTITY: 2,
+};
 
+const AGGREGATED_ORDERS_DATASET_QUERY: StructuredDatasetQuery = {
+  type: "query",
+  database: SAMPLE_DB_ID,
+  query: {
+    "source-table": ORDERS_ID,
+    aggregation: [
+      ["count"],
+      [
+        "sum",
         [
-          "USER_ID",
-          [
-            {
-              type: "drill-thru/fk-filter",
-            } as FKFilterDrillThruInfo,
-            {
-              type: "drill-thru/fk-details",
-              objectId: ORDERS_ROW_VALUES.USER_ID,
-              "manyPks?": false,
-            } as FKDetailsDrillThruInfo,
-          ],
+          "field",
+          ORDERS.TAX,
+          {
+            "base-type": "type/Float",
+          },
         ],
-
+      ],
+      [
+        "max",
         [
-          "SUBTOTAL",
-          [
-            {
-              type: "drill-thru/zoom",
-              objectId: ORDERS_ROW_VALUES.ID,
-              "manyPks?": false,
-            } as ZoomDrillThruInfo,
-            {
-              type: "drill-thru/quick-filter",
-              operators: ["<", ">", "=", "≠"],
-            } as QuickFilterDrillThruInfo,
-          ],
+          "field",
+          ORDERS.DISCOUNT,
+          {
+            "base-type": "type/Float",
+          },
         ],
+      ],
+    ],
+    breakout: [
+      [
+        "field",
+        ORDERS.PRODUCT_ID,
+        {
+          "base-type": "type/Integer",
+        },
+      ],
+      [
+        "field",
+        ORDERS.CREATED_AT,
+        {
+          "base-type": "type/DateTime",
+          "temporal-unit": "month",
+        },
+      ],
+    ],
+  },
+};
+const AGGREGATED_ORDERS_QUESTION = Question.create({
+  metadata: SAMPLE_METADATA,
+  dataset_query: AGGREGATED_ORDERS_DATASET_QUERY,
+});
+const AGGREGATED_ORDERS_COLUMNS = {
+  PRODUCT_ID: createOrdersProductIdDatasetColumn({
+    source: "breakout",
+    field_ref: [
+      "field",
+      ORDERS.PRODUCT_ID,
+      {
+        "base-type": "type/Integer",
+      },
+    ],
+  }),
+  CREATED_AT: createOrdersCreatedAtDatasetColumn({
+    source: "breakout",
+    field_ref: [
+      "field",
+      ORDERS.CREATED_AT,
+      {
+        "base-type": "type/DateTime",
+        "temporal-unit": "month",
+      },
+    ],
+  }),
 
-        [
-          "CREATED_AT",
-          [
-            {
-              type: "drill-thru/zoom",
-              objectId: ORDERS_ROW_VALUES.ID,
-              "manyPks?": false,
-            } as ZoomDrillThruInfo,
-            {
-              type: "drill-thru/quick-filter",
-              operators: ["<", ">", "=", "≠"],
-            } as QuickFilterDrillThruInfo,
-          ],
-        ],
-      ])("ORDERS -> %s cell click", (clickedColumnName, expectedDrills) => {
-        const { query, stageIndex, column, cellValue, row } = setup({
-          clickedColumnName,
-          columns: ORDERS_COLUMNS,
-          rowValues: ORDERS_ROW_VALUES,
-        });
+  count: createMockColumn({
+    base_type: "type/BigInteger",
+    name: "count",
+    display_name: "Count",
+    semantic_type: "type/Quantity",
+    source: "aggregation",
+    field_ref: ["aggregation", 0],
+    effective_type: "type/BigInteger",
+  }),
 
-        const drills = availableDrillThrus(
-          query,
-          stageIndex,
-          column,
-          cellValue,
-          row,
-          undefined,
-        );
+  sum: createMockColumn({
+    base_type: "type/Float",
+    name: "sum",
+    display_name: "Sum of Tax",
+    source: "aggregation",
+    field_ref: ["aggregation", 1],
+    effective_type: "type/Float",
+  }),
 
-        expect(
-          drills.map(drill => Lib.displayInfo(query, stageIndex, drill)),
-        ).toEqual(expectedDrills);
-      });
+  max: createMockColumn({
+    base_type: "type/Float",
+    name: "max",
+    display_name: "Max of Discount",
+    source: "aggregation",
+    field_ref: ["aggregation", 2],
+    effective_type: "type/Float",
+  }),
+};
+const AGGREGATED_ORDERS_ROW_VALUES: Record<
+  keyof typeof AGGREGATED_ORDERS_COLUMNS,
+  RowValue
+> = {
+  PRODUCT_ID: 3,
+  CREATED_AT: "2022-12-01T00:00:00+02:00",
+  count: 77,
+  sum: 1,
+  max: null,
+};
 
-      it.each<TestCaseConfig<keyof typeof ORDERS_COLUMNS>>([
-        [
-          "ID",
-          [
-            {
-              initialOp: expect.objectContaining({ short: "=" }),
-              type: "drill-thru/column-filter",
-            } as ColumnFilterDrillThruInfo,
-            {
-              directions: ["asc", "desc"],
-              type: "drill-thru/sort",
-            } as SortDrillThruInfo,
-            {
-              aggregations: ["distinct"],
-              type: "drill-thru/summarize-column",
-            } as SummarizeColumnDrillThruInfo,
-          ],
-        ],
-        [
-          "PRODUCT_ID",
-          [
-            {
-              type: "drill-thru/distribution",
-            } as DistributionDrillThruInfo,
-            {
-              initialOp: expect.objectContaining({ short: "=" }),
-              type: "drill-thru/column-filter",
-            } as ColumnFilterDrillThruInfo,
-            {
-              directions: ["asc", "desc"],
-              type: "drill-thru/sort",
-            } as SortDrillThruInfo,
-            {
-              aggregations: ["distinct"],
-              type: "drill-thru/summarize-column",
-            } as SummarizeColumnDrillThruInfo,
-          ],
-        ],
-        [
-          "SUBTOTAL",
-          [
-            { type: "drill-thru/distribution" } as DistributionDrillThruInfo,
-            {
-              type: "drill-thru/column-filter",
-              initialOp: expect.objectContaining({ short: "=" }),
-            } as ColumnFilterDrillThruInfo,
-            {
-              type: "drill-thru/sort",
-              directions: ["asc", "desc"],
-            } as SortDrillThruInfo,
-            {
-              type: "drill-thru/summarize-column",
-              aggregations: ["distinct", "sum", "avg"],
-            } as SummarizeColumnDrillThruInfo,
-            {
-              type: "drill-thru/summarize-column-by-time",
-            } as SummarizeColumnByTimeDrillThruInfo,
-          ],
-        ],
-        [
-          "CREATED_AT",
-          [
-            { type: "drill-thru/distribution" } as DistributionDrillThruInfo,
-            {
-              type: "drill-thru/column-filter",
-              initialOp: null,
-            } as ColumnFilterDrillThruInfo,
-            {
-              type: "drill-thru/sort",
-              directions: ["asc", "desc"],
-            } as SortDrillThruInfo,
-            {
-              type: "drill-thru/summarize-column",
-              aggregations: ["distinct"],
-            } as SummarizeColumnDrillThruInfo,
-          ],
-        ],
-      ])("ORDERS -> %s header click", (clickedColumnName, expectedDrills) => {
-        const { query, stageIndex, column } = setup({
-          clickedColumnName,
-          columns: ORDERS_COLUMNS,
-          rowValues: ORDERS_ROW_VALUES,
-        });
+const PRODUCTS_DATASET_QUERY: StructuredDatasetQuery = {
+  database: SAMPLE_DB_ID,
+  type: "query",
+  query: {
+    "source-table": PRODUCTS_ID,
+  },
+};
+const PRODUCTS_QUESTION = Question.create({
+  metadata: SAMPLE_METADATA,
+  dataset_query: PRODUCTS_DATASET_QUERY,
+});
+const PRODUCTS_COLUMNS = {
+  ID: createProductsIdDatasetColumn(),
+  EAN: createProductsEanDatasetColumn(),
+  TITLE: createProductsTitleDatasetColumn(),
+  CATEGORY: createProductsCategoryDatasetColumn(),
+  VENDOR: createProductsVendorDatasetColumn(),
+  PRICE: createProductsPriceDatasetColumn(),
+  RATING: createProductsRatingDatasetColumn(),
+  CREATED_AT: createProductsCreatedAtDatasetColumn(),
+};
+const PRODUCTS_ROW_VALUES: Record<keyof typeof PRODUCTS_COLUMNS, RowValue> = {
+  ID: "3",
+  EAN: "4966277046676",
+  TITLE: "Synergistic Granite Chair",
+  CATEGORY: "Doohickey",
+  VENDOR: "Murray, Watsica and Wunsch",
+  PRICE: 35.38,
+  RATING: 4,
+  CREATED_AT: "2024-09-08T22:03:20.239+03:00",
+};
 
-        const drills = availableDrillThrus(
-          query,
-          stageIndex,
-          column,
-          undefined,
-          undefined,
-          undefined,
-        );
+const AGGREGATED_PRODUCTS_DATASET_QUERY: StructuredDatasetQuery = {
+  type: "query",
+  database: SAMPLE_DB_ID,
+  query: {
+    "source-table": PRODUCTS_ID,
+    aggregation: [["count"]],
+    breakout: [
+      [
+        "field",
+        PRODUCTS.CATEGORY,
+        {
+          "base-type": "type/Text",
+        },
+      ],
+    ],
+  },
+};
+const AGGREGATED_PRODUCTS_QUESTION = Question.create({
+  metadata: SAMPLE_METADATA,
+  dataset_query: AGGREGATED_PRODUCTS_DATASET_QUERY,
+});
+const AGGREGATED_PRODUCTS_COLUMNS = {
+  CATEGORY: createProductsCategoryDatasetColumn({
+    source: "breakout",
+    field_ref: [
+      "field",
+      PRODUCTS.CATEGORY,
+      {
+        "base-type": "type/Text",
+      },
+    ],
+  }),
 
-        expect(
-          drills.map(drill => Lib.displayInfo(query, stageIndex, drill)),
-        ).toEqual(expectedDrills);
-      });
-    });
+  count: createMockColumn({
+    base_type: "type/BigInteger",
+    name: "count",
+    display_name: "Count",
+    semantic_type: "type/Quantity",
+    source: "aggregation",
+    field_ref: ["aggregation", 0],
+    effective_type: "type/BigInteger",
+  }),
+};
+const AGGREGATED_PRODUCTS_ROW_VALUES: Record<
+  keyof typeof AGGREGATED_PRODUCTS_COLUMNS,
+  RowValue
+> = {
+  CATEGORY: "Doohickey",
+  count: 42,
+};
 
-    // FIXME MLv2 returns distribution drill for aggregated query, which is does not match current behavior on stats
-    // eslint-disable-next-line jest/no-disabled-tests
-    describe.skip("aggregated query", () => {
-      const COLUMNS = {
-        PRODUCT_ID: createOrdersProductIdDatasetColumn({
-          source: "breakout",
-          field_ref: [
-            "field",
-            ORDERS.PRODUCT_ID,
-            {
-              "base-type": "type/Integer",
-            },
-          ],
-        }),
-
-        count: createMockColumn({
-          base_type: "type/BigInteger",
-          name: "count",
-          display_name: "Count",
-          semantic_type: "type/Quantity",
-          source: "aggregation",
-          field_ref: ["aggregation", 0],
-          effective_type: "type/BigInteger",
-        }),
-      };
-      const ROW_VALUES = {
-        PRODUCT_ID: 3,
-        count: 77,
-      };
-      const QUESTION = Question.create({
-        databaseId: SAMPLE_DB_ID,
-        tableId: ORDERS_ID,
+const STAGE_INDEX = -1;
+
+describe("availableDrillThrus", () => {
+  it.each<AvailableDrillsTestCase>([
+    {
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "ID",
+      expectedDrills: [
+        {
+          type: "drill-thru/zoom",
+          objectId: ORDERS_ROW_VALUES.ID as string,
+          "manyPks?": false,
+        },
+      ],
+    },
+    {
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedDrills: [
+        {
+          type: "drill-thru/fk-filter",
+        },
+        {
+          type: "drill-thru/fk-details",
+          objectId: ORDERS_ROW_VALUES.USER_ID as string,
+          "manyPks?": false,
+        },
+      ],
+    },
+    {
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "SUBTOTAL",
+      expectedDrills: [
+        {
+          type: "drill-thru/zoom",
+          objectId: ORDERS_ROW_VALUES.ID as string,
+          "manyPks?": false,
+        },
+        {
+          type: "drill-thru/quick-filter",
+          operators: ["<", ">", "=", "≠"],
+        },
+      ],
+    },
+    {
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedDrills: [
+        {
+          type: "drill-thru/zoom",
+          objectId: ORDERS_ROW_VALUES.ID as string,
+          "manyPks?": false,
+        },
+        {
+          type: "drill-thru/quick-filter",
+          operators: ["<", ">", "=", "≠"],
+        },
+      ],
+    },
+    {
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "ID",
+      expectedDrills: [
+        {
+          initialOp: expect.objectContaining({ short: "=" }),
+          type: "drill-thru/column-filter",
+        },
+        {
+          directions: ["asc", "desc"],
+          type: "drill-thru/sort",
+        },
+        {
+          aggregations: ["distinct"],
+          type: "drill-thru/summarize-column",
+        },
+      ],
+    },
+    {
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "PRODUCT_ID",
+      expectedDrills: [
+        {
+          type: "drill-thru/distribution",
+        },
+        {
+          initialOp: expect.objectContaining({ short: "=" }),
+          type: "drill-thru/column-filter",
+        },
+        {
+          directions: ["asc", "desc"],
+          type: "drill-thru/sort",
+        },
+        {
+          aggregations: ["distinct"],
+          type: "drill-thru/summarize-column",
+        },
+      ],
+    },
+    {
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "SUBTOTAL",
+      expectedDrills: [
+        { type: "drill-thru/distribution" },
+        {
+          type: "drill-thru/column-filter",
+          initialOp: expect.objectContaining({ short: "=" }),
+        },
+        {
+          type: "drill-thru/sort",
+          directions: ["asc", "desc"],
+        },
+        {
+          type: "drill-thru/summarize-column",
+          aggregations: ["distinct", "sum", "avg"],
+        },
+        {
+          type: "drill-thru/summarize-column-by-time",
+        },
+      ],
+    },
+    {
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedDrills: [
+        { type: "drill-thru/distribution" },
+        {
+          type: "drill-thru/column-filter",
+          initialOp: null,
+        },
+        {
+          type: "drill-thru/sort",
+          directions: ["asc", "desc"],
+        },
+        {
+          type: "drill-thru/summarize-column",
+          aggregations: ["distinct"],
+        },
+      ],
+    },
+    // FIXME: fk-filter gets returned for non-fk column (metabase#34440), fk-details gets returned for non-fk colum (metabase#34441), underlying-records drill gets shown two times for aggregated query (metabase#34439)
+    // {
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "count",
+    //   expectedDrills: [
+    //     {
+    //       type: "drill-thru/quick-filter",
+    //       operators: ["<", ">", "=", "≠"],
+    //     },
+    //     {
+    //       type: "drill-thru/underlying-records",
+    //       rowCount: 2, // FIXME: (metabase#32108) this should return real count of rows
+    //       tableName: "Orders",
+    //     },
+    //     {
+    //       displayName: "See this month by week",
+    //       type: "drill-thru/zoom-in.timeseries",
+    //     },
+    //   ],
+    // },
+    // FIXME: fk-filter gets returned for non-fk column (metabase#34440), fk-details gets returned for non-fk colum (metabase#34441), underlying-records drill gets shown two times for aggregated query (metabase#34439)
+    // {
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "max",
+    //   expectedDrills: [
+    //     {
+    //       type: "drill-thru/quick-filter",
+    //       operators: ["=", "≠"],
+    //     },
+    //     {
+    //       type: "drill-thru/underlying-records",
+    //       rowCount: 2, // FIXME: (metabase#32108) this should return real count of rows
+    //       tableName: "Orders",
+    //     },
+    //
+    //     {
+    //       type: "drill-thru/zoom-in.timeseries",
+    //       displayName: "See this month by week",
+    //     },
+    //   ],
+    // },
+    // FIXME: quick-filter gets returned for non-metric column (metabase#34443)
+    // {
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "PRODUCT_ID",
+    //   expectedDrills: [
+    //     {
+    //       type: "drill-thru/fk-filter",
+    //     },
+    //     {
+    //       type: "drill-thru/fk-details",
+    //       objectId: AGGREGATED_ORDERS_ROW_VALUES.PRODUCT_ID as number,
+    //       "manyPks?": false,
+    //     },
+    //     {
+    //       rowCount: 2, // FIXME: (metabase#32108) this should return real count of rows
+    //       tableName: "Orders",
+    //       type: "drill-thru/underlying-records",
+    //     },
+    //   ],
+    // },
+    // FIXME: quick-filter gets returned for non-metric column (metabase#34443)
+    // {
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "CREATED_AT",
+    //   expectedDrills: [
+    //     {
+    //       type: "drill-thru/quick-filter",
+    //       operators: ["<", ">", "=", "≠"],
+    //     },
+    //     {
+    //       rowCount: 3, // FIXME: (metabase#32108) this should return real count of rows
+    //       tableName: "Orders",
+    //       type: "drill-thru/underlying-records",
+    //     },
+    //   ],
+    // },
+
+    // FIXME for some reason the results for aggregated query are not correct (metabase#34223, metabase#34341)
+    // We expect column-filter and sort drills, but get distribution and summarize-column
+    // {
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "count",
+    //   expectedDrills: [
+    //     {
+    //       initialOp: expect.objectContaining({ short: "=" }),
+    //       type: "drill-thru/column-filter",
+    //     },
+    //     {
+    //       directions: ["asc", "desc"],
+    //       type: "drill-thru/sort",
+    //     },
+    //   ],
+    // },
+    // FIXME for some reason the results for aggregated query are not correct (metabase#34223, metabase#34341)
+    // We expect column-filter and sort drills, but get distribution and summarize-column
+    // {
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "PRODUCT_ID",
+    //   expectedDrills: [
+    //     {
+    //       initialOp: expect.objectContaining({ short: "=" }),
+    //       type: "drill-thru/column-filter",
+    //     },
+    //     {
+    //       directions: ["asc", "desc"],
+    //       type: "drill-thru/sort",
+    //     },
+    //   ],
+    // },
+    // FIXME for some reason the results for aggregated query are not correct (metabase#34223, metabase#34341)
+    // We expect column-filter and sort drills, but get distribution and summarize-column
+    // {
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "CREATED_AT",
+    //   expectedDrills: [
+    //     {
+    //       initialOp: expect.objectContaining({ short: "=" }),
+    //       type: "drill-thru/column-filter",
+    //     },
+    //     {
+    //       directions: ["asc", "desc"],
+    //       type: "drill-thru/sort",
+    //     },
+    //   ],
+    // },
+  ])(
+    "should return correct drills for $columnName $clickType in $queryType query",
+    ({
+      columnName,
+      clickType,
+      queryType,
+      expectedDrills,
+      queryTable = "ORDERS",
+    }) => {
+      const { drillsDisplayInfo } =
+        queryTable === "PRODUCTS"
+          ? setupAvailableDrillsWithProductsQuery({
+              clickType,
+              queryType,
+              columnName,
+            })
+          : setupAvailableDrillsWithOrdersQuery({
+              clickType,
+              queryType,
+              columnName,
+            });
+
+      expect(drillsDisplayInfo).toEqual(expectedDrills);
+    },
+  );
+
+  it.each<DrillDisplayInfoTestCase>([
+    // region --- drill-thru/sort
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "ID",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "TOTAL",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "TOTAL",
+      customQuestion: Question.create({
         metadata: SAMPLE_METADATA,
         dataset_query: {
-          type: "query",
           database: SAMPLE_DB_ID,
+          type: "query",
           query: {
+            "order-by": [["desc", ["field", ORDERS.TOTAL, null]]],
             "source-table": ORDERS_ID,
-            aggregation: [["count"]],
-            breakout: [
-              ["field", ORDERS.PRODUCT_ID, { "base-type": "type/Integer" }],
-            ],
           },
         },
-      });
-
-      it.each<TestCaseConfig<keyof typeof COLUMNS>>([
-        [
-          "count",
-          [
-            {
-              type: "drill-thru/quick-filter",
-              operators: ["<", ">", "=", "≠"],
-            } as QuickFilterDrillThruInfo,
-            {
-              type: "drill-thru/underlying-records",
-              rowCount: 77,
-              tableName: "Orders",
-            } as UnderlyingRecordsDrillThruInfo,
-          ],
-        ],
-        [
-          "PRODUCT_ID",
-          [
-            {
-              type: "drill-thru/fk-filter",
-            } as FKFilterDrillThruInfo,
-            {
-              type: "drill-thru/fk-details",
-              objectId: ROW_VALUES.PRODUCT_ID,
-              "manyPks?": false,
-            } as FKDetailsDrillThruInfo,
-          ],
-        ],
-      ])("ORDERS -> %s cell click", (clickedColumnName, expectedDrills) => {
-        const { query, stageIndex, column, cellValue, row } = setup({
-          question: QUESTION,
-          clickedColumnName,
-          columns: COLUMNS,
-          rowValues: ROW_VALUES,
-        });
-
-        const dimensions = row
-          .filter(
-            ({ col }) =>
-              col.source === "breakout" && col.name !== clickedColumnName,
-          )
-          .map(({ value, col }) => ({ value, column: col }));
-
-        const drills = availableDrillThrus(
-          query,
-          stageIndex,
-          column,
-          cellValue,
-          row,
-          dimensions.length ? dimensions : undefined,
-        );
-
-        expect(
-          drills.map(drill => Lib.displayInfo(query, stageIndex, drill)),
-        ).toEqual(expectedDrills);
-      });
+      }),
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "PRODUCT_ID",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "count",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    {
+      drillType: "drill-thru/sort",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "max",
+      expectedParameters: {
+        type: "drill-thru/sort",
+        directions: ["asc", "desc"],
+      },
+    },
+    // endregion
 
-      it.each<TestCaseConfig<keyof typeof COLUMNS>>([
-        [
-          "count",
+    // region --- drill-thru/column-filter
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "ID",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "TAX",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "DISCOUNT",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: null,
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "QUANTITY",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "PRODUCT_ID",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "PRODUCT_ID",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: expect.objectContaining({ short: "=" }),
+      },
+    },
+    {
+      drillType: "drill-thru/column-filter",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/column-filter",
+        initialOp: null,
+      },
+    },
+    // FIXME "column-filter" should be available for aggregated query metric column (metabase#34223)
+    // {
+    //   drillType: "drill-thru/column-filter",
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "count",
+    //   expectedParameters: {
+    //     type: "drill-thru/column-filter",
+    //     initialOp: expect.objectContaining({ short: "=" }),
+    //   },
+    // },
+    // FIXME "column-filter" should be available for aggregated query metric column (metabase#34223)
+    // {
+    //   drillType: "drill-thru/column-filter",
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "max",
+    //   expectedParameters: {
+    //     type: "drill-thru/column-filter",
+    //     initialOp: expect.objectContaining({ short: "=" }),
+    //   },
+    // },
+    // endregion
+
+    // region --- drill-thru/summarize-column
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "ID",
+      expectedParameters: {
+        type: "drill-thru/summarize-column",
+        aggregations: ["distinct"],
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedParameters: {
+        type: "drill-thru/summarize-column",
+        aggregations: ["distinct"],
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "SUBTOTAL",
+      expectedParameters: {
+        type: "drill-thru/summarize-column",
+        aggregations: ["distinct", "sum", "avg"],
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/summarize-column",
+        aggregations: ["distinct"],
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "QUANTITY",
+      expectedParameters: {
+        type: "drill-thru/summarize-column",
+        aggregations: ["distinct", "sum", "avg"],
+      },
+    },
+    // endregion
+
+    // region --- drill-thru/distribution
+    {
+      drillType: "drill-thru/distribution",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedParameters: {
+        type: "drill-thru/distribution",
+      },
+    },
+    {
+      drillType: "drill-thru/distribution",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "TAX",
+      expectedParameters: {
+        type: "drill-thru/distribution",
+      },
+    },
+    {
+      drillType: "drill-thru/distribution",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "QUANTITY",
+      expectedParameters: {
+        type: "drill-thru/distribution",
+      },
+    },
+    {
+      drillType: "drill-thru/distribution",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "PRODUCT_ID",
+      expectedParameters: {
+        type: "drill-thru/distribution",
+      },
+    },
+    {
+      drillType: "drill-thru/distribution",
+      clickType: "header",
+      queryType: "aggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/distribution",
+      },
+    },
+    // endregion
+
+    // region --- drill-thru/fk-filter
+    {
+      drillType: "drill-thru/fk-filter",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedParameters: {
+        type: "drill-thru/fk-filter",
+      },
+    },
+    {
+      drillType: "drill-thru/fk-filter",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "PRODUCT_ID",
+      expectedParameters: {
+        type: "drill-thru/fk-filter",
+      },
+    },
+    // FIXME: `fk-filter` doesn't get returned for fk column that was used as breakout (metabase#34440)
+    // {
+    //   drillType: "drill-thru/fk-filter",
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "PRODUCT_ID",
+    //   expectedParameters: {
+    //     type: "drill-thru/fk-filter",
+    //   },
+    // },
+    // endregion
+
+    // region --- drill-thru/quick-filter
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "SUBTOTAL",
+      expectedParameters: {
+        type: "drill-thru/quick-filter",
+        operators: ["<", ">", "=", "≠"],
+      },
+    },
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "DISCOUNT",
+      expectedParameters: {
+        type: "drill-thru/quick-filter",
+        operators: ["=", "≠"],
+      },
+    },
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/quick-filter",
+        operators: ["<", ">", "=", "≠"],
+      },
+    },
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "QUANTITY",
+      expectedParameters: {
+        type: "drill-thru/quick-filter",
+        operators: ["<", ">", "=", "≠"],
+      },
+    },
+    // FIXME: quick-filter doesn't get returned for CREATED_AT column in aggregated query (metabase#34443)
+    // {
+    //   drillType: "drill-thru/quick-filter",
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "CREATED_AT",
+    //   expectedParameters: {
+    //     type: "drill-thru/quick-filter",
+    //     operators: ["<", ">", "=", "≠"],
+    //   },
+    // },
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      queryType: "aggregated",
+      columnName: "count",
+      expectedParameters: {
+        type: "drill-thru/quick-filter",
+        operators: ["<", ">", "=", "≠"],
+      },
+    },
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      queryType: "aggregated",
+      columnName: "sum",
+      expectedParameters: {
+        type: "drill-thru/quick-filter",
+        operators: ["<", ">", "=", "≠"],
+      },
+    },
+    // FIXME: quick-filter returns extra "<", ">" operators for cell with no value (metabase#34445)
+    // {
+    //   drillType: "drill-thru/quick-filter",
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   columnName: "max",
+    //   expectedParameters: {
+    //     type: "drill-thru/quick-filter",
+    //     operators: ["=", "≠"],
+    //   },
+    // },
+    // endregion
+
+    // region --- drill-thru/underlying-records
+    {
+      drillType: "drill-thru/underlying-records",
+      clickType: "cell",
+      queryType: "aggregated",
+      columnName: "count",
+      expectedParameters: {
+        type: "drill-thru/underlying-records",
+        rowCount: 3, // FIXME: (metabase#32108) this should return real count of rows
+        tableName: "Orders",
+      },
+    },
+    {
+      drillType: "drill-thru/underlying-records",
+      clickType: "cell",
+      queryType: "aggregated",
+      columnName: "sum",
+      expectedParameters: {
+        type: "drill-thru/underlying-records",
+        rowCount: 3, // FIXME: (metabase#32108) this should return real count of rows
+        tableName: "Orders",
+      },
+    },
+    {
+      drillType: "drill-thru/underlying-records",
+      clickType: "cell",
+      queryType: "aggregated",
+      columnName: "max",
+      expectedParameters: {
+        type: "drill-thru/underlying-records",
+        rowCount: 3, // FIXME: (metabase#32108) this should return real count of rows
+        tableName: "Orders",
+      },
+    },
+    // endregion
+
+    // region --- drill-thru/summarize-column-by-time
+    {
+      drillType: "drill-thru/summarize-column-by-time",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "SUBTOTAL",
+      expectedParameters: {
+        type: "drill-thru/summarize-column-by-time",
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column-by-time",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "DISCOUNT",
+      expectedParameters: {
+        type: "drill-thru/summarize-column-by-time",
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column-by-time",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "QUANTITY",
+      expectedParameters: {
+        type: "drill-thru/summarize-column-by-time",
+      },
+    },
+    // endregion
+
+    // region --- drill-thru/zoom-in.timeseries
+    // FIXME: "zoom-in.timeseries" should be returned for aggregated query metric click (metabase#33811)
+    // {
+    //   drillType: "drill-thru/zoom-in.timeseries",
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "count",
+    //   expectedParameters: {
+    //     type: "drill-thru/zoom-in.timeseries",
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/zoom-in.timeseries",
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "max",
+    //   expectedParameters: {
+    //     type: "drill-thru/zoom-in.timeseries",
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/zoom-in.timeseries",
+    //   clickType: "header",
+    //   queryType: "aggregated",
+    //   columnName: "sum",
+    //   expectedParameters: {
+    //     type: "drill-thru/zoom-in.timeseries",
+    //   },
+    // },
+    // endregion
+
+    // region --- drill-thru/zoom
+    {
+      drillType: "drill-thru/zoom",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "ID",
+      expectedParameters: {
+        type: "drill-thru/zoom",
+        objectId: ORDERS_ROW_VALUES.ID as string,
+        "manyPks?": false,
+      },
+    },
+    {
+      drillType: "drill-thru/zoom",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "TAX",
+      expectedParameters: {
+        type: "drill-thru/zoom",
+        objectId: ORDERS_ROW_VALUES.ID as string,
+        "manyPks?": false,
+      },
+    },
+    {
+      drillType: "drill-thru/zoom",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "DISCOUNT",
+      expectedParameters: {
+        type: "drill-thru/zoom",
+        objectId: ORDERS_ROW_VALUES.ID as string,
+        "manyPks?": false,
+      },
+    },
+    {
+      drillType: "drill-thru/zoom",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "CREATED_AT",
+      expectedParameters: {
+        type: "drill-thru/zoom",
+        objectId: ORDERS_ROW_VALUES.ID as string,
+        "manyPks?": false,
+      },
+    },
+    {
+      drillType: "drill-thru/zoom",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "QUANTITY",
+      expectedParameters: {
+        type: "drill-thru/zoom",
+        objectId: ORDERS_ROW_VALUES.ID as string,
+        "manyPks?": false,
+      },
+    },
+    // endregion
+
+    // region --- drill-thru/pk
+    // FIXME: how to trigger this ???
+    // endregion
+
+    // region --- drill-thru/fk-details
+    {
+      drillType: "drill-thru/fk-details",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "PRODUCT_ID",
+      expectedParameters: {
+        type: "drill-thru/fk-details",
+        objectId: ORDERS_ROW_VALUES.PRODUCT_ID as string,
+        "manyPks?": false,
+      },
+    },
+    {
+      drillType: "drill-thru/fk-details",
+      clickType: "cell",
+      queryType: "unaggregated",
+      columnName: "USER_ID",
+      expectedParameters: {
+        type: "drill-thru/fk-details",
+        objectId: ORDERS_ROW_VALUES.USER_ID as string,
+        "manyPks?": false,
+      },
+    },
+    // endregion
+
+    // region --- drill-thru/pivot
+    // FIXME: pivot is not implemented yet (metabase#33559)
+    // {
+    //   drillType: "drill-thru/pivot",
+    //   clickType: "cell",
+    //   queryType: "aggregated",
+    //   queryTable: "PRODUCTS",
+    //   columnName: "count",
+    //   expectedParameters: {
+    //     type: "drill-thru/pivot",
+    //   },
+    // },
+    // endregion
+  ])(
+    'should return "$drillType" drill config for $columnName $clickType in $queryType query',
+    ({
+      drillType,
+      columnName,
+      clickType,
+      queryType,
+      queryTable = "ORDERS",
+      customQuestion,
+      expectedParameters,
+    }) => {
+      const { drillDisplayInfo } =
+        queryTable === "PRODUCTS"
+          ? setupDrillDisplayInfoWithProductsQuery({
+              drillType,
+              clickType,
+              queryType,
+              columnName,
+              customQuestion,
+            })
+          : setupDrillDisplayInfoWithOrdersQuery({
+              drillType,
+              clickType,
+              queryType,
+              columnName,
+              customQuestion,
+            });
+
+      expect(drillDisplayInfo).toEqual(expectedParameters);
+    },
+  );
+
+  it("should return list of available drills for aggregated query with custom column", () => {
+    const question = Question.create({
+      metadata: SAMPLE_METADATA,
+      dataset_query: {
+        database: SAMPLE_DB_ID,
+        type: "query",
+        query: {
+          "source-table": ORDERS_ID,
+          expressions: { CustomColumn: ["+", 1, 1] },
+          aggregation: [["count"]],
+          breakout: [
+            ["expression", "CustomColumn"],
+            [
+              "field",
+              ORDERS.CREATED_AT,
+              { "base-type": "type/DateTime", "temporal-unit": "month" },
+            ],
+          ],
+        },
+      } as StructuredDatasetQuery,
+    });
+
+    const columns = {
+      CustomColumn: createMockColumn({
+        base_type: "type/Integer",
+        name: "Custom",
+        display_name: "Custom",
+        expression_name: "Custom",
+        field_ref: ["expression", "Custom"],
+        source: "breakout",
+        effective_type: "type/Integer",
+      }),
+      CREATED_AT: createOrdersCreatedAtDatasetColumn({
+        source: "breakout",
+        field_ref: [
+          "field",
+          ORDERS.CREATED_AT,
+          {
+            "base-type": "type/DateTime",
+            "temporal-unit": "month",
+          },
+        ],
+      }),
+      count: createMockColumn({
+        base_type: "type/BigInteger",
+        name: "count",
+        display_name: "Count",
+        semantic_type: "type/Quantity",
+        source: "aggregation",
+        field_ref: ["aggregation", 0],
+        effective_type: "type/BigInteger",
+      }),
+    };
+    const rowValues = {
+      Math: 2,
+      CREATED_AT: "2022-06-01T00:00:00+03:00",
+      count: 37,
+    };
+    const clickedColumnName = "count";
+
+    const { query, stageIndex, column, cellValue, row } = setup({
+      question,
+      clickedColumnName,
+      columns,
+      rowValues,
+      tableName: "ORDERS",
+    });
+
+    const dimensions = row
+      .filter(({ col }) => col?.name !== clickedColumnName)
+      .map(({ value, col }) => ({ value, column: col }));
+
+    const drills = availableDrillThrus(
+      query,
+      stageIndex,
+      column,
+      cellValue,
+      row,
+      dimensions,
+    );
+
+    expect(drills).toBeInstanceOf(Array);
+  });
+});
+
+describe("drillThru", () => {
+  it.each<ApplyDrillTestCase>([
+    // FIXME: sort drill returns wrong result query (metabase#34342)
+    // {
+    //   drillType: "drill-thru/sort",
+    //   clickType: "header",
+    //   columnName: "ID",
+    //   queryType: "unaggregated",
+    //   drillArgs: ["asc"],
+    //   expectedQuery: {
+    //     "order-by": [
+    //       [
+    //         "asc",
+    //         [
+    //           "field",
+    //           ORDERS.ID,
+    //           {
+    //             "base-type": "type/BigInteger",
+    //           },
+    //         ],
+    //       ],
+    //     ],
+    //     "source-table": ORDERS_ID,
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/sort",
+    //   clickType: "header",
+    //   columnName: "PRODUCT_ID",
+    //   queryType: "unaggregated",
+    //   drillArgs: ["desc"],
+    //   expectedQuery: {
+    //     "order-by": [
+    //       [
+    //         "desc",
+    //         [
+    //           "field",
+    //           ORDERS.PRODUCT_ID,
+    //           {
+    //             "base-type": "type/Integer",
+    //           },
+    //         ],
+    //       ],
+    //     ],
+    //     "source-table": ORDERS_ID,
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/sort",
+    //   clickType: "header",
+    //   columnName: "SUBTOTAL",
+    //   queryType: "unaggregated",
+    //   drillArgs: ["asc"],
+    //   expectedQuery: {
+    //     "order-by": [
+    //       [
+    //         "asc",
+    //         [
+    //           "field",
+    //           ORDERS.SUBTOTAL,
+    //           {
+    //             "base-type": "type/Float",
+    //           },
+    //         ],
+    //       ],
+    //     ],
+    //     "source-table": ORDERS_ID,
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/sort",
+    //   clickType: "header",
+    //   columnName: "DISCOUNT",
+    //   queryType: "unaggregated",
+    //   drillArgs: ["desc"],
+    //   expectedQuery: {
+    //     "order-by": [
+    //       [
+    //         "desc",
+    //         [
+    //           "field",
+    //           ORDERS.DISCOUNT,
+    //           {
+    //             "base-type": "type/Float",
+    //           },
+    //         ],
+    //       ],
+    //     ],
+    //     "source-table": ORDERS_ID,
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/sort",
+    //   clickType: "header",
+    //   columnName: "CREATED_AT",
+    //   queryType: "unaggregated",
+    //   drillArgs: ["asc"],
+    //   expectedQuery: {
+    //     "order-by": [
+    //       [
+    //         "asc",
+    //         [
+    //           "field",
+    //           ORDERS.CREATED_AT,
+    //           {
+    //             "base-type": "type/DateTime",
+    //           },
+    //         ],
+    //       ],
+    //     ],
+    //     "source-table": ORDERS_ID,
+    //   },
+    // },
+
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      queryType: "unaggregated",
+      columnName: "ID",
+      drillArgs: ["distinct"],
+      expectedQuery: {
+        aggregation: [
+          [
+            "distinct",
+            [
+              "field",
+              ORDERS.ID,
+              {
+                "base-type": "type/BigInteger",
+              },
+            ],
+          ],
+        ],
+        "source-table": ORDERS_ID,
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      columnName: "PRODUCT_ID",
+      queryType: "unaggregated",
+      drillArgs: ["distinct"],
+      expectedQuery: {
+        aggregation: [
+          [
+            "distinct",
+            [
+              "field",
+              ORDERS.PRODUCT_ID,
+              {
+                "base-type": "type/Integer",
+              },
+            ],
+          ],
+        ],
+        "source-table": ORDERS_ID,
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      columnName: "SUBTOTAL",
+      queryType: "unaggregated",
+      drillArgs: ["distinct"],
+      expectedQuery: {
+        aggregation: [
+          [
+            "distinct",
+            [
+              "field",
+              ORDERS.SUBTOTAL,
+              {
+                "base-type": "type/Float",
+              },
+            ],
+          ],
+        ],
+        "source-table": ORDERS_ID,
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      columnName: "TAX",
+      queryType: "unaggregated",
+      drillArgs: ["sum"],
+      expectedQuery: {
+        aggregation: [
+          [
+            "sum",
+            [
+              "field",
+              ORDERS.TAX,
+              {
+                "base-type": "type/Float",
+              },
+            ],
+          ],
+        ],
+        "source-table": ORDERS_ID,
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      columnName: "DISCOUNT",
+      queryType: "unaggregated",
+      drillArgs: ["avg"],
+      expectedQuery: {
+        aggregation: [
           [
-            {
-              initialOp: expect.objectContaining({ short: "=" }),
-              type: "drill-thru/column-filter",
-            } as ColumnFilterDrillThruInfo,
-            {
-              directions: ["asc", "desc"],
-              type: "drill-thru/sort",
-            } as SortDrillThruInfo,
+            "avg",
+            [
+              "field",
+              ORDERS.DISCOUNT,
+              {
+                "base-type": "type/Float",
+              },
+            ],
           ],
         ],
-        [
-          "PRODUCT_ID",
+        "source-table": ORDERS_ID,
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      columnName: "CREATED_AT",
+      queryType: "unaggregated",
+      drillArgs: ["distinct"],
+      expectedQuery: {
+        aggregation: [
           [
-            {
-              initialOp: expect.objectContaining({ short: "=" }),
-              type: "drill-thru/column-filter",
-            } as ColumnFilterDrillThruInfo,
-            {
-              directions: ["asc", "desc"],
-              type: "drill-thru/sort",
-            } as SortDrillThruInfo,
+            "distinct",
+            [
+              "field",
+              ORDERS.CREATED_AT,
+              {
+                "base-type": "type/DateTime",
+              },
+            ],
           ],
         ],
-      ])("ORDERS -> %s header click", (clickedColumnName, expectedDrills) => {
-        const { query, stageIndex, column } = setup({
-          question: QUESTION,
-          clickedColumnName,
-          columns: COLUMNS,
-          rowValues: ROW_VALUES,
-        });
-
-        const drills = availableDrillThrus(
-          query,
-          stageIndex,
-          column,
-          undefined,
-          undefined,
-          undefined,
-        );
-
-        expect(
-          drills.map(drill => Lib.displayInfo(query, stageIndex, drill)),
-        ).toEqual(expectedDrills);
-      });
-    });
-
-    // FIXME MLv2 throws runtime error when we have a custom expression column
-    // eslint-disable-next-line jest/no-disabled-tests
-    it.skip("should return list of available drills for aggregated query with custom column", () => {
-      const question = Question.create({
-        databaseId: SAMPLE_DB_ID,
-        tableId: ORDERS_ID,
-        metadata: SAMPLE_METADATA,
-        dataset_query: {
-          database: SAMPLE_DB_ID,
-          type: "query",
-          query: {
-            "source-table": ORDERS_ID,
-            expressions: { CustomColumn: ["+", 1, 1] },
-            aggregation: [["count"]],
-            breakout: [
-              ["expression", "CustomColumn"],
-              [
-                "field",
-                ORDERS.CREATED_AT,
-                { "base-type": "type/DateTime", "temporal-unit": "month" },
-              ],
+        "source-table": ORDERS_ID,
+      },
+    },
+    {
+      drillType: "drill-thru/summarize-column",
+      clickType: "header",
+      columnName: "QUANTITY",
+      queryType: "unaggregated",
+      drillArgs: ["avg"],
+      expectedQuery: {
+        aggregation: [
+          [
+            "avg",
+            [
+              "field",
+              ORDERS.QUANTITY,
+              {
+                "base-type": "type/Integer",
+              },
             ],
-          },
-          parameters: [],
-        } as StructuredDatasetQuery,
-      });
-      const columns = {
-        Math: createMockColumn({
-          base_type: "type/Integer",
-          name: "Math",
-          display_name: "Math",
-          expression_name: "Math",
-          field_ref: ["expression", "Math"],
-          source: "breakout",
-          effective_type: "type/Integer",
-        }),
-        CREATED_AT: createOrdersCreatedAtDatasetColumn({
-          source: "breakout",
-          field_ref: [
-            "field",
-            ORDERS.CREATED_AT,
-            {
-              "base-type": "type/DateTime",
-              "temporal-unit": "month",
-            },
           ],
-        }),
-        count: createMockColumn({
-          base_type: "type/BigInteger",
-          name: "count",
-          display_name: "Count",
-          semantic_type: "type/Quantity",
-          source: "aggregation",
-          field_ref: ["aggregation", 0],
-          effective_type: "type/BigInteger",
-        }),
-      };
-      const rowValues = {
-        Math: 2,
-        CREATED_AT: "2022-06-01T00:00:00+03:00",
-        count: 37,
-      };
-      const clickedColumnName = "count";
-
-      const { query, stageIndex, column, cellValue, row } = setup({
-        question,
-        clickedColumnName,
-        columns,
-        rowValues,
-      });
-
-      const dimensions = row
-        .filter(({ col }) => col?.name !== clickedColumnName)
-        .map(({ value, col }) => ({ value, column: col }));
-
-      const drills = availableDrillThrus(
-        query,
-        stageIndex,
-        column,
-        cellValue,
-        row,
-        dimensions,
-      );
-
-      expect(drills).toBeInstanceOf(Array);
-    });
-  });
-});
-
-describe("drillThru", () => {
-  it.each<{
-    drillType: DrillThruType;
-    clickType: "cell" | "header";
-    columnName: string;
-    drillArgs?: any[];
-    expectedQuery: StructuredQueryApi;
-  }>([
-    // FIXME: sort drill is not yet implemented on the BE side
-    // {
-    //   drillType: "drill-thru/sort",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.ID.name,
-    //   drillArgs: ["asc"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/sort",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.PRODUCT_ID.name,
-    //   drillArgs: ["desc"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/sort",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.SUBTOTAL.name,
-    //   drillArgs: ["asc"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/sort",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.DISCOUNT.name,
-    //   drillArgs: ["desc"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/sort",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.CREATED_AT.name,
-    //   drillArgs: ["asc"],
-    //   expectedQuery: {},
-    // },
-
-    // FIXME: summarize-column drill does not work due to metabase#33480
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.ID.name,
-    //   drillArgs: ["distinct"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.PRODUCT_ID.name,
-    //   drillArgs: ["distinct"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.SUBTOTAL.name,
-    //   drillArgs: ["distinct"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.TAX.name,
-    //   drillArgs: ["sum"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.DISCOUNT.name,
-    //   drillArgs: ["avg"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.CREATED_AT.name,
-    //   drillArgs: ["distinct"],
-    //   expectedQuery: {},
-    // },
-    // {
-    //   drillType: "drill-thru/summarize-column",
-    //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.QUANTITY.name,
-    //   drillArgs: ["avg"],
-    //   expectedQuery: {},
-    // },
+        ],
+        "source-table": ORDERS_ID,
+      },
+    },
 
-    // FIXME: distribution drill does not work on FK columns
+    // FIXME: distribution drill result for FK columns creates extra binning, which is wrong (metabase#34343)
     // {
     //   drillType: "drill-thru/distribution",
     //   clickType: "header",
-    //   columnName: ORDERS_COLUMNS.USER_ID.name,
+    //   columnName: "USER_ID",
+    //   queryType: "unaggregated",
     //   expectedQuery: {
     //     aggregation: [["count"]],
     //     breakout: [["field", ORDERS.USER_ID, null]],
@@ -602,7 +1649,8 @@ describe("drillThru", () => {
     {
       drillType: "drill-thru/distribution",
       clickType: "header",
-      columnName: ORDERS_COLUMNS.SUBTOTAL.name,
+      columnName: "SUBTOTAL",
+      queryType: "unaggregated",
       expectedQuery: {
         aggregation: [["count"]],
         breakout: [
@@ -623,7 +1671,8 @@ describe("drillThru", () => {
     {
       drillType: "drill-thru/distribution",
       clickType: "header",
-      columnName: ORDERS_COLUMNS.CREATED_AT.name,
+      columnName: "CREATED_AT",
+      queryType: "unaggregated",
       expectedQuery: {
         aggregation: [["count"]],
         breakout: [
@@ -643,7 +1692,8 @@ describe("drillThru", () => {
     {
       drillType: "drill-thru/summarize-column-by-time",
       clickType: "header",
-      columnName: ORDERS_COLUMNS.TAX.name,
+      columnName: "TAX",
+      queryType: "unaggregated",
       expectedQuery: {
         aggregation: [
           [
@@ -673,7 +1723,8 @@ describe("drillThru", () => {
     {
       drillType: "drill-thru/summarize-column-by-time",
       clickType: "header",
-      columnName: ORDERS_COLUMNS.QUANTITY.name,
+      columnName: "QUANTITY",
+      queryType: "unaggregated",
       expectedQuery: {
         aggregation: [
           [
@@ -701,19 +1752,33 @@ describe("drillThru", () => {
       },
     },
 
-    // FIXME: cell quick-filter drill doesn't work yet with a simple operator like "=", seems we need to implement MLv2 Filters first
-    // {
-    //   drillType: "drill-thru/quick-filter",
-    //   clickType: "cell",
-    //   columnName: ORDERS_COLUMNS.SUBTOTAL.name,
-    //   drillArgs: ["="],
-    //   expectedQuery: {},
-    // },
+    {
+      drillType: "drill-thru/quick-filter",
+      clickType: "cell",
+      columnName: "SUBTOTAL",
+      queryType: "unaggregated",
+      drillArgs: ["="],
+      expectedQuery: {
+        filter: [
+          "=",
+          [
+            "field",
+            ORDERS.SUBTOTAL,
+            {
+              "base-type": "type/Float",
+            },
+          ],
+          ORDERS_ROW_VALUES.SUBTOTAL,
+        ],
+        "source-table": ORDERS_ID,
+      },
+    },
 
     {
       drillType: "drill-thru/fk-filter",
       clickType: "cell",
-      columnName: ORDERS_COLUMNS.USER_ID.name,
+      columnName: "USER_ID",
+      queryType: "unaggregated",
       expectedQuery: {
         filter: [
           "=",
@@ -732,7 +1797,8 @@ describe("drillThru", () => {
     {
       drillType: "drill-thru/fk-filter",
       clickType: "cell",
-      columnName: ORDERS_COLUMNS.PRODUCT_ID.name,
+      columnName: "PRODUCT_ID",
+      queryType: "unaggregated",
       expectedQuery: {
         filter: [
           "=",
@@ -748,36 +1814,125 @@ describe("drillThru", () => {
         "source-table": ORDERS_ID,
       },
     },
-  ])(
-    'should apply "$drillType" drill to $columnName on $clickType click',
-    ({ drillType, columnName, clickType, expectedQuery, drillArgs = [] }) => {
-      const { query, stageIndex, column, cellValue, row } = setup({
-        question: ORDERS_QUESTION,
-        clickedColumnName: columnName,
-        columns: ORDERS_COLUMNS,
-        rowValues: ORDERS_ROW_VALUES,
-      });
 
-      const drills =
-        clickType === "cell"
-          ? availableDrillThrus(
-              query,
-              stageIndex,
-              column,
-              cellValue,
-              row,
-              undefined,
-            )
-          : availableDrillThrus(
-              query,
-              stageIndex,
-              column,
-              undefined,
-              undefined,
-              undefined,
-            );
-
-      const drill = findDrillByType(drills, drillType, query, stageIndex);
+    // FIXME: filter gets applied on the the same query stage as aggregations, but it should wrap the query (metabase#34346)
+    // {
+    //   drillType: "drill-thru/quick-filter",
+    //   clickType: "cell",
+    //   columnName: "sum",
+    //   queryType: "aggregated",
+    //   drillArgs: ["="],
+    //   expectedQuery: {
+    //     "source-query": AGGREGATED_ORDERS_DATASET_QUERY.query,
+    //     filter: [
+    //       "=",
+    //       [
+    //         "field",
+    //         "sum",
+    //         {
+    //           "base-type": "type/Float",
+    //         },
+    //       ],
+    //       AGGREGATED_ORDERS_ROW_VALUES.sum,
+    //     ],
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/quick-filter",
+    //   clickType: "cell",
+    //   columnName: "CREATED_AT",
+    //   queryType: "aggregated",
+    //   drillArgs: ["<"],
+    //   expectedQuery: {
+    //     ...AGGREGATED_ORDERS_DATASET_QUERY.query,
+    //     filter: [
+    //       "<",
+    //       [
+    //         "field",
+    //         ORDERS.CREATED_AT,
+    //         {
+    //           "base-type": "type/DateTime",
+    //           "temporal-unit": "month",
+    //         },
+    //       ],
+    //       AGGREGATED_ORDERS_ROW_VALUES.CREATED_AT,
+    //     ] as ComparisonFilter,
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/quick-filter",
+    //   clickType: "cell",
+    //   columnName: "max",
+    //   queryType: "aggregated",
+    //   drillArgs: ["≠"],
+    //   expectedQuery: {
+    //     "source-query": AGGREGATED_ORDERS_DATASET_QUERY.query,
+    //     filter: [
+    //       "not-null",
+    //       [
+    //         "field",
+    //         "max",
+    //         {
+    //           "base-type": "type/Float",
+    //         },
+    //       ],
+    //     ],
+    //   },
+    // },
+
+    // FIXME: fk-details doesn't create a query for fk target table (metabase#34383)
+    // {
+    //   drillType: "drill-thru/fk-details",
+    //   clickType: "cell",
+    //   columnName: "PRODUCT_ID",
+    //   queryType: "unaggregated",
+    //   expectedQuery: {
+    //     filter: [
+    //       "=",
+    //       ["field", PRODUCTS.ID, null],
+    //       ORDERS_ROW_VALUES.PRODUCT_ID,
+    //     ],
+    //     "source-table": PRODUCTS_ID,
+    //   },
+    // },
+    // {
+    //   drillType: "drill-thru/fk-details",
+    //   clickType: "cell",
+    //   columnName: "USER_ID",
+    //   queryType: "unaggregated",
+    //   expectedQuery: {
+    //     filter: ["=", ["field", PEOPLE.ID, null], ORDERS_ROW_VALUES.USER_ID],
+    //     "source-table": PEOPLE_ID,
+    //   },
+    // },
+  ])(
+    'should return correct result on "$drillType" drill apply to $columnName on $clickType in $queryType query',
+    ({
+      drillType,
+      columnName,
+      clickType,
+      queryType,
+      queryTable,
+      customQuestion,
+      drillArgs = [],
+      expectedQuery,
+    }) => {
+      const { drill, stageIndex, query } =
+        queryTable === "PRODUCTS"
+          ? setupDrillDisplayInfoWithProductsQuery({
+              drillType,
+              clickType,
+              queryType,
+              columnName,
+              customQuestion,
+            })
+          : setupDrillDisplayInfoWithOrdersQuery({
+              drillType,
+              clickType,
+              queryType,
+              columnName,
+              customQuestion,
+            });
 
       const updatedQuery = drillThru(query, stageIndex, drill, ...drillArgs);
 
@@ -790,16 +1945,30 @@ describe("drillThru", () => {
   );
 });
 
+const getMetadataColumns = (query: Lib.Query): Lib.ColumnMetadata[] => {
+  const aggregations = Lib.aggregations(query, STAGE_INDEX);
+  const breakouts = Lib.breakouts(query, STAGE_INDEX);
+
+  return aggregations.length === 0 && breakouts.length === 0
+    ? Lib.visibleColumns(query, STAGE_INDEX)
+    : [
+        ...Lib.breakoutableColumns(query, STAGE_INDEX),
+        ...Lib.orderableColumns(query, STAGE_INDEX),
+      ];
+};
+
 function setup({
   question = ORDERS_QUESTION,
   clickedColumnName,
   columns,
   rowValues,
+  tableName,
 }: {
   question?: Question;
   clickedColumnName: string;
   columns: Record<string, DatasetColumn>;
   rowValues: Record<string, RowValue>;
+  tableName: string;
 }) {
   const query = question._getMLv2Query();
   const legacyQuery = question.query() as StructuredQuery;
@@ -808,10 +1977,16 @@ function setup({
 
   const legacyColumns = legacyQuery.columns();
 
+  const metadataColumns = getMetadataColumns(query);
+  const column = columnFinder(query, metadataColumns)(
+    tableName,
+    clickedColumnName,
+  );
+
   return {
     query,
     stageIndex,
-    column: columns[clickedColumnName],
+    column,
     cellValue: rowValues[clickedColumnName],
     row: legacyColumns.map(({ name }) => ({
       col: columns[name],
@@ -820,19 +1995,233 @@ function setup({
   };
 }
 
-function findDrillByType(
-  drills: DrillThru[],
-  drillType: DrillThruType,
-  query: Query,
-  stageIndex: number,
-): DrillThru {
-  const drill = drills.find(
-    drill => Lib.displayInfo(query, stageIndex, drill)?.type === drillType,
+function setupAvailableDrillsWithOrdersQuery({
+  clickType,
+  queryType,
+  columnName,
+  customQuestion,
+}: {
+  clickType: "cell" | "header";
+  queryType: TestCaseQueryType;
+  columnName: string;
+  customQuestion?: Question;
+  debug?: boolean;
+}) {
+  const { query, stageIndex, column, cellValue, row } = setup(
+    queryType === "unaggregated"
+      ? {
+          question: customQuestion || ORDERS_QUESTION,
+          clickedColumnName: columnName,
+          columns: ORDERS_COLUMNS,
+          rowValues: ORDERS_ROW_VALUES,
+          tableName: "ORDERS",
+        }
+      : {
+          question: customQuestion || AGGREGATED_ORDERS_QUESTION,
+          clickedColumnName: columnName,
+          columns: AGGREGATED_ORDERS_COLUMNS,
+          rowValues: AGGREGATED_ORDERS_ROW_VALUES,
+          tableName: "ORDERS",
+        },
+  );
+
+  return {
+    ...setupDrillDisplayInfo({
+      clickType,
+      queryType,
+      columnName,
+      query,
+      stageIndex,
+      column,
+      cellValue,
+      row,
+    }),
+    query,
+    stageIndex,
+  };
+}
+
+function setupDrillDisplayInfoWithOrdersQuery({
+  drillType,
+  clickType,
+  queryType,
+  columnName,
+  customQuestion,
+}: {
+  drillType: Lib.DrillThruType;
+  clickType: "cell" | "header";
+  queryType: TestCaseQueryType;
+  columnName: string;
+  customQuestion?: Question;
+}) {
+  const { drills, drillsDisplayInfo, query, stageIndex } =
+    setupAvailableDrillsWithOrdersQuery({
+      clickType,
+      queryType,
+      columnName,
+      customQuestion,
+    });
+
+  const drillIndex = drillsDisplayInfo.findIndex(
+    ({ type }) => type === drillType,
+  );
+  const drill = drills[drillIndex];
+  const drillDisplayInfo = drillsDisplayInfo[drillIndex];
+
+  if (!drill) {
+    throw new TypeError(`Failed to find ${drillType} drill`);
+  }
+
+  return {
+    drill,
+    drillDisplayInfo,
+    query,
+    stageIndex,
+  };
+}
+
+function setupAvailableDrillsWithProductsQuery({
+  clickType,
+  queryType,
+  columnName,
+  customQuestion,
+}: {
+  clickType: "cell" | "header";
+  queryType: TestCaseQueryType;
+  columnName: string;
+  customQuestion?: Question;
+  debug?: boolean;
+}) {
+  const { query, stageIndex, column, cellValue, row } = setup(
+    queryType === "unaggregated"
+      ? {
+          question: customQuestion || PRODUCTS_QUESTION,
+          clickedColumnName: columnName,
+          columns: PRODUCTS_COLUMNS,
+          rowValues: PRODUCTS_ROW_VALUES,
+          tableName: "PRODUCTS",
+        }
+      : {
+          question: customQuestion || AGGREGATED_PRODUCTS_QUESTION,
+          clickedColumnName: columnName,
+          columns: AGGREGATED_PRODUCTS_COLUMNS,
+          rowValues: AGGREGATED_PRODUCTS_ROW_VALUES,
+          tableName: "PRODUCTS",
+        },
+  );
+
+  return {
+    ...setupDrillDisplayInfo({
+      clickType,
+      queryType,
+      columnName,
+      query,
+      stageIndex,
+      column,
+      cellValue,
+      row,
+    }),
+    query,
+    stageIndex,
+  };
+}
+
+function setupDrillDisplayInfoWithProductsQuery({
+  drillType,
+  clickType,
+  queryType,
+  columnName,
+  customQuestion,
+}: {
+  drillType: Lib.DrillThruType;
+  clickType: "cell" | "header";
+  queryType: TestCaseQueryType;
+  columnName: string;
+  customQuestion?: Question;
+  debug?: boolean;
+}) {
+  const { drills, drillsDisplayInfo, query, stageIndex } =
+    setupAvailableDrillsWithProductsQuery({
+      clickType,
+      queryType,
+      columnName,
+      customQuestion,
+    });
+
+  const drillIndex = drillsDisplayInfo.findIndex(
+    ({ type }) => type === drillType,
   );
+  const drill = drills[drillIndex];
+  const drillDisplayInfo = drillsDisplayInfo[drillIndex];
 
   if (!drill) {
-    throw new TypeError();
+    throw new TypeError(`Failed to find ${drillType} drill`);
   }
 
-  return drill;
+  return {
+    drill,
+    drillDisplayInfo,
+    query,
+    stageIndex,
+  };
+}
+
+function setupDrillDisplayInfo({
+  clickType,
+  queryType,
+  columnName,
+  query,
+  stageIndex,
+  column,
+  cellValue,
+  row,
+}: {
+  clickType: "cell" | "header";
+  queryType: TestCaseQueryType;
+  columnName: string;
+  query: Lib.Query;
+  stageIndex: number;
+  column: Lib.ColumnMetadata;
+  cellValue: RowValue;
+  row: {
+    col: DatasetColumn;
+    value: RowValue;
+  }[];
+}) {
+  const dimensions =
+    queryType === "aggregated"
+      ? row
+          .filter(
+            ({ col }) => col?.source === "breakout" && col?.name !== columnName,
+          )
+          .map(({ value, col }) => ({ value, column: col }))
+      : undefined;
+
+  const drills =
+    clickType === "cell"
+      ? availableDrillThrus(
+          query,
+          stageIndex,
+          column,
+          cellValue,
+          row,
+          dimensions,
+        )
+      : availableDrillThrus(
+          query,
+          stageIndex,
+          column,
+          undefined,
+          undefined,
+          undefined,
+        );
+
+  const drillsDisplayInfo = drills.map(drill =>
+    Lib.displayInfo(query, stageIndex, drill),
+  );
+
+  return {
+    drills,
+    drillsDisplayInfo,
+  };
 }
diff --git a/frontend/src/metabase-lib/test-helpers.ts b/frontend/src/metabase-lib/test-helpers.ts
index bc632328858..e20b99af50e 100644
--- a/frontend/src/metabase-lib/test-helpers.ts
+++ b/frontend/src/metabase-lib/test-helpers.ts
@@ -53,6 +53,12 @@ export const columnFinder =
   (tableName: string, columnName: string): ML.ColumnMetadata => {
     const column = columns.find(column => {
       const displayInfo = ML.displayInfo(query, 0, column);
+
+      // for non-table columns - aggregations, custom columns
+      if (!displayInfo.table) {
+        return displayInfo?.name === columnName;
+      }
+
       return (
         displayInfo?.table?.name === tableName &&
         displayInfo?.name === columnName
diff --git a/frontend/src/metabase-lib/types.ts b/frontend/src/metabase-lib/types.ts
index 4d716f80b78..9586a923d3f 100644
--- a/frontend/src/metabase-lib/types.ts
+++ b/frontend/src/metabase-lib/types.ts
@@ -255,7 +255,8 @@ export type DrillThruType =
   | "drill-thru/summarize-column"
   | "drill-thru/summarize-column-by-time"
   | "drill-thru/column-filter"
-  | "drill-thru/underlying-records";
+  | "drill-thru/underlying-records"
+  | "drill-thru/zoom-in.timeseries";
 
 export type BaseDrillThruInfo<Type extends DrillThruType> = { type: Type };
 
@@ -273,7 +274,8 @@ export type PKDrillThruInfo = ObjectDetailsDrillThruInfo<"drill-thru/pk">;
 export type ZoomDrillThruInfo = ObjectDetailsDrillThruInfo<"drill-thru/zoom">;
 export type FKDetailsDrillThruInfo =
   ObjectDetailsDrillThruInfo<"drill-thru/fk-details">;
-export type PivotDrillThruInfo = ObjectDetailsDrillThruInfo<"drill-thru/pivot">;
+
+export type PivotDrillThruInfo = BaseDrillThruInfo<"drill-thru/pivot">;
 
 export type FKFilterDrillThruInfo = BaseDrillThruInfo<"drill-thru/fk-filter">;
 export type DistributionDrillThruInfo =
@@ -283,9 +285,14 @@ export type SortDrillThruInfo = BaseDrillThruInfo<"drill-thru/sort"> & {
   directions: Array<"asc" | "desc">;
 };
 
+export type SummarizeColumnDrillAggregationOperator =
+  | "sum"
+  | "avg"
+  | "distinct";
+
 export type SummarizeColumnDrillThruInfo =
   BaseDrillThruInfo<"drill-thru/summarize-column"> & {
-    aggregations: Array<"sum" | "avg" | "distinct">;
+    aggregations: Array<SummarizeColumnDrillAggregationOperator>;
   };
 export type SummarizeColumnByTimeDrillThruInfo =
   BaseDrillThruInfo<"drill-thru/summarize-column-by-time">;
@@ -301,6 +308,11 @@ export type UnderlyingRecordsDrillThruInfo =
     tableName: string;
   };
 
+export type ZoomTimeseriesDrillThruInfo =
+  BaseDrillThruInfo<"drill-thru/zoom-in.timeseries"> & {
+    displayName?: string;
+  };
+
 export type DrillThruDisplayInfo =
   | QuickFilterDrillThruInfo
   | PKDrillThruInfo
@@ -313,7 +325,8 @@ export type DrillThruDisplayInfo =
   | SummarizeColumnDrillThruInfo
   | SummarizeColumnByTimeDrillThruInfo
   | ColumnFilterDrillThruInfo
-  | UnderlyingRecordsDrillThruInfo;
+  | UnderlyingRecordsDrillThruInfo
+  | ZoomTimeseriesDrillThruInfo;
 
 export interface Dimension {
   column: DatasetColumn;
diff --git a/frontend/src/metabase-types/api/mocks/presets/sample_database.ts b/frontend/src/metabase-types/api/mocks/presets/sample_database.ts
index e3bd614acb7..31014e8e375 100644
--- a/frontend/src/metabase-types/api/mocks/presets/sample_database.ts
+++ b/frontend/src/metabase-types/api/mocks/presets/sample_database.ts
@@ -1459,3 +1459,103 @@ export const createOrdersTableDatasetColumns = () => [
   createOrdersCreatedAtDatasetColumn(),
   createOrdersQuantityDatasetColumn(),
 ];
+
+export const createProductsIdDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsIdField(),
+    id: PRODUCTS.ID,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.ID, null],
+    semantic_type: "type/PK",
+    ...opts,
+  });
+
+export const createProductsEanDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsEanField(),
+    id: PRODUCTS.EAN,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.EAN, null],
+    ...opts,
+  });
+
+export const createProductsTitleDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsTitleField(),
+    id: PRODUCTS.TITLE,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.TITLE, null],
+    ...opts,
+  });
+
+export const createProductsCategoryDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsCategoryField(),
+    id: PRODUCTS.CATEGORY,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.CATEGORY, null],
+    ...opts,
+  });
+
+export const createProductsVendorDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsVendorField(),
+    id: PRODUCTS.VENDOR,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.VENDOR, null],
+    ...opts,
+  });
+
+export const createProductsPriceDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsPriceField(),
+    id: PRODUCTS.PRICE,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.PRICE, null],
+    ...opts,
+  });
+
+export const createProductsRatingDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsRatingField(),
+    id: PRODUCTS.RATING,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.RATING, null],
+    ...opts,
+  });
+
+export const createProductsCreatedAtDatasetColumn = (
+  opts?: Partial<DatasetColumn>,
+): DatasetColumn =>
+  createMockColumn({
+    ...createProductsCreatedAtField(),
+    id: PRODUCTS.CREATED_AT,
+    source: "fields",
+    field_ref: ["field", PRODUCTS.CREATED_AT, null],
+    ...opts,
+  });
+
+export const createProductsTableDatasetColumns = () => [
+  createProductsIdDatasetColumn(),
+  createProductsEanDatasetColumn(),
+  createProductsTitleDatasetColumn(),
+  createProductsCategoryDatasetColumn(),
+  createProductsVendorDatasetColumn(),
+  createProductsPriceDatasetColumn(),
+  createProductsRatingDatasetColumn(),
+  createProductsCreatedAtDatasetColumn(),
+];
diff --git a/frontend/src/metabase-types/api/query.ts b/frontend/src/metabase-types/api/query.ts
index 3f661d02205..fdec97bb791 100644
--- a/frontend/src/metabase-types/api/query.ts
+++ b/frontend/src/metabase-types/api/query.ts
@@ -199,7 +199,7 @@ export type FieldFilter =
 type NotFilter = ["not", Filter];
 
 type EqualityFilter = ["=" | "!=", ConcreteFieldReference, Value];
-type ComparisonFilter = [
+export type ComparisonFilter = [
   "<" | "<=" | ">=" | ">",
   ConcreteFieldReference,
   OrderableValue,
diff --git a/frontend/src/metabase/visualizations/click-actions/Mode/constants.ts b/frontend/src/metabase/visualizations/click-actions/Mode/constants.ts
index ce523363e5f..3e3e54f8375 100644
--- a/frontend/src/metabase/visualizations/click-actions/Mode/constants.ts
+++ b/frontend/src/metabase/visualizations/click-actions/Mode/constants.ts
@@ -37,4 +37,5 @@ export const DRILL_TYPE_TO_HANDLER_MAP: Record<
   "drill-thru/summarize-column": null, // SummarizeColumnDrill,
   "drill-thru/summarize-column-by-time": SummarizeColumnByTimeDrill,
   "drill-thru/underlying-records": null, // UnderlyingRecordsDrill,
+  "drill-thru/zoom-in.timeseries": null,
 };
diff --git a/frontend/src/metabase/visualizations/click-actions/drills/mlv2/QuickFilterDrill.tsx b/frontend/src/metabase/visualizations/click-actions/drills/mlv2/QuickFilterDrill.tsx
new file mode 100644
index 00000000000..cbcbdf93289
--- /dev/null
+++ b/frontend/src/metabase/visualizations/click-actions/drills/mlv2/QuickFilterDrill.tsx
@@ -0,0 +1,146 @@
+import type * as React from "react";
+import { t } from "ttag";
+import type { DatasetColumn, RowValue } from "metabase-types/api";
+import type {
+  ClickActionButtonType,
+  Drill,
+} from "metabase/visualizations/types/click-actions";
+import type * as Lib from "metabase-lib";
+import { isBoolean, isDate, isNumeric } from "metabase-lib/types/utils/isa";
+import { TextIcon } from "../QuickFilterDrill/QuickFilterDrill.styled";
+
+type FilterOperator = "=" | "≠" | "<" | ">";
+type DateQuickFilterOperatorType = "<" | ">" | "=" | "≠";
+type FilterValueType = "null" | "numeric" | "date" | "boolean" | "text";
+
+const DateButtonTitleMap: Record<DateQuickFilterOperatorType, string> = {
+  ["<"]: t`Before`,
+  [">"]: t`After`,
+  ["="]: t`On`,
+  ["≠"]: t`Not on`,
+};
+
+const SPECIFIC_VALUE_TITLE_MAX_LENGTH = 20;
+
+const getTextValueTitle = (value: string): string => {
+  if (value.length === 0) {
+    return t`empty`;
+  }
+
+  if (value.length > SPECIFIC_VALUE_TITLE_MAX_LENGTH) {
+    return t`this`;
+  }
+
+  return value;
+};
+
+const getOperatorOverrides = (
+  operator: FilterOperator,
+  valueType: FilterValueType,
+  value: RowValue | undefined,
+): {
+  title?: string;
+  icon?: React.ReactNode;
+  buttonType?: ClickActionButtonType;
+} | null => {
+  if (valueType === "text" && typeof value === "string") {
+    const textValue = getTextValueTitle(value);
+
+    if (operator === "=") {
+      return {
+        title: t`Is ${textValue}`,
+        icon: <TextIcon>=</TextIcon>,
+        buttonType: "horizontal",
+      };
+    }
+    if (operator === "≠") {
+      return {
+        title: t`Is not ${textValue}`,
+        icon: <TextIcon>≠</TextIcon>,
+        buttonType: "horizontal",
+      };
+    }
+    // if (operator === "contains") {
+    //   return {
+    //     title: t`Contains…`,
+    //     icon: "filter",
+    //     buttonType: "horizontal",
+    //   };
+    // }
+    // if (operator === "does-not-contain") {
+    //   return {
+    //     title: t`Does not contain…`,
+    //     icon: <TextIcon>≠</TextIcon>,
+    //     buttonType: "horizontal",
+    //   };
+    // }
+  }
+
+  if (valueType === "date") {
+    return {
+      title: DateButtonTitleMap[operator],
+      buttonType: "horizontal",
+    };
+  }
+
+  return null;
+};
+
+export const QuickFilterDrill: Drill<Lib.QuickFilterDrillThruInfo> = ({
+  drill,
+  drillDisplayInfo,
+  applyDrill,
+  clicked,
+}) => {
+  if (!drill || !clicked || !clicked.column) {
+    return [];
+  }
+
+  const { operators } = drillDisplayInfo;
+  const { value, column } = clicked;
+
+  const columnValueType = getValueType(value, column);
+
+  return operators.map(operator => {
+    const overrides = getOperatorOverrides(operator, columnValueType, value);
+
+    return {
+      name: operator,
+      title: operator,
+      section: "filter",
+      buttonType: "token-filter",
+
+      question: () => applyDrill(drill, operator),
+
+      extra: () => ({
+        valueType: columnValueType,
+        columnName: clicked.column?.display_name,
+      }),
+
+      ...overrides,
+    };
+  });
+};
+
+const getValueType = (
+  value: unknown,
+  column: DatasetColumn,
+): FilterValueType => {
+  if (value == null) {
+    return "null";
+  }
+
+  if (isNumeric(column)) {
+    return "numeric";
+  }
+
+  if (isDate(column)) {
+    return "date";
+  }
+
+  if (isBoolean(column)) {
+    return "boolean";
+  }
+
+  return "text";
+};
diff --git a/frontend/src/metabase/visualizations/click-actions/drills/mlv2/SummarizeColumnDrill.ts b/frontend/src/metabase/visualizations/click-actions/drills/mlv2/SummarizeColumnDrill.ts
new file mode 100644
index 00000000000..d88a46a83ab
--- /dev/null
+++ b/frontend/src/metabase/visualizations/click-actions/drills/mlv2/SummarizeColumnDrill.ts
@@ -0,0 +1,49 @@
+import { t } from "ttag";
+import type {
+  ClickActionBase,
+  Drill,
+} from "metabase/visualizations/types/click-actions";
+import type { Dispatch } from "metabase-types/store";
+import type * as Lib from "metabase-lib";
+
+const ACTIONS: Record<
+  Lib.SummarizeColumnDrillAggregationOperator,
+  Omit<ClickActionBase, "name">
+> = {
+  sum: {
+    title: t`Sum`,
+    section: "sum",
+    buttonType: "token",
+  },
+  avg: {
+    title: t`Avg`,
+    section: "sum",
+    buttonType: "token",
+  },
+  distinct: {
+    title: t`Distinct values`,
+    section: "sum",
+    buttonType: "token",
+  },
+};
+
+export const SummarizeColumnDrill: Drill<Lib.SummarizeColumnDrillThruInfo> = ({
+  drill,
+  drillDisplayInfo,
+  applyDrill,
+}) => {
+  if (!drill) {
+    return [];
+  }
+
+  const { aggregations } = drillDisplayInfo;
+
+  return aggregations.map(operator => ({
+    name: operator,
+    ...ACTIONS[operator],
+    question: () => applyDrill(drill, operator),
+    action: () => (dispatch: Dispatch) =>
+      // HACK: drill through closes sidebars, so open sidebar asynchronously
+      setTimeout(() => dispatch({ type: "metabase/qb/EDIT_SUMMARY" })),
+  }));
+};
diff --git a/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.unit.spec.tsx b/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.unit.spec.tsx
index 371ee56af25..187b41f2310 100644
--- a/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.unit.spec.tsx
+++ b/frontend/src/metabase/visualizations/components/ClickActions/ClickActionsPopover.unit.spec.tsx
@@ -2,6 +2,8 @@ import userEvent from "@testing-library/user-event";
 import { waitFor } from "@testing-library/react";
 import { getIcon, renderWithProviders, screen } from "__support__/ui";
 import {
+  createOrdersCreatedAtDatasetColumn,
+  createOrdersDiscountDatasetColumn,
   createOrdersIdDatasetColumn,
   createOrdersProductIdDatasetColumn,
   createOrdersQuantityDatasetColumn,
@@ -16,8 +18,8 @@ import { ClickActionsPopover } from "metabase/visualizations/components/ClickAct
 import type { RegularClickAction } from "metabase/visualizations/types";
 import { getMode } from "metabase/visualizations/click-actions/lib/modes";
 import { checkNotNull } from "metabase/core/utils/types";
+import type { DatasetQuery, Filter, Series } from "metabase-types/api";
 import registerVisualizations from "metabase/visualizations/register";
-import type { DatasetQuery, Series } from "metabase-types/api";
 import { POPOVER_TEST_ID } from "metabase/visualizations/click-actions/actions/ColumnFormattingAction/ColumnFormattingAction";
 import { createMockSingleSeries } from "metabase-types/api/mocks";
 import type { ClickObject } from "metabase-lib/queries/drills/types";
@@ -29,6 +31,17 @@ import type Dimension from "metabase-lib/Dimension";
 registerVisualizations();
 
 const ORDERS_COLUMNS = createOrdersTableDatasetColumns();
+const ORDERS_ROW_VALUES = {
+  ID: "3",
+  USER_ID: "1",
+  PRODUCT_ID: "105",
+  SUBTOTAL: 52.723521442619514,
+  TAX: 2.9,
+  TOTAL: 49.206842233769756,
+  DISCOUNT: 6.416679208849759,
+  CREATED_AT: "2025-12-06T22:22:48.544+02:00",
+  QUANTITY: 2,
+};
 
 describe("ClickActionsPopover", function () {
   describe("apply click actions", () => {
@@ -120,6 +133,7 @@ describe("ClickActionsPopover", function () {
       it.each([
         {
           column: createOrdersTotalDatasetColumn(),
+          columnName: createOrdersTotalDatasetColumn().name,
           expectedCard: {
             dataset_query: getSummarizedOverTimeResultDatasetQuery(
               ORDERS.TOTAL,
@@ -130,6 +144,7 @@ describe("ClickActionsPopover", function () {
         },
         {
           column: createOrdersQuantityDatasetColumn(),
+          columnName: createOrdersQuantityDatasetColumn().name,
           expectedCard: {
             dataset_query: getSummarizedOverTimeResultDatasetQuery(
               ORDERS.QUANTITY,
@@ -139,7 +154,7 @@ describe("ClickActionsPopover", function () {
           },
         },
       ])(
-        "should apply drill to default ORDERS question on header click",
+        "should apply drill to default ORDERS question on $columnName header click",
         async ({ column, expectedCard }) => {
           const { props } = await setup({
             clicked: {
@@ -213,6 +228,77 @@ describe("ClickActionsPopover", function () {
         },
       );
     });
+
+    describe("QuickFilterDrill", () => {
+      it.each([
+        {
+          column: createOrdersTotalDatasetColumn(),
+          columnName: createOrdersTotalDatasetColumn().name,
+          cellValue: ORDERS_ROW_VALUES.TOTAL,
+          drillTitle: ">",
+          expectedCard: {
+            dataset_query: getQuickFilterResultDatasetQuery({
+              filteredColumnId: ORDERS.TOTAL,
+              filterOperator: ">",
+              cellValue: ORDERS_ROW_VALUES.TOTAL,
+            }),
+            display: "table",
+          },
+        },
+
+        {
+          column: createOrdersCreatedAtDatasetColumn(),
+          columnName: createOrdersCreatedAtDatasetColumn().name,
+          cellValue: ORDERS_ROW_VALUES.CREATED_AT,
+          drillTitle: "Before",
+          expectedCard: {
+            dataset_query: getQuickFilterResultDatasetQuery({
+              filteredColumnId: ORDERS.CREATED_AT,
+              filterOperator: "<",
+              cellValue: ORDERS_ROW_VALUES.CREATED_AT,
+            }),
+            display: "table",
+          },
+        },
+
+        {
+          column: createOrdersDiscountDatasetColumn(),
+          columnName: createOrdersDiscountDatasetColumn().name,
+          cellValue: null,
+          drillTitle: "=",
+          expectedCard: {
+            dataset_query: getQuickFilterResultDatasetQuery({
+              filteredColumnId: ORDERS.DISCOUNT,
+              filterOperator: "is-null",
+              cellValue: null,
+            }),
+            display: "table",
+          },
+        },
+      ])(
+        "should apply drill on $columnName cell click",
+        async ({ column, cellValue, drillTitle, expectedCard }) => {
+          const { props } = await setup({
+            clicked: {
+              column,
+              value: cellValue,
+            },
+          });
+
+          const drill = screen.getByText(drillTitle);
+          expect(drill).toBeInTheDocument();
+
+          userEvent.click(drill);
+
+          expect(props.onChangeCardAndRun).toHaveBeenCalledTimes(1);
+          expect(props.onChangeCardAndRun).toHaveBeenLastCalledWith(
+            expect.objectContaining({
+              nextCard: expect.objectContaining(expectedCard),
+            }),
+          );
+        },
+      );
+    });
   });
 });
 
@@ -387,3 +473,30 @@ function getFKFilteredResultDatasetQuery(
     type: "query",
   };
 }
+
+function getQuickFilterResultDatasetQuery({
+  filteredColumnId,
+  filterOperator,
+  cellValue,
+}: {
+  filteredColumnId: number;
+  filterOperator: "=" | "!=" | ">" | "<" | "is-null" | "not-null";
+  cellValue: string | number | null | undefined;
+}): DatasetQuery {
+  const filterClause = ["is-null", "not-null"].includes(filterOperator)
+    ? ([filterOperator, ["field", filteredColumnId, null]] as Filter)
+    : ([
+        filterOperator,
+        ["field", filteredColumnId, null],
+        cellValue,
+      ] as Filter);
+
+  return {
+    database: SAMPLE_DB_ID,
+    query: {
+      filter: filterClause,
+      "source-table": ORDERS_ID,
+    },
+    type: "query",
+  };
+}
-- 
GitLab