From ad6f5c0d0248e466b82f5d13bf50b3964a3646cd Mon Sep 17 00:00:00 2001
From: Anton Kulyk <kuliks.anton@gmail.com>
Date: Fri, 19 May 2023 18:13:04 +0100
Subject: [PATCH] Use sentence case for temporal bucket names (#30875)

---
 .../binning/binning-options.cy.spec.js        | 16 +++++-----
 .../binning/binning-reproductions.cy.spec.js  |  2 +-
 .../binning/correctness/shared/constants.js   | 16 +++++-----
 .../correctness/time-series.cy.spec.js        | 19 ++++--------
 .../custom-column/custom-column.cy.spec.js    |  2 +-
 .../question/summarization.cy.spec.js         |  2 +-
 .../sharing/reproductions/16918.cy.spec.js    |  2 +-
 frontend/src/metabase-lib/Dimension.ts        | 16 +++++-----
 .../api/mocks/presets/sample_database.ts      | 30 +++++++++----------
 src/metabase/api/table.clj                    | 30 +++++++++----------
 src/metabase/pulse/render/datetime.clj        |  2 +-
 11 files changed, 64 insertions(+), 73 deletions(-)

diff --git a/e2e/test/scenarios/binning/binning-options.cy.spec.js b/e2e/test/scenarios/binning/binning-options.cy.spec.js
index 4989e798d96..71472260f53 100644
--- a/e2e/test/scenarios/binning/binning-options.cy.spec.js
+++ b/e2e/test/scenarios/binning/binning-options.cy.spec.js
@@ -71,14 +71,14 @@ const TIME_BUCKETS = [
   "Month",
   "Quarter",
   "Year",
-  "Minute of Hour",
-  "Hour of Day",
-  "Day of Week",
-  "Day of Month",
-  "Day of Year",
-  "Week of Year",
-  "Month of Year",
-  "Quarter of Year",
+  "Minute of hour",
+  "Hour of day",
+  "Day of week",
+  "Day of month",
+  "Day of year",
+  "Week of year",
+  "Month of year",
+  "Quarter of year",
 ];
 
 const LONGITUDE_BUCKETS = [
diff --git a/e2e/test/scenarios/binning/binning-reproductions.cy.spec.js b/e2e/test/scenarios/binning/binning-reproductions.cy.spec.js
index 45119e40cb3..554630381d1 100644
--- a/e2e/test/scenarios/binning/binning-reproductions.cy.spec.js
+++ b/e2e/test/scenarios/binning/binning-reproductions.cy.spec.js
@@ -216,7 +216,7 @@ describe("binning related reproductions", () => {
       });
     // // this step is maybe redundant since it fails to even find "by month"
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Hour of Day");
+    cy.findByText("Hour of day");
   });
 
   it("shouldn't duplicate the breakout field (metabase#22382)", () => {
diff --git a/e2e/test/scenarios/binning/correctness/shared/constants.js b/e2e/test/scenarios/binning/correctness/shared/constants.js
index 19a03b8936d..2fe900cfc79 100644
--- a/e2e/test/scenarios/binning/correctness/shared/constants.js
+++ b/e2e/test/scenarios/binning/correctness/shared/constants.js
@@ -30,36 +30,36 @@ export const TIME_OPTIONS = {
     selected: "by year",
     representativeValues: ["2016", "2017", "2018", "2019", "2020"],
   },
-  "Minute of Hour": {
+  "Minute of hour": {
     selected: "by minute of hour",
     representativeValues: ["0", "5", "8", "13"],
     type: "extended",
   },
-  "Hour of Day": {
+  "Hour of day": {
     selected: "by hour of day",
     representativeValues: ["12:00 AM", "2:00 AM", "12:00 PM", "8:00 PM"],
   },
-  "Day of Week": {
+  "Day of week": {
     selected: "by day of week",
     representativeValues: ["Saturday", "Tuesday", "Friday", "Sunday"],
   },
-  "Day of Month": {
+  "Day of month": {
     selected: "by day of month",
     representativeValues: ["5", "10", "15", "30"],
   },
-  "Day of Year": {
+  "Day of year": {
     selected: "by day of year",
     representativeValues: ["1", "10", "12"],
   },
-  "Week of Year": {
+  "Week of year": {
     selected: "by week of year",
     representativeValues: ["1st", "2nd", "3rd", "10th"],
   },
-  "Month of Year": {
+  "Month of year": {
     selected: "by month of year",
     representativeValues: ["January", "June", "December"],
   },
-  "Quarter of Year": {
+  "Quarter of year": {
     selected: "by quarter of year",
     representativeValues: ["Q1", "Q2", "Q3", "Q4"],
   },
diff --git a/e2e/test/scenarios/binning/correctness/time-series.cy.spec.js b/e2e/test/scenarios/binning/correctness/time-series.cy.spec.js
index ad3afe5b36b..e9c0158c16a 100644
--- a/e2e/test/scenarios/binning/correctness/time-series.cy.spec.js
+++ b/e2e/test/scenarios/binning/correctness/time-series.cy.spec.js
@@ -39,12 +39,6 @@ describe("scenarios > binning > correctness > time series", () => {
 
   Object.entries(TIME_OPTIONS).forEach(
     ([bucketSize, { selected, representativeValues }]) => {
-      // We are forced to ignore the case here because we construct titles like so:
-      // "Day of Month" (bucket) -> "Day of month" (title)
-      // This feels weird and is probably worth investigating further.
-      const titleRegex = new RegExp(`Count by Created At: ${bucketSize}`, "i");
-      const bucketRegex = new RegExp(bucketSize, "i");
-
       it(`should return correct values for ${bucketSize}`, () => {
         popover().within(() => {
           cy.findByText(bucketSize).click();
@@ -59,12 +53,12 @@ describe("scenarios > binning > correctness > time series", () => {
         // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
         cy.findByText("Done").click();
 
-        getTitle(titleRegex);
+        getTitle(`Count by Created At: ${bucketSize}`);
 
         assertOnHeaderCells(bucketSize);
         assertOnTableValues(representativeValues);
 
-        assertOnTimeSeriesFooter(bucketRegex);
+        assertOnTimeSeriesFooter(bucketSize);
       });
     },
   );
@@ -81,10 +75,7 @@ function getTitle(title) {
 }
 
 function assertOnHeaderCells(bucketSize) {
-  const headerRegex = new RegExp(`Created At: ${bucketSize}`, "i");
-
-  cy.get(".cellData").eq(0).contains(headerRegex);
-
+  cy.get(".cellData").eq(0).contains(`Created At: ${bucketSize}`);
   cy.get(".cellData").eq(1).contains("Count");
 }
 
@@ -94,7 +85,7 @@ function assertOnTableValues(values) {
   });
 }
 
-function assertOnTimeSeriesFooter(regex) {
+function assertOnTimeSeriesFooter(str) {
   cy.findAllByTestId("select-button-content")
     .first()
     .invoke("text")
@@ -102,5 +93,5 @@ function assertOnTimeSeriesFooter(regex) {
   cy.findAllByTestId("select-button-content")
     .last()
     .invoke("text")
-    .should("match", regex);
+    .should("contain", str);
 }
diff --git a/e2e/test/scenarios/custom-column/custom-column.cy.spec.js b/e2e/test/scenarios/custom-column/custom-column.cy.spec.js
index aed04df9324..56366fe5e77 100644
--- a/e2e/test/scenarios/custom-column/custom-column.cy.spec.js
+++ b/e2e/test/scenarios/custom-column/custom-column.cy.spec.js
@@ -94,7 +94,7 @@ describe("scenarios > question > custom column", () => {
       name: "Product Date",
     }).click();
 
-    popover().last().findByText("Month of Year").click();
+    popover().last().findByText("Month of year").click();
 
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
     cy.findByText("Product Date: Month of year").should("be.visible");
diff --git a/e2e/test/scenarios/question/summarization.cy.spec.js b/e2e/test/scenarios/question/summarization.cy.spec.js
index 36d572c8d54..55b46a23ef3 100644
--- a/e2e/test/scenarios/question/summarization.cy.spec.js
+++ b/e2e/test/scenarios/question/summarization.cy.spec.js
@@ -236,7 +236,7 @@ describe("scenarios > question > summarize sidebar", () => {
     });
     // this should be among the granular selection choices
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
-    cy.findByText("Hour of Day").click();
+    cy.findByText("Hour of day").click();
   });
 
   it.skip("should handle (removing) multiple metrics when one is sorted (metabase#12625)", () => {
diff --git a/e2e/test/scenarios/sharing/reproductions/16918.cy.spec.js b/e2e/test/scenarios/sharing/reproductions/16918.cy.spec.js
index 3c4d47eb529..3a7cba8c902 100644
--- a/e2e/test/scenarios/sharing/reproductions/16918.cy.spec.js
+++ b/e2e/test/scenarios/sharing/reproductions/16918.cy.spec.js
@@ -28,7 +28,7 @@ describe("issue 16918", () => {
     });
   });
 
-  it(`should load question binned by "Month of Year" or similar granularity (metabase#16918)`, () => {
+  it(`should load question binned by "Month of year" or similar granularity (metabase#16918)`, () => {
     cy.visit("/pulse/create");
 
     // eslint-disable-next-line no-unscoped-text-selectors -- deprecated usage
diff --git a/frontend/src/metabase-lib/Dimension.ts b/frontend/src/metabase-lib/Dimension.ts
index afb8ca517a7..e66e362f035 100644
--- a/frontend/src/metabase-lib/Dimension.ts
+++ b/frontend/src/metabase-lib/Dimension.ts
@@ -1717,49 +1717,49 @@ const DATETIME_SUBDIMENSIONS = [
     },
   },
   {
-    name: t`Minute of Hour`,
+    name: t`Minute of hour`,
     options: {
       "temporal-unit": "minute-of-hour",
     },
   },
   {
-    name: t`Hour of Day`,
+    name: t`Hour of day`,
     options: {
       "temporal-unit": "hour-of-day",
     },
   },
   {
-    name: t`Day of Week`,
+    name: t`Day of week`,
     options: {
       "temporal-unit": "day-of-week",
     },
   },
   {
-    name: t`Day of Month`,
+    name: t`Day of month`,
     options: {
       "temporal-unit": "day-of-month",
     },
   },
   {
-    name: t`Day of Year`,
+    name: t`Day of year`,
     options: {
       "temporal-unit": "day-of-year",
     },
   },
   {
-    name: t`Week of Year`,
+    name: t`Week of year`,
     options: {
       "temporal-unit": "week-of-year",
     },
   },
   {
-    name: t`Month of Year`,
+    name: t`Month of year`,
     options: {
       "temporal-unit": "month-of-year",
     },
   },
   {
-    name: t`Quarter of Year`,
+    name: t`Quarter of year`,
     options: {
       "temporal-unit": "quarter-of-year",
     },
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 ec290cf2a5a..b62d795358e 100644
--- a/frontend/src/metabase-types/api/mocks/presets/sample_database.ts
+++ b/frontend/src/metabase-types/api/mocks/presets/sample_database.ts
@@ -1110,32 +1110,32 @@ function createTemporalBucketingOptions(): Record<
       type: "type/Date",
     },
     "5": {
-      name: "Day of Week",
+      name: "Day of week",
       mbql: ["field", null, { "temporal-unit": "day-of-week" }],
       type: "type/Date",
     },
     "6": {
-      name: "Day of Month",
+      name: "Day of month",
       mbql: ["field", null, { "temporal-unit": "day-of-month" }],
       type: "type/Date",
     },
     "7": {
-      name: "Day of Year",
+      name: "Day of year",
       mbql: ["field", null, { "temporal-unit": "day-of-year" }],
       type: "type/Date",
     },
     "8": {
-      name: "Week of Year",
+      name: "Week of year",
       mbql: ["field", null, { "temporal-unit": "week-of-year" }],
       type: "type/Date",
     },
     "9": {
-      name: "Month of Year",
+      name: "Month of year",
       mbql: ["field", null, { "temporal-unit": "month-of-year" }],
       type: "type/Date",
     },
     "10": {
-      name: "Quarter of Year",
+      name: "Quarter of year",
       mbql: ["field", null, { "temporal-unit": "quarter-of-year" }],
       type: "type/Date",
     },
@@ -1175,42 +1175,42 @@ function createTemporalBucketingOptions(): Record<
       type: "type/DateTime",
     },
     "18": {
-      name: "Minute of Hour",
+      name: "Minute of hour",
       mbql: ["field", null, { "temporal-unit": "minute-of-hour" }],
       type: "type/DateTime",
     },
     "19": {
-      name: "Hour of Day",
+      name: "Hour of day",
       mbql: ["field", null, { "temporal-unit": "hour-of-day" }],
       type: "type/DateTime",
     },
     "20": {
-      name: "Day of Week",
+      name: "Day of week",
       mbql: ["field", null, { "temporal-unit": "day-of-week" }],
       type: "type/DateTime",
     },
     "21": {
-      name: "Day of Month",
+      name: "Day of month",
       mbql: ["field", null, { "temporal-unit": "day-of-month" }],
       type: "type/DateTime",
     },
     "22": {
-      name: "Day of Year",
+      name: "Day of year",
       mbql: ["field", null, { "temporal-unit": "day-of-year" }],
       type: "type/DateTime",
     },
     "23": {
-      name: "Week of Year",
+      name: "Week of year",
       mbql: ["field", null, { "temporal-unit": "week-of-year" }],
       type: "type/DateTime",
     },
     "24": {
-      name: "Month of Year",
+      name: "Month of year",
       mbql: ["field", null, { "temporal-unit": "month-of-year" }],
       type: "type/DateTime",
     },
     "25": {
-      name: "Quarter of Year",
+      name: "Quarter of year",
       mbql: ["field", null, { "temporal-unit": "quarter-of-year" }],
       type: "type/DateTime",
     },
@@ -1225,7 +1225,7 @@ function createTemporalBucketingOptions(): Record<
       type: "type/Time",
     },
     "28": {
-      name: "Minute of Hour",
+      name: "Minute of hour",
       mbql: ["field", null, { "temporal-unit": "minute-of-hour" }],
       type: "type/Time",
     },
diff --git a/src/metabase/api/table.clj b/src/metabase/api/table.clj
index 27ff6393577..9d63fa9b1d2 100644
--- a/src/metabase/api/table.clj
+++ b/src/metabase/api/table.clj
@@ -140,7 +140,7 @@
 (def ^:private time-options
   [[minute-str "minute"]
    [hour-str "hour"]
-   [(deferred-tru "Minute of Hour") "minute-of-hour"]])
+   [(deferred-tru "Minute of hour") "minute-of-hour"]])
 
 (def ^:private datetime-options
   [[minute-str "minute"]
@@ -150,14 +150,14 @@
    [(deferred-tru "Month") "month"]
    [(deferred-tru "Quarter") "quarter"]
    [(deferred-tru "Year") "year"]
-   [(deferred-tru "Minute of Hour") "minute-of-hour"]
-   [(deferred-tru "Hour of Day") "hour-of-day"]
-   [(deferred-tru "Day of Week") "day-of-week"]
-   [(deferred-tru "Day of Month") "day-of-month"]
-   [(deferred-tru "Day of Year") "day-of-year"]
-   [(deferred-tru "Week of Year") "week-of-year"]
-   [(deferred-tru "Month of Year") "month-of-year"]
-   [(deferred-tru "Quarter of Year") "quarter-of-year"]])
+   [(deferred-tru "Minute of hour") "minute-of-hour"]
+   [(deferred-tru "Hour of day") "hour-of-day"]
+   [(deferred-tru "Day of week") "day-of-week"]
+   [(deferred-tru "Day of month") "day-of-month"]
+   [(deferred-tru "Day of year") "day-of-year"]
+   [(deferred-tru "Week of year") "week-of-year"]
+   [(deferred-tru "Month of year") "month-of-year"]
+   [(deferred-tru "Quarter of year") "quarter-of-year"]])
 
 (def ^:private date-options
   [[day-str "day"]
@@ -165,12 +165,12 @@
    [(deferred-tru "Month") "month"]
    [(deferred-tru "Quarter") "quarter"]
    [(deferred-tru "Year") "year"]
-   [(deferred-tru "Day of Week") "day-of-week"]
-   [(deferred-tru "Day of Month") "day-of-month"]
-   [(deferred-tru "Day of Year") "day-of-year"]
-   [(deferred-tru "Week of Year") "week-of-year"]
-   [(deferred-tru "Month of Year") "month-of-year"]
-   [(deferred-tru "Quarter of Year") "quarter-of-year"]])
+   [(deferred-tru "Day of week") "day-of-week"]
+   [(deferred-tru "Day of month") "day-of-month"]
+   [(deferred-tru "Day of year") "day-of-year"]
+   [(deferred-tru "Week of year") "week-of-year"]
+   [(deferred-tru "Month of year") "month-of-year"]
+   [(deferred-tru "Quarter of year") "quarter-of-year"]])
 
 (def ^:private dimension-options
   (let [default-entry [auto-bin-str ["default"]]]
diff --git a/src/metabase/pulse/render/datetime.clj b/src/metabase/pulse/render/datetime.clj
index fcdcca30a4a..1271c70bc06 100644
--- a/src/metabase/pulse/render/datetime.clj
+++ b/src/metabase/pulse/render/datetime.clj
@@ -93,7 +93,7 @@
                                                                      (str/replace #"EEEE" "EEE")
                                                                      (str/replace #"DDD" "D")))]
                                             (-> conditional-changes
-                                                ;; 'D' formats as Day of Year, we want Day of Month, which is  'd' (issue #27469)
+                                                ;; 'D' formats as Day of year, we want Day of month, which is  'd' (issue #27469)
                                                 (str/replace #"D" "d"))))]
        (case (:unit col)
          ;; these types have special formatting
-- 
GitLab