Skip to content
Snippets Groups Projects
Unverified Commit 7860a623 authored by Cam Saul's avatar Cam Saul
Browse files

Add new humanization-strategy Setting

parent 326b2655
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,7 @@
[dashboard-card :refer [DashboardCard]]
[database :refer [Database virtual-id]]
[field :refer [Field]]
[humanization :as humanization]
[permissions :as perms :refer [Permissions]]
[permissions-group :as perm-group]
[permissions-group-membership :as perm-membership :refer [PermissionsGroupMembership]]
......@@ -341,3 +342,21 @@
:when (not= db-id virtual-id)]
(db/update-where! Card {:id [:in (map :id cards)]}
:database_id db-id)))
;; Prior to version 0.28.0 humanization was configured using the boolean setting `enable-advanced-humanization`.
;; `true` meant "use advanced humanization", while `false` meant "use simple humanization". In 0.28.0, this Setting
;; was replaced by the `humanization-strategy` Setting, which (at the time of this writing) allows for a choice
;; between three options: advanced, simple, or none. Migrate any values of the old Setting, if set, to the new one.
(defmigration ^{:author "camsaul", :added "0.28.0"} migrate-humanization-setting
(when-let [enable-advanced-humanization-str (db/select-one-field :value Setting, :key "enable-advanced-humanization")]
(when (seq enable-advanced-humanization-str)
;; if an entry exists for the old Setting, it will be a boolean string, either "true" or "false". Try inserting
;; a record for the new setting with the appropriate new value. This might fail if for some reason
;; humanization-strategy has been set already, or enable-advanced-humanization has somehow been set to an
;; invalid value. In that case, fail silently.
(u/ignore-exceptions
(humanization/humanization-strategy (if (Boolean/parseBoolean enable-advanced-humanization-str)
"advanced"
"simple"))))
;; either way, delete the old value from the DB since we'll never be using it again.
(db/delete! Setting, :key "enable-advanced-humanization")))
......@@ -13,7 +13,7 @@
[hydrate :refer [hydrate]]
[models :as models]]))
;;; ------------------------------------------------------------ Type Mappings ------------------------------------------------------------
;;; ------------------------------------------------- Type Mappings --------------------------------------------------
(def ^:const visibility-types
"Possible values for `Field.visibility_type`."
......@@ -24,8 +24,7 @@
:retired}) ; For fields that no longer exist in the physical db. automatically set by Metabase. QP should error if encountered in a query.
;;; ------------------------------------------------------------ Entity & Lifecycle ------------------------------------------------------------
;;; ----------------------------------------------- Entity & Lifecycle -----------------------------------------------
(models/defmodel Field :metabase_field)
......@@ -111,8 +110,7 @@
:can-write? i/superuser?}))
;;; ------------------------------------------------------------ Hydration / Util Fns ------------------------------------------------------------
;;; ---------------------------------------------- Hydration / Util Fns ----------------------------------------------
(defn target
"Return the FK target `Field` that this `Field` points to."
......
(ns metabase.models.humanization
"Logic related to humanization of table names and other identifiers,
e.g. taking an identifier like `my_table` and returning a human-friendly one like `My Table`.
"Logic related to humanization of table names and other identifiers, e.g. taking an identifier like `my_table` and
returning a human-friendly one like `My Table`.
There are two implementations of humanization logic; advanced, cost-based logic is the default;
which implementation is used is determined by the Setting `enable-advanced-humanization`.
There are currently three implementations of humanization logic; `:advanced`, cost-based logic is the default; which
implementation is used is determined by the Setting `humanization-strategy`; `:simple`, which merely replaces
underscores and dashes with spaces, and `:none`, which predictibly is merely an identity function that does nothing
to the results.
The actual algorithm for advanced humanization is in `metabase.util.infer-spaces`."
(:require [clojure.string :as s]
The actual algorithm for advanced humanization is in `metabase.util.infer-spaces`. (NOTE: some of the logic is here,
such as the `captialize-word` function; maybe we should move that so all the logic is in one place?)"
(:require [clojure.string :as str]
[clojure.tools.logging :as log]
[metabase.models.setting :as setting :refer [defsetting]]
[metabase.util.infer-spaces :refer [infer-spaces]]
......@@ -16,75 +19,98 @@
#{"id" "url" "ip" "uid" "uuid" "guid"})
(defn- capitalize-word [word]
(if (contains? acronyms (s/lower-case word))
(s/upper-case word)
(s/capitalize word)))
(defn- name->human-readable-name:advanced
"Implementation of `name->human-readable-name` used if the Setting `enable-advanced-humanization` is `false`."
^String [^String s]
(when (seq s)
;; explode string on spaces, underscores, hyphens, and camelCase
(s/join " " (for [part (s/split s #"[-_\s]+|(?<=[a-z])(?=[A-Z])")
:when (not (s/blank? part))
word (dedupe (flatten (infer-spaces part)))]
(capitalize-word word)))))
(defn- name->human-readable-name:simple
"Implementation of `name->human-readable-name` used if the Setting `enable-advanced-humanization` is `true`."
^String [^String s]
;; explode on hypens, underscores, and spaces
(when (seq s)
(s/join " " (for [part (s/split s #"[-_\s]+")
:when (not (s/blank? part))]
(capitalize-word part)))))
(declare enable-advanced-humanization)
(defn name->human-readable-name
"Convert a string NAME of some object like a `Table` or `Field` to one more friendly to humans.
(name->human-readable-name \"admin_users\") -> \"Admin Users\"
(The actual implementation of this function depends on the value of `enable-advanced-humanization`; by default,
`name->human-readable-name:advanced` is used)."
^String [^String s]
((if (enable-advanced-humanization)
name->human-readable-name:advanced
name->human-readable-name:simple) s))
(if (contains? acronyms (str/lower-case word))
(str/upper-case word)
(str/capitalize word)))
(declare humanization-strategy)
(defmulti ^String name->human-readable-name
"Convert a name, such as `num_toucans`, to a human-readable name, such as `Num Toucans`. With one arg, this uses the
strategy defined by the Setting `humanization-strategy`. With two args, you may specify a custom strategy (intended
mainly for the internal implementation):
(humanization-strategy :advanced)
(name->human-readable-name \"cooltoucans\") ;-> \"Cool Toucans\"
;; this is the same as:
(name->human-readable-name (humanization-strategy) \"cooltoucans\") ;-> \"Cool Toucans\"
;; specifiy a different strategy:
(name->human-readable-name :none \"cooltoucans\") ;-> \"cooltoucans\""
{:arglists '([s] [strategy s])}
(fn
([_] (keyword (humanization-strategy)))
([strategy _] (keyword strategy))))
;; :advanced is the default implementation
(defmethod name->human-readable-name :advanced
([s] (name->human-readable-name :advanced s))
([_, ^String s]
(when (seq s)
;; explode string on spaces, underscores, hyphens, and camelCase
(str/join " " (for [part (str/split s #"[-_\s]+|(?<=[a-z])(?=[A-Z])")
:when (not (str/blank? part))
word (dedupe (flatten (infer-spaces part)))]
(capitalize-word word))))))
;; simple replaces hyphens and underscores with spaces
(defmethod name->human-readable-name :simple
([s] (name->human-readable-name :simple s))
([_, ^String s]
;; explode on hypens, underscores, and spaces
(when (seq s)
(str/join " " (for [part (str/split s #"[-_\s]+")
:when (not (str/blank? part))]
(capitalize-word part))))))
;; :none is just an identity implementation
(defmethod name->human-readable-name :none
([s] s)
([_ s] s))
(defn- custom-display-name?
"Is DISPLAY-NAME a custom name that was set manually by the user in the metadata edit screen?"
"Is `display-name` a custom name that was set manually by the user in the metadata edit screen?"
[internal-name display-name]
(and (not= display-name (name->human-readable-name:simple internal-name))
(not= display-name (name->human-readable-name:advanced internal-name))))
;; Try all the different implementations of name->human-readable-name. If any (f internal-name) is equal to
;; display-name we can safely assume that display-name was set automatically using that strategy and stop there.
;; Otherwise if none of the strategies match (i.e. `some` returns `nil`) we can assume a custom name was set.
(nil? (some #(= display-name (% internal-name))
(vals (methods name->human-readable-name)))))
(defn- re-humanize-names! [model]
(doseq [{id :id, internal-name :name, display-name :display_name} (db/select [model :id :name :display_name])
:let [new-display-name (name->human-readable-name internal-name)]
:when (and (not= display-name new-display-name)
(not (custom-display-name? internal-name display-name)))]
(log/info (format "Updating display name for %s '%s': '%s' -> '%s'" (name model) internal-name display-name new-display-name))
:let [new-display-name (name->human-readable-name internal-name)]
:when (and (not= display-name new-display-name)
(not (custom-display-name? internal-name display-name)))]
(log/info (format "Updating display name for %s '%s': '%s' -> '%s'"
(name model) internal-name display-name new-display-name))
(db/update! model id
:display_name new-display-name)))
(defn- re-humanize-table-and-field-names!
"Update the display names of all tables in the database using new values obtained from the (obstensibly toggled implementation of) `name->human-readable-name`."
"Update the display names of all tables in the database using new values obtained from the (obstensibly toggled
implementation of) `name->human-readable-name`."
[]
(re-humanize-names! 'Table)
(re-humanize-names! 'Field))
(defn- set-enable-advanced-humanization! [^Boolean new-value]
(setting/set-boolean! :enable-advanced-humanization new-value)
(log/info (format "Now using %s table name humanization." (if (enable-advanced-humanization) "ADVANCED" "SIMPLE")))
(defn- set-humanization-strategy! [new-strategy]
;; check to make sure `new-strategy` is a valid strategy, or throw an Exception it is it not.
(when-not (get-method name->human-readable-name (keyword new-strategy))
(throw (IllegalArgumentException. (format "Invalid humanization strategy %s. Valid strategies are: %s"
new-strategy (keys (methods name->human-readable-name))))))
;; ok, now set the new value
(setting/set-string! :humanization-strategy (name new-strategy))
;; now rehumanize all the Tables and Fields using the new strategy.
;; TODO: do this in a background thread because it is potentially slow?
(log/info (format "Now using %s table name humanization." new-strategy))
(re-humanize-table-and-field-names!))
(defsetting enable-advanced-humanization
"Metabase can attempt to transform your table and field names into more sensible, human-readable versions, e.g. \"somehorriblename\" becomes \"Some Horrible Name\".
This doesn’t work all that well if the names are in a language other than English, however. Do you want us to take a guess?"
:type :boolean
:default true
:setter set-enable-advanced-humanization!)
(defsetting ^{:added "0.28.0"} humanization-strategy
"Metabase can attempt to transform your table and field names into more sensible, human-readable versions, e.g.
\"somehorriblename\" becomes \"Some Horrible Name\". This doesn’t work all that well if the names are in a language
other than English, however. Do you want us to take a guess?"
:default "advanced"
:setter set-humanization-strategy!)
......@@ -15,7 +15,7 @@
[db :as db]
[models :as models]]))
;;; ------------------------------------------------------------ Constants + Entity ------------------------------------------------------------
;;; ----------------------------------------------- Constants + Entity -----------------------------------------------
;; TODO - I don't think this is used for anything anymore
(def ^:const ^:deprecated entity-types
......@@ -31,7 +31,7 @@
(models/defmodel Table :metabase_table)
;;; ------------------------------------------------------------ Lifecycle ------------------------------------------------------------
;;; --------------------------------------------------- Lifecycle ----------------------------------------------------
(defn- pre-insert [table]
(let [defaults {:display_name (humanization/name->human-readable-name (:name table))}]
......@@ -62,7 +62,7 @@
:perms-objects-set perms-objects-set}))
;;; ------------------------------------------------------------ Hydration ------------------------------------------------------------
;;; --------------------------------------------------- Hydration ----------------------------------------------------
(defn fields
"Return the `FIELDS` belonging to a single TABLE."
......@@ -94,7 +94,10 @@
"Return the ID of the primary key `Field` for TABLE."
{:hydrate :pk_field, :arglists '([table])}
[{:keys [id]}]
(db/select-one-id Field, :table_id id, :special_type (mdb/isa :type/PK), :visibility_type [:not-in ["sensitive" "retired"]]))
(db/select-one-id Field
:table_id id
:special_type (mdb/isa :type/PK)
:visibility_type [:not-in ["sensitive" "retired"]]))
(defn- with-objects [hydration-key fetch-objects-fn tables]
......@@ -128,14 +131,18 @@
[tables]
(with-objects :fields
(fn [table-ids]
(db/select Field :table_id [:in table-ids], :visibility_type [:not= "retired"], {:order-by [[:position :asc] [:name :asc]]}))
(db/select Field
:table_id [:in table-ids]
:visibility_type [:not= "retired"]
{:order-by [[:position :asc] [:name :asc]]}))
tables))
;;; ------------------------------------------------------------ Convenience Fns ------------------------------------------------------------
;;; ------------------------------------------------ Convenience Fns -------------------------------------------------
(defn qualified-identifier
"Return a keyword identifier for TABLE in the form `:schema.table-name` (if the Table has a non-empty `:schema` field) or `:table-name` (if the Table has no `:schema`)."
"Return a keyword identifier for TABLE in the form `:schema.table-name` (if the Table has a non-empty `:schema` field)
or `:table-name` (if the Table has no `:schema`)."
^clojure.lang.Keyword [{schema :schema, table-name :name}]
(keyword (str (when (seq schema)
(str schema \.))
......
......@@ -141,7 +141,7 @@
:check_for_updates (public-settings/check-for-updates)
:site_name (not= (public-settings/site-name) "Metabase")
:report_timezone (driver/report-timezone)
:friendly_names (humanization/enable-advanced-humanization)
:friendly_names (= (humanization/humanization-strategy) "advanced")
:email_configured (email/email-configured?)
:slack_configured (slack/slack-configured?)
:sso_configured (boolean (session-api/google-auth-client-id))
......
......@@ -8,149 +8,141 @@
[toucan.db :as db]
[toucan.util.test :as tt]))
;;; #'humanization/name->human-readable-name:advanced
(expect nil (#'humanization/name->human-readable-name:advanced nil))
(expect nil (#'humanization/name->human-readable-name:advanced ""))
(expect "" (#'humanization/name->human-readable-name:advanced "_"))
(expect "" (#'humanization/name->human-readable-name:advanced "-"))
(expect "ID" (#'humanization/name->human-readable-name:advanced "_id"))
(expect "UID" (#'humanization/name->human-readable-name:advanced "uid"))
(expect "UUID" (#'humanization/name->human-readable-name:advanced "uuid"))
(expect "GUID" (#'humanization/name->human-readable-name:advanced "guid"))
(expect "IP" (#'humanization/name->human-readable-name:advanced "ip"))
(expect "URL" (#'humanization/name->human-readable-name:advanced "url"))
(expect "Agent Invite Migration" (#'humanization/name->human-readable-name:advanced "_agent_invite_migration"))
(expect "Agent Invite Migration" (#'humanization/name->human-readable-name:advanced "-agent-invite-migration"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:advanced "fooBar"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:advanced "foo-bar"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:advanced "foo_bar"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:advanced "foo bar"))
(expect "Dashboard Card Subscription" (#'humanization/name->human-readable-name:advanced "dashboardcardsubscription"))
(expect "Foo ID" (#'humanization/name->human-readable-name:advanced "foo_id"))
(expect "Receiver ID" (#'humanization/name->human-readable-name:advanced "receiver_id"))
(expect "Inbox" (#'humanization/name->human-readable-name:advanced "inbox"))
(expect "Acquirer" (#'humanization/name->human-readable-name:advanced "acquirer"))
(expect "Auth Authenticator" (#'humanization/name->human-readable-name:advanced "auth_authenticator"))
(expect "Auth Provider" (#'humanization/name->human-readable-name:advanced "authprovider"))
(expect "User Social Auth" (#'humanization/name->human-readable-name:advanced "usersocialauth"))
;;; #'humanization/name->human-readable-name:simple
(expect nil (#'humanization/name->human-readable-name:simple nil))
(expect nil (#'humanization/name->human-readable-name:simple ""))
(expect "" (#'humanization/name->human-readable-name:simple "_"))
(expect "" (#'humanization/name->human-readable-name:simple "-"))
(expect "ID" (#'humanization/name->human-readable-name:simple "_id"))
(expect "UID" (#'humanization/name->human-readable-name:simple "uid"))
(expect "UUID" (#'humanization/name->human-readable-name:simple "uuid"))
(expect "GUID" (#'humanization/name->human-readable-name:simple "guid"))
(expect "IP" (#'humanization/name->human-readable-name:simple "ip"))
(expect "URL" (#'humanization/name->human-readable-name:simple "url"))
(expect "Agent Invite Migration" (#'humanization/name->human-readable-name:simple "_agent_invite_migration"))
(expect "Agent Invite Migration" (#'humanization/name->human-readable-name:simple "-agent-invite-migration"))
(expect "Foobar" (#'humanization/name->human-readable-name:simple "fooBar"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:simple "foo-bar"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:simple "foo_bar"))
(expect "Foo Bar" (#'humanization/name->human-readable-name:simple "foo bar"))
(expect "Dashboardcardsubscription" (#'humanization/name->human-readable-name:simple "dashboardcardsubscription"))
(expect "Foo ID" (#'humanization/name->human-readable-name:simple "foo_id"))
(expect "Receiver ID" (#'humanization/name->human-readable-name:simple "receiver_id"))
(expect "Inbox" (#'humanization/name->human-readable-name:simple "inbox"))
(expect "Acquirer" (#'humanization/name->human-readable-name:simple "acquirer"))
(expect "Auth Authenticator" (#'humanization/name->human-readable-name:simple "auth_authenticator"))
(expect "Authprovider" (#'humanization/name->human-readable-name:simple "authprovider"))
(expect "Usersocialauth" (#'humanization/name->human-readable-name:simple "usersocialauth"))
;;; :advanced humanization
(expect nil (humanization/name->human-readable-name :advanced nil))
(expect nil (humanization/name->human-readable-name :advanced ""))
(expect "" (humanization/name->human-readable-name :advanced "_"))
(expect "" (humanization/name->human-readable-name :advanced "-"))
(expect "ID" (humanization/name->human-readable-name :advanced "_id"))
(expect "UID" (humanization/name->human-readable-name :advanced "uid"))
(expect "UUID" (humanization/name->human-readable-name :advanced "uuid"))
(expect "GUID" (humanization/name->human-readable-name :advanced "guid"))
(expect "IP" (humanization/name->human-readable-name :advanced "ip"))
(expect "URL" (humanization/name->human-readable-name :advanced "url"))
(expect "Agent Invite Migration" (humanization/name->human-readable-name :advanced "_agent_invite_migration"))
(expect "Agent Invite Migration" (humanization/name->human-readable-name :advanced "-agent-invite-migration"))
(expect "Foo Bar" (humanization/name->human-readable-name :advanced "fooBar"))
(expect "Foo Bar" (humanization/name->human-readable-name :advanced "foo-bar"))
(expect "Foo Bar" (humanization/name->human-readable-name :advanced "foo_bar"))
(expect "Foo Bar" (humanization/name->human-readable-name :advanced "foo bar"))
(expect "Dashboard Card Subscription" (humanization/name->human-readable-name :advanced "dashboardcardsubscription"))
(expect "Foo ID" (humanization/name->human-readable-name :advanced "foo_id"))
(expect "Receiver ID" (humanization/name->human-readable-name :advanced "receiver_id"))
(expect "Inbox" (humanization/name->human-readable-name :advanced "inbox"))
(expect "Acquirer" (humanization/name->human-readable-name :advanced "acquirer"))
(expect "Auth Authenticator" (humanization/name->human-readable-name :advanced "auth_authenticator"))
(expect "Auth Provider" (humanization/name->human-readable-name :advanced "authprovider"))
(expect "User Social Auth" (humanization/name->human-readable-name :advanced "usersocialauth"))
;;; :simple humanization
(expect nil (humanization/name->human-readable-name :simple nil))
(expect nil (humanization/name->human-readable-name :simple ""))
(expect "" (humanization/name->human-readable-name :simple "_"))
(expect "" (humanization/name->human-readable-name :simple "-"))
(expect "ID" (humanization/name->human-readable-name :simple "_id"))
(expect "UID" (humanization/name->human-readable-name :simple "uid"))
(expect "UUID" (humanization/name->human-readable-name :simple "uuid"))
(expect "GUID" (humanization/name->human-readable-name :simple "guid"))
(expect "IP" (humanization/name->human-readable-name :simple "ip"))
(expect "URL" (humanization/name->human-readable-name :simple "url"))
(expect "Agent Invite Migration" (humanization/name->human-readable-name :simple "_agent_invite_migration"))
(expect "Agent Invite Migration" (humanization/name->human-readable-name :simple "-agent-invite-migration"))
(expect "Foobar" (humanization/name->human-readable-name :simple "fooBar"))
(expect "Foo Bar" (humanization/name->human-readable-name :simple "foo-bar"))
(expect "Foo Bar" (humanization/name->human-readable-name :simple "foo_bar"))
(expect "Foo Bar" (humanization/name->human-readable-name :simple "foo bar"))
(expect "Dashboardcardsubscription" (humanization/name->human-readable-name :simple "dashboardcardsubscription"))
(expect "Foo ID" (humanization/name->human-readable-name :simple "foo_id"))
(expect "Receiver ID" (humanization/name->human-readable-name :simple "receiver_id"))
(expect "Inbox" (humanization/name->human-readable-name :simple "inbox"))
(expect "Acquirer" (humanization/name->human-readable-name :simple "acquirer"))
(expect "Auth Authenticator" (humanization/name->human-readable-name :simple "auth_authenticator"))
(expect "Authprovider" (humanization/name->human-readable-name :simple "authprovider"))
(expect "Usersocialauth" (humanization/name->human-readable-name :simple "usersocialauth"))
;;; :none humanization
(expect nil (humanization/name->human-readable-name :none nil))
(expect "" (humanization/name->human-readable-name :none ""))
(expect "_" (humanization/name->human-readable-name :none "_"))
(expect "-" (humanization/name->human-readable-name :none "-"))
(expect "_id" (humanization/name->human-readable-name :none "_id"))
(expect "uid" (humanization/name->human-readable-name :none "uid"))
(expect "uuid" (humanization/name->human-readable-name :none "uuid"))
(expect "guid" (humanization/name->human-readable-name :none "guid"))
(expect "ip" (humanization/name->human-readable-name :none "ip"))
(expect "url" (humanization/name->human-readable-name :none "url"))
(expect "_agent_invite_migration" (humanization/name->human-readable-name :none "_agent_invite_migration"))
(expect "-agent-invite-migration" (humanization/name->human-readable-name :none "-agent-invite-migration"))
(expect "fooBar" (humanization/name->human-readable-name :none "fooBar"))
(expect "foo-bar" (humanization/name->human-readable-name :none "foo-bar"))
(expect "foo_bar" (humanization/name->human-readable-name :none "foo_bar"))
(expect "foo bar" (humanization/name->human-readable-name :none "foo bar"))
(expect "dashboardcardsubscription" (humanization/name->human-readable-name :none "dashboardcardsubscription"))
(expect "foo_id" (humanization/name->human-readable-name :none "foo_id"))
(expect "receiver_id" (humanization/name->human-readable-name :none "receiver_id"))
(expect "inbox" (humanization/name->human-readable-name :none "inbox"))
(expect "acquirer" (humanization/name->human-readable-name :none "acquirer"))
(expect "auth_authenticator" (humanization/name->human-readable-name :none "auth_authenticator"))
(expect "authprovider" (humanization/name->human-readable-name :none "authprovider"))
(expect "usersocialauth" (humanization/name->human-readable-name :none "usersocialauth"))
;;; Re-humanization
;; check that we get the expected :display_name with advanced humanization *enabled*
(expect
"Toucans Are Cool"
(tu/with-temporary-setting-values [enable-advanced-humanization true]
(tt/with-temp Table [{table-id :id} {:name "toucansare_cool"}]
(defn- get-humanized-display-name [actual-name strategy]
(tu/with-temporary-setting-values [humanization-strategy strategy]
(tt/with-temp Table [{table-id :id} {:name actual-name}]
(db/select-one-field :display_name Table, :id table-id))))
(expect
"Fussy Bird Sightings"
(tu/with-temporary-setting-values [enable-advanced-humanization true]
(tt/with-temp Field [{field-id :id} {:name "fussybird_sightings"}]
(db/select-one-field :display_name Field, :id field-id))))
;; check that we get the expected :display_name with advanced humanization *enabled*
(expect "Toucans Are Cool" (get-humanized-display-name "toucansare_cool" "advanced"))
(expect "Toucansare Cool" (get-humanized-display-name "toucansare_cool" "simple"))
(expect "toucansare_cool" (get-humanized-display-name "toucansare_cool" "none"))
;; check that we get the expected :display_name with advanced humanization *disabled*
(expect
"Toucansare Cool"
(tu/with-temporary-setting-values [enable-advanced-humanization false]
(tt/with-temp Table [{table-id :id} {:name "toucansare_cool"}]
(db/select-one-field :display_name Table, :id table-id))))
(expect "Fussy Bird Sightings" (get-humanized-display-name "fussybird_sightings" "advanced"))
(expect "Fussybird Sightings" (get-humanized-display-name "fussybird_sightings" "simple"))
(expect "fussybird_sightings" (get-humanized-display-name "fussybird_sightings" "none"))
(expect
"Fussybird Sightings"
(tu/with-temporary-setting-values [enable-advanced-humanization false]
(tt/with-temp Field [{field-id :id} {:name "fussybird_sightings"}]
(db/select-one-field :display_name Field, :id field-id))))
;; now check that existing tables have their :display_names updated appropriately when the setting `enabled-advanced-humanization` is toggled
(expect
["Toucans Are Cool"
"Toucansare Cool"
"Toucans Are Cool"]
(tu/with-temporary-setting-values [enable-advanced-humanization true]
(tt/with-temp Table [{table-id :id} {:name "toucansare_cool"}]
;; now check that existing tables have their :display_names updated appropriately when the setting
;; `enabled-advanced-humanization` is changed
(defn- switch-strategies-and-get-display-names [actual-name]
(tu/with-temporary-setting-values [humanization-strategy "advanced"]
(tt/with-temp Table [{table-id :id} {:name actual-name}]
(let [display-name #(db/select-one-field :display_name Table, :id table-id)]
[(display-name)
(do (enable-advanced-humanization false)
(display-name))
(do (enable-advanced-humanization true)
(display-name))]))))
{:initial (display-name)
:simple (do (humanization-strategy "simple") (display-name))
:advanced (do (humanization-strategy "advanced") (display-name))
:none (do (humanization-strategy "none") (display-name))}))))
(expect
["Fussy Bird Sightings"
"Fussybird Sightings"
"Fussy Bird Sightings"]
(tu/with-temporary-setting-values [enable-advanced-humanization true]
(tt/with-temp Field [{field-id :id} {:name "fussybird_sightings"}]
(let [display-name #(db/select-one-field :display_name Field, :id field-id)]
[(display-name)
(do (enable-advanced-humanization false)
(display-name))
(do (enable-advanced-humanization true)
(display-name))]))))
;; check that if we give a field a custom display_name that re-humanization doesn't overwrite it
(expect
"My Favorite Table"
(tu/with-temporary-setting-values [enable-advanced-humanization true]
(tt/with-temp Table [{table-id :id} {:name "toucansare_cool"}]
(db/update! Table table-id
:display_name "My Favorite Table")
(enable-advanced-humanization false)
(db/select-one-field :display_name Table, :id table-id))))
{:initial "Toucans Are Cool"
:simple "Toucansare Cool"
:advanced "Toucans Are Cool"
:none "toucansare_cool"}
(switch-strategies-and-get-display-names "toucansare_cool"))
(expect
"My Favorite Field"
(tu/with-temporary-setting-values [enable-advanced-humanization true]
(tt/with-temp Field [{field-id :id} {:name "fussybird_sightings"}]
(db/update! Field field-id
:display_name "My Favorite Field")
(enable-advanced-humanization false)
(db/select-one-field :display_name Field, :id field-id))))
;; make sure switching in the other direction doesn't stomp all over custom names either
(expect
"My Favorite Table"
(tu/with-temporary-setting-values [enable-advanced-humanization false]
{:initial "Fussy Bird Sightings"
:simple "Fussybird Sightings"
:advanced "Fussy Bird Sightings"
:none "fussybird_sightings"}
(switch-strategies-and-get-display-names "fussybird_sightings"))
;; check that if we give a field a custom display_name that changing strategy doesn't overwrite it
(defn- switch-strategies-and-get-display-name [initial-strategy new-strategy]
(tu/with-temporary-setting-values [humanization-strategy initial-strategy]
(tt/with-temp Table [{table-id :id} {:name "toucansare_cool"}]
(db/update! Table table-id
:display_name "My Favorite Table")
(enable-advanced-humanization true)
(humanization-strategy new-strategy)
(db/select-one-field :display_name Table, :id table-id))))
(expect
"My Favorite Field"
(tu/with-temporary-setting-values [enable-advanced-humanization false]
(tt/with-temp Field [{field-id :id} {:name "fussybird_sightings"}]
(db/update! Field field-id
:display_name "My Favorite Field")
(enable-advanced-humanization true)
(db/select-one-field :display_name Field, :id field-id))))
(expect "My Favorite Table" (switch-strategies-and-get-display-name "advanced" "simple"))
(expect "My Favorite Table" (switch-strategies-and-get-display-name "advanced" "none"))
(expect "My Favorite Table" (switch-strategies-and-get-display-name "simple" "advanced"))
(expect "My Favorite Table" (switch-strategies-and-get-display-name "simple" "none"))
(expect "My Favorite Table" (switch-strategies-and-get-display-name "none" "advanced"))
(expect "My Favorite Table" (switch-strategies-and-get-display-name "none" "simple"))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment