From e2522f4fa7874665a838e74cc95a89896d86f8e9 Mon Sep 17 00:00:00 2001
From: metamben <103100869+metamben@users.noreply.github.com>
Date: Tue, 19 Nov 2024 19:39:35 +0300
Subject: [PATCH] Fix model conversion (#50215)

---
 .../reproductions-3.cy.spec.js                | 49 +++++++++++++++++++
 .../metabase/query_builder/actions/models.ts  | 45 +++--------------
 2 files changed, 57 insertions(+), 37 deletions(-)

diff --git a/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js b/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js
index 6c743f13a56..5f1c8b9b2c5 100644
--- a/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js
+++ b/e2e/test/scenarios/question-reproductions/reproductions-3.cy.spec.js
@@ -28,6 +28,7 @@ import {
   openNotebook,
   openOrdersTable,
   openProductsTable,
+  openQuestionActions,
   openTable,
   popover,
   queryBuilderFooter,
@@ -2436,3 +2437,51 @@ describe("issue 50038", () => {
     });
   });
 });
+
+describe("issue 47940", () => {
+  const questionDetails = {
+    name: "Issue 47940",
+    query: {
+      "source-table": ORDERS_ID,
+      limit: 5,
+    },
+  };
+
+  beforeEach(() => {
+    restore();
+    cy.signInAsAdmin();
+    cy.intercept("PUT", "/api/card/*").as("updateCard");
+    cy.intercept("POST", "/api/card/*/query").as("cardQuery");
+  });
+
+  it("should be able to convert a question with date casting to a model", () => {
+    cy.log("create a question without any column casting");
+    createQuestion(questionDetails, { visitQuestion: true });
+    cy.wait("@cardQuery");
+
+    cy.log("add coercion");
+    cy.request("PUT", `/api/field/${ORDERS.PRODUCT_ID}`, {
+      semantic_type: "type/Category",
+      coercion_strategy: "Coercion/UNIXMicroSeconds->DateTime",
+    });
+
+    cy.log("get new query results with coercion applied");
+    queryBuilderHeader().findByTestId("run-button").click();
+    cy.wait("@cardQuery");
+    queryBuilderHeader().button("Save").click();
+    modal().button("Save").click();
+    cy.wait("@updateCard");
+
+    cy.log("turn into a model");
+    openQuestionActions();
+    popover().findByText("Turn into a model").click();
+    cy.findByRole("dialog").findByText("Turn this into a model").click();
+    cy.wait("@updateCard");
+
+    cy.log("verify there is a table displayed");
+    cy.findByTestId("visualization-root").should(
+      "contain",
+      "December 31, 1969, 4:00 PM",
+    );
+  });
+});
diff --git a/frontend/src/metabase/query_builder/actions/models.ts b/frontend/src/metabase/query_builder/actions/models.ts
index e02e20855d3..6f1ffe2cde3 100644
--- a/frontend/src/metabase/query_builder/actions/models.ts
+++ b/frontend/src/metabase/query_builder/actions/models.ts
@@ -2,16 +2,13 @@ import { push } from "react-router-redux";
 import { createAction } from "redux-actions";
 import { t } from "ttag";
 
-import Questions from "metabase/entities/questions";
-import { loadMetadataForCard } from "metabase/questions/actions";
 import { addUndo } from "metabase/redux/undo";
-import { getMetadata } from "metabase/selectors/metadata";
 import type { Dispatch, GetState } from "metabase-types/store";
 
 import { getQuestion } from "../selectors";
 
-import { API_UPDATE_QUESTION, apiUpdateQuestion, updateQuestion } from "./core";
-import { runDirtyQuestionQuery, runQuestionQuery } from "./querying";
+import { apiUpdateQuestion, updateQuestion } from "./core";
+import { runDirtyQuestionQuery } from "./querying";
 import { setQueryBuilderMode } from "./ui";
 
 export const setDatasetEditorTab =
@@ -29,41 +26,16 @@ export const onCancelCreateNewModel = () => async (dispatch: Dispatch) => {
 export const turnQuestionIntoModel =
   () => async (dispatch: Dispatch, getState: GetState) => {
     const question = getQuestion(getState());
-
     if (!question) {
       return;
     }
 
-    await dispatch(
-      Questions.actions.update(
-        {
-          id: question.id(),
-        },
-        question
-          .setType("model")
-          .setPinned(true)
-          .setDisplay("table")
-          .setSettings({})
-          .card(),
-      ),
-    );
-
-    const metadata = getMetadata(getState());
-    const dataset = metadata.question(question.id());
-
-    if (!dataset) {
-      return;
-    }
-
-    await dispatch(loadMetadataForCard(dataset.card()));
-
-    await dispatch({ type: API_UPDATE_QUESTION, payload: dataset.card() });
-
-    await dispatch(
-      runQuestionQuery({
-        shouldUpdateUrl: true,
-      }),
-    );
+    const model = question
+      .setType("model")
+      .setPinned(true)
+      .setDisplay("table")
+      .setSettings({});
+    await dispatch(apiUpdateQuestion(model, { rerunQuery: true }));
 
     dispatch(
       addUndo({
@@ -76,7 +48,6 @@ export const turnQuestionIntoModel =
 export const turnModelIntoQuestion =
   () => async (dispatch: Dispatch, getState: GetState) => {
     const model = getQuestion(getState());
-
     if (!model) {
       return;
     }
-- 
GitLab