diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn
index fad16ea34edf17a55a6b9ea8a99a9b9c6ec8919d..0caacded8689f7deea51bf0aae3850c30d82e7d4 100644
--- a/.clj-kondo/config.edn
+++ b/.clj-kondo/config.edn
@@ -34,12 +34,10 @@
    ;;
    ;; TODO -- these should all be made thread safe if possible or renamed so they end in `!`. Then we can remove them
    ;; from this list because by default anything ending in `!` is considered to be thread-unsafe
-   :disallowed
+   :parallel/unsafe
    #{clojure.core/alter-var-root
      clojure.core/with-redefs
      clojure.core/with-redefs-fn
-     metabase-enterprise.sandbox.test-util/with-user-attributes
-     metabase-enterprise.test/with-user-attributes
      metabase.actions.test-util/with-actions
      metabase.actions.test-util/with-actions-disabled
      metabase.actions.test-util/with-actions-enabled
@@ -51,13 +49,14 @@
      metabase.email-test/with-fake-inbox
      metabase.test.data.users/with-group
      metabase.test.data.users/with-group-for-user
-     metabase.test.persistence/with-persistence-enabled
+     metabase.test.data/with-empty-h2-app-db
      metabase.test.util.log/with-log-level
      metabase.test.util.misc/with-single-admin-user
      metabase.test.util/with-all-users-permission
      metabase.test.util/with-discarded-collections-perms-changes
      metabase.test.util/with-env-keys-renamed-by
      metabase.test.util/with-locale
+     metabase.test.util/with-model-cleanup
      metabase.test.util/with-non-admin-groups-no-root-collection-for-namespace-perms
      metabase.test.util/with-non-admin-groups-no-root-collection-perms
      metabase.test.util/with-temp-env-var-value
@@ -73,6 +72,7 @@
      metabase.test/with-actions-test-data-tables
      metabase.test/with-all-users-permission
      metabase.test/with-discarded-collections-perms-changes
+     metabase.test/with-empty-h2-app-db
      metabase.test/with-env-keys-renamed-by
      metabase.test/with-expected-messages
      metabase.test/with-fake-inbox
@@ -80,9 +80,9 @@
      metabase.test/with-group-for-user
      metabase.test/with-locale
      metabase.test/with-log-level
+     metabase.test/with-model-cleanup
      metabase.test/with-non-admin-groups-no-root-collection-for-namespace-perms
      metabase.test/with-non-admin-groups-no-root-collection-perms
-     metabase.test/with-persistence-enabled
      metabase.test/with-single-admin-user
      metabase.test/with-temp-env-var-value
      metabase.test/with-temp-vals-in-db
@@ -91,7 +91,7 @@
      metabase.test/with-user-in-groups}
 
    ;; these functions are allowed in `^:parallel` tests even tho they end in `!`
-   :allowed
+   :parallel/safe
    #{clojure.core/assoc!
      clojure.core/compare-and-set!
      clojure.core/conj!
@@ -735,79 +735,79 @@
     toucan.models                                                 models}}}
 
  :lint-as
- {cljs.cache/defcache                                                                  clojure.core/deftype
-  clojure.core.cache/defcache                                                          clojure.core/deftype
-  clojure.core.logic/defne                                                             clj-kondo.lint-as/def-catch-all
-  clojure.test.check.clojure-test/defspec                                              clojure.test/deftest
-  clojurewerkz.quartzite.jobs/defjob                                                   clojure.core/defn
-  metabase-enterprise.serialization.test-util/with-dbs                                 clojure.core/fn
-  metabase-enterprise.serialization.test-util/with-random-dump-dir                     clojure.core/let
-  metabase.actions.test-util/with-actions                                              clojure.core/let
-  metabase.api.common/defroutes                                                        clojure.core/def
-  metabase.api.common/let-404                                                          clojure.core/let
-  metabase.api.search-test/do-test-users                                               clojure.core/let
-  metabase.async.api-response-test/with-response                                       clojure.core/let
-  metabase.dashboard-subscription-test/with-dashboard-sub-for-card                     clojure.core/let
-  metabase.db.custom-migrations/define-migration                                       clj-kondo.lint-as/def-catch-all
-  metabase.db.custom-migrations/define-reversible-migration                            clj-kondo.lint-as/def-catch-all
-  metabase.db.data-migrations/defmigration                                             clojure.core/def
-  metabase.db.liquibase/with-liquibase                                                 clojure.core/let
-  metabase.db.schema-migrations-test.impl/with-temp-empty-app-db                       clojure.core/let
-  metabase.driver.mongo.connection/with-mongo-client                                   clojure.core/let
-  metabase.driver.mongo.connection/with-mongo-database                                 clojure.core/let
-  metabase.driver.mongo.query-processor/mongo-let                                      clojure.core/let
-  metabase.driver.sql-jdbc.actions/with-jdbc-transaction                               clojure.core/let
-  metabase.driver.sql-jdbc.connection/with-connection-spec-for-testing-connection      clojure.core/let
-  metabase.driver.sql-jdbc.execute.diagnostic/capturing-diagnostic-info                clojure.core/fn
-  metabase.integrations.ldap/with-ldap-connection                                      clojure.core/fn
-  metabase.models.collection-test/with-collection-in-location                          clojure.core/let
-  metabase.models.json-migration/def-json-migration                                    clj-kondo.lint-as/def-catch-all
-  metabase.models.setting.multi-setting/define-multi-setting                           clojure.core/def
-  metabase.models.setting/defsetting                                                   clj-kondo.lint-as/def-catch-all
-  metabase.public-settings.premium-features/defenterprise-schema                       clj-kondo.lint-as/def-catch-all
-  metabase.public-settings.premium-features/define-premium-feature                     clojure.core/def
-  metabase.pulse-test/with-pulse-for-card                                              clojure.core/let
-  metabase.query-processor-test.pipeline-queries-test/pmbql-query                      clojure.core/->
-  metabase.query-processor-test.pipeline-queries-test/run-pmbql-query                  clojure.core/->
-  metabase.query-processor.error-type/deferror                                         clojure.core/def
-  metabase.query-processor.middleware.cache.impl/with-reducible-deserialized-results   clojure.core/let
-  metabase.query-processor.middleware.process-userland-query-test/with-query-execution clojure.core/let
-  metabase.query-processor.setup/with-qp-setup                                         clojure.core/let
-  metabase.shared.util.namespaces/import-fns                                           potemkin/import-vars
-  metabase.sync.util/sum-for                                                           clojure.core/for
-  metabase.sync.util/with-emoji-progress-bar                                           clojure.core/let
-  metabase.test.data.interface/defdataset                                              clojure.core/def
-  metabase.test.data.interface/defdataset-edn                                          clojure.core/def
-  metabase.test/defdataset                                                             clojure.core/def
-  metabase.test/let-url                                                                clojure.core/let
-  metabase.test/with-actions                                                           clojure.core/let
-  metabase.test/with-grouper-batches!                                                  clojure.core/fn
-  metabase.test/with-open-channels                                                     clojure.core/let
-  metabase.test/with-single-admin-user                                                 clojure.core/fn
-  metabase.test/with-temp-dir                                                          clojure.core/let
-  metabase.test/with-temp-empty-app-db                                                 clojure.core/let
-  metabase.test/with-temp-file                                                         clojure.core/let
-  metabase.test/with-user-in-groups                                                    clojure.core/let
-  metabase.upload-test/with-upload-table!                                              clojure.core/let
-  metabase.util.files/with-open-path-to-resource                                       clojure.core/let
-  metabase.util.malli.defn/defn                                                        schema.core/defn
-  metabase.util.malli.defn/defn-                                                       schema.core/defn
-  metabase.util.malli.fn/fn                                                            schema.core/fn
-  metabase.util.malli/defmethod                                                        schema.core/defmethod
-  metabase.util.malli/defn                                                             schema.core/defn
-  metabase.util.malli/defn-                                                            schema.core/defn
-  metabase.util.malli/fn                                                               schema.core/fn
-  metabase.util.ssh/with-ssh-tunnel                                                    clojure.core/let
-  metabase.xrays.domain-entities.malli/defn                                            schema.core/defn
-  monger.operators/defoperator                                                         clojure.core/def
-  potemkin.types/defprotocol+                                                          clojure.core/defprotocol
-  potemkin.types/defrecord+                                                            clojure.core/defrecord
-  potemkin.types/deftype+                                                              clojure.core/deftype
-  potemkin/defprotocol+                                                                clojure.core/defprotocol
-  potemkin/defrecord+                                                                  clojure.core/defrecord
-  potemkin/deftype+                                                                    clojure.core/deftype
-  toucan.db/with-call-counting                                                         clojure.core/fn
-  toucan2.core/with-call-count                                                         clojure.core/fn}
+ {cljs.cache/defcache                                                                   clojure.core/deftype
+  clojure.core.cache/defcache                                                           clojure.core/deftype
+  clojure.core.logic/defne                                                              clj-kondo.lint-as/def-catch-all
+  clojure.test.check.clojure-test/defspec                                               clojure.test/deftest
+  clojurewerkz.quartzite.jobs/defjob                                                    clojure.core/defn
+  metabase-enterprise.serialization.test-util/with-dbs                                  clojure.core/fn
+  metabase-enterprise.serialization.test-util/with-random-dump-dir                      clojure.core/let
+  metabase.actions.test-util/with-actions                                               clojure.core/let
+  metabase.api.common/defroutes                                                         clojure.core/def
+  metabase.api.common/let-404                                                           clojure.core/let
+  metabase.api.search-test/do-test-users                                                clojure.core/let
+  metabase.async.api-response-test/with-response                                        clojure.core/let
+  metabase.dashboard-subscription-test/with-dashboard-sub-for-card                      clojure.core/let
+  metabase.db.custom-migrations/define-migration                                        clj-kondo.lint-as/def-catch-all
+  metabase.db.custom-migrations/define-reversible-migration                             clj-kondo.lint-as/def-catch-all
+  metabase.db.data-migrations/defmigration                                              clojure.core/def
+  metabase.db.liquibase/with-liquibase                                                  clojure.core/let
+  metabase.db.schema-migrations-test.impl/with-temp-empty-app-db                        clojure.core/let
+  metabase.driver.mongo.connection/with-mongo-client                                    clojure.core/let
+  metabase.driver.mongo.connection/with-mongo-database                                  clojure.core/let
+  metabase.driver.mongo.query-processor/mongo-let                                       clojure.core/let
+  metabase.driver.sql-jdbc.actions/with-jdbc-transaction                                clojure.core/let
+  metabase.driver.sql-jdbc.connection/with-connection-spec-for-testing-connection       clojure.core/let
+  metabase.driver.sql-jdbc.execute.diagnostic/capturing-diagnostic-info                 clojure.core/fn
+  metabase.integrations.ldap/with-ldap-connection                                       clojure.core/fn
+  metabase.models.collection-test/with-collection-in-location                           clojure.core/let
+  metabase.models.json-migration/def-json-migration                                     clj-kondo.lint-as/def-catch-all
+  metabase.models.setting.multi-setting/define-multi-setting                            clojure.core/def
+  metabase.models.setting/defsetting                                                    clj-kondo.lint-as/def-catch-all
+  metabase.public-settings.premium-features/defenterprise-schema                        clj-kondo.lint-as/def-catch-all
+  metabase.public-settings.premium-features/define-premium-feature                      clojure.core/def
+  metabase.pulse-test/with-pulse-for-card                                               clojure.core/let
+  metabase.query-processor-test.pipeline-queries-test/pmbql-query                       clojure.core/->
+  metabase.query-processor-test.pipeline-queries-test/run-pmbql-query                   clojure.core/->
+  metabase.query-processor.error-type/deferror                                          clojure.core/def
+  metabase.query-processor.middleware.cache.impl/with-reducible-deserialized-results    clojure.core/let
+  metabase.query-processor.middleware.process-userland-query-test/with-query-execution! clojure.core/let
+  metabase.query-processor.setup/with-qp-setup                                          clojure.core/let
+  metabase.shared.util.namespaces/import-fns                                            potemkin/import-vars
+  metabase.sync.util/sum-for                                                            clojure.core/for
+  metabase.sync.util/with-emoji-progress-bar                                            clojure.core/let
+  metabase.test.data.interface/defdataset                                               clojure.core/def
+  metabase.test.data.interface/defdataset-edn                                           clojure.core/def
+  metabase.test/defdataset                                                              clojure.core/def
+  metabase.test/let-url                                                                 clojure.core/let
+  metabase.test/with-actions                                                            clojure.core/let
+  metabase.test/with-grouper-batches!                                                   clojure.core/fn
+  metabase.test/with-open-channels                                                      clojure.core/let
+  metabase.test/with-single-admin-user                                                  clojure.core/fn
+  metabase.test/with-temp-dir                                                           clojure.core/let
+  metabase.test/with-temp-empty-app-db                                                  clojure.core/let
+  metabase.test/with-temp-file                                                          clojure.core/let
+  metabase.test/with-user-in-groups                                                     clojure.core/let
+  metabase.upload-test/with-upload-table!                                               clojure.core/let
+  metabase.util.files/with-open-path-to-resource                                        clojure.core/let
+  metabase.util.malli.defn/defn                                                         schema.core/defn
+  metabase.util.malli.defn/defn-                                                        schema.core/defn
+  metabase.util.malli.fn/fn                                                             schema.core/fn
+  metabase.util.malli/defmethod                                                         schema.core/defmethod
+  metabase.util.malli/defn                                                              schema.core/defn
+  metabase.util.malli/defn-                                                             schema.core/defn
+  metabase.util.malli/fn                                                                schema.core/fn
+  metabase.util.ssh/with-ssh-tunnel                                                     clojure.core/let
+  metabase.xrays.domain-entities.malli/defn                                             schema.core/defn
+  monger.operators/defoperator                                                          clojure.core/def
+  potemkin.types/defprotocol+                                                           clojure.core/defprotocol
+  potemkin.types/defrecord+                                                             clojure.core/defrecord
+  potemkin.types/deftype+                                                               clojure.core/deftype
+  potemkin/defprotocol+                                                                 clojure.core/defprotocol
+  potemkin/defrecord+                                                                   clojure.core/defrecord
+  potemkin/deftype+                                                                     clojure.core/deftype
+  toucan.db/with-call-counting                                                          clojure.core/fn
+  toucan2.core/with-call-count                                                          clojure.core/fn}
 
  :hooks
  {:analyze-call
@@ -822,25 +822,25 @@
    metabase-enterprise.audit-app.pages-test/with-temp-objects                                                                hooks.common/with-one-binding
    metabase-enterprise.cache.config-test/with-temp-persist-models                                                            hooks.common/with-seven-bindings
    metabase-enterprise.serialization.test-util/with-temp-dpc                                                                 hooks.toucan2.tools.with-temp/with-temp
-   metabase.analytics.prometheus-test/with-prometheus-system                                                                 hooks.common/with-two-bindings
-   metabase.api.alert-test/with-alert-in-collection                                                                          hooks.common/with-four-bindings
-   metabase.api.automagic-dashboards-test/with-indexed-model                                                                 hooks.metabase.api.automagic-dashboards-test/with-indexed-model
+   metabase.analytics.prometheus-test/with-prometheus-system!                                                                hooks.common/with-two-bindings
+   metabase.api.alert-test/with-alert-in-collection!                                                                         hooks.common/with-four-bindings
+   metabase.api.automagic-dashboards-test/with-indexed-model!                                                                hooks.metabase.api.automagic-dashboards-test/with-indexed-model!
    metabase.api.card-test/with-card-param-values-fixtures                                                                    hooks.common/let-one-with-optional-value
-   metabase.api.card-test/with-persistence-setup                                                                             hooks.common/with-one-top-level-binding
+   metabase.api.card-test/with-persistence-setup!                                                                            hooks.common/with-one-top-level-binding
    metabase.api.card-test/with-temp-native-card!                                                                             hooks.common/with-two-bindings
    metabase.api.card-test/with-temp-native-card-with-params!                                                                 hooks.common/with-two-bindings
-   metabase.api.collection-test/with-french-user-and-personal-collection                                                     hooks.common/with-two-top-level-bindings
+   metabase.api.collection-test/with-french-user-and-personal-collection!                                                    hooks.common/with-two-top-level-bindings
    metabase.api.common/defendpoint                                                                                           hooks.metabase.api.common/defendpoint
    metabase.api.common/defendpoint-async                                                                                     hooks.metabase.api.common/defendpoint
    metabase.api.common/defendpoint-async-schema                                                                              hooks.metabase.api.common/defendpoint
    metabase.api.dashboard-test/with-chain-filter-fixtures                                                                    hooks.common/let-one-with-optional-value
    metabase.api.dashboard-test/with-simple-dashboard-with-tabs                                                               hooks.common/with-one-binding
    metabase.api.embed-test/do-response-formats                                                                               hooks.common/with-two-bindings
-   metabase.api.embed-test/with-chain-filter-fixtures                                                                        hooks.common/let-one-with-optional-value
+   metabase.api.embed-test/with-chain-filter-fixtures!                                                                       hooks.common/let-one-with-optional-value
    metabase.api.embed-test/with-temp-card                                                                                    hooks.common/let-one-with-optional-value
    metabase.api.embed-test/with-temp-dashcard                                                                                hooks.common/let-one-with-optional-value
-   metabase.api.persist-test/with-setup                                                                                      hooks.common/with-one-top-level-binding
-   metabase.api.public-test/with-required-param-card                                                                         hooks.common/with-one-binding
+   metabase.api.persist-test/with-setup!                                                                                     hooks.common/with-one-top-level-binding
+   metabase.api.public-test/with-required-param-card!                                                                        hooks.common/with-one-binding
    metabase.api.public-test/with-temp-public-card                                                                            hooks.common/let-one-with-optional-value
    metabase.api.public-test/with-temp-public-dashboard                                                                       hooks.common/let-one-with-optional-value
    metabase.api.public-test/with-temp-public-dashboard-and-card                                                              hooks.common/with-three-bindings
@@ -859,21 +859,21 @@
    metabase.lib.test-util.macros/$ids                                                                                        hooks.metabase.test.data/$ids
    metabase.lib.test-util.macros/mbql-query                                                                                  hooks.metabase.test.data/mbql-query
    metabase.lib.test-util.macros/with-testing-against-standard-queries                                                       hooks.metabase.lib.test-util.macros/with-testing-against-standard-queries
-   metabase.models.collection-test/with-collection-hierarchy                                                                 hooks.common/let-one-with-optional-value
+   metabase.models.collection-test/with-collection-hierarchy!                                                                hooks.common/let-one-with-optional-value
    metabase.models.collection-test/with-personal-and-impersonal-collections                                                  hooks.common/with-two-bindings
    metabase.models.dashboard-tab-test/with-dashtab-in-personal-collection                                                    hooks.common/with-one-top-level-binding
-   metabase.models.dashboard-test/with-dash-in-collection                                                                    hooks.common/with-three-bindings
+   metabase.models.dashboard-test/with-dash-in-collection!                                                                   hooks.common/with-three-bindings
    metabase.models.interface/define-batched-hydration-method                                                                 hooks.metabase.models.interface/define-hydration-method
    metabase.models.interface/define-simple-hydration-method                                                                  hooks.metabase.models.interface/define-hydration-method
-   metabase.models.pulse-test/with-dashboard-subscription-in-collection                                                      hooks.common/with-four-bindings
-   metabase.models.pulse-test/with-pulse-in-collection                                                                       hooks.common/with-four-bindings
+   metabase.models.pulse-test/with-dashboard-subscription-in-collection!                                                     hooks.common/with-four-bindings
+   metabase.models.pulse-test/with-pulse-in-collection!                                                                      hooks.common/with-four-bindings
    metabase.models.setting.multi-setting/define-multi-setting                                                                hooks.metabase.models.setting/define-multi-setting
    metabase.models.setting/defsetting                                                                                        hooks.metabase.models.setting/defsetting
    metabase.public-settings.premium-features/defenterprise                                                                   hooks.metabase.public-settings.premium-features/defenterprise
    metabase.pulse.test-util/checkins-query-card                                                                              hooks.metabase.test.data/$ids
    metabase.query-processor-test.expressions-test/calculate-bird-scarcity                                                    hooks.metabase.query-processor-test.expressions-test/calculate-bird-scarcity
    metabase.query-processor-test.filter-test/count-with-filter-clause                                                        hooks.metabase.test.data/$ids
-   metabase.query-processor.middleware.cache-test/with-mock-cache                                                            hooks.common/with-two-bindings
+   metabase.query-processor.middleware.cache-test/with-mock-cache!                                                           hooks.common/with-two-bindings
    metabase.sample-data-test/with-temp-sample-database-db                                                                    hooks.common/with-one-binding
    metabase.stale-test/with-stale-items                                                                                      hooks.toucan2.tools.with-temp/with-temp
    metabase.test.data.users/with-group                                                                                       hooks.common/let-one-with-optional-value
@@ -920,43 +920,43 @@
    metabase.util/format-color                                                                                                hooks.metabase.util/format-color}
 
   :macroexpand
-  {clojurewerkz.quartzite.jobs/build                                            macros.quartz/build-job
-   clojurewerkz.quartzite.schedule.cron/schedule                                macros.quartz/schedule
-   clojurewerkz.quartzite.schedule.simple/schedule                              macros.quartz/simple-schedule
-   clojurewerkz.quartzite.triggers/build                                        macros.quartz/build-trigger
-   metabase-enterprise.sandbox.test-util/with-gtaps!                            macros.metabase-enterprise.sandbox.test-util/with-gtaps!
-   metabase-enterprise.sandbox.test-util/with-gtaps-for-user!                   macros.metabase-enterprise.sandbox.test-util/with-gtaps!
-   metabase-enterprise.serialization.test-util/with-world                       macros.metabase-enterprise.serialization.test-util/with-world
-   metabase-enterprise.test/with-gtaps!                                         macros.metabase-enterprise.sandbox.test-util/with-gtaps!
-   metabase-enterprise.test/with-gtaps-for-user!                                macros.metabase-enterprise.sandbox.test-util/with-gtaps!
-   metabase-enterprise.advanced-permissions.api.util-test/with-impersonations!  macros.metabase-enterprise.advanced-permissions.api.util-test/with-impersonations!
-   metabase-enterprise.query-reference-validation.api-test/with-test-setup      macros.metabase-enterprise.query-reference-validation.api-test/with-test-setup
-   metabase.api.card-test/with-ordered-items                                    macros.metabase.api.card-test/with-ordered-items
-   metabase.api.collection-test/with-collection-hierarchy                       macros.metabase.api.collection-test/with-collection-hierarchy
-   metabase.api.collection-test/with-some-children-of-collection                macros.metabase.api.collection-test/with-some-children-of-collection
-   metabase.api.common/define-routes                                            macros.metabase.api.common/define-routes
-   metabase.api.embed-test/with-embedding-enabled-and-temp-card-referencing     macros.metabase.api.embed-test/with-embedding-enabled-and-temp-card-referencing
-   metabase.api.embed-test/with-embedding-enabled-and-temp-dashcard-referencing macros.metabase.api.embed-test/with-embedding-enabled-and-temp-dashcard-referencing
-   metabase.api.public-test/with-sharing-enabled-and-temp-card-referencing      macros.metabase.api.public-test/with-sharing-enabled-and-temp-card-referencing
-   metabase.api.public-test/with-sharing-enabled-and-temp-dashcard-referencing  macros.metabase.api.public-test/with-sharing-enabled-and-temp-dashcard-referencing
-   metabase.lib.filter/deffilter                                                macros.metabase.lib.filter/deffilter
-   metabase.lib.common/defop                                                    macros.metabase.lib.common/defop
-   metabase.models.params.chain-filter-test/chain-filter                        macros.metabase.models.params.chain-filter-test/chain-filter
-   metabase.models.params.chain-filter-test/chain-filter-search                 macros.metabase.models.params.chain-filter-test/chain-filter
-   metabase.models.query-analysis-test/with-test-setup                          macros.metabase.models.query-analysis-test/with-test-setup
-   metabase.models.user-test/with-groups                                        macros.metabase.models.user-test/with-groups
-   metabase.query-processor.streaming/streaming-response                        macros.metabase.query-processor.streaming/streaming-response
-   metabase.related-test/with-world                                             macros.metabase.related-test/with-world
-   metabase.shared.util.namespaces/import-fn                                    macros.metabase.shared.util.namespaces/import-fn
-   metabase.task.setup.query-analysis-setup/with-test-setup!                    macros.metabase.task.setup.query-analysis-setup/with-test-setup!
-   metabase.test.data.users/with-group-for-user                                 macros.metabase.test.data.users/with-group-for-user
-   metabase.test.util/with-temp-env-var-value!                                  macros.metabase.test.util/with-temp-env-var-value!
-   metabase.test.util/with-temporary-raw-setting-values                         macros.metabase.test.util/with-temporary-raw-setting-values
-   metabase.test/with-group-for-user                                            macros.metabase.test.data.users/with-group-for-user
-   metabase.test/with-persistence-enabled                                       macros.metabase.test.persistence/with-persistence-enabled
-   metabase.test/with-temp-env-var-value!                                       macros.metabase.test.util/with-temp-env-var-value!
-   metabase.test/with-temporary-raw-setting-values                              macros.metabase.test.util/with-temporary-raw-setting-values
-   metabase.xrays.domain-entities.malli/define-getters-and-setters              macros.metabase.xrays.domain-entities.malli/define-getters-and-setters}}
+  {clojurewerkz.quartzite.jobs/build                                             macros.quartz/build-job
+   clojurewerkz.quartzite.schedule.cron/schedule                                 macros.quartz/schedule
+   clojurewerkz.quartzite.schedule.simple/schedule                               macros.quartz/simple-schedule
+   clojurewerkz.quartzite.triggers/build                                         macros.quartz/build-trigger
+   metabase-enterprise.sandbox.test-util/with-gtaps!                             macros.metabase-enterprise.sandbox.test-util/with-gtaps!
+   metabase-enterprise.sandbox.test-util/with-gtaps-for-user!                    macros.metabase-enterprise.sandbox.test-util/with-gtaps!
+   metabase-enterprise.serialization.test-util/with-world                        macros.metabase-enterprise.serialization.test-util/with-world
+   metabase-enterprise.test/with-gtaps!                                          macros.metabase-enterprise.sandbox.test-util/with-gtaps!
+   metabase-enterprise.test/with-gtaps-for-user!                                 macros.metabase-enterprise.sandbox.test-util/with-gtaps!
+   metabase-enterprise.advanced-permissions.api.util-test/with-impersonations!   macros.metabase-enterprise.advanced-permissions.api.util-test/with-impersonations!
+   metabase-enterprise.query-reference-validation.api-test/with-test-setup!      macros.metabase-enterprise.query-reference-validation.api-test/with-test-setup!
+   metabase.api.card-test/with-ordered-items                                     macros.metabase.api.card-test/with-ordered-items
+   metabase.api.collection-test/with-collection-hierarchy!                       macros.metabase.api.collection-test/with-collection-hierarchy!
+   metabase.api.collection-test/with-some-children-of-collection!                macros.metabase.api.collection-test/with-some-children-of-collection!
+   metabase.api.common/define-routes                                             macros.metabase.api.common/define-routes
+   metabase.api.embed-test/with-embedding-enabled-and-temp-card-referencing!     macros.metabase.api.embed-test/with-embedding-enabled-and-temp-card-referencing!
+   metabase.api.embed-test/with-embedding-enabled-and-temp-dashcard-referencing! macros.metabase.api.embed-test/with-embedding-enabled-and-temp-dashcard-referencing!
+   metabase.api.public-test/with-sharing-enabled-and-temp-card-referencing!      macros.metabase.api.public-test/with-sharing-enabled-and-temp-card-referencing!
+   metabase.api.public-test/with-sharing-enabled-and-temp-dashcard-referencing!  macros.metabase.api.public-test/with-sharing-enabled-and-temp-dashcard-referencing!
+   metabase.lib.filter/deffilter                                                 macros.metabase.lib.filter/deffilter
+   metabase.lib.common/defop                                                     macros.metabase.lib.common/defop
+   metabase.models.params.chain-filter-test/chain-filter                         macros.metabase.models.params.chain-filter-test/chain-filter
+   metabase.models.params.chain-filter-test/chain-filter-search                  macros.metabase.models.params.chain-filter-test/chain-filter
+   metabase.models.query-analysis-test/with-test-setup                           macros.metabase.models.query-analysis-test/with-test-setup
+   metabase.models.user-test/with-groups                                         macros.metabase.models.user-test/with-groups
+   metabase.query-processor.streaming/streaming-response                         macros.metabase.query-processor.streaming/streaming-response
+   metabase.related-test/with-world                                              macros.metabase.related-test/with-world
+   metabase.shared.util.namespaces/import-fn                                     macros.metabase.shared.util.namespaces/import-fn
+   metabase.task.setup.query-analysis-setup/with-test-setup!                     macros.metabase.task.setup.query-analysis-setup/with-test-setup!
+   metabase.test.data.users/with-group-for-user                                  macros.metabase.test.data.users/with-group-for-user
+   metabase.test.util/with-temp-env-var-value!                                   macros.metabase.test.util/with-temp-env-var-value!
+   metabase.test.util/with-temporary-raw-setting-values                          macros.metabase.test.util/with-temporary-raw-setting-values
+   metabase.test/with-group-for-user                                             macros.metabase.test.data.users/with-group-for-user
+   metabase.test/with-persistence-enabled!                                       macros.metabase.test.persistence/with-persistence-enabled!
+   metabase.test/with-temp-env-var-value!                                        macros.metabase.test.util/with-temp-env-var-value!
+   metabase.test/with-temporary-raw-setting-values                               macros.metabase.test.util/with-temporary-raw-setting-values
+   metabase.xrays.domain-entities.malli/define-getters-and-setters               macros.metabase.xrays.domain-entities.malli/define-getters-and-setters}}
 
  :config-in-comment
  {:linters {:unresolved-symbol {:level :off}}}
diff --git a/.clj-kondo/macros/metabase/api/collection_test.clj b/.clj-kondo/macros/metabase/api/collection_test.clj
index 45f5bd29cf4e38357085839f2c1be870e98c85f3..27668bbb14c92a94d43277d4d86195c47f878934 100644
--- a/.clj-kondo/macros/metabase/api/collection_test.clj
+++ b/.clj-kondo/macros/metabase/api/collection_test.clj
@@ -1,7 +1,7 @@
 (ns macros.metabase.api.collection-test
   (:require [macros.common]))
 
-(defmacro with-collection-hierarchy [bindings & body]
+(defmacro with-collection-hierarchy! [bindings & body]
   `(let [~(macros.common/ignore-unused 'a) nil
          ~(macros.common/ignore-unused 'b) nil
          ~(macros.common/ignore-unused 'c) nil
@@ -12,6 +12,6 @@
      ~bindings
      ~@body))
 
-(defmacro with-some-children-of-collection [collection-or-id-or-nil & body]
+(defmacro with-some-children-of-collection! [collection-or-id-or-nil & body]
   `(let [~(macros.common/ignore-unused '&ids) ~collection-or-id-or-nil]
      ~@body))
diff --git a/.clj-kondo/macros/metabase/api/embed_test.clj b/.clj-kondo/macros/metabase/api/embed_test.clj
index c49770b6c2fd13efa69771af406e928d354bab99..da7a0bc02fae73ccc9bb18f7882b67601ab5afaa 100644
--- a/.clj-kondo/macros/metabase/api/embed_test.clj
+++ b/.clj-kondo/macros/metabase/api/embed_test.clj
@@ -1,11 +1,11 @@
 (ns macros.metabase.api.embed-test)
 
-(defmacro with-embedding-enabled-and-temp-card-referencing
+(defmacro with-embedding-enabled-and-temp-card-referencing!
   [table-kw field-kw [card-binding] & body]
   `(let [~card-binding [~table-kw ~field-kw]]
      ~@body))
 
-(defmacro with-embedding-enabled-and-temp-dashcard-referencing
+(defmacro with-embedding-enabled-and-temp-dashcard-referencing!
   [table-kw field-kw [dash-binding card-binding dashcard-binding] & body]
   `(let [~dash-binding             [~table-kw ~field-kw]
          ~(or card-binding '_)     nil
diff --git a/.clj-kondo/macros/metabase/api/public_test.clj b/.clj-kondo/macros/metabase/api/public_test.clj
index 043f87bb44f4dcd9d096f2901e2703b636abae96..dddab913af14d5265452b836fd914678a2eb8ef1 100644
--- a/.clj-kondo/macros/metabase/api/public_test.clj
+++ b/.clj-kondo/macros/metabase/api/public_test.clj
@@ -1,11 +1,11 @@
 (ns macros.metabase.api.public-test)
 
-(defmacro with-sharing-enabled-and-temp-card-referencing
+(defmacro with-sharing-enabled-and-temp-card-referencing!
   [table-kw field-kw [card-binding] & body]
   `(let [~card-binding [~table-kw ~field-kw]]
      ~@body))
 
-(defmacro with-sharing-enabled-and-temp-dashcard-referencing
+(defmacro with-sharing-enabled-and-temp-dashcard-referencing!
   [table-kw field-kw [dash-binding card-binding dashcard-binding] & body]
   `(let [~dash-binding             [~table-kw ~field-kw]
          ~(or card-binding '_)     nil
diff --git a/.clj-kondo/macros/metabase/test/persistence.clj b/.clj-kondo/macros/metabase/test/persistence.clj
index 30d72cb0c0be115945862f15354166209df1d9f6..c240211776210d4f62af707ab27a9f7553a85819 100644
--- a/.clj-kondo/macros/metabase/test/persistence.clj
+++ b/.clj-kondo/macros/metabase/test/persistence.clj
@@ -1,5 +1,5 @@
 (ns macros.metabase.test.persistence)
 
-(defmacro with-persistence-enabled [[persist-fn-sym] & body]
+(defmacro with-persistence-enabled! [[persist-fn-sym] & body]
   `(clojure.core/let [~persist-fn-sym (fn [])]
      ~@body))
diff --git a/.clj-kondo/macros/metabase_enterprise/query_reference_validation/api_test.clj b/.clj-kondo/macros/metabase_enterprise/query_reference_validation/api_test.clj
index 893091db106389dcad437e4b36fe9e479f259d9f..8a706ed80f0389b198d814bd5c4e92927711ef1f 100644
--- a/.clj-kondo/macros/metabase_enterprise/query_reference_validation/api_test.clj
+++ b/.clj-kondo/macros/metabase_enterprise/query_reference_validation/api_test.clj
@@ -1,7 +1,7 @@
 (ns macros.metabase-enterprise.query-reference-validation.api-test
   (:require [macros.common]))
 
-(defmacro with-test-setup [& body]
+(defmacro with-test-setup! [& body]
   `(let [~(macros.common/ignore-unused 'card-1) 1
          ~(macros.common/ignore-unused 'card-2) 2
          ~(macros.common/ignore-unused 'card-3) 3
diff --git a/.clj-kondo/src/hooks/clojure/core.clj b/.clj-kondo/src/hooks/clojure/core.clj
index d8fe34f5fbc5d3a844700b33062e5a72927f34d4..37149622891f8a3a1c4f1b4c269d51c95d584445 100644
--- a/.clj-kondo/src/hooks/clojure/core.clj
+++ b/.clj-kondo/src/hooks/clojure/core.clj
@@ -141,7 +141,7 @@
   (str/ends-with? s "!"))
 
 (defn- non-thread-safe-form-should-end-with-exclamation*
-  [{[defn-or-defmacro form-name] :children, :as node}]
+  [{[defn-or-defmacro form-name] :children, :as node} config]
   (when-not (and (:string-value form-name)
                  (end-with-exclamation? (:string-value form-name)))
     (letfn [(walk [f form]
@@ -151,9 +151,10 @@
       (walk (fn [form]
               (when-let [qualified-symbol (hooks.common/node->qualified-symbol form)]
                 (when (and (not (contains? symbols-allowed-in-fns-not-ending-in-an-exclamation-point qualified-symbol))
-                           (end-with-exclamation? qualified-symbol))
+                           (or (end-with-exclamation? qualified-symbol)
+                               (contains? (get-in config [:linters :metabase/validate-deftest :parallel/unsafe]) qualified-symbol)))
                   (hooks/reg-finding! (assoc (meta form-name)
-                                             :message (format "The name of this %s should end with `!` because it contains calls to non thread safe form `%s`."
+                                             :message (format "The name of this %s should end with `!` because it contains calls to non thread safe form `%s`. [:metabase/test-helpers-use-non-thread-safe-functions]"
                                                               (:string-value defn-or-defmacro) qualified-symbol)
                                              :type :metabase/test-helpers-use-non-thread-safe-functions)))))
             node))
@@ -164,10 +165,10 @@
   A function or a macro can be defined as 'not thread safe' when their funciton name ends with a `!`.
 
   Only used in tests to identify thread-safe/non-thread-safe test helpers. See #37126"
-  [{:keys [node cljc lang]}]
+  [{:keys [node cljc lang config]}]
   (when (or (not cljc)
             (= lang :clj))
-    (non-thread-safe-form-should-end-with-exclamation* node))
+    (non-thread-safe-form-should-end-with-exclamation* node config))
   {:node node})
 
 (comment
diff --git a/.clj-kondo/src/hooks/clojure/test.clj b/.clj-kondo/src/hooks/clojure/test.clj
index 8585dd8caf7525a1d1b1693b8fef9a03e05671c2..2cc51e1bba2e1617f4e3e63b48fbccd05f0e38d0 100644
--- a/.clj-kondo/src/hooks/clojure/test.clj
+++ b/.clj-kondo/src/hooks/clojure/test.clj
@@ -12,10 +12,10 @@
           (f [form]
             (when-let [qualified-symbol (hooks.common/node->qualified-symbol form)]
               (cond
-                (contains? (:disallowed config) qualified-symbol)
+                (contains? (:parallel/unsafe config) qualified-symbol)
                 (error! form (format "%s is not allowed inside a ^:parallel test or test fixture [:metabase/validate-deftest]" qualified-symbol))
 
-                (and (not (contains? (:allowed config) qualified-symbol))
+                (and (not (contains? (:parallel/safe config) qualified-symbol))
                      (str/ends-with? (name qualified-symbol) "!"))
                 (error! form (format "destructive functions like %s are not allowed inside a ^:parallel test or test fixture. If this should be allowed, add it to the whitelist in the Kondo config file [:metabase/validate-deftest]"
                                      qualified-symbol)))))
diff --git a/.clj-kondo/src/hooks/metabase/api/automagic_dashboards_test.clj b/.clj-kondo/src/hooks/metabase/api/automagic_dashboards_test.clj
index 5fe321c6937e3de26ec6fc757710ff1962f81cd8..262db63225f7552643bc8ef37d19dda0b824dc11 100644
--- a/.clj-kondo/src/hooks/metabase/api/automagic_dashboards_test.clj
+++ b/.clj-kondo/src/hooks/metabase/api/automagic_dashboards_test.clj
@@ -4,8 +4,8 @@
 (comment
 
   (def input (hooks/parse-string
-              "(with-indexed-model [{:keys [model model-index model-index-value]}
-                                    {:query :some-query}]
+              "(with-indexed-model! [{:keys [model model-index model-index-value]}
+                                     {:query :some-query}]
                   :foo :bar :body)"))
 
   (println (hooks/sexpr input))
@@ -13,12 +13,12 @@
   (let [f (load-file ".clj-kondo/hooks/metabase/api/automagic_dashboards_test.clj")]
     (f {:node input})))
 
-(defn with-indexed-model
+(defn with-indexed-model!
   [{node :node}]
   (let [[_macro-call binding-and-query-info & body] (:children node)
         [binding query-info] (:children binding-and-query-info)
         node* (hooks/list-node
-               [(hooks/token-node 'do-with-testing-model)
+               [(hooks/token-node 'do-with-indexed-model!)
                 query-info
                 (hooks/list-node
                  (list* (hooks/token-node 'fn)
diff --git a/.clj-kondo/src/hooks/metabase/api/common.clj b/.clj-kondo/src/hooks/metabase/api/common.clj
index 83e46a7c3fc6d8a8c2a74292fc6babc6f0902926..622ff3c8c2d66d474914741a4409e00c671f8334 100644
--- a/.clj-kondo/src/hooks/metabase/api/common.clj
+++ b/.clj-kondo/src/hooks/metabase/api/common.clj
@@ -15,16 +15,17 @@
   [arg]
   (letfn [(update-defendpoint [node]
             (let [[_defendpoint method route & body] (:children node)]
-              (api/list-node
-               (list
-                (api/token-node 'do)
-                (api/token-node (symbol "compojure.core" (str (api/sexpr method))))
-                (-> (api/list-node
-                     (list*
-                      (api/token-node 'clojure.core/defn)
-                      (api/token-node (route-fn-name (api/sexpr method) (api/sexpr route)))
-                      body))
-                    (with-meta (meta node)))))))]
+              (-> (api/list-node
+                   (list
+                    (api/token-node 'do)
+                    (api/token-node (symbol "compojure.core" (str (api/sexpr method))))
+                    (-> (api/list-node
+                         (list*
+                          (api/token-node 'clojure.core/defn)
+                          (api/token-node (route-fn-name (api/sexpr method) (api/sexpr route)))
+                          body))
+                        (with-meta (meta node)))))
+                  (with-meta {:clj-kondo/ignore [:clojure-lsp/unused-public-var]}))))]
     (update arg :node update-defendpoint)))
 
 (comment
diff --git a/enterprise/backend/test/metabase_enterprise/advanced_permissions/api/util_test.clj b/enterprise/backend/test/metabase_enterprise/advanced_permissions/api/util_test.clj
index 778439a56f476f712c34afcbf7d50bee38d4b5dc..44bfd8ab16f2e82b9acd719475175aadc491f724 100644
--- a/enterprise/backend/test/metabase_enterprise/advanced_permissions/api/util_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/advanced_permissions/api/util_test.clj
@@ -35,7 +35,7 @@
                 (data-perms/set-database-permission! group (data/id) :perms/create-queries :query-builder-and-native)
                 (let [{:keys [impersonations attributes]} args]
                   ;; set user login_attributes
-                  (met/with-user-attributes test-user-name-or-user-id attributes
+                  (met/with-user-attributes! test-user-name-or-user-id attributes
                     (do-with-conn-impersonation-defs group impersonations
                       (fn []
                         ;; bind user as current user, then run f
diff --git a/enterprise/backend/test/metabase_enterprise/airgap_test.clj b/enterprise/backend/test/metabase_enterprise/airgap_test.clj
index 58db1cede52a361a08f87e2babe3e3160ab2bbf8..0f8ba9c33a59f2d68c7adaea79cdba185181325f 100644
--- a/enterprise/backend/test/metabase_enterprise/airgap_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/airgap_test.clj
@@ -5,7 +5,7 @@
                [metabase-enterprise.airgap :as airgap]
                [metabase.public-settings.premium-features :as premium-features]))
 
-(defn- test-fake-features [& {:keys [token-fn pubk-fn]}]
+(defn- test-fake-features! [& {:keys [token-fn pubk-fn]}]
   (with-redefs
     ;; due to the way premium embedding token is implemented, we need to provide a token and a public key,
     ;; so we cannot set this with `mt/with-temporary-setting-values`.
@@ -19,26 +19,26 @@
 
 (deftest ag-token-decryption-test
   ;; Checks for a specific feature encoded into the fake token:
-  (is (contains? (set (map hash (:features (test-fake-features)))) 2117420126)))
+  (is (contains? (set (map hash (:features (test-fake-features!)))) 2117420126)))
 
 (deftest ag-token-valid-now-test
   (testing "Token time is valid"
     ;; the test token is valid until 2054
-    (is (true? (#'airgap/valid-now? (test-fake-features))))))
+    (is (true? (#'airgap/valid-now? (test-fake-features!))))))
 
 (deftest ag-invalid-token-test
   (testing "Invalid token format"
     (is (thrown-with-msg? Exception
          #"Message seems corrupt or manipulated."
-         (test-fake-features :token-fn (fn [token] (str token "x"))))))
+         (test-fake-features! :token-fn (fn [token] (str token "x"))))))
   (testing "Invalid public key format"
     (is (thrown-with-msg? Exception
          #"unable to convert key pair: encoded key spec not recognized: invalid info structure in RSA public key"
-         (test-fake-features
+         (test-fake-features!
           :pubk-fn (fn [_] (io/reader (io/resource "broken_pubkey.pem"))))))))
 
 (deftest ag-missing-pubkey-test
   (testing "Missing public key"
     (is (thrown-with-msg? Exception
          #"No public key available for airgap token"
-         (test-fake-features :pubk-fn (fn [_] nil))))))
+         (test-fake-features! :pubk-fn (fn [_] nil))))))
diff --git a/enterprise/backend/test/metabase_enterprise/enhancements/integrations/ldap_test.clj b/enterprise/backend/test/metabase_enterprise/enhancements/integrations/ldap_test.clj
index 9f9da6588e5d22ec5c4bd4b690b2df017c72d8fa..b284264c65ef9e2efe9df8a15f805dcc7f96b7c5 100644
--- a/enterprise/backend/test/metabase_enterprise/enhancements/integrations/ldap_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/enhancements/integrations/ldap_test.clj
@@ -13,7 +13,7 @@
 
 (deftest find-test
   (mt/with-premium-features #{:sso-ldap}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "find by username"
         (is (= {:dn         "cn=John Smith,ou=People,dc=metabase,dc=com"
                 :first-name "John"
@@ -93,7 +93,7 @@
 
 (deftest attribute-sync-test
   (mt/with-premium-features #{:sso-ldap}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "find by email/username should return other attributes as well"
         (is (= {:dn         "cn=Lucky Pigeon,ou=Birds,dc=metabase,dc=com"
                 :first-name "Lucky"
@@ -166,7 +166,7 @@
 
 (deftest update-attributes-on-login-test
   (mt/with-premium-features #{:sso-ldap}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "Existing user's attributes are updated on fetch"
         (try
           (let [user-info (ldap/find-user "jsmith1")]
@@ -216,7 +216,7 @@
 
 (deftest fetch-or-create-user-test
   (mt/with-premium-features #{:sso-ldap}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "a new user is created when they don't already exist"
         (try
          (ldap/fetch-or-create-user! (ldap/find-user "jsmith1"))
@@ -252,7 +252,7 @@
 
 (deftest ldap-no-user-provisioning-test
   (mt/with-premium-features #{:sso-ldap}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "an error is thrown when a new user is fetched and user provisioning is not enabled"
         (with-redefs [sso-settings/ldap-user-provisioning-enabled? (constantly false)
                       public-settings/site-name (constantly "test")]
diff --git a/enterprise/backend/test/metabase_enterprise/query_reference_validation/api_test.clj b/enterprise/backend/test/metabase_enterprise/query_reference_validation/api_test.clj
index ef7e5262a46e35416ea23b90681065fa0054aeec..a88e5f4770e5ad531a48bd982065c6e5991b6a9e 100644
--- a/enterprise/backend/test/metabase_enterprise/query_reference_validation/api_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/query_reference_validation/api_test.clj
@@ -8,7 +8,7 @@
    [toucan2.core :as t2]
    [toucan2.tools.with-temp :as t2.with-temp]))
 
-(defn- do-with-test-setup [f]
+(defn- do-with-test-setup! [f]
   (query-analysis/without-analysis
    (t2.with-temp/with-temp [:model/Table      {table-1 :id}  {:name "T1"}
                             :model/Table      {table-2 :id}  {:name "T2" :active false}
@@ -117,14 +117,14 @@
        (mt/with-temporary-setting-values [query-analysis-enabled true]
          (mt/call-with-map-params f [card-1 card-2 card-3 card-4 card-5 coll-2 coll-3]))))))
 
-(defmacro ^:private with-test-setup
+(defmacro ^:private with-test-setup!
   "Creates some non-stale QueryFields and anaphorically provides stale QueryField IDs called `qf-{1-3}` and `qf-1b` and
   their corresponding Card IDs (`card-{1-3}`). The cards are named A, B, and C. The Fields are called FA, FB, FB and
   they all point to a Table called T. Both `qf-1` and `qf-1b` refer to `card-1`.
 
   `card-4` is guaranteed not to have problems"
   [& body]
-  `(do-with-test-setup
+  `(do-with-test-setup!
     (mt/with-anaphora [card-1 card-2 card-3 card-4 card-5 coll-2 coll-3]
       ~@body)))
 
@@ -137,7 +137,7 @@
 
 (deftest collection-ancestors-test
   (testing "The response includes collection ancestors"
-    (with-test-setup
+    (with-test-setup!
       (is (= [{:collection {:id nil
                             :name nil
                             :authority_level nil
@@ -175,14 +175,14 @@
 
 (deftest setting-test
   (testing "It requires the query analysis setting"
-    (with-test-setup
+    (with-test-setup!
       (mt/with-temporary-setting-values [query-analysis-enabled false]
         (is (= "Query Analysis must be enabled to use the Query Reference Validator"
                (mt/user-http-request :crowberto :get 429 url)))))))
 
 (deftest list-invalid-cards-basic-test
   (testing "Only returns cards with problematic field refs"
-    (with-test-setup
+    (with-test-setup!
       (is (= {:total 4
               :data
               [{:id     card-1
@@ -204,7 +204,7 @@
 
 (deftest pagination-test
   (testing "Lets you page results"
-    (with-test-setup
+    (with-test-setup!
       (is (= {:total  4
               :limit  2
               :offset 0
@@ -235,7 +235,7 @@
 
 (deftest sorting-test
   (testing "Lets you specify the sort key"
-    (with-test-setup
+    (with-test-setup!
       (is (= {:total 4
               :data
               [{:id card-3}
@@ -265,7 +265,7 @@
                  (with-data-keys [:id]))))))
 
   (testing "Rejects bad keys"
-    (with-test-setup
+    (with-test-setup!
       (is (str/starts-with? (:sort_column
                              (:errors
                               (mt/user-http-request :crowberto :get 400 (str url "?sort_column=favorite_bird"))))
@@ -273,7 +273,7 @@
 
 (deftest filter-on-collection
   (testing "can filter on collection id"
-    (with-test-setup
+    (with-test-setup!
       (testing "we can just look in coll-3"
         (is (= {:total 1
                 :data
diff --git a/enterprise/backend/test/metabase_enterprise/sandbox/api/gtap_test.clj b/enterprise/backend/test/metabase_enterprise/sandbox/api/gtap_test.clj
index 7c9812f2c5cac50b5313e162004c18b57895333f..6a8a178671a211b8486c08cc8778459ba55d3066 100644
--- a/enterprise/backend/test/metabase_enterprise/sandbox/api/gtap_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/sandbox/api/gtap_test.clj
@@ -28,7 +28,7 @@
    :group_id             true
    :attribute_remappings {:foo 1}})
 
-(defmacro ^:private with-gtap-cleanup
+(defmacro ^:private with-gtap-cleanup!
   "Invokes `body` ensuring any `GroupTableAccessPolicy` created will be removed afterward. Leaving behind a GTAP can
   case referential integrity failures for any related `Card` that would be cleaned up as part of a `with-temp*` call"
   [& body]
@@ -58,7 +58,7 @@
 
 (deftest fetch-gtap-test
   (testing "GET /api/mt/gtap/"
-    (with-gtap-cleanup
+    (with-gtap-cleanup!
       (mt/with-temp [Table                  {table-id-1 :id} {}
                      Table                  {table-id-2 :id} {}
                      PermissionsGroup       {group-id-1 :id} {}
@@ -90,7 +90,7 @@
                    PermissionsGroup {group-id :id} {}]
       (testing "Test that we can create a new GTAP"
         (t2.with-temp/with-temp [Card {card-id :id}]
-          (with-gtap-cleanup
+          (with-gtap-cleanup!
             (let [post-results (gtap-post {:table_id             table-id
                                            :group_id             group-id
                                            :card_id              card-id
@@ -101,7 +101,7 @@
                      (mt/user-http-request :crowberto :get 200 (format "mt/gtap/%s" (:id post-results)))))))))
 
       (testing "Test that we can create a new GTAP without a card"
-        (with-gtap-cleanup
+        (with-gtap-cleanup!
           (let [post-results (gtap-post {:table_id             table-id
                                          :group_id             group-id
                                          :card_id              nil
@@ -116,7 +116,7 @@
                        Card  {card-id :id} {:dataset_query (mt/mbql-query venues
                                                                           {:fields      [[:expression "My field"]]
                                                                            :expressions {"My field" [:ltrim "wow"]}})}]
-          (with-gtap-cleanup
+          (with-gtap-cleanup!
             (is (=? {:message  "Sandbox Questions can't return columns that have different types than the Table they are sandboxing."
                      :expected "type/Integer"
                      :actual   "type/Text"}
@@ -132,14 +132,14 @@
                    PermissionsGroup {group-id :id} {}]
       (testing "A valid sandbox passes validation and returns no error"
         (t2.with-temp/with-temp [Card {card-id :id}]
-          (with-gtap-cleanup
+          (with-gtap-cleanup!
             (mt/user-http-request :crowberto :post 204 "mt/gtap/validate"
                                   {:table_id             table-id
                                    :group_id             group-id
                                    :card_id              card-id}))))
 
       (testing "A sandbox without a card-id passes validation, because the validation is not applicable in this case"
-        (with-gtap-cleanup
+        (with-gtap-cleanup!
           (mt/user-http-request :crowberto :post 204 "mt/gtap/validate"
                                 {:table_id             table-id
                                  :group_id             group-id
@@ -151,7 +151,7 @@
                        Card  {card-id :id} {:dataset_query (mt/mbql-query venues
                                                              {:fields      [[:expression "My field"]]
                                                               :expressions {"My field" [:ltrim "wow"]}})}]
-          (with-gtap-cleanup
+          (with-gtap-cleanup!
             (is (=? {:message  "Sandbox Questions can't return columns that have different types than the Table they are sandboxing."
                      :expected "type/Integer"
                      :actual   "type/Text"}
@@ -167,7 +167,7 @@
       (mt/with-temp [Table            {table-id :id} {}
                      PermissionsGroup {group-id :id} {}
                      Card             {card-id :id} {}]
-        (with-gtap-cleanup
+        (with-gtap-cleanup!
           (let [{:keys [id]} (gtap-post {:table_id             table-id
                                          :group_id             group-id
                                          :card_id              card-id
@@ -234,7 +234,7 @@
                    Card             {card-id-1 :id}  {}
                    Card             {card-id-2 :id}  {}]
       (mt/with-premium-features #{:sandboxes}
-        (with-gtap-cleanup
+        (with-gtap-cleanup!
           (testing "Test that we can create a new sandbox using the permission graph API"
             (let [graph  (-> (data-perms.graph/api-graph)
                              (assoc-in [:groups group-id (mt/id) :view-data] {"PUBLIC" {table-id-1 :sandboxed}})
diff --git a/enterprise/backend/test/metabase_enterprise/sandbox/pulse_test.clj b/enterprise/backend/test/metabase_enterprise/sandbox/pulse_test.clj
index c3c17b3117e3ca22c2af0fcdba6441ca87f71773..02790cce8289f25dbd0191557fc4c2659916b61b 100644
--- a/enterprise/backend/test/metabase_enterprise/sandbox/pulse_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/sandbox/pulse_test.clj
@@ -34,7 +34,7 @@
       (is (= [[10]]
              (send-pulse-created-by-user! :rasta))))))
 
-(defn- alert-results
+(defn- alert-results!
   "Results for creating and running an Alert"
   [query]
   (mt/with-temp [Card                  pulse-card {:name          "Test card"
@@ -122,7 +122,7 @@
         (testing "GTAPs should apply to Pulses — they should get the same results as if running that query normally"
           (is (= [[3 13]]
                  (mt/rows
-                  (alert-results query)))))))))
+                  (alert-results! query)))))))))
 
 (defn- html->row-count [html]
   (or (some->> html (re-find #"of <strong.+>(\d+)</strong> rows") second Integer/parseUnsignedInt)
@@ -151,7 +151,7 @@
 
             (testing "Pulse should be sandboxed"
               (is (= 22
-                     (count (mt/rows (alert-results query))))))))))))
+                     (count (mt/rows (alert-results! query))))))))))))
 
 (deftest pulse-preview-test
   (testing "Pulse preview endpoints should be sandboxed"
diff --git a/enterprise/backend/test/metabase_enterprise/sandbox/query_processor/middleware/row_level_restrictions_test.clj b/enterprise/backend/test/metabase_enterprise/sandbox/query_processor/middleware/row_level_restrictions_test.clj
index 3ce6b1e8d6cbd049c4db5e9dc2ddd51e553f8c1c..aed199784eac671e99862065d2bf72b3d6b477cb 100644
--- a/enterprise/backend/test/metabase_enterprise/sandbox/query_processor/middleware/row_level_restrictions_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/sandbox/query_processor/middleware/row_level_restrictions_test.clj
@@ -470,7 +470,7 @@
                                                         :order-by    [[:asc $venue_id->venues.price]]
                                                         :breakout    [$venue_id->venues.price $user_id->users.name]}))))))))))
 
-(defn- run-query-returning-remark [run-query-fn]
+(defn- run-query-returning-remark! [run-query-fn]
   (let [remark (atom nil)
         orig   qp.util/query->remark]
     (with-redefs [qp.util/query->remark (fn [driver outer-query]
@@ -486,7 +486,7 @@
     (met/with-gtaps! {:gtaps      {:venues (venues-category-mbql-gtap-def)}
                       :attributes {"cat" 50}}
       (is (= (format "Metabase:: userID: %d queryType: MBQL queryHash: <hash>" (mt/user->id :rasta))
-             (run-query-returning-remark
+             (run-query-returning-remark!
               (fn []
                 (mt/user-http-request :rasta :post "dataset" (mt/mbql-query venues {:aggregation [[:count]]})))))))))
 
@@ -735,7 +735,7 @@
                     (mt/rows (run-query)))))))))))
 
 (deftest dont-cache-sandboxes-test
-  (cache-test/with-mock-cache [save-chan]
+  (cache-test/with-mock-cache! [save-chan]
     (met/with-gtaps! {:gtaps      {:venues (venues-category-mbql-gtap-def)}
                       :attributes {"cat" 50}}
       (letfn [(run-query []
@@ -762,7 +762,7 @@
             (is (= [[10]]
                    (mt/rows result)))))
         (testing "Run the query with different User attributes, should not get the cached result"
-          (met/with-user-attributes :rasta {"cat" 40}
+          (met/with-user-attributes! :rasta {"cat" 40}
             ;; re-bind current user so updated attributes come in to effect
             (mt/with-test-user :rasta
               (is (= {"cat" 40}
@@ -1083,7 +1083,7 @@
                                               ["dimension"
                                                [:field (mt/id :products :category)
                                                 nil]]}}}}
-        (mt/with-persistence-enabled [persist-models!]
+        (mt/with-persistence-enabled! [persist-models!]
           (mt/with-temp [Card model {:type          :model
                                      :dataset_query (mt/mbql-query
                                                       products
@@ -1106,7 +1106,7 @@
                                    :database (mt/id)}
                     regular-result (mt/with-test-user :crowberto
                                      (qp/process-query query))
-                    sandboxed-result (met/with-user-attributes :rasta {"category" "Gizmo"}
+                    sandboxed-result (met/with-user-attributes! :rasta {"category" "Gizmo"}
                                        (mt/with-test-user :rasta
                                          (qp/process-query query)))]
                 (testing "Unsandboxed"
@@ -1133,7 +1133,7 @@
                                           :table_id      (mt/id :categories)
                                           :dataset_query (mt/mbql-query categories)}]
         (let [query (:dataset_query card)]
-          (process-userland-query-test/with-query-execution [qe query]
+          (process-userland-query-test/with-query-execution! [qe query]
             (qp/process-query (qp/userland-query query))
             (is (=? {:is_sandboxed true}
                     (qe)))))))))
diff --git a/enterprise/backend/test/metabase_enterprise/sandbox/test_util.clj b/enterprise/backend/test/metabase_enterprise/sandbox/test_util.clj
index a5f50eeca2a7fbcef7e39de4c7fa1b620788fb76..f1ff5f4617999c083de10c1af67f41eb8df24578 100644
--- a/enterprise/backend/test/metabase_enterprise/sandbox/test_util.clj
+++ b/enterprise/backend/test/metabase_enterprise/sandbox/test_util.clj
@@ -17,20 +17,20 @@
    [metabase.util :as u]
    [toucan2.tools.with-temp :as t2.with-temp]))
 
-(defn do-with-user-attributes [test-user-name-or-user-id attributes-map thunk]
-  (mb.hawk.parallel/assert-test-is-not-parallel "with-user-attributes")
+(defn do-with-user-attributes! [test-user-name-or-user-id attributes-map thunk]
+  (mb.hawk.parallel/assert-test-is-not-parallel "with-user-attributes!")
   (let [user-id (test.users/test-user-name-or-user-id->user-id test-user-name-or-user-id)]
     (tu/with-temp-vals-in-db User user-id {:login_attributes attributes-map}
       (thunk))))
 
-(defmacro with-user-attributes
+(defmacro with-user-attributes!
   "Execute `body` with the attributes for a User temporarily set to `attributes-map`. `test-user-name-or-user-id` can be
   either one of the predefined test users e.g. `:rasta` or a User ID.
 
-    (with-user-attributes :rasta {\"cans\" 2} ...)"
+    (with-user-attributes! :rasta {\"cans\" 2} ...)"
   {:style/indent 2}
   [test-user-name-or-user-id attributes-map & body]
-  `(do-with-user-attributes ~test-user-name-or-user-id ~attributes-map (fn [] ~@body)))
+  `(do-with-user-attributes! ~test-user-name-or-user-id ~attributes-map (fn [] ~@body)))
 
 (defn- do-with-gtap-defs!
   {:style/indent 2}
@@ -69,7 +69,7 @@
               (test.users/with-group-for-user [group test-user-name-or-user-id]
                 (let [{:keys [gtaps attributes]} (mc/assert WithGTAPsArgs (args-fn))]
                   ;; set user login_attributes
-                  (with-user-attributes test-user-name-or-user-id attributes
+                  (with-user-attributes! test-user-name-or-user-id attributes
                     (mt/with-additional-premium-features #{:sandboxes}
                       ;; create Cards/GTAPs from defs
                       (do-with-gtap-defs! group gtaps
diff --git a/enterprise/backend/test/metabase_enterprise/snippet_collections/models/native_query_snippet/permissions_test.clj b/enterprise/backend/test/metabase_enterprise/snippet_collections/models/native_query_snippet/permissions_test.clj
index a75f16e5c99bcf4c6bd5b0d146bdba294ff284d7..61ee99ffc1cb9dc257cc3ca1524ef6ff0c250eba 100644
--- a/enterprise/backend/test/metabase_enterprise/snippet_collections/models/native_query_snippet/permissions_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/snippet_collections/models/native_query_snippet/permissions_test.clj
@@ -50,7 +50,7 @@
           (testing "should NOT be allowed if you do not have native query perms for at least one DB"
             (test-perms* false)))))))
 
-(defn- test-with-root-collection-and-collection [f]
+(defn- test-with-root-collection-and-collection! [f]
   (mt/with-non-admin-groups-no-root-collection-for-namespace-perms "snippets"
     (t2.with-temp/with-temp [Collection collection {:name "Parent Collection", :namespace "snippets"}]
       (doseq [coll [root-collection collection]]
@@ -60,7 +60,7 @@
 
 (deftest read-perms-test
   (testing "read a Snippet"
-    (test-with-root-collection-and-collection
+    (test-with-root-collection-and-collection!
      (fn [coll snippet]
        (test-perms!
         :has-perms-for-obj?       #(mi/can-read? snippet)
@@ -70,7 +70,7 @@
 
 (deftest create-perms-test
   (testing "create a Snippet"
-    (test-with-root-collection-and-collection
+    (test-with-root-collection-and-collection!
      (fn [coll snippet]
        (test-perms!
         :has-perms-for-obj?       #(mi/can-create? NativeQuerySnippet (dissoc snippet :id))
@@ -79,7 +79,7 @@
 
 (deftest update-perms-test
   (testing "update a Snippet"
-    (test-with-root-collection-and-collection
+    (test-with-root-collection-and-collection!
      (fn [coll snippet]
        (test-perms!
         :has-perms-for-obj?       #(mi/can-write? snippet)
diff --git a/enterprise/backend/test/metabase_enterprise/sso/integrations/jwt_test.clj b/enterprise/backend/test/metabase_enterprise/sso/integrations/jwt_test.clj
index 6aca3e057b2634865a1bca3a7c40eb2a9ce0efd1..ed33b5b84a783445979250cf3126543dbb06cb22 100644
--- a/enterprise/backend/test/metabase_enterprise/sso/integrations/jwt_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/sso/integrations/jwt_test.clj
@@ -24,13 +24,6 @@
 
 (use-fixtures :once (fixtures/initialize :test-users))
 
-(defn- disable-other-sso-types [thunk]
-  (mt/with-temporary-setting-values [ldap-enabled false
-                                     saml-enabled false]
-    (thunk)))
-
-(use-fixtures :each disable-other-sso-types)
-
 (defn- disable-api-url-prefix
   [thunk]
   (binding [client/*url-prefix* ""]
@@ -38,11 +31,16 @@
 
 (use-fixtures :each disable-api-url-prefix)
 
+(defn- do-with-other-sso-types-disabled! [thunk]
+  (mt/with-temporary-setting-values [ldap-enabled false
+                                     saml-enabled false]
+    (thunk)))
+
 (def ^:private default-idp-uri      "http://test.idp.metabase.com")
 (def ^:private default-redirect-uri "/")
 (def ^:private default-jwt-secret   (crypto-random/hex 32))
 
-(defn- call-with-default-jwt-config [f]
+(defn- call-with-default-jwt-config! [f]
   (let [current-features (premium-features/*token-features*)]
     (mt/with-additional-premium-features #{:sso-jwt}
       (mt/with-temporary-setting-values [jwt-enabled               true
@@ -52,61 +50,63 @@
         (mt/with-premium-features current-features
           (f))))))
 
-(defmacro with-default-jwt-config [& body]
-  `(call-with-default-jwt-config
+(defmacro with-default-jwt-config! [& body]
+  `(call-with-default-jwt-config!
     (fn []
       ~@body)))
 
-(defmacro ^:private with-jwt-default-setup [& body]
+(defmacro ^:private with-jwt-default-setup! [& body]
   `(mt/test-helpers-set-global-values!
      (mt/with-premium-features #{:audit-app}
-       (disable-other-sso-types
+       (do-with-other-sso-types-disabled!
         (fn []
           (mt/with-additional-premium-features #{:sso-jwt}
             (saml-test/call-with-login-attributes-cleared!
              (fn []
-               (call-with-default-jwt-config
+               (call-with-default-jwt-config!
                 (fn []
                   ~@body))))))))))
 
 (deftest sso-prereqs-test
-  (mt/with-additional-premium-features #{:sso-jwt}
-    (testing "SSO requests fail if JWT hasn't been configured or enabled"
-      (mt/with-temporary-setting-values [jwt-enabled               false
-                                         jwt-identity-provider-uri nil
-                                         jwt-shared-secret         nil]
-        (is (= "SSO has not been enabled and/or configured"
-               (client/client :get 400 "/auth/sso")))
+  (do-with-other-sso-types-disabled!
+   (fn []
+     (mt/with-additional-premium-features #{:sso-jwt}
+       (testing "SSO requests fail if JWT hasn't been configured or enabled"
+         (mt/with-temporary-setting-values [jwt-enabled               false
+                                            jwt-identity-provider-uri nil
+                                            jwt-shared-secret         nil]
+           (is (= "SSO has not been enabled and/or configured"
+                  (client/client :get 400 "/auth/sso")))
 
-        (testing "SSO requests fail if they don't have a valid premium-features token"
-          (with-default-jwt-config
-            (mt/with-premium-features #{}
-              (is (= "SSO has not been enabled and/or configured"
-                     (client/client :get 400 "/auth/sso"))))))))
+           (testing "SSO requests fail if they don't have a valid premium-features token"
+             (with-default-jwt-config!
+               (mt/with-premium-features #{}
+                 (is (= "SSO has not been enabled and/or configured"
+                        (client/client :get 400 "/auth/sso"))))))))
 
-    (testing "SSO requests fail if JWT is enabled but hasn't been configured"
-      (mt/with-temporary-setting-values [jwt-enabled               true
-                                         jwt-identity-provider-uri nil]
-        (is (= "SSO has not been enabled and/or configured"
-               (client/client :get 400 "/auth/sso")))))
+       (testing "SSO requests fail if JWT is enabled but hasn't been configured"
+         (mt/with-temporary-setting-values [jwt-enabled               true
+                                            jwt-identity-provider-uri nil]
+           (is (= "SSO has not been enabled and/or configured"
+                  (client/client :get 400 "/auth/sso")))))
 
-    (testing "SSO requests fail if JWT is configured but hasn't been enabled"
-      (mt/with-temporary-setting-values [jwt-enabled               false
-                                         jwt-identity-provider-uri default-idp-uri
-                                         jwt-shared-secret         default-jwt-secret]
-        (is (= "SSO has not been enabled and/or configured"
-               (client/client :get 400 "/auth/sso")))))
+       (testing "SSO requests fail if JWT is configured but hasn't been enabled"
+         (mt/with-temporary-setting-values [jwt-enabled               false
+                                            jwt-identity-provider-uri default-idp-uri
+                                            jwt-shared-secret         default-jwt-secret]
+           (is (= "SSO has not been enabled and/or configured"
+                  (client/client :get 400 "/auth/sso")))))
 
-    (testing "The JWT Shared Secret must also be included for SSO to be configured"
-      (mt/with-temporary-setting-values [jwt-enabled               true
-                                         jwt-identity-provider-uri default-idp-uri
-                                         jwt-shared-secret         nil]
-        (is (= "SSO has not been enabled and/or configured"
-               (client/client :get 400 "/auth/sso")))))))
+       (testing "The JWT Shared Secret must also be included for SSO to be configured"
+         (mt/with-temporary-setting-values [jwt-enabled               true
+                                            jwt-identity-provider-uri default-idp-uri
+                                            jwt-shared-secret         nil]
+           (is (= "SSO has not been enabled and/or configured"
+                  (client/client :get 400 "/auth/sso")))))))))
 
 (deftest redirect-test
   (testing "with JWT configured, a GET request should result in a redirect to the IdP"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (let [result       (client/client-full-response :get 302 "/auth/sso"
                                                       {:request-options {:redirect-strategy :none}}
                                                       :redirect default-redirect-uri)
@@ -114,7 +114,7 @@
         (is (str/starts-with? redirect-url default-idp-uri)))))
   (testing (str "JWT configured with a redirect-uri containing query params, "
                 "a GET request should result in a redirect to the IdP as a correctly formatted URL (#13078)")
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (mt/with-temporary-setting-values [jwt-identity-provider-uri "http://test.idp.metabase.com/login?some_param=yes"]
         (let [result       (client/client-full-response :get 302 "/auth/sso"
                                                         {:request-options {:redirect-strategy :none}}
@@ -123,25 +123,26 @@
           (is (str/includes? redirect-url "&return_to=")))))))
 
 (deftest jwt-saml-both-enabled-test
-  (with-jwt-default-setup
-    (saml-test/with-saml-default-setup
-      (testing "with SAML and JWT configured, a GET request with JWT params should sign in correctly"
-        (let [response (client/client-real-response :get 302 "/auth/sso"
-                                                    {:request-options {:redirect-strategy :none}}
-                                                    :return_to default-redirect-uri
-                                                    :jwt (jwt/sign {:email      "rasta@metabase.com"
-                                                                    :first_name "Rasta"
-                                                                    :last_name  "Toucan"
-                                                                    :extra      "keypairs"
-                                                                    :are        "also present"}
-                                                                   default-jwt-secret))]
-          (is (saml-test/successful-login? response))
-          (testing "redirect URI"
-            (is (= default-redirect-uri
-                   (get-in response [:headers "Location"]))))
-          (testing "login attributes"
-            (is (= {"extra" "keypairs", "are" "also present"}
-                   (t2/select-one-fn :login_attributes User :email "rasta@metabase.com"))))))
+  (with-jwt-default-setup!
+    (saml-test/with-saml-default-setup!
+      (mt/with-temporary-setting-values [jwt-enabled true]
+        (testing "with SAML and JWT configured, a GET request with JWT params should sign in correctly"
+          (let [response (client/client-real-response :get 302 "/auth/sso"
+                                                      {:request-options {:redirect-strategy :none}}
+                                                      :return_to default-redirect-uri
+                                                      :jwt (jwt/sign {:email      "rasta@metabase.com"
+                                                                      :first_name "Rasta"
+                                                                      :last_name  "Toucan"
+                                                                      :extra      "keypairs"
+                                                                      :are        "also present"}
+                                                                     default-jwt-secret))]
+            (is (saml-test/successful-login? response))
+            (testing "redirect URI"
+              (is (= default-redirect-uri
+                     (get-in response [:headers "Location"]))))
+            (testing "login attributes"
+              (is (= {"extra" "keypairs", "are" "also present"}
+                     (t2/select-one-fn :login_attributes User :email "rasta@metabase.com")))))))
 
       (testing "with SAML and JWT configured, a GET request without JWT params should redirect to SAML IdP"
         (let [response (client/client-full-response :get 302 "/auth/sso"
@@ -152,7 +153,7 @@
 (deftest happy-path-test
   (testing (str "Happy path login, valid JWT, checks to ensure the user was logged in successfully and the redirect to "
                 "the right location")
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (let [response (client/client-real-response :get 302 "/auth/sso" {:request-options {:redirect-strategy :none}}
                                                   :return_to default-redirect-uri
                                                   :jwt (jwt/sign {:email      "rasta@metabase.com"
@@ -175,7 +176,7 @@
 
 (deftest no-open-redirect-test
   (testing "Check that we prevent open redirects to untrusted sites"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (doseq [redirect-uri ["https://badsite.com"
                             "//badsite.com"
                             "https:///badsite.com"]]
@@ -193,7 +194,7 @@
 
 (deftest expired-jwt-test
   (testing "Check an expired JWT"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (is (= "Token is older than max-age (180)"
              (:message (client/client :get 401 "/auth/sso" {:request-options {:redirect-strategy :none}}
                                       :return_to default-redirect-uri
@@ -209,7 +210,7 @@
 
 (deftest create-new-account-test
   (testing "A new account will be created for a JWT user we haven't seen before"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (with-users-with-email-deleted "newuser@metabase.com"
         (letfn [(new-user-exists? []
                   (boolean (seq (t2/select User :%lower.email "newuser@metabase.com"))))]
@@ -248,7 +249,7 @@
 
 (deftest update-account-test
   (testing "A new account with 'Unknown' name will be created for a new JWT user without a first or last name."
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (with-users-with-email-deleted "newuser@metabase.com"
         (letfn [(new-user-exists? []
                   (boolean (seq (t2/select User :%lower.email "newuser@metabase.com"))))]
@@ -310,7 +311,7 @@
 
 (deftest login-sync-group-memberships-test
   (testing "login should sync group memberships if enabled"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (mt/with-temp [PermissionsGroup my-group {:name (str ::my-group)}]
         (mt/with-temporary-setting-values [jwt-group-sync       true
                                            jwt-group-mappings   {"my_group" [(u/the-id my-group)]}
@@ -333,7 +334,7 @@
 
 (deftest create-new-jwt-user-no-user-provisioning-test
   (testing "When user provisioning is disabled, throw an error if we attempt to create a new user."
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (with-redefs [sso-settings/jwt-user-provisioning-enabled? (constantly false)
                     public-settings/site-name (constantly "test")]
         (is
@@ -344,7 +345,7 @@
 
 (deftest jwt-token-test
   (testing "should return a session token when token=true"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (mt/with-temporary-setting-values [enable-embedding true]
         (let [jwt-iat-time (buddy-util/now)
               jwt-exp-time (+ (buddy-util/now) 3600)
@@ -365,7 +366,7 @@
                   (:body result)))))))
 
   (testing "should not return a session token when embedding is disabled"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (mt/with-temporary-setting-values [enable-embedding false]
         (let [jwt-iat-time (buddy-util/now)
               jwt-exp-time (+ (buddy-util/now) 3600)
@@ -383,7 +384,7 @@
           (is result nil)))))
 
   (testing "should not return a session token when token=false"
-    (with-jwt-default-setup
+    (with-jwt-default-setup!
       (mt/with-temporary-setting-values [enable-embedding true]
         (let [jwt-iat-time (buddy-util/now)
               jwt-exp-time (+ (buddy-util/now) 3600)
diff --git a/enterprise/backend/test/metabase_enterprise/sso/integrations/saml_test.clj b/enterprise/backend/test/metabase_enterprise/sso/integrations/saml_test.clj
index a83fe848f6834060956c2f1bf7c009730f24ffc4..f42842f2d0b8764b1c5f5d26077435c7a46351cd 100644
--- a/enterprise/backend/test/metabase_enterprise/sso/integrations/saml_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/sso/integrations/saml_test.clj
@@ -5,12 +5,11 @@
    [clojure.test :refer :all]
    [metabase-enterprise.sso.integrations.saml :as saml.mt]
    [metabase-enterprise.sso.integrations.sso-settings :as sso-settings]
+   [metabase.api.ldap]
    [metabase.http-client :as client]
    [metabase.models.permissions-group :refer [PermissionsGroup]]
-   [metabase.models.permissions-group-membership
-    :refer [PermissionsGroupMembership]]
+   [metabase.models.permissions-group-membership :refer [PermissionsGroupMembership]]
    [metabase.models.user :refer [User]]
-   [metabase.plugins.classloader :as classloader]
    [metabase.public-settings :as public-settings]
    [metabase.public-settings.premium-features :as premium-features]
    [metabase.server.middleware.session :as mw.session]
@@ -30,10 +29,18 @@
 
 (set! *warn-on-reflection* true)
 
-(use-fixtures :once (fixtures/initialize :test-users))
+(comment metabase.api.ldap/keep-me) ; for [[metabase.api.ldap/ldap-enabled]]
 
-(defn- disable-other-sso-types [thunk]
-  (classloader/require 'metabase.api.ldap)
+(use-fixtures :once (fixtures/initialize :test-users :web-server))
+
+(defn- disable-api-url-prefix
+  [thunk]
+  (binding [client/*url-prefix* ""]
+    (thunk)))
+
+(use-fixtures :each disable-api-url-prefix)
+
+(defn- do-with-other-sso-types-disabled! [thunk]
   (let [current-features (premium-features/*token-features*)]
     ;; The :sso-jwt token is needed to set the jwt-enabled setting
     (mt/test-helpers-set-global-values!
@@ -43,21 +50,15 @@
           (mt/with-premium-features current-features
             (thunk)))))))
 
-(use-fixtures :each disable-other-sso-types)
-
-(defn- disable-api-url-prefix
-  [thunk]
-  (binding [client/*url-prefix* ""]
-    (thunk)))
-
-(use-fixtures :once disable-api-url-prefix)
+(defmacro ^:private with-other-sso-types-disabled! [& body]
+  `(do-with-other-sso-types-disabled! (fn [] ~@body)))
 
 (def ^:private default-idp-uri            "http://test.idp.metabase.com")
 (def ^:private default-redirect-uri       "http://localhost:3000/test")
 (def ^:private default-idp-uri-with-param (str default-idp-uri "?someparam=true"))
 (def ^:private default-idp-cert           (slurp "test_resources/sso/auth0-public-idp.cert"))
 
-(defn call-with-default-saml-config [f]
+(defn call-with-default-saml-config! [f]
   (let [current-features (premium-features/*token-features*)]
     (mt/with-premium-features #{:sso-saml}
       (mt/with-temporary-setting-values [saml-enabled                       true
@@ -69,28 +70,29 @@
         (mt/with-premium-features current-features
           (f))))))
 
-(defmacro with-default-saml-config [& body]
-  `(call-with-default-saml-config
+(defmacro with-default-saml-config! [& body]
+  `(call-with-default-saml-config!
     (fn []
       ~@body)))
 
 (defn call-with-login-attributes-cleared!
   "If login_attributes remain after these tests run, depending on the order that the tests run, lots of tests will
   fail as the login_attributes data from this tests is unexpected in those other tests"
-  [f]
+  [thunk]
   (try
-    (f)
+    (thunk)
     (finally
-      (u/ignore-exceptions (do (t2/update! User {} {:login_attributes nil})
-                               (t2/update! User {:email "rasta@metabase.com"} {:first_name "Rasta" :last_name "Toucan" :sso_source nil}))))))
+      (u/ignore-exceptions
+        (t2/update! User {} {:login_attributes nil})
+        (t2/update! User {:email "rasta@metabase.com"} {:first_name "Rasta" :last_name "Toucan" :sso_source nil})))))
 
-(defmacro with-saml-default-setup [& body]
+(defmacro with-saml-default-setup! [& body]
   ;; most saml tests make actual http calls, so ensuring any nested with-temp doesn't create transaction
   `(mt/test-helpers-set-global-values!
      (mt/with-additional-premium-features #{:sso-saml}
        (call-with-login-attributes-cleared!
          (fn []
-           (call-with-default-saml-config
+           (call-with-default-saml-config!
             (fn []
               ~@body)))))))
 
@@ -99,16 +101,15 @@
   [resp]
   (string? (get-in resp [:cookies mw.session/metabase-session-cookie :value])))
 
-(defn- do-with-some-validators-disabled
+(defn- do-with-some-validators-disabled!
   "The sample responses all have `InResponseTo=\"_1\"` and invalid assertion signatures (they were edited by hand) so
   manually add `_1` to the state manager and turn off the <Assertion> signature validator so we can actually run
   tests."
-  {:style/indent [:defn 2]}
-  ([f]
-   (do-with-some-validators-disabled nil #{:signature :not-on-or-after :recipient :issuer}
-     f))
+  ([thunk]
+   (do-with-some-validators-disabled! nil #{:signature :not-on-or-after :recipient :issuer}
+     thunk))
 
-  ([disabled-response-validators disabled-assertion-validators f]
+  ([disabled-response-validators disabled-assertion-validators thunk]
    (let [orig              saml/validate
          remove-validators (fn [options]
                              (-> options
@@ -120,43 +121,45 @@
                                    ([response idp-cert sp-private-key options]
                                     (let [options (merge saml/default-validation-options options)]
                                       (orig response idp-cert sp-private-key (remove-validators options)))))]
-       (f)))))
+       (thunk)))))
 
-(deftest validate-certificate-test
+(deftest ^:parallel validate-certificate-test
   (testing "make sure our test certificate is actually valid"
     (is (some? (#'sso-settings/validate-saml-idp-cert default-idp-cert)))))
 
 (deftest require-valid-premium-features-token-test
   (testing "SSO requests fail if they don't have a valid premium-features token"
-    (mt/with-premium-features #{}
-      (with-default-saml-config
-        (is (= "SSO has not been enabled and/or configured"
-               (client/client :get 400 "/auth/sso")))))))
+    (with-other-sso-types-disabled!
+      (mt/with-premium-features #{}
+        (with-default-saml-config!
+          (is (= "SSO has not been enabled and/or configured"
+                 (client/client :get 400 "/auth/sso"))))))))
 
 (deftest require-saml-enabled-test
-  (mt/with-premium-features #{:sso-saml}
-    (testing "SSO requests fail if SAML hasn't been configured or enabled"
-      (mt/with-temporary-setting-values [saml-enabled                       false
-                                         saml-identity-provider-uri         nil
-                                         saml-identity-provider-certificate nil]
-        (is (some? (client/client :get 400 "/auth/sso")))))
-
-    (testing "SSO requests fail if SAML has been configured but not enabled"
-      (mt/with-temporary-setting-values [saml-enabled                       false
-                                         saml-identity-provider-uri         default-idp-uri
-                                         saml-identity-provider-certificate default-idp-cert]
-        (is (some? (client/client :get 400 "/auth/sso")))))
-
-    (testing "SSO requests fail if SAML is enabled but hasn't been configured"
-      (mt/with-temporary-setting-values [saml-enabled               true
-                                         saml-identity-provider-uri nil]
-        (is (some? (client/client :get 400 "/auth/sso")))))
-
-    (testing "The IDP provider certificate must also be included for SSO to be configured"
-      (mt/with-temporary-setting-values [saml-enabled                       true
-                                         saml-identity-provider-uri         default-idp-uri
-                                         saml-identity-provider-certificate nil]
-        (is (some? (client/client :get 400 "/auth/sso")))))))
+  (with-other-sso-types-disabled!
+    (mt/with-premium-features #{:sso-saml}
+      (testing "SSO requests fail if SAML hasn't been configured or enabled"
+        (mt/with-temporary-setting-values [saml-enabled                       false
+                                           saml-identity-provider-uri         nil
+                                           saml-identity-provider-certificate nil]
+          (is (some? (client/client :get 400 "/auth/sso")))))
+
+      (testing "SSO requests fail if SAML has been configured but not enabled"
+        (mt/with-temporary-setting-values [saml-enabled                       false
+                                           saml-identity-provider-uri         default-idp-uri
+                                           saml-identity-provider-certificate default-idp-cert]
+          (is (some? (client/client :get 400 "/auth/sso")))))
+
+      (testing "SSO requests fail if SAML is enabled but hasn't been configured"
+        (mt/with-temporary-setting-values [saml-enabled               true
+                                           saml-identity-provider-uri nil]
+          (is (some? (client/client :get 400 "/auth/sso")))))
+
+      (testing "The IDP provider certificate must also be included for SSO to be configured"
+        (mt/with-temporary-setting-values [saml-enabled                       true
+                                           saml-identity-provider-uri         default-idp-uri
+                                           saml-identity-provider-certificate nil]
+          (is (some? (client/client :get 400 "/auth/sso"))))))))
 
 ;; TODO - maybe this belongs in a util namespace?
 (defn- uri->params-map
@@ -168,81 +171,85 @@
    (for [^BasicNameValuePair pair (-> (URL. uri-str) .getQuery (URLEncodedUtils/parse StandardCharsets/UTF_8))]
      [(keyword (.getName pair)) (.getValue pair)])))
 
-(deftest uri->params-map-test
+(deftest ^:parallel uri->params-map-test
   (is (= {:a "b", :c "d"}
          (uri->params-map "http://localhost?a=b&c=d"))))
 
 (deftest request-xml-test
   (testing "Make sure the requests we generate look correct"
-    (with-saml-default-setup
-      (mt/with-temporary-setting-values [site-url "http://localhost:3000"]
-        (let [orig saml/request]
-          (with-redefs [saml/request (fn [m]
-                                       (testing "Request ID should be of the format id-<uuid>"
-                                         (is (re= (re-pattern (str "^id-" u/uuid-regex "$"))
-                                                  (:request-id m))))
-                                       (mt/with-clock #t "2020-09-30T17:53:32Z"
-                                         (orig (assoc m :request-id "id-419507d5-1d2a-43c4-bcde-3e5b9746bb47"))))]
-            (let [request  (client/client-real-response :get 302 "/auth/sso"
-                                                        {:request-options {:redirect-strategy :none}}
-                                                        :redirect default-redirect-uri)
-                  location (get-in request [:headers "Location"])
-                  base-64  (-> location uri->params-map :SAMLRequest)
-                  xml      (-> base-64
-                               codec/url-decode
-                               encode-decode/base64->inflate->str
-                               (str/replace #"\n+" "")
-                               (str/replace #">\s+<" "><"))]
-              (is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-                          "<samlp:AuthnRequest"
-                          " xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\""
-                          " AssertionConsumerServiceURL=\"http://localhost:3000/auth/sso\""
-                          " Destination=\"http://test.idp.metabase.com\""
-                          " ID=\"id-419507d5-1d2a-43c4-bcde-3e5b9746bb47\""
-                          " IssueInstant=\"2020-09-30T17:53:32Z\""
-                          " ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\""
-                          " ProviderName=\"Metabase\""
-                          " Version=\"2.0\">"
-                          "<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">Metabase</saml:Issuer>"
-                          "</samlp:AuthnRequest>")
-                     xml)))))))))
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (mt/with-temporary-setting-values [site-url "http://localhost:3000"]
+          (let [orig saml/request]
+            (with-redefs [saml/request (fn [m]
+                                         (testing "Request ID should be of the format id-<uuid>"
+                                           (is (re= (re-pattern (str "^id-" u/uuid-regex "$"))
+                                                    (:request-id m))))
+                                         (mt/with-clock #t "2020-09-30T17:53:32Z"
+                                           (orig (assoc m :request-id "id-419507d5-1d2a-43c4-bcde-3e5b9746bb47"))))]
+              (let [request  (client/client-real-response :get 302 "/auth/sso"
+                                                          {:request-options {:redirect-strategy :none}}
+                                                          :redirect default-redirect-uri)
+                    location (get-in request [:headers "Location"])
+                    base-64  (-> location uri->params-map :SAMLRequest)
+                    xml      (-> base-64
+                                 codec/url-decode
+                                 encode-decode/base64->inflate->str
+                                 (str/replace #"\n+" "")
+                                 (str/replace #">\s+<" "><"))]
+                (is (= (str "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+                            "<samlp:AuthnRequest"
+                            " xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\""
+                            " AssertionConsumerServiceURL=\"http://localhost:3000/auth/sso\""
+                            " Destination=\"http://test.idp.metabase.com\""
+                            " ID=\"id-419507d5-1d2a-43c4-bcde-3e5b9746bb47\""
+                            " IssueInstant=\"2020-09-30T17:53:32Z\""
+                            " ProtocolBinding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\""
+                            " ProviderName=\"Metabase\""
+                            " Version=\"2.0\">"
+                            "<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">Metabase</saml:Issuer>"
+                            "</samlp:AuthnRequest>")
+                       xml))))))))))
 
 (deftest redirect-test
   (testing "With SAML configured, a GET request should result in a redirect to the IDP"
-    (with-saml-default-setup
-      (let [result       (client/client-real-response :get 302 "/auth/sso"
-                                                      {:request-options {:redirect-strategy :none}}
-                                                      :redirect default-redirect-uri)
-            redirect-url (get-in result [:headers "Location"])]
-        (is (str/starts-with? redirect-url default-idp-uri))))))
-
-(deftest redirect-append-paramters-test
-  (testing (str "When the identity provider already includes a query parameter, the SAML code should spot that and "
-                "append more parameters onto the query string (rather than always include a `?newparam=here`).")
-    (with-saml-default-setup
-      (mt/with-temporary-setting-values [saml-identity-provider-uri default-idp-uri-with-param]
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
         (let [result       (client/client-real-response :get 302 "/auth/sso"
                                                         {:request-options {:redirect-strategy :none}}
                                                         :redirect default-redirect-uri)
               redirect-url (get-in result [:headers "Location"])]
-          (is (= #{:someparam :SAMLRequest :RelayState}
-                 (set (keys (uri->params-map redirect-url))))))))))
+          (is (str/starts-with? redirect-url default-idp-uri)))))))
+
+(deftest redirect-append-paramters-test
+  (testing (str "When the identity provider already includes a query parameter, the SAML code should spot that and "
+                "append more parameters onto the query string (rather than always include a `?newparam=here`).")
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (mt/with-temporary-setting-values [saml-identity-provider-uri default-idp-uri-with-param]
+          (let [result       (client/client-real-response :get 302 "/auth/sso"
+                                                          {:request-options {:redirect-strategy :none}}
+                                                          :redirect default-redirect-uri)
+                redirect-url (get-in result [:headers "Location"])]
+            (is (= #{:someparam :SAMLRequest :RelayState}
+                   (set (keys (uri->params-map redirect-url)))))))))))
 
 ;; The RelayState is data we include in the redirect request to the IDP. The IDP will include the RelayState in it's
 ;; response via the POST. This allows the FE to track what the original route the user was trying to access was and
 ;; redirect the user back to that original URL after successful authentication
 (deftest relay-state-test
-  (with-saml-default-setup
-    (do-with-some-validators-disabled
-      (fn []
-       (let [result        (client/client-real-response :get 302 "/auth/sso"
-                                                        {:request-options {:redirect-strategy :none}}
-                                                        :redirect default-redirect-uri)
-              redirect-url (get-in result [:headers "Location"])]
-          (testing (format "result = %s" (pr-str result))
-            (is (string? redirect-url))
-            (is (= default-redirect-uri
-                   (saml/base64->str (:RelayState (uri->params-map redirect-url)))))))))))
+  (with-other-sso-types-disabled!
+    (with-saml-default-setup!
+      (do-with-some-validators-disabled!
+       (fn []
+         (let [result        (client/client-real-response :get 302 "/auth/sso"
+                                                          {:request-options {:redirect-strategy :none}}
+                                                          :redirect default-redirect-uri)
+               redirect-url (get-in result [:headers "Location"])]
+           (testing (format "result = %s" (pr-str result))
+             (is (string? redirect-url))
+             (is (= default-redirect-uri
+                    (saml/base64->str (:RelayState (uri->params-map redirect-url))))))))))))
 
 (defn- saml-response-from-file [filename]
   (u/encode-base64 (slurp filename)))
@@ -289,120 +296,108 @@
 
 (deftest validate-request-id-test
   (testing "Sample response should fail because _1 isn't a request ID that we issued."
-    (with-saml-default-setup
-      (do-with-some-validators-disabled
-        (fn []
-          (testing (str "After a successful login with the identity provider, the SAML provider will POST to the "
-                        "`/auth/sso` route.")
-            (let [req-options (saml-post-request-options (saml-test-response)
-                                                         (saml/str->base64 default-redirect-uri))
-                  response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-              (is (successful-login? response))
-              (is (= default-redirect-uri
-                     (get-in response [:headers "Location"])))
-              (is (= (some-saml-attributes "rasta")
-                     (saml-login-attributes "rasta@metabase.com"))))))))))
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (do-with-some-validators-disabled!
+         (fn []
+           (testing (str "After a successful login with the identity provider, the SAML provider will POST to the "
+                         "`/auth/sso` route.")
+             (let [req-options (saml-post-request-options (saml-test-response)
+                                                          (saml/str->base64 default-redirect-uri))
+                   response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+               (is (successful-login? response))
+               (is (= default-redirect-uri
+                      (get-in response [:headers "Location"])))
+               (is (= (some-saml-attributes "rasta")
+                      (saml-login-attributes "rasta@metabase.com")))))))))))
 
 (deftest validate-signatures-test
   ;; they were edited by hand I think, so the signatures are now incorrect (?)
   (testing "The sample responses should normally fail because the <Assertion> signatures don't match"
-    (with-saml-default-setup
-      (do-with-some-validators-disabled nil #{:not-on-or-after :recipient :issuer}
-        (fn []
-          (let [req-options (saml-post-request-options (saml-test-response)
-                                                       default-redirect-uri)
-                response    (client/client-real-response :post 401 "/auth/sso" req-options)]
-            (testing (format "response =\n%s" (u/pprint-to-str response))
-              (is (not (successful-login? response))))))))))
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (do-with-some-validators-disabled!
+          nil #{:not-on-or-after :recipient :issuer}
+          (fn []
+            (let [req-options (saml-post-request-options (saml-test-response)
+                                                         default-redirect-uri)
+                  response    (client/client-real-response :post 401 "/auth/sso" req-options)]
+              (testing (format "response =\n%s" (u/pprint-to-str response))
+                (is (not (successful-login? response)))))))))))
 
 (deftest validate-not-on-or-after-test
-  (with-saml-default-setup
-    (testing "The sample responses should normally fail because the <Assertion> NotOnOrAfter has passed"
-      (do-with-some-validators-disabled nil #{:signature :recipient}
-        (fn []
-          (let [req-options (saml-post-request-options (saml-test-response)
-                                                       (saml/str->base64 default-redirect-uri))]
-            (is (not (successful-login? (client/client-real-response :post 401 "/auth/sso" req-options))))))))
-    (testing "If we time-travel then the sample responses *should* work"
-      (let [orig saml/validate]
-        (with-redefs [saml/validate (fn [& args]
-                                      (mt/with-clock #t "2018-07-01T00:00:00.000Z"
-                                        (apply orig args)))]
-          (do-with-some-validators-disabled nil #{:signature :recipient :issuer}
-            (fn []
-              (let [req-options (saml-post-request-options (saml-test-response)
-                                                           (saml/str->base64 default-redirect-uri))]
-                (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options)))))))))))
+  (with-other-sso-types-disabled!
+    (with-saml-default-setup!
+      (testing "The sample responses should normally fail because the <Assertion> NotOnOrAfter has passed"
+        (do-with-some-validators-disabled!
+          nil #{:signature :recipient}
+          (fn []
+            (let [req-options (saml-post-request-options (saml-test-response)
+                                                         (saml/str->base64 default-redirect-uri))]
+              (is (not (successful-login? (client/client-real-response :post 401 "/auth/sso" req-options)))))))))))
+
+(deftest validate-not-on-or-after-test-2
+  (with-other-sso-types-disabled!
+    (with-saml-default-setup!
+      (testing "If we time-travel then the sample responses *should* work"
+        (let [orig saml/validate]
+          (with-redefs [saml/validate (fn [& args]
+                                        (mt/with-clock #t "2018-07-01T00:00:00.000Z"
+                                          (apply orig args)))]
+            (do-with-some-validators-disabled!
+             nil #{:signature :recipient :issuer}
+             (fn []
+               (let [req-options (saml-post-request-options (saml-test-response)
+                                                            (saml/str->base64 default-redirect-uri))]
+                 (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options))))))))))))
 
 (deftest validate-recipient-test
-  (with-saml-default-setup
-    (testing (str "The sample responses all have <Recipient> of localhost:3000. "
-                  "If (site-url) is set to something different, this should fail.")
-      (do-with-some-validators-disabled nil #{:signature :not-on-or-after :issuer}
-        (fn []
-          (testing "with incorrect acs-url"
-            (mt/with-temporary-setting-values [site-url "http://localhost:9876"]
-              (let [req-options (saml-post-request-options (saml-test-response)
-                                                           (saml/str->base64 default-redirect-uri))]
-                (is (not (successful-login? (client/client-real-response :post 401 "/auth/sso" req-options)))))))
-          (testing "with correct acs-url"
-            (mt/with-temporary-setting-values [site-url "http://localhost:3000"]
-              (let [req-options (saml-post-request-options (saml-test-response)
-                                                           (saml/str->base64 default-redirect-uri))]
-                (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options)))))))))))
+  (with-other-sso-types-disabled!
+    (with-saml-default-setup!
+      (testing (str "The sample responses all have <Recipient> of localhost:3000. "
+                    "If (site-url) is set to something different, this should fail.")
+        (do-with-some-validators-disabled!
+         nil #{:signature :not-on-or-after :issuer}
+         (fn []
+           (testing "with incorrect acs-url"
+             (mt/with-temporary-setting-values [site-url "http://localhost:9876"]
+               (let [req-options (saml-post-request-options (saml-test-response)
+                                                            (saml/str->base64 default-redirect-uri))]
+                 (is (not (successful-login? (client/client-real-response :post 401 "/auth/sso" req-options)))))))
+           (testing "with correct acs-url"
+             (mt/with-temporary-setting-values [site-url "http://localhost:3000"]
+               (let [req-options (saml-post-request-options (saml-test-response)
+                                                            (saml/str->base64 default-redirect-uri))]
+                 (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options))))))))))))
 
 (deftest validate-issuer-test
-  (with-saml-default-setup
-    (testing "If the `saml-identity-provider-issuer` Setting is set, we should validate <Issuer> in Responses"
-      (do-with-some-validators-disabled nil #{:signature :not-on-or-after :recipient}
-        (letfn [(login [expected-status-code]
-                  (let [req-options (saml-post-request-options (saml-test-response)
-                                                               (saml/str->base64 default-redirect-uri))]
-                    (client/client-real-response :post expected-status-code "/auth/sso" req-options)))]
-          (fn []
-            (testing "<Issuer> matches saml-identity-provider-issuer"
-              (mt/with-temporary-setting-values [saml-identity-provider-issuer "urn:saml-metabase-test.auth0.com"]
-                (is (successful-login? (login 302)))))
-            (testing "<Issuer> does not match saml-identity-provider-issuer"
-              (mt/with-temporary-setting-values [saml-identity-provider-issuer "WRONG"]
-                (is (not (successful-login? (login 401))))))
-            (testing "saml-identity-provider-issuer is not set: shouldn't do any validation"
-              (mt/with-temporary-setting-values [saml-identity-provider-issuer nil]
-                (is (successful-login? (login 302)))))))))))
+  (with-other-sso-types-disabled!
+    (with-saml-default-setup!
+      (testing "If the `saml-identity-provider-issuer` Setting is set, we should validate <Issuer> in Responses"
+        (do-with-some-validators-disabled!
+         nil #{:signature :not-on-or-after :recipient}
+         (letfn [(login [expected-status-code]
+                   (let [req-options (saml-post-request-options (saml-test-response)
+                                                                (saml/str->base64 default-redirect-uri))]
+                     (client/client-real-response :post expected-status-code "/auth/sso" req-options)))]
+           (fn []
+             (testing "<Issuer> matches saml-identity-provider-issuer"
+               (mt/with-temporary-setting-values [saml-identity-provider-issuer "urn:saml-metabase-test.auth0.com"]
+                 (is (successful-login? (login 302)))))
+             (testing "<Issuer> does not match saml-identity-provider-issuer"
+               (mt/with-temporary-setting-values [saml-identity-provider-issuer "WRONG"]
+                 (is (not (successful-login? (login 401))))))
+             (testing "saml-identity-provider-issuer is not set: shouldn't do any validation"
+               (mt/with-temporary-setting-values [saml-identity-provider-issuer nil]
+                 (is (successful-login? (login 302))))))))))))
 
 ;; Part of accepting the POST is validating the response and the relay state so we can redirect the user to their
 ;; original destination
 (deftest login-test
   (testing "After a successful login with the identity provider, the SAML provider will POST to the `/auth/sso` route."
-    (with-saml-default-setup
-      (do-with-some-validators-disabled
-        (fn []
-          (let [req-options (saml-post-request-options (saml-test-response)
-                                                       (saml/str->base64 default-redirect-uri))
-                response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-            (is (successful-login? response))
-            (is (= default-redirect-uri
-                   (get-in response [:headers "Location"])))
-            (is (= (some-saml-attributes "rasta")
-                   (saml-login-attributes "rasta@metabase.com"))))))))
-  (testing "Still works with whitespace in the SAML post response (#23451)"
-    (with-saml-default-setup
-      (do-with-some-validators-disabled
-        (fn []
-          (let [req-options (saml-post-request-options (whitespace-response)
-                                                       (saml/str->base64 default-redirect-uri))
-                response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-            (is (successful-login? response))
-            (is (= default-redirect-uri
-                   (get-in response [:headers "Location"])))
-            (is (= (some-saml-attributes "rasta")
-                   (saml-login-attributes "rasta@metabase.com")))))))))
-
-(deftest jwt-saml-both-enabled-saml-success-test
-  (mt/with-additional-premium-features #{:sso-jwt}
-    (testing "with SAML and JWT configured, a GET request without JWT params successfully logins with SAML."
-      (with-saml-default-setup
-        (do-with-some-validators-disabled
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (do-with-some-validators-disabled!
          (fn []
            (let [req-options (saml-post-request-options (saml-test-response)
                                                         (saml/str->base64 default-redirect-uri))
@@ -413,118 +408,154 @@
              (is (= (some-saml-attributes "rasta")
                     (saml-login-attributes "rasta@metabase.com"))))))))))
 
+(deftest login-test-2
+  (testing "Still works with whitespace in the SAML post response (#23451)"
+    (with-saml-default-setup!
+      (with-other-sso-types-disabled!
+        (do-with-some-validators-disabled!
+         (fn []
+           (let [req-options (saml-post-request-options (whitespace-response)
+                                                        (saml/str->base64 default-redirect-uri))
+                 response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+             (is (successful-login? response))
+             (is (= default-redirect-uri
+                    (get-in response [:headers "Location"])))
+             (is (= (some-saml-attributes "rasta")
+                    (saml-login-attributes "rasta@metabase.com"))))))))))
+
+(deftest jwt-saml-both-enabled-saml-success-test
+  (with-other-sso-types-disabled!
+    (mt/with-additional-premium-features #{:sso-jwt}
+      (testing "with SAML and JWT configured, a GET request without JWT params successfully logins with SAML."
+        (with-saml-default-setup!
+          (do-with-some-validators-disabled!
+           (fn []
+             (let [req-options (saml-post-request-options (saml-test-response)
+                                                          (saml/str->base64 default-redirect-uri))
+                   response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+               (is (successful-login? response))
+               (is (= default-redirect-uri
+                      (get-in response [:headers "Location"])))
+               (is (= (some-saml-attributes "rasta")
+                      (saml-login-attributes "rasta@metabase.com")))))))))))
+
 (deftest login-invalid-relay-state-test
   (testing (str "if the RelayState is not set or is invalid, you are redirected back to the home page rather than "
                 "failing the entire login")
-    (doseq [relay-state ["something-random_#!@__^^"
-                         ""
-                         "   "
-                         "/"
-                         "https://badsite.com"
-                         "//badsite.com"
-                         "https:///badsite.com"]]
-      (testing (format "\nRelayState = %s" (pr-str relay-state))
-        (with-saml-default-setup
-          (do-with-some-validators-disabled
-            (fn []
-              (let [req-options (saml-post-request-options (saml-test-response) relay-state)
-                    response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-                (is (successful-login? response))
-                (is (= (public-settings/site-url)
-                       (get-in response [:headers "Location"])))
-                (is (= (some-saml-attributes "rasta")
-                       (saml-login-attributes "rasta@metabase.com"))))))))))
-
+    (with-other-sso-types-disabled!
+      (doseq [relay-state ["something-random_#!@__^^"
+                           ""
+                           "   "
+                           "/"
+                           "https://badsite.com"
+                           "//badsite.com"
+                           "https:///badsite.com"]]
+        (testing (format "\nRelayState = %s" (pr-str relay-state))
+          (with-saml-default-setup!
+            (do-with-some-validators-disabled!
+             (fn []
+               (let [req-options (saml-post-request-options (saml-test-response) relay-state)
+                     response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+                 (is (successful-login? response))
+                 (is (= (public-settings/site-url)
+                        (get-in response [:headers "Location"])))
+                 (is (= (some-saml-attributes "rasta")
+                        (saml-login-attributes "rasta@metabase.com"))))))))))))
+
+(deftest login-invalid-relay-state-test-2
   (testing "if the RelayState leads us to the wrong host, avoid the open redirect (boat#160)"
-    (doseq [redirect-url ["https://badsite.com"
-                          "//badsite.com"
-                          "https:///badsite.com"]]
-      (with-saml-default-setup
-        (mt/with-temporary-setting-values [site-url "http://localhost:3000"]
-          (do-with-some-validators-disabled
-            (fn []
-             (let [get-response (client/client :get 400 "/auth/sso"
-                                  {:request-options {:redirect-strategy :none}}
-                                  :redirect redirect-url)]
-               (testing (format "\n%s should not redirect" redirect-url)
-                 (is (= "Invalid redirect URL" (:message get-response))))))))))))
+    (with-other-sso-types-disabled!
+      (doseq [redirect-url ["https://badsite.com"
+                            "//badsite.com"
+                            "https:///badsite.com"]]
+        (with-saml-default-setup!
+          (mt/with-temporary-setting-values [site-url "http://localhost:3000"]
+            (do-with-some-validators-disabled!
+             (fn []
+               (let [get-response (client/client :get 400 "/auth/sso"
+                                                 {:request-options {:redirect-strategy :none}}
+                                                 :redirect redirect-url)]
+                 (testing (format "\n%s should not redirect" redirect-url)
+                   (is (= "Invalid redirect URL" (:message get-response)))))))))))))
 
 (deftest login-create-account-test
   (testing "A new account will be created for a SAML user we haven't seen before"
-    (mt/with-premium-features #{:audit-app}
-      (do-with-some-validators-disabled
-       (fn []
-         (with-saml-default-setup
-           (try
-            (is (not (t2/exists? User :%lower.email "newuser@metabase.com")))
-            (let [req-options (saml-post-request-options (new-user-saml-test-response)
-                                                         (saml/str->base64 default-redirect-uri))]
-              (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options))))
-            (let [new-user (t2/select-one User :email "newuser@metabase.com")]
-              (is (= {:email        "newuser@metabase.com"
-                      :first_name   "New"
-                      :is_qbnewb    true
-                      :is_superuser false
-                      :id           true
-                      :last_name    "User"
-                      :date_joined  true
-                      :common_name  "New User"}
-                     (-> (mt/boolean-ids-and-timestamps new-user)
-                         (dissoc :last_login))))
-              (testing "User Invite Event is logged."
-                (is (= {:details  {:email      "newuser@metabase.com"
-                                   :first_name "New"
-                                   :last_name  "User"
-                                   :user_group_memberships [{:id 1}]
-                                   :sso_source "saml"}
-                        :model    "User"
-                        :model_id (:id new-user)
-                        :topic    :user-invited
-                        :user_id  nil}
-                       (mt/latest-audit-log-entry :user-invited (:id new-user))))))
-            (testing "attributes"
-              (is (= (some-saml-attributes "newuser")
-                     (saml-login-attributes "newuser@metabase.com"))))
-            (finally
-             (t2/delete! User :%lower.email "newuser@metabase.com")))))))))
+    (with-other-sso-types-disabled!
+      (mt/with-premium-features #{:audit-app}
+        (do-with-some-validators-disabled!
+         (fn []
+           (with-saml-default-setup!
+             (try
+               (is (not (t2/exists? User :%lower.email "newuser@metabase.com")))
+               (let [req-options (saml-post-request-options (new-user-saml-test-response)
+                                                            (saml/str->base64 default-redirect-uri))]
+                 (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options))))
+               (let [new-user (t2/select-one User :email "newuser@metabase.com")]
+                 (is (= {:email        "newuser@metabase.com"
+                         :first_name   "New"
+                         :is_qbnewb    true
+                         :is_superuser false
+                         :id           true
+                         :last_name    "User"
+                         :date_joined  true
+                         :common_name  "New User"}
+                        (-> (mt/boolean-ids-and-timestamps new-user)
+                            (dissoc :last_login))))
+                 (testing "User Invite Event is logged."
+                   (is (= {:details  {:email      "newuser@metabase.com"
+                                      :first_name "New"
+                                      :last_name  "User"
+                                      :user_group_memberships [{:id 1}]
+                                      :sso_source "saml"}
+                           :model    "User"
+                           :model_id (:id new-user)
+                           :topic    :user-invited
+                           :user_id  nil}
+                          (mt/latest-audit-log-entry :user-invited (:id new-user))))))
+               (testing "attributes"
+                 (is (= (some-saml-attributes "newuser")
+                        (saml-login-attributes "newuser@metabase.com"))))
+               (finally
+                 (t2/delete! User :%lower.email "newuser@metabase.com"))))))))))
 
 (deftest login-update-account-test
   (testing "A new 'Unknown' name account will be created for a SAML user with no configured first or last name"
-    (do-with-some-validators-disabled
-      (fn []
-        (with-saml-default-setup
-          (try
-            (is (not (t2/exists? User :%lower.email "newuser@metabase.com")))
+    (with-other-sso-types-disabled!
+      (do-with-some-validators-disabled!
+       (fn []
+         (with-saml-default-setup!
+           (try
+             (is (not (t2/exists? User :%lower.email "newuser@metabase.com")))
             ;; login with a user with no givenname or surname attributes
-            (let [req-options (saml-post-request-options (new-user-no-names-saml-test-response)
-                                                         (saml/str->base64 default-redirect-uri))]
-              (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options)))
-              (is (= [{:email        "newuser@metabase.com"
-                       :first_name   nil
-                       :is_qbnewb    true
-                       :is_superuser false
-                       :id           true
-                       :last_name    nil
-                       :date_joined  true
-                       :common_name  "newuser@metabase.com"}]
-                     (->> (mt/boolean-ids-and-timestamps (t2/select User :email "newuser@metabase.com"))
-                          (map #(dissoc % :last_login))))))
+             (let [req-options (saml-post-request-options (new-user-no-names-saml-test-response)
+                                                          (saml/str->base64 default-redirect-uri))]
+               (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options)))
+               (is (= [{:email        "newuser@metabase.com"
+                        :first_name   nil
+                        :is_qbnewb    true
+                        :is_superuser false
+                        :id           true
+                        :last_name    nil
+                        :date_joined  true
+                        :common_name  "newuser@metabase.com"}]
+                      (->> (mt/boolean-ids-and-timestamps (t2/select User :email "newuser@metabase.com"))
+                           (map #(dissoc % :last_login))))))
             ;; login with the same user, but now givenname and surname attributes exist
-            (let [req-options (saml-post-request-options (new-user-saml-test-response)
-                                                         (saml/str->base64 default-redirect-uri))]
-              (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options)))
-              (is (= [{:email        "newuser@metabase.com"
-                       :first_name   "New"
-                       :is_qbnewb    true
-                       :is_superuser false
-                       :id           true
-                       :last_name    "User"
-                       :date_joined  true
-                       :common_name  "New User"}]
-                     (->> (mt/boolean-ids-and-timestamps (t2/select User :email "newuser@metabase.com"))
-                          (map #(dissoc % :last_login))))))
-            (finally
-              (t2/delete! User :%lower.email "newuser@metabase.com"))))))))
+             (let [req-options (saml-post-request-options (new-user-saml-test-response)
+                                                          (saml/str->base64 default-redirect-uri))]
+               (is (successful-login? (client/client-real-response :post 302 "/auth/sso" req-options)))
+               (is (= [{:email        "newuser@metabase.com"
+                        :first_name   "New"
+                        :is_qbnewb    true
+                        :is_superuser false
+                        :id           true
+                        :last_name    "User"
+                        :date_joined  true
+                        :common_name  "New User"}]
+                      (->> (mt/boolean-ids-and-timestamps (t2/select User :email "newuser@metabase.com"))
+                           (map #(dissoc % :last_login))))))
+             (finally
+               (t2/delete! User :%lower.email "newuser@metabase.com")))))))))
 
 (defn- group-memberships [user-or-id]
   (when-let [group-ids (seq (t2/select-fn-set :group_id PermissionsGroupMembership :user_id (u/the-id user-or-id)))]
@@ -532,188 +563,200 @@
 
 (deftest login-should-sync-single-group-membership
   (testing "saml group sync works when there's just a single group, which gets interpreted as a string"
-    (with-saml-default-setup
-      (do-with-some-validators-disabled
-        (fn []
-          (t2.with-temp/with-temp [PermissionsGroup group-1 {:name (str ::group-1)}]
-            (mt/with-temporary-setting-values [saml-group-sync      true
-                                               saml-group-mappings  {"group_1" [(u/the-id group-1)]}
-                                               saml-attribute-group "GroupMembership"]
-              (try
-                ;; user doesn't exist until SAML request
-                (is (not (t2/select-one-pk User :%lower.email "newuser@metabase.com")))
-                (let [req-options (saml-post-request-options (new-user-with-single-group-saml-test-response)
-                                                             (saml/str->base64 default-redirect-uri))
-                      response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-                  (is (successful-login? response))
-                  (is (= #{"All Users"
-                           ":metabase-enterprise.sso.integrations.saml-test/group-1"}
-                         (group-memberships (t2/select-one-pk User :email "newuser@metabase.com")))))
-                (finally
-                  (t2/delete! User :%lower.email "newuser@metabase.com"))))))))))
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (do-with-some-validators-disabled!
+         (fn []
+           (t2.with-temp/with-temp [PermissionsGroup group-1 {:name (str ::group-1)}]
+             (mt/with-temporary-setting-values [saml-group-sync      true
+                                                saml-group-mappings  {"group_1" [(u/the-id group-1)]}
+                                                saml-attribute-group "GroupMembership"]
+               (try
+                 ;; user doesn't exist until SAML request
+                 (is (not (t2/select-one-pk User :%lower.email "newuser@metabase.com")))
+                 (let [req-options (saml-post-request-options (new-user-with-single-group-saml-test-response)
+                                                              (saml/str->base64 default-redirect-uri))
+                       response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+                   (is (successful-login? response))
+                   (is (= #{"All Users"
+                            ":metabase-enterprise.sso.integrations.saml-test/group-1"}
+                          (group-memberships (t2/select-one-pk User :email "newuser@metabase.com")))))
+                 (finally
+                   (t2/delete! User :%lower.email "newuser@metabase.com")))))))))))
 
 (deftest login-should-sync-multiple-group-membership
   (testing "saml group sync works when there are multiple groups, which gets interpreted as a list of strings"
     (testing "when only one Attribute node exists"
-      (with-saml-default-setup
-        (do-with-some-validators-disabled
-          (fn []
-            (mt/with-temp [PermissionsGroup group-1 {:name (str ::group-1)}
-                           PermissionsGroup group-2 {:name (str ::group-2)}]
-              (mt/with-temporary-setting-values [saml-group-sync      true
-                                                 saml-group-mappings  {"group_1" [(u/the-id group-1)]
-                                                                       "group_2" [(u/the-id group-2)]}
-                                                 saml-attribute-group "GroupMembership"]
-                (try
-                  (testing "user doesn't exist until SAML request"
-                    (is (not (t2/select-one-pk User :%lower.email "newuser@metabase.com"))))
-                  (let [req-options (saml-post-request-options (new-user-with-groups-saml-test-response)
-                                                               (saml/str->base64 default-redirect-uri))
-                        response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-                    (is (successful-login? response))
-                    (is (= #{"All Users"
-                             ":metabase-enterprise.sso.integrations.saml-test/group-1"
-                             ":metabase-enterprise.sso.integrations.saml-test/group-2"}
-                           (group-memberships (t2/select-one-pk User :email "newuser@metabase.com")))))
-                  (finally
-                    (t2/delete! User :%lower.email "newuser@metabase.com")))))))))
-    (testing "when several Attribute nodes exist (issue #20744)"
-      (with-saml-default-setup
-        (do-with-some-validators-disabled
-          (fn []
-            (mt/with-temp [PermissionsGroup group-1 {:name (str ::group-1)}
-                           PermissionsGroup group-2 {:name (str ::group-2)}]
-              (mt/with-temporary-setting-values [saml-group-sync      true
-                                                 saml-group-mappings  {"group_1" [(u/the-id group-1)]
-                                                                       "group_2" [(u/the-id group-2)]}
-                                                 saml-attribute-group "GroupMembership"]
-                (try
-                  (testing "user doesn't exist until SAML request"
-                    (is (not (t2/select-one-pk User :%lower.email "newuser@metabase.com"))))
-                  (let [req-options (saml-post-request-options (new-user-with-groups-in-separate-attribute-nodes-saml-test-response)
-                                                               (saml/str->base64 default-redirect-uri))
-                        response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-                    (is (successful-login? response))
-                    (is (= #{"All Users"
-                             ":metabase-enterprise.sso.integrations.saml-test/group-1"
-                             ":metabase-enterprise.sso.integrations.saml-test/group-2"}
-                           (group-memberships (t2/select-one-pk User :email "newuser@metabase.com")))))
-                  (finally
-                    (t2/delete! User :%lower.email "newuser@metabase.com")))))))))))
+      (with-other-sso-types-disabled!
+        (with-saml-default-setup!
+          (do-with-some-validators-disabled!
+           (fn []
+             (mt/with-temp [PermissionsGroup group-1 {:name (str ::group-1)}
+                            PermissionsGroup group-2 {:name (str ::group-2)}]
+               (mt/with-temporary-setting-values [saml-group-sync      true
+                                                  saml-group-mappings  {"group_1" [(u/the-id group-1)]
+                                                                        "group_2" [(u/the-id group-2)]}
+                                                  saml-attribute-group "GroupMembership"]
+                 (try
+                   (testing "user doesn't exist until SAML request"
+                     (is (not (t2/select-one-pk User :%lower.email "newuser@metabase.com"))))
+                   (let [req-options (saml-post-request-options (new-user-with-groups-saml-test-response)
+                                                                (saml/str->base64 default-redirect-uri))
+                         response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+                     (is (successful-login? response))
+                     (is (= #{"All Users"
+                              ":metabase-enterprise.sso.integrations.saml-test/group-1"
+                              ":metabase-enterprise.sso.integrations.saml-test/group-2"}
+                            (group-memberships (t2/select-one-pk User :email "newuser@metabase.com")))))
+                   (finally
+                     (t2/delete! User :%lower.email "newuser@metabase.com"))))))))))))
+
+(deftest login-should-sync-multiple-group-membership-2
+  (testing "saml group sync works when there are multiple groups, which gets interpreted as a list of strings"
+    (testing "when several Attribute nodes exist (#20744)"
+      (with-other-sso-types-disabled!
+        (with-saml-default-setup!
+          (do-with-some-validators-disabled!
+           (fn []
+             (mt/with-temp [PermissionsGroup group-1 {:name (str ::group-1)}
+                            PermissionsGroup group-2 {:name (str ::group-2)}]
+               (mt/with-temporary-setting-values [saml-group-sync      true
+                                                  saml-group-mappings  {"group_1" [(u/the-id group-1)]
+                                                                        "group_2" [(u/the-id group-2)]}
+                                                  saml-attribute-group "GroupMembership"]
+                 (try
+                   (testing "user doesn't exist until SAML request"
+                     (is (not (t2/select-one-pk User :%lower.email "newuser@metabase.com"))))
+                   (let [req-options (saml-post-request-options (new-user-with-groups-in-separate-attribute-nodes-saml-test-response)
+                                                                (saml/str->base64 default-redirect-uri))
+                         response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+                     (is (successful-login? response))
+                     (is (= #{"All Users"
+                              ":metabase-enterprise.sso.integrations.saml-test/group-1"
+                              ":metabase-enterprise.sso.integrations.saml-test/group-2"}
+                            (group-memberships (t2/select-one-pk User :email "newuser@metabase.com")))))
+                   (finally
+                     (t2/delete! User :%lower.email "newuser@metabase.com"))))))))))))
 
 (deftest relay-state-e2e-test
   (testing "Redirect URL (RelayState) should work correctly end-to-end (#13666)"
-    (with-saml-default-setup
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
       ;; The test HTTP client will automatically URL encode these for us.
-      (doseq [redirect-url ["http://localhost:3001/collection/root"
-                            default-redirect-uri
-                            "http://localhost:3001/"]]
-        (testing (format "\nredirect URL = %s" redirect-url)
-          (let [result     (client/client-real-response :get 302 "/auth/sso"
-                                                        {:request-options {:redirect-strategy :none}}
-                                                        :redirect redirect-url)
-                location   (get-in result [:headers "Location"])
-                _          (is (string? location))
-                params-map (uri->params-map location)]
-            (testing (format "\nresult =\n%s" (u/pprint-to-str params-map))
-              (testing "\nRelay state URL should be base-64 encoded"
-                (is (= (saml/str->base64 redirect-url)
-                       (:RelayState params-map))))
-              (testing "\nPOST request should redirect to the original redirect URL"
-                (do-with-some-validators-disabled
-                 (fn []
-                   (let [req-options (saml-post-request-options (saml-test-response)
-                                                                (:RelayState params-map))
-                         response    (client/client-real-response :post 302 "/auth/sso" req-options)]
-                     (is (successful-login? response))
-                     (is (= redirect-url
-                            (get-in response [:headers "Location"]))))))))))))))
-
-(deftest sso-subpath-e2e-test
-  (testing "Redirect URL should correcly append the site-url when the redirect is a relative path (#28650)"
-    (with-saml-default-setup
-      (doseq [redirect-url ["/collection/root"
-                            "/test"
-                            "/"]]
-        (testing (format "\nredirect URL = %s" redirect-url)
-          (mt/with-temporary-setting-values [site-url "http://localhost:3001/path"]
+        (doseq [redirect-url ["http://localhost:3001/collection/root"
+                              default-redirect-uri
+                              "http://localhost:3001/"]]
+          (testing (format "\nredirect URL = %s" redirect-url)
             (let [result     (client/client-real-response :get 302 "/auth/sso"
-                                                   {:request-options {:redirect-strategy :none}}
-                                                   :redirect redirect-url)
+                                                          {:request-options {:redirect-strategy :none}}
+                                                          :redirect redirect-url)
                   location   (get-in result [:headers "Location"])
                   _          (is (string? location))
                   params-map (uri->params-map location)]
               (testing (format "\nresult =\n%s" (u/pprint-to-str params-map))
-                (testing "\nPOST request should redirect to the original redirect URL with the correct site-url path"
-                  (do-with-some-validators-disabled
+                (testing "\nRelay state URL should be base-64 encoded"
+                  (is (= (saml/str->base64 redirect-url)
+                         (:RelayState params-map))))
+                (testing "\nPOST request should redirect to the original redirect URL"
+                  (do-with-some-validators-disabled!
                    (fn []
                      (let [req-options (saml-post-request-options (saml-test-response)
                                                                   (:RelayState params-map))
                            response    (client/client-real-response :post 302 "/auth/sso" req-options)]
                        (is (successful-login? response))
-                       (is (= (str "http://localhost:3001/path" redirect-url)
+                       (is (= redirect-url
                               (get-in response [:headers "Location"])))))))))))))))
 
+(deftest sso-subpath-e2e-test
+  (testing "Redirect URL should correcly append the site-url when the redirect is a relative path (#28650)"
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (doseq [redirect-url ["/collection/root"
+                              "/test"
+                              "/"]]
+          (testing (format "\nredirect URL = %s" redirect-url)
+            (mt/with-temporary-setting-values [site-url "http://localhost:3001/path"]
+              (let [result     (client/client-real-response :get 302 "/auth/sso"
+                                                            {:request-options {:redirect-strategy :none}}
+                                                            :redirect redirect-url)
+                    location   (get-in result [:headers "Location"])
+                    _          (is (string? location))
+                    params-map (uri->params-map location)]
+                (testing (format "\nresult =\n%s" (u/pprint-to-str params-map))
+                  (testing "\nPOST request should redirect to the original redirect URL with the correct site-url path"
+                    (do-with-some-validators-disabled!
+                     (fn []
+                       (let [req-options (saml-post-request-options (saml-test-response)
+                                                                    (:RelayState params-map))
+                             response    (client/client-real-response :post 302 "/auth/sso" req-options)]
+                         (is (successful-login? response))
+                         (is (= (str "http://localhost:3001/path" redirect-url)
+                                (get-in response [:headers "Location"]))))))))))))))))
+
 (deftest create-new-saml-user-no-user-provisioning-test
   (testing "When user provisioning is disabled, throw an error if we attempt to create a new user."
-    (with-saml-default-setup
-     (with-redefs [sso-settings/saml-user-provisioning-enabled? (constantly false)
-                   public-settings/site-name (constantly "test")]
-         (is
-          (thrown-with-msg?
-           clojure.lang.ExceptionInfo
-           #"Sorry, but you'll need a test account to view this page. Please contact your administrator."
-           (#'saml.mt/fetch-or-create-user! {:first-name "Test"
-                                             :last-name  "user"
-                                             :email      "test1234@metabsae.com"})))))))
+    (with-other-sso-types-disabled!
+      (with-saml-default-setup!
+        (with-redefs [sso-settings/saml-user-provisioning-enabled? (constantly false)
+                      public-settings/site-name (constantly "test")]
+          (is
+           (thrown-with-msg?
+            clojure.lang.ExceptionInfo
+            #"Sorry, but you'll need a test account to view this page. Please contact your administrator."
+            (#'saml.mt/fetch-or-create-user! {:first-name "Test"
+                                              :last-name  "user"
+                                              :email      "test1234@metabsae.com"}))))))))
 
 (deftest logout-should-delete-session-test-slo-enabled
   (testing "Successful SAML SLO logouts should delete the user's session, when saml-slo-enabled."
-    (mt/with-temporary-setting-values [saml-slo-enabled true]
-      (let [session-id (str (random-uuid))]
-        (mt/with-temp [:model/User user {:email "saml_test@metabase.com" :sso_source "saml"}
-                       :model/Session _ {:user_id (:id user) :id session-id}]
-          (with-saml-default-setup
-            (is (t2/exists? :model/Session :id session-id))
-            (let [req-options (-> (saml-post-request-options
-                                   (saml-slo-test-response)
-                                   (saml/str->base64 default-redirect-uri))
+    (with-other-sso-types-disabled!
+      (mt/with-temporary-setting-values [saml-slo-enabled true]
+        (let [session-id (str (random-uuid))]
+          (mt/with-temp [:model/User user {:email "saml_test@metabase.com" :sso_source "saml"}
+                         :model/Session _ {:user_id (:id user) :id session-id}]
+            (with-saml-default-setup!
+              (is (t2/exists? :model/Session :id session-id))
+              (let [req-options (-> (saml-post-request-options
+                                     (saml-slo-test-response)
+                                     (saml/str->base64 default-redirect-uri))
                                   ;; Client sends their session cookie during the SLO request redirect from the IDP.
-                                  (assoc-in [:request-options :cookies mw.session/metabase-session-cookie :value] session-id))
-                  response    (client/client-real-response :post 302 "/auth/sso/handle_slo" req-options)]
-              (is (str/blank? (get-in response [:cookies mw.session/metabase-session-cookie :value]))
-                  "After a successful log-out, you don't have a session")
-              (is (not (t2/exists? :model/Session :id session-id))
-                  "After a successful log-out, the session is deleted"))))))))
+                                    (assoc-in [:request-options :cookies mw.session/metabase-session-cookie :value] session-id))
+                    response    (client/client-real-response :post 302 "/auth/sso/handle_slo" req-options)]
+                (is (str/blank? (get-in response [:cookies mw.session/metabase-session-cookie :value]))
+                    "After a successful log-out, you don't have a session")
+                (is (not (t2/exists? :model/Session :id session-id))
+                    "After a successful log-out, the session is deleted")))))))))
 
 (deftest logout-should-delete-session-test-slo-disabled
   (testing "Successful SAML SLO logouts should not delete the user's session, when not saml-slo-enabled."
-    (mt/with-temporary-setting-values [saml-slo-enabled false]
-      (let [session-id (str (random-uuid))]
-        (mt/with-temp [:model/User user {:email "saml_test@metabase.com" :sso_source "saml"}
-                       :model/Session _ {:user_id (:id user) :id session-id}]
-          (with-saml-default-setup
-            (is (t2/exists? :model/Session :id session-id))
-            (let [req-options (-> (saml-post-request-options
-                                   (saml-slo-test-response)
-                                   (saml/str->base64 default-redirect-uri))
+    (with-other-sso-types-disabled!
+      (mt/with-temporary-setting-values [saml-slo-enabled false]
+        (let [session-id (str (random-uuid))]
+          (mt/with-temp [:model/User user {:email "saml_test@metabase.com" :sso_source "saml"}
+                         :model/Session _ {:user_id (:id user) :id session-id}]
+            (with-saml-default-setup!
+              (is (t2/exists? :model/Session :id session-id))
+              (let [req-options (-> (saml-post-request-options
+                                     (saml-slo-test-response)
+                                     (saml/str->base64 default-redirect-uri))
                                   ;; Client sends their session cookie during the SLO request redirect from the IDP.
-                                  (assoc-in [:request-options :cookies mw.session/metabase-session-cookie :value] session-id))
-                  response    (client/client-real-response :post 403 "/auth/sso/handle_slo" req-options)]
-              (is (str/blank? (get-in response [:cookies mw.session/metabase-session-cookie :value]))
-                  "After a successful log-out, you don't have a session")
-              (is (t2/exists? :model/Session :id session-id)
-                  "After a successful log-out, the session is deleted"))))))))
+                                    (assoc-in [:request-options :cookies mw.session/metabase-session-cookie :value] session-id))
+                    response    (client/client-real-response :post 403 "/auth/sso/handle_slo" req-options)]
+                (is (str/blank? (get-in response [:cookies mw.session/metabase-session-cookie :value]))
+                    "After a successful log-out, you don't have a session")
+                (is (t2/exists? :model/Session :id session-id)
+                    "After a successful log-out, the session is deleted")))))))))
 
 (deftest logout-should-delete-session-when-idp-slo-conf-missing-test
   (testing "Missing SAML SLO config logouts should still delete the user's session."
-    (let [session-id (str (random-uuid))]
-      (mt/with-temp [:model/User user {:email "saml_test@metabase.com" :sso_source "saml"}
-                     :model/Session _ {:user_id (:id user) :id session-id}]
-        (is (t2/exists? :model/Session :id session-id))
-        (let [req-options (-> (saml-post-request-options
-                               (saml-test-response)
-                               (saml/str->base64 default-redirect-uri))
-                              (assoc-in [:request-options :cookies mw.session/metabase-session-cookie :value] session-id))]
-          (client/client :post "/auth/sso/logout" req-options)
-          (is (not (t2/exists? :model/Session :id session-id))))))))
+    (with-other-sso-types-disabled!
+      (let [session-id (str (random-uuid))]
+        (mt/with-temp [:model/User user {:email "saml_test@metabase.com" :sso_source "saml"}
+                       :model/Session _ {:user_id (:id user) :id session-id}]
+          (is (t2/exists? :model/Session :id session-id))
+          (let [req-options (-> (saml-post-request-options
+                                 (saml-test-response)
+                                 (saml/str->base64 default-redirect-uri))
+                                (assoc-in [:request-options :cookies mw.session/metabase-session-cookie :value] session-id))]
+            (client/client :post "/auth/sso/logout" req-options)
+            (is (not (t2/exists? :model/Session :id session-id)))))))))
diff --git a/enterprise/backend/test/metabase_enterprise/stale/api_test.clj b/enterprise/backend/test/metabase_enterprise/stale/api_test.clj
index 028ffc0b68ed9a7b32ed319886232c79372e26e6..2f14e499b8357dc6ad8cd328a3814e27f710e492 100644
--- a/enterprise/backend/test/metabase_enterprise/stale/api_test.clj
+++ b/enterprise/backend/test/metabase_enterprise/stale/api_test.clj
@@ -3,7 +3,7 @@
              [clojure.test :refer [deftest testing is]]
              [metabase.analytics.snowplow-test :as snowplow-test]
              [metabase.models.collection :as collection]
-             [metabase.models.collection-test :refer [with-collection-hierarchy]]
+             [metabase.models.collection-test :refer [with-collection-hierarchy!]]
              [metabase.stale-test :as stale.test]
              [metabase.test :as mt]
              [metabase.util :as u]))
@@ -21,7 +21,7 @@
 
 (deftest can-fetch-stale-candidates
   (mt/with-premium-features #{:collection-cleanup}
-    (with-collection-hierarchy [{:keys [a b c d e]}]
+    (with-collection-hierarchy! [{:keys [a b c d e]}]
       (stale.test/with-stale-items [:model/Card card {:collection_id (:id a)}
                                     :model/Dashboard dashboard {:collection_id (:id a)}]
         (let [result (mt/user-http-request :crowberto :get 200 (str "collection/" (u/the-id a) "/stale"))]
@@ -180,7 +180,7 @@
 (deftest stale-items-limits-and-offsets-work-correctly
   (mt/with-premium-features #{:collection-cleanup}
     (testing "Limits and offsets work correctly"
-      (with-collection-hierarchy [{:keys [a]}]
+      (with-collection-hierarchy! [{:keys [a]}]
         (let [get-names-page (fn [limit offset]
                                (->> (mt/user-http-request :crowberto :get 200 (str "collection/" (:id a) "/stale")
                                                           :limit limit
@@ -204,7 +204,7 @@
 
 (deftest snowplow-events-are-emitted
   (mt/with-premium-features #{:collection-cleanup}
-    (with-collection-hierarchy [{:keys [a]}]
+    (with-collection-hierarchy! [{:keys [a]}]
       (snowplow-test/with-fake-snowplow-collector
         (mt/user-http-request :crowberto :get 200 (str "collection/" (u/the-id a) "/stale")
                               :before_date "1988-01-21")
diff --git a/enterprise/backend/test/metabase_enterprise/test.clj b/enterprise/backend/test/metabase_enterprise/test.clj
index 92c277be72182add4f217d804d75923de723158b..053eaf8bced03abca2f43c8fc3122c507eb5b7b3 100644
--- a/enterprise/backend/test/metabase_enterprise/test.clj
+++ b/enterprise/backend/test/metabase_enterprise/test.clj
@@ -10,4 +10,4 @@
  [sandbox.tu
   with-gtaps!
   with-gtaps-for-user!
-  with-user-attributes])
+  with-user-attributes!])
diff --git a/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj b/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj
index 596a9bf0b952cd585df9b05c6ac71c284c4273f3..6a0850bff3e710b00f1969175b19cf7845c7d1a8 100644
--- a/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj
+++ b/modules/drivers/druid/test/metabase/driver/druid/query_processor_test.clj
@@ -89,14 +89,14 @@
                [:= [:field 2 nil] "threecan"]]))
           ":or filters with no temporal filters should return nil"))))
 
-(defn- do-query->native [query]
+(defn- do-query->native! [query]
   (driver/with-driver :druid
     (tqpt/with-flattened-dbdef
       (with-redefs [druid.qp/random-query-id (constantly "<Query ID>")]
         (qp.compile/compile query)))))
 
-(defmacro ^:private query->native [query]
-  `(do-query->native
+(defmacro ^:private query->native! [query]
+  `(do-query->native!
     (mt/mbql-query ~'checkins
       ~query)))
 
@@ -124,7 +124,7 @@
                               :aggregator {:type :count, :name "__count_0"}}]}
               :query-type  ::druid.qp/topN
               :mbql?       true}
-             (query->native
+             (query->native!
               #_:clj-kondo/ignore
               {:aggregation [[:* [:count $id] 10]]
                :breakout    [$venue_price]}))))))
@@ -148,7 +148,7 @@
                                             :round      true}]}
               :query-type  ::druid.qp/topN
               :mbql?       true}
-             (query->native
+             (query->native!
               #_:clj-kondo/ignore
               {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
                :breakout    [$venue_category_name]
@@ -175,7 +175,7 @@
                                                      {:dimension "user_name", :direction :ascending}]}}
               :query-type  ::druid.qp/groupBy
               :mbql?       true}
-             (query->native
+             (query->native!
               #_:clj-kondo/ignore
               {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
                :breakout    [$venue_category_name $user_name]
@@ -203,7 +203,7 @@
                                            :limit   5}}
               :query-type  ::druid.qp/groupBy
               :mbql?       true}
-             (query->native
+             (query->native!
               {:aggregation [[:aggregation-options [:distinct $checkins.venue_name] {:name "__count_0"}]]
                :breakout    [$venue_category_name $user_name]
                :order-by    [[:desc [:aggregation 0]] [:asc $checkins.venue_category_name]]
@@ -232,7 +232,7 @@
                                                    {:type :finalizingFieldAccess, :fieldName "__distinct_0"}]}]}
                 :query-type  ::druid.qp/total
                 :mbql?       true}
-               (query->native
+               (query->native!
                 {:aggregation [[:+ 1 [:aggregation-options [:distinct $checkins.venue_name] {:name "__distinct_0"}]]]})))))))
 
 (defn- table-rows-sample []
diff --git a/modules/drivers/redshift/test/metabase/driver/redshift_test.clj b/modules/drivers/redshift/test/metabase/driver/redshift_test.clj
index 9db1a8422bbd0f49f52b397de3e663b70e28dc1f..59a8512a9b09eaae7cc6f782e6532f2e5ccf90ef 100644
--- a/modules/drivers/redshift/test/metabase/driver/redshift_test.clj
+++ b/modules/drivers/redshift/test/metabase/driver/redshift_test.clj
@@ -53,7 +53,7 @@
               (#'sql.qp/add-default-select :redshift)
               (sql.qp/format-honeysql :redshift)))))
 
-(defn- query->native [query]
+(defn- query->native! [query]
   (let [native-query (atom nil)
         check-sql-fn (fn [_ _ sql & _]
                        (reset! native-query sql)
@@ -94,7 +94,7 @@
                            (str/replace #"\Q{{schema}}\E" (redshift.test/unique-session-schema))))]
         (is (= expected
                (sql->lines
-                (query->native
+                (query->native!
                  (assoc
                   (mt/mbql-query users {:limit 2000})
                   :parameters [{:type   "id"
@@ -317,7 +317,7 @@
   (mt/test-driver :redshift
     (testing "metabase_cache tables should be excluded from the describe-database results"
       (mt/dataset avian-singles
-        (mt/with-persistence-enabled [persist-models!]
+        (mt/with-persistence-enabled! [persist-models!]
           (let [details (assoc (:details (mt/db))
                                :schema-filters-type "inclusion"
                                :schema-filters-patterns "metabase_cache*,20*,pg_*")] ; 20* matches test session schemas
diff --git a/modules/drivers/snowflake/test/metabase/driver/snowflake_test.clj b/modules/drivers/snowflake/test/metabase/driver/snowflake_test.clj
index 3825b16a304e43d952837b52f24f9c6734f91db6..066c0c687ab53677a3e5e6280d8076282852c405 100644
--- a/modules/drivers/snowflake/test/metabase/driver/snowflake_test.clj
+++ b/modules/drivers/snowflake/test/metabase/driver/snowflake_test.clj
@@ -41,7 +41,7 @@
 
 (set! *warn-on-reflection* true)
 
-(defn- query->native [query]
+(defn- query->native! [query]
   (let [check-sql-fn (fn [_ _ sql & _]
                        (throw (ex-info "done" {::native-query sql})))]
     (with-redefs [sql-jdbc.execute/prepared-statement check-sql-fn
@@ -702,7 +702,7 @@
                           "userId" 1000
                           "databaseId" (mt/id)}
             result-query (driver/prettify-native-form :snowflake
-                           (query->native
+                           (query->native!
                              (assoc
                                (mt/mbql-query users {:limit 2000})
                                :parameters [{:type   "id"
diff --git a/test/metabase/actions/execution_test.clj b/test/metabase/actions/execution_test.clj
index 7e9ad8a89336693159f994fb7325898058bec761..84d2e086236ccb24431155e0fc173276c4ec8a1e 100644
--- a/test/metabase/actions/execution_test.clj
+++ b/test/metabase/actions/execution_test.clj
@@ -27,7 +27,7 @@
                      :cache-strategy nil)]
           (mt/with-actions [_                   {:type :model :dataset_query dataset-query}
                             {:keys [action-id]} {:type :implicit :kind "row/update"}]
-            (process-userland-query-test/with-query-execution [qe query]
+            (process-userland-query-test/with-query-execution! [qe query]
               (is (= {"id" 1 "name" "Red Medicine"}
                      (actions.execution/fetch-values (action/select-action :id action-id) {"id" 1})))
               (is (=? {:action_id action-id}
diff --git a/test/metabase/actions/test_util.clj b/test/metabase/actions/test_util.clj
index 20421ae06e94b980b4131f695b2badc1e9e8f111..b06d795b0dfaaf327c5903c9cc3cd4d5b993b139 100644
--- a/test/metabase/actions/test_util.clj
+++ b/test/metabase/actions/test_util.clj
@@ -237,6 +237,8 @@
                                        options-map))]
         {:action-id action-id :model-id model-id}))))
 
+;;; TODO FIXME -- rename this to [[with-actions!]] and then remove the Kondo ignore comment below
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-actions
   "Execute `body` with newly created Actions.
   `binding-forms-and-options-maps` is a vector of even number of elements, binding and options-map,
@@ -310,6 +312,8 @@
   [& body]
   `(do-with-actions-set! false (fn [] ~@body)))
 
+;;; TODO FIXME -- rename this to [[with-actions!]] and then remove the Kondo ignore comment below
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-actions-test-data-and-actions-enabled
   "Combines [[with-actions-test-data]] and [[with-actions-enabled]]."
   {:style/indent 0}
diff --git a/test/metabase/actions_test.clj b/test/metabase/actions_test.clj
index 755a6c02b789ca2463d879a85756ba2d0105c14d..f151f621c31968b8792ef7511d0f127ff9a1df8b 100644
--- a/test/metabase/actions_test.clj
+++ b/test/metabase/actions_test.clj
@@ -19,7 +19,7 @@
 
 (set! *warn-on-reflection* true)
 
-(defmacro with-actions-test-data-and-actions-permissively-enabled
+(defmacro with-actions-test-data-and-actions-permissively-enabled!
   "Combines [[mt/with-actions-test-data-and-actions-enabled]] with full permissions."
   {:style/indent 0}
   [& body]
@@ -38,7 +38,7 @@
 (deftest create-test
   (testing "row/create"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (let [response (actions/perform-action! :row/create
                                                 (assoc (mt/mbql-query categories) :create-row {(format-field-name :name) "created_row"}))]
           (is (=? {:created-row {(format-field-name :id)   76
@@ -52,7 +52,7 @@
 (deftest create-invalid-data-test
   (testing "row/create -- invalid data"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (is (= 75
                (categories-row-count)))
         (is (thrown-with-msg? Exception (case driver/*driver*
@@ -72,7 +72,7 @@
 (deftest update-test
   (testing "row/update"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (is (= {:rows-updated [1]}
                (actions/perform-action! :row/update
                                         (assoc (mt/mbql-query categories {:filter [:= $id 50]})
@@ -85,7 +85,7 @@
 (deftest delete-test
   (testing "row/delete"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (is (= {:rows-deleted [1]}
                (actions/perform-action! :row/delete
                                         (mt/mbql-query categories {:filter [:= $id 50]})))
@@ -210,7 +210,7 @@
   (testing "row/delete"
     (testing "should return error message if value cannot be parsed correctly for Field in question"
       (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-        (with-actions-test-data-and-actions-permissively-enabled
+        (with-actions-test-data-and-actions-permissively-enabled!
           (is (thrown-with-msg? Exception #"Error filtering against :type/(Big)?Integer Field: unable to parse String \"one\" to a :type/(Big)?Integer"
                                 ;; TODO -- this really should be returning a 400 but we need to rework the code in
                                 ;; [[metabase.driver.sql-jdbc.actions]] a little to have that happen without changing other stuff
@@ -227,7 +227,7 @@
     (testing "FK constraint violations errors should have nice error messages (at least for Postgres) (#24021)"
       (mt/test-drivers (mt/normal-drivers-with-feature :actions)
         (mt/with-actions-test-data-tables #{"venues" "categories"}
-          (with-actions-test-data-and-actions-permissively-enabled
+          (with-actions-test-data-and-actions-permissively-enabled!
 
             ;; attempting to delete the `Pizza` category should fail because there are several rows in `venues` that have
             ;; this `category_id` -- it's an FK constraint violation.
@@ -255,7 +255,7 @@
 (deftest bulk-create-happy-path-test
   (testing "bulk/create"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (is (= 75
                (categories-row-count)))
         (is (= {:created-rows [{(format-field-name :id) 76, (format-field-name :name) "NEW_A"}
@@ -275,7 +275,7 @@
 (deftest bulk-create-failure-test
   (testing "bulk/create"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (testing "error in some of the rows in request body"
           (is (= 75
                  (categories-row-count)))
@@ -311,7 +311,7 @@
 (deftest bulk-delete-happy-path-test
   (testing "bulk/delete"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (is (= 75
                (categories-row-count)))
         (is (= {:success true}
@@ -326,7 +326,7 @@
 (deftest bulk-delete-failure-test
   (testing "bulk/delete"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (testing "error in some of the rows"
           (is (= 75
                  (categories-row-count)))
@@ -389,7 +389,7 @@
 (deftest bulk-update-happy-path-test
   (testing "bulk/update"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (is (= [[1 "African"]
                 [2 "American"]
                 [3 "Artisan"]]
@@ -413,7 +413,7 @@
 (deftest bulk-update-failure-test
   (testing "bulk/update"
     (mt/test-drivers (mt/normal-drivers-with-feature :actions)
-      (with-actions-test-data-and-actions-permissively-enabled
+      (with-actions-test-data-and-actions-permissively-enabled!
         (let [id                 (format-field-name :id)
               name               (format-field-name :name)
               update-categories! (fn [rows]
@@ -497,7 +497,7 @@
     (let [username "username", password "password"]
       (with-open [ssh-server (basic-auth-ssh-server username password)]
         (doseq [[correct-password? ssh-password] [[true password] [false "wrong-password"]]]
-          (with-actions-test-data-and-actions-permissively-enabled
+          (with-actions-test-data-and-actions-permissively-enabled!
             (let [ssh-port (.getPort ^SshServer ssh-server)]
               (let [details (t2/select-one-fn :details 'Database :id (mt/id))]
                 (t2/update! 'Database (mt/id)
diff --git a/test/metabase/analytics/prometheus_test.clj b/test/metabase/analytics/prometheus_test.clj
index 52ff2f9e7277f5de05d7a1ac4867828427c9b566..9981879bffd75966a747426481c91b97959aa010 100644
--- a/test/metabase/analytics/prometheus_test.clj
+++ b/test/metabase/analytics/prometheus_test.clj
@@ -95,7 +95,7 @@
        str/split-lines
        (remove #(str/starts-with? % "#"))))
 
-(defmacro with-prometheus-system
+(defmacro with-prometheus-system!
   "Run tests with a prometheus web server and registry. Provide binding symbols in a tuple of [port system]. Port will
   be bound to the random port used for the metrics endpoint and system will be a [[PrometheusSystem]] which has a
   registry and web-server."
@@ -110,27 +110,27 @@
 
 (deftest web-server-test
   (testing "Can get metrics from the web-server"
-    (with-prometheus-system [port _]
+    (with-prometheus-system! [port _]
       (let [metrics-in-registry (metric-tags port)]
         (is (seq (set/intersection common-metrics metrics-in-registry))
             "Did not get metrics from the port"))))
   (testing "Throws helpful message if cannot start server"
     ;; start another system on the same port
-    (with-prometheus-system [port _]
+    (with-prometheus-system! [port _]
       (is (thrown-with-msg? clojure.lang.ExceptionInfo
                             #"Failed to initialize Prometheus on port"
                             (#'prometheus/make-prometheus-system port "test-failure"))))))
 
 (deftest c3p0-collector-test
   (testing "Registry has c3p0 registered"
-    (with-prometheus-system [_ system]
+    (with-prometheus-system! [_ system]
       (let [registry       (.registry system)
             c3p0-collector (registry/get registry {:name      "c3p0-stats"
                                                    :namespace "metabase_database"}
                                          nil)]
         (is c3p0-collector "c3p0 stats not found"))))
   (testing "Registry has an entry for each database in [[prometheus/connection-pool-info]]"
-    (with-prometheus-system [_ system]
+    (with-prometheus-system! [_ system]
       (let [registry       (.registry system)
             c3p0-collector (registry/get registry {:name      "c3p0_stats"
                                                    :namespace "metabase_database"}
@@ -143,7 +143,7 @@
                (count (.samples ^GaugeMetricFamily (first measurements))))
             "Expected one entry per database for each measurement"))))
   (testing "Registry includes c3p0 stats"
-    (with-prometheus-system [port _]
+    (with-prometheus-system! [port _]
       (let [[db-name values] (first (prometheus/connection-pool-info))
             tag-name         (comp :label #'prometheus/label-translation)
             expected-lines   (set (for [[tag value] values]
@@ -156,7 +156,7 @@
 
 (deftest email-collector-test
   (testing "Registry has email metrics registered"
-    (with-prometheus-system [port _]
+    (with-prometheus-system! [port _]
       (is (= #{"metabase_email_messages_total" "metabase_email_messages_created" "metabase_email_message_errors_total" "metabase_email_message_errors_created"}
              (->> (metric-lines port)
                   (map #(str/split % #"\s+"))
@@ -168,9 +168,9 @@
   (testing "inc has no effect if system is not setup"
     (prometheus/inc :metabase-email/messages)) ; << Does not throw.
   (testing "inc has no effect when called with unknown metric"
-    (with-prometheus-system [_ _system]
+    (with-prometheus-system! [_ _system]
       (prometheus/inc :metabase-email/unknown-metric))) ; << Does not throw.
   (testing "inc is recorded for known metrics"
-    (with-prometheus-system [_ system]
+    (with-prometheus-system! [_ system]
       (prometheus/inc :metabase-email/messages)
       (is (< 0 (-> system :registry :metabase-email/messages ops/read-value))))))
diff --git a/test/metabase/analytics/snowplow_test.clj b/test/metabase/analytics/snowplow_test.clj
index 5bebbd1ab57097cdf3294a28851d00a7b07c1ef9..1e0e9b275701af675a4f5c5d4afcef3f075f5ab8 100644
--- a/test/metabase/analytics/snowplow_test.clj
+++ b/test/metabase/analytics/snowplow_test.clj
@@ -45,7 +45,7 @@
         context                            (normalize-map (.getMap context-json))]
     (swap! collector conj {:properties properties, :subject subject, :context context})))
 
-(defn do-with-fake-snowplow-collector
+(defn do-with-fake-snowplow-collector!
   "Impl for `with-fake-snowplow-collector` macro; prefer using that rather than calling this directly."
   [f]
   (mt/with-temporary-setting-values [snowplow-available    true
@@ -55,7 +55,8 @@
         (with-redefs [snowplow/track-event-impl! (partial fake-track-event-impl! collector)]
           (f))))))
 
-;;; TODO -- rename to `with-fake-snowplow-collector!` because this is not thread-safe.
+;;; TODO -- rename to `with-fake-snowplow-collector!` because this is not thread-safe and remove the Kondo ignore rule below
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-fake-snowplow-collector
   "Creates a new fake snowplow collector in a dynamic scope, and redefines the track-event! function so that analytics
   events are parsed and added to the fake collector.
@@ -63,7 +64,7 @@
   Fetch the contents of the collector by calling [[snowplow-collector-contents]]."
   [& body]
   {:style/indent 0}
-  `(do-with-fake-snowplow-collector (fn [] ~@body)))
+  `(do-with-fake-snowplow-collector! (fn [] ~@body)))
 
 (defn- clear-snowplow-collector!
   []
diff --git a/test/metabase/api/alert_test.clj b/test/metabase/api/alert_test.clj
index f176c48d13e183e92fd121c6fc2d96e6e9d20e3e..30cc052b8d004ffb30bcc86479e34f5dcbffeac2 100644
--- a/test/metabase/api/alert_test.clj
+++ b/test/metabase/api/alert_test.clj
@@ -63,20 +63,20 @@
 (defn- alert-response [response]
   (m/dissoc-in response [:creator :last_login]))
 
-(defmacro ^:private with-test-email [& body]
+(defmacro ^:private with-test-email! [& body]
   `(mt/with-temporary-setting-values [~'site-url "https://metabase.com/testmb"]
      (mt/with-fake-inbox
        ~@body)))
 
-(defmacro ^:private with-alert-setup
+(defmacro ^:private with-alert-setup!
   "Macro that will cleanup any created pulses and setups a fake-inbox to validate emails are sent for new alerts"
   [& body]
   `(mt/with-model-cleanup [Pulse]
-     (with-test-email
+     (with-test-email!
        ~@body)))
 
-(defn- do-with-alert-in-collection [f]
-  (pulse-test/with-pulse-in-collection [db collection alert card]
+(defn- do-with-alert-in-collection! [f]
+  (pulse-test/with-pulse-in-collection! [db collection alert card]
     (assert (t2/exists? PulseCard :card_id (u/the-id card), :pulse_id (u/the-id alert)))
     ;; Make this Alert actually be an alert
     (t2/update! Pulse (u/the-id alert) {:alert_condition "rows"})
@@ -87,7 +87,7 @@
       (let [card (t2/select-one Card :id (u/the-id card))]
         (f db collection alert card)))))
 
-(defmacro ^:private with-alert-in-collection
+(defmacro ^:private with-alert-in-collection!
   "Do `body` with a temporary Alert whose Card is in a Collection, setting the stage to write various tests below. (Make
   sure to grant All Users permissions to the Collection if needed.)"
   {:style/indent 1}
@@ -97,12 +97,12 @@
     (assert (not= alert-binding 'card)))
   (when card-binding
     (assert (not= card-binding 'alert)))
-  `(do-with-alert-in-collection
+  `(do-with-alert-in-collection!
     (fn [~(or db-binding '_) ~(or collection-binding '_) ~(or alert-binding '_) ~(or card-binding '_)]
       ~@body)))
 
 ;; This stuff below is separate from `with-alert-in-collection` above!
-(defn- do-with-alerts-in-a-collection
+(defn- do-with-alerts-in-a-collection!
   "Do `f` with the Cards associated with `alerts-or-ids` in a new temporary Collection. Grant perms to All Users to that
   Collection using `f`.
 
@@ -119,11 +119,11 @@
           (t2/update! Card (u/the-id card) {:collection_id (u/the-id collection)})))
       (f))))
 
-(defmacro ^:private with-alerts-in-readable-collection [alerts-or-ids & body]
-  `(do-with-alerts-in-a-collection perms/grant-collection-read-permissions! ~alerts-or-ids (fn [] ~@body)))
+(defmacro ^:private with-alerts-in-readable-collection! [alerts-or-ids & body]
+  `(do-with-alerts-in-a-collection! perms/grant-collection-read-permissions! ~alerts-or-ids (fn [] ~@body)))
 
-(defmacro ^:private with-alerts-in-writeable-collection [alerts-or-ids & body]
-  `(do-with-alerts-in-a-collection perms/grant-collection-readwrite-permissions! ~alerts-or-ids (fn [] ~@body)))
+(defmacro ^:private with-alerts-in-writeable-collection! [alerts-or-ids & body]
+  `(do-with-alerts-in-a-collection! perms/grant-collection-readwrite-permissions! ~alerts-or-ids (fn [] ~@body)))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -149,28 +149,28 @@
 (deftest get-alerts-test
   (testing "archived alerts should be excluded"
     (is (= #{"Not Archived"}
-           (with-alert-in-collection [_ _ not-archived-alert]
-             (with-alert-in-collection [_ _ archived-alert]
+           (with-alert-in-collection! [_ _ not-archived-alert]
+             (with-alert-in-collection! [_ _ archived-alert]
                (t2/update! Pulse (u/the-id not-archived-alert) {:name "Not Archived"})
                (t2/update! Pulse (u/the-id archived-alert)     {:name "Archived", :archived true})
-               (with-alerts-in-readable-collection [not-archived-alert archived-alert]
+               (with-alerts-in-readable-collection! [not-archived-alert archived-alert]
                  (set (map :name (mt/user-http-request :rasta :get 200 "alert")))))))))
 
   (testing "fetch archived alerts"
     (is (= #{"Archived"}
-           (with-alert-in-collection [_ _ not-archived-alert]
-             (with-alert-in-collection [_ _ archived-alert]
+           (with-alert-in-collection! [_ _ not-archived-alert]
+             (with-alert-in-collection! [_ _ archived-alert]
                (t2/update! Pulse (u/the-id not-archived-alert) {:name "Not Archived"})
                (t2/update! Pulse (u/the-id archived-alert)     {:name "Archived", :archived true})
-               (with-alerts-in-readable-collection [not-archived-alert archived-alert]
+               (with-alerts-in-readable-collection! [not-archived-alert archived-alert]
                  (set (map :name (mt/user-http-request :rasta :get 200 "alert" :archived true)))))))))
 
   (testing "fetch alerts by user ID -- should return alerts created by the user,
            or alerts for which the user is a known recipient"
-    (with-alert-in-collection [_ _ creator-alert]
-      (with-alert-in-collection [_ _ recipient-alert]
-        (with-alert-in-collection [_ _ other-alert]
-          (with-alerts-in-readable-collection [creator-alert recipient-alert other-alert]
+    (with-alert-in-collection! [_ _ creator-alert]
+      (with-alert-in-collection! [_ _ recipient-alert]
+        (with-alert-in-collection! [_ _ other-alert]
+          (with-alerts-in-readable-collection! [creator-alert recipient-alert other-alert]
             (t2/update! Pulse (u/the-id creator-alert) {:name "LuckyCreator" :creator_id (mt/user->id :lucky)})
             (t2/update! Pulse (u/the-id recipient-alert) {:name "LuckyRecipient"})
             (t2/update! Pulse (u/the-id other-alert) {:name "Other"})
@@ -196,8 +196,8 @@
 
 (deftest get-alert-test
   (testing "an alert can be fetched by ID"
-    (with-alert-in-collection [_ _ alert]
-      (with-alerts-in-readable-collection [alert]
+    (with-alert-in-collection! [_ _ alert]
+      (with-alerts-in-readable-collection! [alert]
         (is (= (u/the-id alert)
                (:id (mt/user-http-request :rasta :get 200 (str "alert/" (u/the-id alert)))))))))
 
@@ -314,7 +314,7 @@
            (mt/with-non-admin-groups-no-root-collection-perms
              (t2.with-temp/with-temp [Collection collection]
                (t2/update! Card (u/the-id card) {:collection_id (u/the-id collection)})
-               (with-alert-setup
+               (with-alert-setup!
                  (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
                  [(et/with-expected-messages 1
                     (alert-response
@@ -350,7 +350,7 @@
                                                  {"My question"                  true
                                                   "now getting alerts"           true
                                                   "confirmation that your alert" false}))}
-           (with-alert-setup
+           (with-alert-setup!
              (array-map
               :response (et/with-expected-messages 2
                           (-> ((alert-client :crowberto) :post 200 "alert"
@@ -376,7 +376,7 @@
                                            :display       "line"
                                            :collection_id (u/the-id collection)}]
              (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
-             (with-alert-setup
+             (with-alert-setup!
                (et/with-expected-messages 1
                  (mt/user-http-request
                   :rasta :post 200 "alert"
@@ -398,7 +398,7 @@
                                            :display       "bar"
                                            :collection_id (u/the-id collection)}]
              (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
-             (with-alert-setup
+             (with-alert-setup!
                (et/with-expected-messages 1
                  (mt/user-http-request
                   :rasta :post 200 "alert"
@@ -529,7 +529,7 @@
                   (assoc-in [:channels 0 :recipients] (set (map recipient-details [:crowberto :rasta]))))
               (et/email-to :rasta {:subject "Crowberto Corv added you to an alert"
                                    :body    {"https://metabase.com/testmb" true, "now getting alerts" true}})]
-             (with-alert-setup
+             (with-alert-setup!
                [(et/with-expected-messages 1
                   (alert-response
                    (setify-recipient-emails
@@ -548,7 +548,7 @@
                    PulseChannelRecipient _     (recipient pc :rasta)]
       (is (= (-> (default-alert card)
                  (assoc-in [:card :collection_id] true))
-             (with-alerts-in-writeable-collection [alert]
+             (with-alerts-in-writeable-collection! [alert]
                (mt/with-model-cleanup [Pulse]
                  (alert-response
                   ((alert-client :rasta) :put 200 (alert-url alert)
@@ -562,7 +562,7 @@
                    PulseChannelRecipient _     (recipient pc :rasta)]
       (is (= (str "Non-admin users without monitoring or subscription permissions "
                   "are not allowed to modify the channels for an alert")
-             (with-alerts-in-writeable-collection [alert]
+             (with-alerts-in-writeable-collection! [alert]
                (mt/with-model-cleanup [Pulse]
                  ((alert-client :rasta) :put 403 (alert-url alert)
                   (default-alert-req card pc {} [(mt/fetch-user :crowberto)])))))))))
@@ -575,7 +575,7 @@
                    PulseChannel          pc    (pulse-channel alert)
                    PulseChannelRecipient _     (recipient pc :crowberto)
                    PulseChannelRecipient _     (recipient pc :rasta)]
-      (with-alert-setup
+      (with-alert-setup!
         (testing "API response"
           (is (= (-> (default-alert card)
                      (assoc-in [:channels 0 :recipients] [(recipient-details :crowberto)]))
@@ -600,7 +600,7 @@
                           PulseChannel          pc    (pulse-channel alert)
                           PulseChannelRecipient _     (recipient pc :rasta)]
              (mt/with-non-admin-groups-no-root-collection-perms
-               (with-alert-setup
+               (with-alert-setup!
                  ((alert-client :rasta) :put 403 (alert-url alert)
                   (default-alert-req card pc)))))))))
 
@@ -612,13 +612,13 @@
                             PulseCard             _     (pulse-card alert card)
                             PulseChannel          pc    (pulse-channel alert)
                             PulseChannelRecipient _     (recipient pc :crowberto)]
-               (with-alert-setup
+               (with-alert-setup!
                  ((alert-client :rasta) :put 403 (alert-url alert)
                   (default-alert-req card pc))))))))
 
   (testing "Non-admin users can update alerts in collection they have view permisisons"
     (mt/with-non-admin-groups-no-root-collection-perms
-      (with-alert-in-collection [_ collection alert card]
+      (with-alert-in-collection! [_ collection alert card]
         (mt/with-temp [PulseCard pc (pulse-card alert card)]
           (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
 
@@ -637,7 +637,7 @@
                                                 :display       "bar"
                                                 :collection_id (u/the-id collection)}]
         (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
-        (with-alert-setup
+        (with-alert-setup!
           (et/with-expected-messages 1
             (let [alert-details {:card             {:id (u/the-id card), :include_csv false, :include_xls false, :dashboard_card_id nil}
                                  :collection_id    (u/the-id collection)
@@ -709,9 +709,9 @@
                 (update-in [:channels 0] merge {:schedule_hour 15, :schedule_type "daily"})
                 (assoc-in [:card :collection_id] true))]
            (mt/with-non-admin-groups-no-root-collection-perms
-             (with-alert-setup
+             (with-alert-setup!
                (map alert-response
-                    (with-alerts-in-readable-collection [alert]
+                    (with-alerts-in-readable-collection! [alert]
                       ((alert-client :rasta) :get 200 (alert-question-url card)))))))))
 
   (testing "Non-admin users shouldn't see alerts they created if they're no longer recipients"
@@ -723,8 +723,8 @@
                           PulseChannel          pc    (pulse-channel alert)
                           PulseChannelRecipient pcr   (recipient pc :rasta)
                           PulseChannelRecipient _     (recipient pc :crowberto)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (array-map
                   :count-1 (count ((alert-client :rasta) :get 200 (alert-question-url card)))
                   :count-2 (do
@@ -748,8 +748,8 @@
                           PulseChannel          pc-2    (pulse-channel alert-2)
                           PulseChannelRecipient _       (recipient pc-2 :crowberto)
                           PulseChannel          _       (assoc (pulse-channel alert-2) :channel_type "slack")]
-             (with-alerts-in-readable-collection [alert-1 alert-2]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert-1 alert-2]
+               (with-alert-setup!
                  (array-map
                   :rasta     (api:alert-question-count :rasta     card)
                   :crowberto (api:alert-question-count :crowberto card))))))))
@@ -771,8 +771,8 @@
                    PulseChannel          pc-2    (pulse-channel alert-2)
                    PulseChannelRecipient _       (recipient pc-2 :crowberto)
                    PulseChannel          _       (assoc (pulse-channel alert-2) :channel_type "slack")]
-      (with-alerts-in-readable-collection [alert-1 alert-2]
-        (with-alert-setup
+      (with-alerts-in-readable-collection! [alert-1 alert-2]
+        (with-alert-setup!
           (is (= {:rasta     0
                   :crowberto 0}
                  (array-map
@@ -814,8 +814,8 @@
                           PulseChannel          pc    (pulse-channel alert)
                           PulseChannelRecipient _     (recipient pc :rasta)
                           PulseChannelRecipient _     (recipient pc :crowberto)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (array-map
                   :recipients-1 (recipient-emails (mt/user-http-request
                                                    :rasta :get 200 (alert-question-url card)))
@@ -837,8 +837,8 @@
                           PulseChannel          pc    (pulse-channel alert)
                           PulseChannelRecipient _     (recipient pc :rasta)
                           PulseChannelRecipient _     (recipient pc :crowberto)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (array-map
                   :recipients-1 (recipient-emails (mt/user-http-request :rasta :get 200 (alert-question-url card)))
                   :recipients-2 (do
@@ -856,8 +856,8 @@
                           PulseCard             _     (pulse-card alert card)
                           PulseChannel          pc    (pulse-channel alert)
                           PulseChannelRecipient _     (recipient pc :rasta)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (et/with-expected-messages 1 (api:unsubscribe! :rasta 204 alert))
                  (array-map
                   :archived? (t2/select-one-fn :archived Pulse :id (u/the-id alert))
@@ -873,8 +873,8 @@
                           PulseChannel          pc-1  (assoc (pulse-channel alert) :channel_type :email)
                           PulseChannel          _     (assoc (pulse-channel alert) :channel_type :slack)
                           PulseChannelRecipient _     (recipient pc-1 :rasta)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (et/with-expected-messages 1 (api:unsubscribe! :rasta 204 alert))
                  (array-map
                   :archived? (t2/select-one-fn :archived Pulse :id (u/the-id alert))
@@ -892,8 +892,8 @@
                           PulseChannel          pc-1  (assoc (pulse-channel alert) :channel_type :email)
                           PulseChannel          _pc-2 (assoc (pulse-channel alert) :channel_type :slack)
                           PulseChannelRecipient _     (recipient pc-1 :rasta)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (et/with-expected-messages 1
                    ((alert-client :crowberto)
                     :put 200 (alert-url alert) (assoc-in (default-alert-req card pc-1) [:channels 0 :enabled] false)))
@@ -913,8 +913,8 @@
                           PulseChannel          pc-1  (assoc (pulse-channel alert) :channel_type :email, :enabled false)
                           PulseChannel          _pc-2 (assoc (pulse-channel alert) :channel_type :slack)
                           PulseChannelRecipient _     (recipient pc-1 :rasta)]
-             (with-alerts-in-readable-collection [alert]
-               (with-alert-setup
+             (with-alerts-in-readable-collection! [alert]
+               (with-alert-setup!
                  (et/with-expected-messages 1
                    ((alert-client :crowberto)
                     :put 200 (alert-url alert) (assoc-in (default-alert-req card pc-1) [:channels 0 :enabled] true)))
diff --git a/test/metabase/api/automagic_dashboards_test.clj b/test/metabase/api/automagic_dashboards_test.clj
index 00dbe2ac3c90fdc75a849d9e26ac0bf85e3bea18..634b61df43d00141823db5d82b9962ecbcc8f760 100644
--- a/test/metabase/api/automagic_dashboards_test.clj
+++ b/test/metabase/api/automagic_dashboards_test.clj
@@ -288,7 +288,7 @@
                                                                     {:col 10 :size_x 10}])]
       (is (= 20 size_x)))))
 
-(defn- do-with-testing-model
+(defn- do-with-indexed-model!
   [{:keys [query pk-ref value-ref]} f]
   (t2.with-temp/with-temp [Card model {:type          :model
                                        :dataset_query query}]
@@ -304,7 +304,7 @@
                                               :model_index_id (:id model-index)
                                               :model_pk 1)})))))
 
-(defmacro with-indexed-model
+(defmacro with-indexed-model!
   "Creates a model based on `query-info`, which is indexed.
 
   `query-info` is a map with keys:
@@ -312,8 +312,8 @@
   - pk-ref: a field_ref for the model's pk
   - value-ref: a field_ref for the model's label."
   [[bindings query-info] & body]
-  `(do-with-testing-model ~query-info
-                          (fn [~bindings] ~@body)))
+  `(do-with-indexed-model! ~query-info
+                           (fn [~bindings] ~@body)))
 
 (def Tab-Id-Schema
   "Schema for tab-ids. Must be integers for the front-end, but negative so we know they do not (yet) exist in the db."
@@ -356,10 +356,10 @@
 (deftest create-linked-dashboard-test-regular-queries
   (mt/dataset test-data
     (testing "x-ray an mbql model"
-      (with-indexed-model [{:keys [model model-index model-index-value]}
-                           {:query     (mt/mbql-query products)
-                            :pk-ref    (mt/$ids :products $id)
-                            :value-ref (mt/$ids :products $title)}]
+      (with-indexed-model! [{:keys [model model-index model-index-value]}
+                            {:query     (mt/mbql-query products)
+                             :pk-ref    (mt/$ids :products $id)
+                             :value-ref (mt/$ids :products $title)}]
         (let [dash (#'api.magic/create-linked-dashboard
                     {:model             model
                      :model-index       model-index
@@ -416,10 +416,10 @@
               id-field-ref    (:field_ref (by-id results-meta "id"))
               title-field-ref (:field_ref (by-id results-meta "title"))
               id-field-id     (mt/id :products :id)]
-          (with-indexed-model [{:keys [model model-index model-index-value]}
-                               {:query     (mt/native-query {:query "select * from products"})
-                                :pk-ref    id-field-ref
-                                :value-ref title-field-ref}]
+          (with-indexed-model! [{:keys [model model-index model-index-value]}
+                                {:query     (mt/native-query {:query "select * from products"})
+                                 :pk-ref    id-field-ref
+                                 :value-ref title-field-ref}]
             ;; need user metadata edits to find linked tables to an otherwise opaque native query
             (t2/update! :model/Card (:id model)
                         {:result_metadata (annotating results-meta id-field-ref
@@ -452,7 +452,7 @@
 (deftest create-linked-dashboard-test-single-link
   (mt/dataset test-data
     (testing "with only single linked table"
-      (with-indexed-model [{:keys [model model-index model-index-value]}
+      (with-indexed-model! [{:keys [model model-index model-index-value]}
                            {:query     (mt/mbql-query people)
                             :pk-ref    (mt/$ids :people $id)
                             :value-ref (mt/$ids :people $email)}]
diff --git a/test/metabase/api/card_test.clj b/test/metabase/api/card_test.clj
index 74223f77e3b64172f23fbbdae8cd6697579cd92b..f20f6b0ba1d810ca952bcb7a8118a643ede6397a 100644
--- a/test/metabase/api/card_test.clj
+++ b/test/metabase/api/card_test.clj
@@ -140,7 +140,7 @@
   `(do-with-temp-native-card! (fn [~(or db-binding '_) ~(or card-binding '_)]
                                 ~@body)))
 
-(defn do-with-cards-in-a-collection [card-or-cards-or-ids grant-perms-fn! f]
+(defn do-with-cards-in-a-collection! [card-or-cards-or-ids grant-perms-fn! f]
   (mt/with-non-admin-groups-no-root-collection-perms
     (t2.with-temp/with-temp [Collection collection]
       ;; put all the Card(s) in our temp `collection`
@@ -153,18 +153,18 @@
       ;; call (f)
       (f))))
 
-(defmacro with-cards-in-readable-collection
+(defmacro with-cards-in-readable-collection!
   "Execute `body` with `card-or-cards-or-ids` added to a temporary Collection that All Users have read permissions for."
   {:style/indent 1}
   [card-or-cards-or-ids & body]
-  `(do-with-cards-in-a-collection ~card-or-cards-or-ids perms/grant-collection-read-permissions! (fn [] ~@body)))
+  `(do-with-cards-in-a-collection! ~card-or-cards-or-ids perms/grant-collection-read-permissions! (fn [] ~@body)))
 
-(defmacro with-cards-in-writeable-collection
+(defmacro with-cards-in-writeable-collection!
   "Execute `body` with `card-or-cards-or-ids` added to a temporary Collection that All Users have *write* permissions
   for."
   {:style/indent 1}
   [card-or-cards-or-ids & body]
-  `(do-with-cards-in-a-collection ~card-or-cards-or-ids perms/grant-collection-readwrite-permissions! (fn [] ~@body)))
+  `(do-with-cards-in-a-collection! ~card-or-cards-or-ids perms/grant-collection-readwrite-permissions! (fn [] ~@body)))
 
 (defn- do-with-temp-native-card-with-params! [f]
   (mt/with-temp
@@ -249,7 +249,7 @@
   (mt/with-temp [Database db {}
                  :model/Card     card-1 {:database_id (mt/id)}
                  :model/Card     card-2 {:database_id (u/the-id db)}]
-    (with-cards-in-readable-collection [card-1 card-2]
+    (with-cards-in-readable-collection! [card-1 card-2]
       (is (= true
              (card-returned? :database (mt/id) card-1)))
       (is (= false
@@ -272,7 +272,7 @@
                    Table    table-2  {:db_id (u/the-id db)}
                    :model/Card     card-1   {:table_id (u/the-id table-1)}
                    :model/Card     card-2   {:table_id (u/the-id table-2)}]
-      (with-cards-in-readable-collection [card-1 card-2]
+      (with-cards-in-readable-collection! [card-1 card-2]
         (is (= true
                (card-returned? :table (u/the-id table-1) (u/the-id card-1))))
         (is (= false
@@ -290,7 +290,7 @@
     (mt/with-temp [:model/Card card-1 {:name "Card 1"}
                    :model/Card card-2 {:name "Card 2"}
                    :model/Card card-3 {:name "Card 3"}]
-      (with-cards-in-readable-collection [card-1 card-2 card-3]
+      (with-cards-in-readable-collection! [card-1 card-2 card-3]
         (mt/user-http-request :crowberto :put 200 (format "card/%d" (u/the-id card-2)) {:archived true})
         (mt/user-http-request :crowberto :put 200 (format "card/%d" (u/the-id card-3)) {:archived true})
         (is (= #{"Card 2" "Card 3"}
@@ -354,7 +354,7 @@
                    :model/Card         card-3 {:name "Card 3"}
                    CardBookmark _ {:card_id (u/the-id card-1), :user_id (mt/user->id :rasta)}
                    CardBookmark _ {:card_id (u/the-id card-2), :user_id (mt/user->id :crowberto)}]
-      (with-cards-in-readable-collection [card-1 card-2 card-3]
+      (with-cards-in-readable-collection! [card-1 card-2 card-3]
         (is (= [{:name "Card 1"}]
                (for [card (mt/user-http-request :rasta :get 200 "card", :f :bookmarked)]
                  (select-keys card [:name]))))))))
@@ -444,7 +444,7 @@
                                      :archived true
                                      :dataset_query {:query {:source-table (str "card__" model-id)}}}]
     (testing "list cards using a model"
-      (with-cards-in-readable-collection [model card-1 card-2 card-3 card-4 card-5 card-6 card-7]
+      (with-cards-in-readable-collection! [model card-1 card-2 card-3 card-4 card-5 card-6 card-7]
         (is (= #{"Card 1" "Card 3" "Card 4"}
                (into #{} (map :name) (mt/user-http-request :rasta :get 200 "card"
                                                            :f :using_model :model_id model-id))))
@@ -458,7 +458,7 @@
 (deftest get-cards-with-last-edit-info-test
   (mt/with-temp [:model/Card {card-1-id :id} {:name "Card 1"}
                  :model/Card {card-2-id :id} {:name "Card 2"}]
-    (with-cards-in-readable-collection [card-1-id card-2-id]
+    (with-cards-in-readable-collection! [card-1-id card-2-id]
       (doseq [user-id [(mt/user->id :rasta) (mt/user->id :crowberto)]]
         (revision/push-revision!
          {:entity       :model/Card
@@ -551,7 +551,7 @@
                                   {:name       "A Native query table"
                                    :display    :table
                                    :query_type "native"})]
-      (with-cards-in-readable-collection [line bar area scalar scalar-2 native pie table native-2 metric metric-2]
+      (with-cards-in-readable-collection! [line bar area scalar scalar-2 native pie table native-2 metric metric-2]
        (doseq [:let [excluded #{"A Scalar 2" "Another Metric" "A Line with no access" "A pie" "A table" "A Native query table"}]
                [card-id display-type expected excluded]
                [[(:id line)   :line   #{"A Native query" "An Area" "A Bar" "A Metric"} excluded]
@@ -1316,7 +1316,7 @@
 
 (deftest test-that-we-can-edit-a-card
   (t2.with-temp/with-temp [:model/Card card {:name "Original Name"}]
-    (with-cards-in-writeable-collection card
+    (with-cards-in-writeable-collection! card
       (is (= "Original Name"
              (t2/select-one-fn :name :model/Card, :id (u/the-id card))))
       (is (= {:timestamp true, :first_name "Rasta", :last_name "Toucan", :email "rasta@metabase.com", :id true}
@@ -1328,7 +1328,7 @@
 
 (deftest can-we-update-a-card-s-archived-status-
   (t2.with-temp/with-temp [:model/Card card]
-    (with-cards-in-writeable-collection card
+    (with-cards-in-writeable-collection! card
       (let [archived?     (fn [] (:archived (t2/select-one :model/Card :id (u/the-id card))))
             set-archived! (fn [archived]
                             (mt/user-http-request :rasta :put 200 (str "card/" (u/the-id card)) {:archived archived})
@@ -1359,13 +1359,13 @@
 (deftest clear-description-test
   (testing "Can we clear the description of a Card? (#4738)"
     (t2.with-temp/with-temp [:model/Card card {:description "What a nice Card"}]
-      (with-cards-in-writeable-collection card
+      (with-cards-in-writeable-collection! card
         (mt/user-http-request :rasta :put 200 (str "card/" (u/the-id card)) {:description nil})
         (is (nil? (t2/select-one-fn :description :model/Card :id (u/the-id card))))))))
 
 (deftest description-should-be-blankable-as-well
   (t2.with-temp/with-temp [:model/Card card {:description "What a nice Card"}]
-    (with-cards-in-writeable-collection card
+    (with-cards-in-writeable-collection! card
       (mt/user-http-request :rasta :put 200 (str "card/" (u/the-id card)) {:description ""})
       (is (= ""
              (t2/select-one-fn :description :model/Card :id (u/the-id card)))))))
@@ -1437,7 +1437,7 @@
 
 (deftest can-we-change-the-collection-position-of-a-card-
   (t2.with-temp/with-temp [:model/Card card]
-    (with-cards-in-writeable-collection card
+    (with-cards-in-writeable-collection! card
       (mt/user-http-request :rasta :put 200 (str "card/" (u/the-id card))
                             {:collection_position 1})
       (is (= 1
@@ -1445,7 +1445,7 @@
 
 (deftest can-we-change-the-collection-preview-flag-of-a-card-
   (t2.with-temp/with-temp [:model/Card card]
-    (with-cards-in-writeable-collection card
+    (with-cards-in-writeable-collection! card
       (mt/user-http-request :rasta :put 200 (str "card/" (u/the-id card))
                             {:collection_preview false})
       (is (= false
@@ -1453,7 +1453,7 @@
 
 (deftest ---and-unset--unpin--it-as-well-
   (t2.with-temp/with-temp [:model/Card card {:collection_position 1}]
-    (with-cards-in-writeable-collection card
+    (with-cards-in-writeable-collection! card
       (mt/user-http-request :rasta :put 200 (str "card/" (u/the-id card))
                             {:collection_position nil})
       (is (= nil
@@ -1850,7 +1850,7 @@
            PulseChannelRecipient _     {:user_id          (mt/user->id :rasta)
                                         :pulse_channel_id (u/the-id pc)}]
           (mt/with-temporary-setting-values [site-url "https://metabase.com"]
-            (with-cards-in-writeable-collection card
+            (with-cards-in-writeable-collection! card
               (mt/with-fake-inbox
                 (when deleted?
                   (u/with-timeout 5000
@@ -1883,7 +1883,7 @@
                         PulseChannel          pc    {:pulse_id (u/the-id pulse)}
                         PulseChannelRecipient _     {:user_id          (mt/user->id :rasta)
                                                      :pulse_channel_id (u/the-id pc)}]
-           (with-cards-in-writeable-collection card
+           (with-cards-in-writeable-collection! card
              (mt/with-fake-inbox
                (array-map
                 :emails-1 (do
@@ -1902,7 +1902,7 @@
 
 (deftest check-that-we-can-delete-a-card
   (is (nil? (t2.with-temp/with-temp [:model/Card card]
-              (with-cards-in-writeable-collection card
+              (with-cards-in-writeable-collection! card
                 (mt/user-http-request :rasta :delete 204 (str "card/" (u/the-id card)))
                 (t2/select-one :model/Card :id (u/the-id card)))))))
 
@@ -2044,7 +2044,7 @@
 (deftest csv-download-test
   (testing "no parameters"
     (with-temp-native-card! [_ card]
-      (with-cards-in-readable-collection card
+      (with-cards-in-readable-collection! card
         (is (= ["COUNT(*)"
                 "75"]
                (str/split-lines
@@ -2052,7 +2052,7 @@
                                                                (u/the-id card)))))))))
   (testing "with parameters"
     (with-temp-native-card-with-params! [_ card]
-      (with-cards-in-readable-collection card
+      (with-cards-in-readable-collection! card
         (is (= ["COUNT(*)"
                 "8"]
                (str/split-lines
@@ -2063,12 +2063,12 @@
 (deftest json-download-test
   (testing "no parameters"
     (with-temp-native-card! [_ card]
-      (with-cards-in-readable-collection card
+      (with-cards-in-readable-collection! card
         (is (= [{(keyword "COUNT(*)") "75"}]
                (mt/user-http-request :rasta :post 200 (format "card/%d/query/json" (u/the-id card))))))))
   (testing "with parameters"
     (with-temp-native-card-with-params! [_ card]
-      (with-cards-in-readable-collection card
+      (with-cards-in-readable-collection! card
         (is (= [{(keyword "COUNT(*)") "8"}]
                (mt/user-http-request :rasta :post 200 (format "card/%d/query/json" (u/the-id card))
                                      :parameters encoded-params)))))))
@@ -2168,13 +2168,13 @@
 (deftest xlsx-download-test
   (testing "no parameters"
     (with-temp-native-card! [_ card]
-      (with-cards-in-readable-collection card
+      (with-cards-in-readable-collection! card
         (is (= [{:col "COUNT(*)"} {:col 75.0}]
                (parse-xlsx-results
                 (mt/user-http-request :rasta :post 200 (format "card/%d/query/xlsx" (u/the-id card)))))))))
   (testing "with parameters"
     (with-temp-native-card-with-params! [_ card]
-      (with-cards-in-readable-collection card
+      (with-cards-in-readable-collection! card
         (is (= [{:col "COUNT(*)"} {:col 8.0}]
                (parse-xlsx-results
                 (mt/user-http-request :rasta :post 200 (format "card/%d/query/xlsx" (u/the-id card))
@@ -2422,7 +2422,7 @@
                                                              :query      {:source-table (mt/id :venues)}
                                                              :middleware {:add-default-userland-constraints? true
                                                                           :userland-query?                   true}}}]
-    (with-cards-in-readable-collection card
+    (with-cards-in-readable-collection! card
       (let [orig qp.card/process-query-for-card]
         (with-redefs [qp.card/process-query-for-card (fn [card-id export-format & options]
                                                        (apply orig card-id export-format
@@ -3029,8 +3029,8 @@
                                     :data :cols last :visibility_type))
               "in cols (important for the saved metadata)"))))))
 
-(defn- do-with-persistence-setup [f]
-  ;; mt/with-temp-scheduler actually just reuses the current scheduler. The scheduler factory caches by name set in
+(defn- do-with-persistence-setup! [f]
+  ;; mt/with-temp-scheduler! actually just reuses the current scheduler. The scheduler factory caches by name set in
   ;; the resources/quartz.properties file and we reuse that scheduler
   (let [sched (.getScheduler
                (StdSchedulerFactory. (doto (java.util.Properties.)
@@ -3052,11 +3052,11 @@
         (finally
           (qs/shutdown sched))))))
 
-(defmacro ^:private with-persistence-setup
+(defmacro ^:private with-persistence-setup!
   "Sets up a temp scheduler, a temp database and enabled persistence. Scheduler will be in standby mode so that jobs
   won't run. Just check for trigger presence."
   [db-binding & body]
-  `(do-with-persistence-setup (fn [~db-binding] ~@body)))
+  `(do-with-persistence-setup! (fn [~db-binding] ~@body)))
 
 (defn- job-info-for-individual-refresh
   "Return a set of PersistedInfo ids of all jobs scheduled for individual refreshes."
@@ -3071,7 +3071,7 @@
 
 (deftest refresh-persistence
   (testing "Can schedule refreshes for models"
-    (with-persistence-setup db
+    (with-persistence-setup! db
       (t2.with-temp/with-temp
         [:model/Card          model      {:type :model :database_id (u/the-id db)}
          :model/Card          notmodel   {:type :question :database_id (u/the-id db)}
@@ -3096,7 +3096,7 @@
               "Scheduled refresh of archived model"))))))
 
 (deftest unpersist-persist-model-test
-  (with-persistence-setup db
+  (with-persistence-setup! db
     (t2.with-temp/with-temp
       [:model/Card          model     {:database_id (u/the-id db), :type :model}
        :model/PersistedInfo pmodel    {:database_id (u/the-id db), :card_id (u/the-id model)}]
@@ -3443,7 +3443,7 @@
                                                                                                        :columns [],
                                                                                                        :values [[:aggregation 0]]},
                                                                             :table.cell_column "sum"}}]
-          (with-cards-in-readable-collection [model card]
+          (with-cards-in-readable-collection! [model card]
             (is (=?
                   {:data {:cols [{:name "USER_ID"} {:name "pivot-grouping"} {:name "sum"}]}}
                   (mt/user-http-request :rasta :post 202 (format "card/pivot/%d/query" (u/the-id card))))))))
@@ -3461,7 +3461,7 @@
                                                                                                        :columns [],
                                                                                                        :values [[:aggregation 0]]},
                                                                             :table.cell_column "sum"}}]
-          (with-cards-in-readable-collection [model card]
+          (with-cards-in-readable-collection! [model card]
             (is (=?
                   {:data {:cols [{:name "USER_ID"} {:name "pivot-grouping"} {:name "sum"}]}}
                   (mt/user-http-request :rasta :post 202 (format "card/pivot/%d/query" (u/the-id card)))))))))))
diff --git a/test/metabase/api/collection_test.clj b/test/metabase/api/collection_test.clj
index 5bf4de564a9354a41aa5154461e140764f0a64d0..5a76de5fd70eaaf61477dc777795331567a16c47 100644
--- a/test/metabase/api/collection_test.clj
+++ b/test/metabase/api/collection_test.clj
@@ -31,32 +31,32 @@
 
 (use-fixtures :once (fixtures/initialize :test-users-personal-collections))
 
-(defmacro ^:private with-collection-hierarchy
+(defmacro ^:private with-collection-hierarchy!
   "Totally-rad macro that creates a Collection hierarchy and grants the All Users group perms for all the Collections
   you've bound. See docs for [[metabase.models.collection-test/with-collection-hierarchy]] for more details."
   {:style/indent 1}
   [collection-bindings & body]
   {:pre [(vector? collection-bindings)
          (every? symbol? collection-bindings)]}
-  `(collection-test/with-collection-hierarchy [{:keys ~collection-bindings}]
+  `(collection-test/with-collection-hierarchy! [{:keys ~collection-bindings}]
      ~@(for [collection-symb collection-bindings]
          `(perms/grant-collection-read-permissions! (perms-group/all-users) ~collection-symb))
      ~@body))
 
-(defn- do-with-french-user-and-personal-collection [f]
+(defn- do-with-french-user-and-personal-collection! [f]
   (binding [collection/*allow-deleting-personal-collections* true]
-    (mt/with-mock-i18n-bundles {"fr" {:messages {"{0} {1}''s Personal Collection" "Collection personnelle de {0} {1}"}}}
+    (mt/with-mock-i18n-bundles! {"fr" {:messages {"{0} {1}''s Personal Collection" "Collection personnelle de {0} {1}"}}}
       (t2.with-temp/with-temp [User       user       {:locale     "fr"
                                                       :first_name "Taco"
                                                       :last_name  "Bell"}
                                Collection collection {:personal_owner_id (:id user)}]
         (f user collection)))))
 
-(defmacro ^:private with-french-user-and-personal-collection
+(defmacro ^:private with-french-user-and-personal-collection!
   "Create a user with locale's fr and a collection associated with it"
   {:style/indent 2}
   [user collection & body]
-  `(do-with-french-user-and-personal-collection
+  `(do-with-french-user-and-personal-collection!
     (fn [~user ~collection]
       ~@body)))
 
@@ -109,7 +109,7 @@
 (deftest list-collections-personal-collection-locale-test
   (testing "GET /api/collection"
     (testing "Personal Collection's name and slug should be returned in user's locale"
-      (with-french-user-and-personal-collection user _collection
+      (with-french-user-and-personal-collection! user _collection
         (is (= [{:name "Collection personnelle de Taco Bell"
                  :slug "collection_personnelle_de_taco_bell"}]
                (->> (mt/user-http-request user :get 200 "collection")
@@ -233,7 +233,7 @@
     (let [personal-collection (collection/user->personal-collection (mt/user->id :rasta))]
       (testing "sanity check"
         (is (some? personal-collection)))
-      (with-collection-hierarchy [a b c d e f g]
+      (with-collection-hierarchy! [a b c d e f g]
         (let [ids      (set (map :id (cons personal-collection [a b c d e f g])))
               response (mt/user-http-request :rasta :get 200 "collection/tree")]
           (testing "Make sure overall tree shape of the response is as is expected"
@@ -264,7 +264,7 @@
 
 (deftest collections-tree-exclude-other-user-collections-test
   (let [personal-collection (collection/user->personal-collection (mt/user->id :lucky))]
-    (with-collection-hierarchy [a b c d e f g]
+    (with-collection-hierarchy! [a b c d e f g]
       (collection/move-collection! a (collection/children-location personal-collection))
       (let [ids                 (set (map :id (cons personal-collection [a b c d e f g])))
             response-rasta      (mt/user-http-request :rasta :get 200 "collection/tree" :exclude-other-user-collections true)
@@ -290,7 +290,7 @@
 
 (deftest collection-tree-here-and-below-test
   (testing "Tree should properly indicate contents"
-    (with-collection-hierarchy [a b]
+    (with-collection-hierarchy! [a b]
       (let [personal-collection (collection/user->personal-collection (mt/user->id :rasta))]
         (t2.with-temp/with-temp [Card _ {:name "Personal Card"
                                          :collection_preview false
@@ -315,7 +315,7 @@
 
 (deftest collection-tree-shallow-test
   (testing "GET /api/collection/tree?shallow=true"
-    (with-collection-hierarchy [a b c d e f g]
+    (with-collection-hierarchy! [a b c d e f g]
       (let [personal-collection (collection/user->personal-collection (mt/user->id :rasta))
             ids                 (set (map :id (cons personal-collection [a b c d e f g])))]
         (let [response (mt/user-http-request :rasta :get 200 "collection/tree?shallow=true")]
@@ -353,7 +353,7 @@
 
 (deftest select-collections-shallow-test
   (testing "Selecting collections based off collection-id equaling nil works."
-    (with-collection-hierarchy [a b c d e f g]
+    (with-collection-hierarchy! [a b c d e f g]
       (let [personal-collection (collection/user->personal-collection (mt/user->id :crowberto))
             ids      (set (map :id (cons personal-collection [a b c d e f g])))]
         (mt/with-test-user :crowberto
@@ -441,7 +441,7 @@
 (deftest collection-tree-user-locale-test
   (testing "GET /api/collection/tree"
     (testing "for personal collections, it should return name and slug in user's locale"
-      (with-french-user-and-personal-collection user collection
+      (with-french-user-and-personal-collection! user collection
         (is (partial= {:description       nil
                        :archived          false
                        :entity_id         (:entity_id collection)
@@ -515,7 +515,7 @@
       ;; A* -+-> E*
       ;;     |
       ;;     +-> F* -> G*
-      (collection-test/with-collection-hierarchy [{:keys [a b e f g], :as collections}]
+      (collection-test/with-collection-hierarchy! [{:keys [a b e f g], :as collections}]
         (doseq [collection [a b e f g]]
           (perms/grant-collection-read-permissions! (perms-group/all-users) collection))
         (is (= [{:name     "A"
@@ -549,14 +549,14 @@
                  (mt/user-http-request :rasta :get 403 (str "collection/" (u/the-id collection))))))))
 
     (testing "for personal collections, it should return name and slug in user's locale"
-      (with-french-user-and-personal-collection user collection
+      (with-french-user-and-personal-collection! user collection
         (is (=? {:name "Collection personnelle de Taco Bell"
                  :slug "collection_personnelle_de_taco_bell"}
                 (mt/user-http-request (:id user) :get 200 (str "collection/" (:id collection)))))))))
 
 ;;; ------------------------------------------------ Collection Items ------------------------------------------------
 
-(defn- do-with-some-children-of-collection [collection-or-id-or-nil f]
+(defn- do-with-some-children-of-collection! [collection-or-id-or-nil f]
   (mt/with-non-admin-groups-no-root-collection-perms
     (let [collection-id-or-nil (when collection-or-id-or-nil
                                  (u/the-id collection-or-id-or-nil))]
@@ -581,8 +581,8 @@
             :dashboard-subscription-pulse-id dashboard-sub-pulse-id
             :dashboard-sub-pulse-card-id     dashboard-sub-pulse-card-id})))))
 
-(defmacro ^:private with-some-children-of-collection {:style/indent 1} [collection-or-id-or-nil & body]
-  `(do-with-some-children-of-collection
+(defmacro ^:private with-some-children-of-collection! {:style/indent 1} [collection-or-id-or-nil & body]
+  `(do-with-some-children-of-collection!
     ~collection-or-id-or-nil
     (fn [~'&ids]
       ~@body)))
@@ -740,7 +740,7 @@
     (testing "check that you get to see the children as appropriate"
       (t2.with-temp/with-temp [Collection collection {:name "Debt Collection"}]
         (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
-        (with-some-children-of-collection collection
+        (with-some-children-of-collection! collection
           (is (partial= (-> (mapv default-item [{:name "Acme Products", :model "pulse", :entity_id true}
                                                 {:name               "Birthday Card", :description nil,     :model     "card",
                                                  :collection_preview false,           :display     "table", :entity_id true}
@@ -753,7 +753,7 @@
       (testing "...and that you can also filter so that you only see the children you want to see"
         (t2.with-temp/with-temp [Collection collection {:name "Art Collection"}]
           (perms/grant-collection-read-permissions! (perms-group/all-users) collection)
-          (with-some-children-of-collection collection
+          (with-some-children-of-collection! collection
             (is (partial= ()
                           (mt/boolean-ids-and-timestamps
                            (:data (mt/user-http-request :rasta :get 200 (str "collection/" (u/the-id collection) "/items") :models "no_models")))))
@@ -1334,7 +1334,7 @@
 
 (deftest effective-ancestors-and-children-test
   (testing "does a top-level Collection like A have the correct Children?"
-    (with-collection-hierarchy [a b c d g]
+    (with-collection-hierarchy! [a b c d g]
       (testing "ancestors"
         (is (= {:effective_ancestors []
                 :effective_location  "/"}
@@ -1345,7 +1345,7 @@
 
 (deftest effective-ancestors-and-children-second-level-collection-test
   (testing "does a second-level Collection have its parent and its children?"
-    (with-collection-hierarchy [a b c d g]
+    (with-collection-hierarchy! [a b c d g]
       (testing "ancestors"
         (is (= {:effective_ancestors [{:name "A", :type nil, :id true, :can_write false, :personal_owner_id nil}]
                 :effective_location  "/A/"}
@@ -1356,7 +1356,7 @@
 
 (deftest effective-ancestors-and-children-third-level-collection-test
   (testing "Does a third-level Collection? have its parent and its children?"
-    (with-collection-hierarchy [a b c d g]
+    (with-collection-hierarchy! [a b c d g]
       (testing "ancestors"
         (is (= {:effective_ancestors [{:name "A", :type nil, :id true, :can_write false, :personal_owner_id nil}
                                       {:name "C", :type nil, :id true, :can_write false, :personal_owner_id nil}]
@@ -1369,7 +1369,7 @@
 (deftest effective-ancestors-and-children-of-d-test
   (testing (str "for D: if we remove perms for C we should only have A as an ancestor; effective_location should lie "
                 "and say we are a child of A")
-    (with-collection-hierarchy [a b d g]
+    (with-collection-hierarchy! [a b d g]
       (testing "ancestors"
         (is (= {:effective_ancestors [{:name "A", :type nil, :id true, :can_write false, :personal_owner_id nil}]
                 :effective_location  "/A/"}
@@ -1378,7 +1378,7 @@
         (is (= []
                (api-get-collection-children d))))))
   (testing "for D: If, on the other hand, we remove A, we should see C as the only ancestor and as a root-level Collection."
-    (with-collection-hierarchy [b c d g]
+    (with-collection-hierarchy! [b c d g]
       (testing "ancestors"
         (is (= {:effective_ancestors [{:name "C", :type nil, :id true, :can_write false, :personal_owner_id nil}]
                 :effective_location  "/C/"}
@@ -1389,7 +1389,7 @@
 
 (deftest effective-ancestors-and-children-of-c-test
   (testing "for C: if we remove D we should get E and F as effective children"
-    (with-collection-hierarchy [a b c e f g]
+    (with-collection-hierarchy! [a b c e f g]
       (testing "ancestors"
         (is (= {:effective_ancestors [{:name "A", :type nil, :id true, :can_write false, :personal_owner_id nil}]
                 :effective_location  "/A/"}
@@ -1400,7 +1400,7 @@
 
 (deftest effective-ancestors-and-children-collapse-multiple-generations-test
   (testing "Make sure we can collapse multiple generations. For A: removing C and D should move up E and F"
-    (with-collection-hierarchy [a b e f g]
+    (with-collection-hierarchy! [a b e f g]
       (testing "ancestors"
         (is (= {:effective_ancestors []
                 :effective_location  "/"}
@@ -1411,7 +1411,7 @@
 
 (deftest effective-ancestors-and-children-archived-test
   (testing "Let's make sure the 'archived` option works on Collections, nested or not"
-    (with-collection-hierarchy [a b c]
+    (with-collection-hierarchy! [a b c]
       (mt/user-http-request :crowberto :put 200 (str "collection/" (u/the-id b))
                             {:archived true})
       (testing "ancestors"
@@ -1458,7 +1458,7 @@
               :parent_id           nil
               :is_personal         false
               :can_delete          false}
-             (with-some-children-of-collection nil
+             (with-some-children-of-collection! nil
                (mt/user-http-request :crowberto :get 200 "collection/root")))))))
 
 (defn results-matching [collection-items parameters]
@@ -1476,7 +1476,7 @@
                          (assoc :fully_parameterized true))
                      (default-item {:name "Dine & Dashboard", :description nil, :model "dashboard"})
                      (default-item {:name "Electro-Magnetic Pulse", :model "pulse"})]
-                    (with-some-children-of-collection nil
+                    (with-some-children-of-collection! nil
                       (-> (:data (mt/user-http-request :crowberto :get 200 "collection/root/items"))
                           (remove-non-test-items &ids)
                           remove-non-personal-collections
@@ -1484,7 +1484,7 @@
 
 (deftest fetch-root-items-limit-and-offset-test
   (testing "GET /api/collection/root/items"
-    (with-some-children-of-collection nil
+    (with-some-children-of-collection! nil
       (letfn [(items [limit offset]
                 (:data (mt/user-http-request :crowberto :get 200 "collection/root/items"
                                              :limit (str limit), :offset (str offset))))]
@@ -1500,7 +1500,7 @@
 (deftest fetch-root-items-total-test
   (testing "GET /api/collection/root/items"
     (testing "Include :total, even with limit and offset"
-      (with-some-children-of-collection nil
+      (with-some-children-of-collection! nil
         ;; `:total` should be at least 4 items based on `with-some-children-of-collection`. Might be a bit more if
         ;; other stuff was created
         (is (<= 4 (:total (mt/user-http-request :crowberto :get 200 "collection/root/items" :limit "2" :offset "1"))))))))
@@ -1510,12 +1510,12 @@
     (testing "we don't let you see stuff you wouldn't otherwise be allowed to see"
       (is (= []
              ;; if a User doesn't have perms for the Root Collection then they don't get to see things with no collection_id
-             (with-some-children-of-collection nil
+             (with-some-children-of-collection! nil
                (-> (:data (mt/user-http-request :rasta :get 200 "collection/root/items"))
                    remove-non-personal-collections
                    mt/boolean-ids-and-timestamps))))
       (testing "...but if they have read perms for the Root Collection they should get to see them"
-        (with-some-children-of-collection nil
+        (with-some-children-of-collection! nil
           (t2.with-temp/with-temp [PermissionsGroup           group {}
                                    PermissionsGroupMembership _     {:user_id (mt/user->id :rasta), :group_id (u/the-id group)}]
             (perms/grant-permissions! group (perms/collection-read-path {:metabase.models.collection.root/is-root? true}))
@@ -1695,23 +1695,23 @@
     (is (collection/user->personal-collection (mt/user->id :rasta))))
   (testing "GET /api/collection/root/items"
     (testing "Do top-level collections show up as children of the Root Collection?"
-      (with-collection-hierarchy [a b c d e f g]
+      (with-collection-hierarchy! [a b c d e f g]
         (testing "children"
           (is (partial= (map collection-item ["A"])
                         (remove-non-test-collections (api-get-root-collection-children)))))))
 
     (testing "...and collapsing children should work for the Root Collection as well"
-      (with-collection-hierarchy [b d e f g]
+      (with-collection-hierarchy! [b d e f g]
         (testing "children"
           (is (partial= (map collection-item ["B" "D" "F"])
                         (remove-non-test-collections (api-get-root-collection-children)))))))
 
     (testing "does `archived` work on Collections as well?"
-      (with-collection-hierarchy [a b d e f g]
+      (with-collection-hierarchy! [a b d e f g]
         (mt/user-http-request :crowberto :put 200 (str "collection/" (u/the-id a))
                             {:archived true})
         (is (= [] (remove-non-test-collections (api-get-root-collection-children)))))
-      (with-collection-hierarchy [a b d e f g]
+      (with-collection-hierarchy! [a b d e f g]
         (mt/user-http-request :crowberto :put 200 (str "collection/" (u/the-id a))
                               {:archived true})
         (is (= [] (remove-non-test-collections (api-get-root-collection-children))))))
@@ -1830,7 +1830,7 @@
   (testing "POST /api/collection"
     (testing "\nCan I create a Collection as a child of an existing collection?"
       (mt/with-model-cleanup [Collection]
-        (with-collection-hierarchy [a c d]
+        (with-collection-hierarchy! [a c d]
           (is (partial= (merge
                          (mt/object-defaults Collection)
                          {:id          true
@@ -1946,7 +1946,7 @@
 (deftest move-collection-test
   (testing "PUT /api/collection/:id"
     (testing "Can I *change* the `location` of a Collection? (i.e. move it into a different parent Collection)"
-      (with-collection-hierarchy [a b e]
+      (with-collection-hierarchy! [a b e]
         (is (partial= (merge
                        (mt/object-defaults Collection)
                        {:id        true
diff --git a/test/metabase/api/common/internal_test.clj b/test/metabase/api/common/internal_test.clj
index 35eafdb524035f0db1a49f0cf95a377d2bdccb8e..5e99d706f5fc2e3a8752674190580470a82f86b1 100644
--- a/test/metabase/api/common/internal_test.clj
+++ b/test/metabase/api/common/internal_test.clj
@@ -209,7 +209,7 @@
              (:body (post! "/post/closed-test-address" {:id "1" :tags [] :a 1 :b 2}))))
 
       (testing "malli schema message are localized"
-        (mt/with-mock-i18n-bundles  {"es" {:messages
+        (mt/with-mock-i18n-bundles!  {"es" {:messages
                                            {"value must be a non-blank string."
                                             "el valor debe ser una cadena que no esté en blanco."}}}
           (mt/with-temporary-setting-values [site-locale "es"]
diff --git a/test/metabase/api/dashboard_test.clj b/test/metabase/api/dashboard_test.clj
index 8081a8521c4ac102249caea38d48066a85913598..ae4b312b4565c7d2ec0d3a2e25c2f57a5deb8f0c 100644
--- a/test/metabase/api/dashboard_test.clj
+++ b/test/metabase/api/dashboard_test.clj
@@ -123,7 +123,7 @@
       creator       (update :creator #(into {} %))
       dashcards (update :dashcards #(mapv dashcard-response %)))))
 
-(defn- do-with-dashboards-in-a-collection [grant-collection-perms-fn! dashboards-or-ids f]
+(defn- do-with-dashboards-in-a-collection! [grant-collection-perms-fn! dashboards-or-ids f]
   (mt/with-non-admin-groups-no-root-collection-perms
     (t2.with-temp/with-temp [Collection collection]
       (grant-collection-perms-fn! (perms-group/all-users) collection)
@@ -131,11 +131,11 @@
         (t2/update! Dashboard (u/the-id dashboard-or-id) {:collection_id (u/the-id collection)}))
       (f))))
 
-(defmacro ^:private with-dashboards-in-readable-collection [dashboards-or-ids & body]
-  `(do-with-dashboards-in-a-collection perms/grant-collection-read-permissions! ~dashboards-or-ids (fn [] ~@body)))
+(defmacro ^:private with-dashboards-in-readable-collection! [dashboards-or-ids & body]
+  `(do-with-dashboards-in-a-collection! perms/grant-collection-read-permissions! ~dashboards-or-ids (fn [] ~@body)))
 
-(defmacro ^:private with-dashboards-in-writeable-collection [dashboards-or-ids & body]
-  `(do-with-dashboards-in-a-collection perms/grant-collection-readwrite-permissions! ~dashboards-or-ids (fn [] ~@body)))
+(defmacro ^:private with-dashboards-in-writeable-collection! [dashboards-or-ids & body]
+  `(do-with-dashboards-in-a-collection! perms/grant-collection-readwrite-permissions! ~dashboards-or-ids (fn [] ~@body)))
 
 (defn do-with-simple-dashboard-with-tabs
   [f]
@@ -463,8 +463,8 @@
                                                              :object   (revision/serialize-instance dashboard
                                                                                                     dashboard-id
                                                                                                     dashboard)}]
-        (with-dashboards-in-readable-collection [dashboard-id]
-          (api.card-test/with-cards-in-readable-collection [card-id]
+        (with-dashboards-in-readable-collection! [dashboard-id]
+          (api.card-test/with-cards-in-readable-collection! [card-id]
             (is (=? {:name                       "Test Dashboard"
                      :creator_id                 (mt/user->id :rasta)
                      :collection                 true
@@ -552,8 +552,8 @@
                                                        :parameter_mappings [{:card_id      1
                                                                              :parameter_id "foo"
                                                                              :target       [:dimension [:field field-id nil]]}]}]
-        (with-dashboards-in-readable-collection [dashboard-id]
-          (api.card-test/with-cards-in-readable-collection [card-id]
+        (with-dashboards-in-readable-collection! [dashboard-id]
+          (api.card-test/with-cards-in-readable-collection! [card-id]
             (is (=? {:name                       "Test Dashboard"
                      :creator_id                 (mt/user->id :rasta)
                      :collection_id              true
@@ -601,8 +601,8 @@
       (mt/with-temp [Dashboard     {dashboard-id :id} {:name "Test Dashboard"}
                      Card          {card-id :id}      {:name "Dashboard Test Card"}
                      DashboardCard _                  {:dashboard_id dashboard-id, :card_id card-id}]
-        (with-dashboards-in-readable-collection [dashboard-id]
-          (api.card-test/with-cards-in-readable-collection [card-id]
+        (with-dashboards-in-readable-collection! [dashboard-id]
+          (api.card-test/with-cards-in-readable-collection! [card-id]
             (is (nil?
                  (-> (dashboard-response (mt/user-http-request :rasta :get 200 (format "dashboard/%d" dashboard-id)))
                      :collection_authority_level)))
@@ -724,7 +724,7 @@
     (mt/test-helpers-set-global-values!
       (mt/with-temporary-setting-values [synchronous-batch-updates true]
         (t2.with-temp/with-temp [Dashboard {dashboard-id :id} {:name "Test Dashboard"}]
-          (with-dashboards-in-writeable-collection [dashboard-id]
+          (with-dashboards-in-writeable-collection! [dashboard-id]
             (testing "GET before update"
               (is (=? {:name          "Test Dashboard"
                        :creator_id    (mt/user->id :rasta)
@@ -797,7 +797,7 @@
   (testing "PUT /api/dashboard/:id"
     (testing "allow `:caveats` and `:points_of_interest` to be empty strings, and `:show_in_getting_started` should be a boolean"
       (t2.with-temp/with-temp [Dashboard {dashboard-id :id} {:name "Test Dashboard"}]
-        (with-dashboards-in-writeable-collection [dashboard-id]
+        (with-dashboards-in-writeable-collection! [dashboard-id]
           (is (=? {:name                    "Test Dashboard"
                    :creator_id              (mt/user->id :rasta)
                    :collection              true
@@ -821,7 +821,7 @@
   (testing "PUT /api/dashboard/:id"
     (testing "Can we clear the description of a Dashboard? (#4738)"
       (t2.with-temp/with-temp [Dashboard dashboard {:description "What a nice Dashboard"}]
-        (with-dashboards-in-writeable-collection [dashboard]
+        (with-dashboards-in-writeable-collection! [dashboard]
           (mt/user-http-request :rasta :put 200 (str "dashboard/" (u/the-id dashboard)) {:description nil})
           (is (= nil
                  (t2/select-one-fn :description Dashboard :id (u/the-id dashboard))))
@@ -834,7 +834,7 @@
 (deftest update-dashboard-change-collection-id-test
   (testing "PUT /api/dashboard/:id"
     (testing "Can we change the Collection a Dashboard is in (assuming we have the permissions to do so)?"
-      (dashboard-test/with-dash-in-collection [_db collection dash]
+      (dashboard-test/with-dash-in-collection! [_db collection dash]
         (t2.with-temp/with-temp [Collection new-collection]
           ;; grant Permissions for both new and old collections
           (doseq [coll [collection new-collection]]
@@ -847,7 +847,7 @@
 
     (testing "if we don't have the Permissions for the old collection, we should get an Exception"
       (mt/with-non-admin-groups-no-root-collection-perms
-        (dashboard-test/with-dash-in-collection [_db _collection dash]
+        (dashboard-test/with-dash-in-collection! [_db _collection dash]
           (t2.with-temp/with-temp [Collection new-collection]
             ;; grant Permissions for only the *new* collection
             (perms/grant-collection-readwrite-permissions! (perms-group/all-users) new-collection)
@@ -858,7 +858,7 @@
 
     (testing "if we don't have the Permissions for the new collection, we should get an Exception"
       (mt/with-non-admin-groups-no-root-collection-perms
-        (dashboard-test/with-dash-in-collection [_db collection dash]
+        (dashboard-test/with-dash-in-collection! [_db collection dash]
           (t2.with-temp/with-temp [Collection new-collection]
             ;; grant Permissions for only the *old* collection
             (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
@@ -871,7 +871,7 @@
   (testing "PUT /api/dashboard/:id"
     (testing "We can change the dashboard's width between 'fixed' and 'full' settings."
       (t2.with-temp/with-temp [Dashboard dashboard {}]
-        (with-dashboards-in-writeable-collection [dashboard]
+        (with-dashboards-in-writeable-collection! [dashboard]
           (testing "the default dashboard width value is 'fixed'."
             (is (= "fixed"
                    (t2/select-one-fn :width Dashboard :id (u/the-id dashboard)))))
@@ -893,7 +893,7 @@
   (testing "PUT /api/dashboard/:id"
     (testing "We can add a time granularity parameter to a dashboard"
       (t2.with-temp/with-temp [Dashboard dashboard {}]
-        (with-dashboards-in-writeable-collection [dashboard]
+        (with-dashboards-in-writeable-collection! [dashboard]
           (testing "the dashboard starts with no parameters."
             (is (= []
                    (t2/select-one-fn :parameters Dashboard :id (u/the-id dashboard)))))
@@ -1123,7 +1123,7 @@
 
 (deftest delete-test
   (t2.with-temp/with-temp [Dashboard {dashboard-id :id}]
-    (with-dashboards-in-writeable-collection [dashboard-id]
+    (with-dashboards-in-writeable-collection! [dashboard-id]
       (is (= nil
              (mt/user-http-request :rasta :delete 204 (format "dashboard/%d" dashboard-id))))
       (is (= nil
@@ -1606,7 +1606,7 @@
 (deftest copy-dashboard-into-correct-collection-test
   (testing "POST /api/dashboard/:id/copy"
     (testing "Ensure the correct collection is set when copying"
-      (dashboard-test/with-dash-in-collection [_db collection dash]
+      (dashboard-test/with-dash-in-collection! [_db collection dash]
         (t2.with-temp/with-temp [Collection new-collection]
           ;; grant Permissions for both new and old collections
           (doseq [coll [collection new-collection]]
@@ -1871,7 +1871,7 @@
 (deftest e2e-update-tabs-only-test
   (testing "PUT /api/dashboard/:id/cards with create/update/delete tabs in a single req"
     (with-simple-dashboard-with-tabs [{:keys [dashboard-id dashtab-id-1 dashtab-id-2]}]
-      (with-dashboards-in-writeable-collection [dashboard-id]
+      (with-dashboards-in-writeable-collection! [dashboard-id]
         ;; send a request that update and create and delete some cards at the same time
         (is (some? (t2/select-one :model/DashboardTab :id dashtab-id-2)))
         (let [tabs (:tabs (mt/user-http-request :rasta :put 200 (format "dashboard/%d" dashboard-id)
@@ -2010,8 +2010,8 @@
 (deftest simple-creation-with-no-additional-series-test
   (mt/with-temp [Dashboard {dashboard-id :id} {}
                  Card {card-id :id}] {}
-    (with-dashboards-in-writeable-collection [dashboard-id]
-      (api.card-test/with-cards-in-readable-collection [card-id]
+    (with-dashboards-in-writeable-collection! [dashboard-id]
+      (api.card-test/with-cards-in-readable-collection! [card-id]
         (let [resp (:dashcards (mt/user-http-request :rasta :put 200 (format "dashboard/%d" dashboard-id)
                                                      {:dashcards [{:id                     -1
                                                                    :card_id                card-id
@@ -2089,8 +2089,8 @@
   (mt/with-temp [Dashboard {dashboard-id :id} {}
                  Card      {card-id :id} {}
                  Card      {series-id-1 :id} {:name "Series Card"}]
-    (with-dashboards-in-writeable-collection [dashboard-id]
-      (api.card-test/with-cards-in-readable-collection [card-id series-id-1]
+    (with-dashboards-in-writeable-collection! [dashboard-id]
+      (api.card-test/with-cards-in-readable-collection! [card-id series-id-1]
         (let [dashboard-cards (:dashcards (mt/user-http-request :crowberto :put 200 (format "dashboard/%d" dashboard-id)
                                                                 {:dashcards [{:id      -1
                                                                               :card_id card-id
@@ -2220,7 +2220,7 @@
                    DashboardCard {dashcard-id-1 :id} {:dashboard_id dashboard-id, :card_id card-id}
                    DashboardCard {dashcard-id-2 :id} {:dashboard_id dashboard-id, :card_id card-id}
                    Card          {series-id-1 :id}   {:name "Series Card"}]
-      (with-dashboards-in-writeable-collection [dashboard-id]
+      (with-dashboards-in-writeable-collection! [dashboard-id]
         (is (= {:size_x                 4
                 :size_y                 4
                 :col                    0
@@ -2315,7 +2315,7 @@
                                                 :action_id action-id
                                                 :card_id model-id}
                      DashboardCard question-card {:dashboard_id dashboard-id, :card_id model-id}]
-        (with-dashboards-in-writeable-collection [dashboard-id]
+        (with-dashboards-in-writeable-collection! [dashboard-id]
           ;; TODO adds test for return
           ;; Update **both** cards to use the new card id
           (mt/user-http-request :rasta :put 200 (format "dashboard/%d" dashboard-id)
@@ -2357,7 +2357,7 @@
                      DashboardCardSeries _                    {:dashboardcard_id dashcard-id-1, :card_id series-id-1, :position 0}
                      DashboardCardSeries _                    {:dashboardcard_id dashcard-id-1, :card_id series-id-2, :position 1}
                      DashboardCardSeries _                    {:dashboardcard_id dashcard-id-3, :card_id series-id-1, :position 0}]
-        (with-dashboards-in-writeable-collection [dashboard-id]
+        (with-dashboards-in-writeable-collection! [dashboard-id]
           (is (= 3
                  (count (t2/select-pks-set DashboardCard, :dashboard_id dashboard-id))))
           (is (=? {:dashcards [{:id     dashcard-id-3
@@ -2374,7 +2374,7 @@
                      Card          {card-id :id}      {}
                      DashboardCard _                  {:dashboard_id dashboard-id, :card_id card-id}
                      DashboardCard _                  {:dashboard_id dashboard-id, :card_id card-id}]
-        (with-dashboards-in-writeable-collection [dashboard-id]
+        (with-dashboards-in-writeable-collection! [dashboard-id]
           (is (= 2
                  (count (t2/select-pks-set DashboardCard, :dashboard_id dashboard-id))))
           (is (=? {:tabs      []
diff --git a/test/metabase/api/database_test.clj b/test/metabase/api/database_test.clj
index 2f1e3c87a5a916475dce009c3ad087c8f7954d15..7030648fbe2c0eb19254c8af483872bb64189e9e 100644
--- a/test/metabase/api/database_test.clj
+++ b/test/metabase/api/database_test.clj
@@ -307,9 +307,9 @@
                    driver/can-connect? (constantly true)]
        ~@body)))
 
-(defmacro with-db-scheduler-setup
+(defmacro with-db-scheduler-setup!
   [& body]
-  `(mt/with-temp-scheduler
+  `(mt/with-temp-scheduler!
      (#'task.sync-databases/job-init)
      (u/prog1 ~@body
        (qs/delete-job (#'task/scheduler) (.getKey ^JobDetail @#'task.sync-databases/sync-analyze-job))
@@ -318,7 +318,7 @@
 (deftest create-db-default-schedule-test
   (testing "POST /api/database"
     (testing "create a db with default scan options"
-      (with-db-scheduler-setup
+      (with-db-scheduler-setup!
         (with-test-driver-available!
           (let [resp (mt/user-http-request :crowberto :post 200 "database"
                                            {:name    (mt/random-name)
@@ -1146,7 +1146,7 @@
 (deftest create-db-with-manual-schedules-test
   (testing "POST /api/database"
     (testing "create a db with scan field values option is \"regularly on a schedule\""
-      (with-db-scheduler-setup
+      (with-db-scheduler-setup!
         (with-test-driver-available!
           (let [{:keys [details] :as db}
                 (mt/user-http-request :crowberto :post 200 "database"
@@ -1168,7 +1168,7 @@
 (deftest create-db-never-scan-field-values-test
   (testing "POST /api/database"
     (testing "create a db with scan field values option is \"Never, I'll do it myself\""
-      (with-db-scheduler-setup
+      (with-db-scheduler-setup!
         (with-test-driver-available!
           (let [resp (mt/user-http-request :crowberto :post 200 "database"
                                            {:name         (mt/random-name)
@@ -1189,7 +1189,7 @@
 (deftest create-db-on-demand-scan-field-values-test
   (testing "POST /api/database"
     (testing "create a db with scan field values option is \"Only when adding a new filter widget\""
-      (with-db-scheduler-setup
+      (with-db-scheduler-setup!
         (with-test-driver-available!
           (let [resp (mt/user-http-request :crowberto :post 200 "database"
                                            {:name         (mt/random-name)
@@ -1208,7 +1208,7 @@
                    (task.sync-databases-test/query-all-db-sync-triggers-name db)))))))))
 
 (deftest update-db-to-sync-on-custom-schedule-test
-  (with-db-scheduler-setup
+  (with-db-scheduler-setup!
     (with-test-driver-available!
       (mt/with-temp
         [:model/Database db {}]
@@ -1270,7 +1270,7 @@
                      (:cache_field_values_schedule db)))))))))
 
 (deftest update-db-to-never-scan-values-on-demand-test
-  (with-db-scheduler-setup
+  (with-db-scheduler-setup!
     (with-test-driver-available!
       (mt/with-temp
         [:model/Database db {}]
@@ -1292,7 +1292,7 @@
             (is (nil? (:cache_field_values_schedule db)))))))))
 
 (deftest update-db-to-scan-field-values-on-demand-test
-  (with-db-scheduler-setup
+  (with-db-scheduler-setup!
     (with-test-driver-available!
       (testing "update db to scan on demand should remove scan field values trigger"
         (mt/with-temp
@@ -1434,7 +1434,7 @@
    (with-redefs [h2/*allow-testing-h2-connections* true]
      (mt/user-http-request user :post expected-status-code "database/validate" request-body))))
 
-(defn- test-connection-details [engine details]
+(defn- test-connection-details! [engine details]
   (with-redefs [h2/*allow-testing-h2-connections* true]
     (#'api.database/test-connection-details engine details)))
 
@@ -1447,7 +1447,7 @@
 
     (testing "Underlying `test-connection-details` function should work"
       (is (= (:details (mt/db))
-             (test-connection-details "h2" (:details (mt/db))))))
+             (test-connection-details! "h2" (:details (mt/db))))))
 
     (testing "Valid database connection details"
       (is (= (merge (:details (mt/db)) {:valid true})
@@ -1458,7 +1458,7 @@
         (is (= {:errors  {:db "check your connection string"}
                 :message "Implicitly relative file paths are not allowed."
                 :valid   false}
-               (test-connection-details "h2" {:db "ABC"}))))
+               (test-connection-details! "h2" {:db "ABC"}))))
 
       (testing "via the API endpoint"
         (is (= {:errors  {:db "check your connection string"}
diff --git a/test/metabase/api/embed_test.clj b/test/metabase/api/embed_test.clj
index d0ff6e112eb6b6fce57dceaa84d197496226046a..49e5aaa57296d524ec4ca18d27bc744577853cdb 100644
--- a/test/metabase/api/embed_test.clj
+++ b/test/metabase/api/embed_test.clj
@@ -39,13 +39,13 @@
 
 (defn sign [claims] (jwt/sign claims *secret-key*))
 
-(defn do-with-new-secret-key [f]
+(defn do-with-new-secret-key! [f]
   (binding [*secret-key* (random-embedding-secret-key)]
     (mt/with-temporary-setting-values [embedding-secret-key *secret-key*]
       (f))))
 
-(defmacro with-new-secret-key {:style/indent 0} [& body]
-  `(do-with-new-secret-key (fn [] ~@body)))
+(defmacro with-new-secret-key! {:style/indent 0} [& body]
+  `(do-with-new-secret-key! (fn [] ~@body)))
 
 (defn card-token {:style/indent 1} [card-or-id & [additional-token-params]]
   (sign (merge {:resource {:question (u/the-id card-or-id)}
@@ -98,9 +98,9 @@
     (fn [~dashcard-binding]
       ~@body)))
 
-(defmacro with-embedding-enabled-and-new-secret-key {:style/indent 0} [& body]
+(defmacro with-embedding-enabled-and-new-secret-key! {:style/indent 0} [& body]
   `(mt/with-temporary-setting-values [~'enable-embedding true]
-     (with-new-secret-key
+     (with-new-secret-key!
        ~@body)))
 
 (defn ^:deprecated test-query-results
@@ -161,20 +161,20 @@
 (defn card-url [card & [additional-token-params]] (str "embed/card/" (card-token card additional-token-params)))
 
 (deftest it-should-be-possible-to-use-this-endpoint-successfully-if-all-the-conditions-are-met
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-card [card {:enable_embedding true}]
       (is (= successful-card-info
              (dissoc-id-and-name
                (client/client :get 200 (card-url card))))))))
 
 (deftest we-should-fail-when-attempting-to-use-an-expired-token
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-card [card {:enable_embedding true}]
       (is (re= #"Token is expired.*"
                (client/client :get 400 (card-url card {:exp (buddy-util/to-timestamp yesterday)})))))))
 
 (deftest bad-card-id-fails
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (let [card-url (str "embed/card/" (sign {:resource {:question "8"}
                                              :params   {}}))]
       (is (= "Card id should be a positive integer."
@@ -182,13 +182,13 @@
 
 (deftest check-that-the-endpoint-doesn-t-work-if-embedding-isn-t-enabled
   (mt/with-temporary-setting-values [enable-embedding false]
-    (with-new-secret-key
+    (with-new-secret-key!
       (with-temp-card [card]
         (is (= "Embedding is not enabled."
                (client/client :get 400 (card-url card))))))))
 
 (deftest check-that-if-embedding-is-enabled-globally-but-not-for-the-card-the-request-fails
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-card [card]
       (is (= "Embedding is not enabled for this object."
              (client/client :get 400 (card-url card)))))))
@@ -196,14 +196,14 @@
 (deftest global-embedding-requests-fail-with-wrong-key
   (testing (str "check that if embedding is enabled globally and for the object that requests fail if they are signed "
                 "with the wrong key")
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-card [card {:enable_embedding true}]
         (is (= "Message seems corrupt or manipulated"
-               (client/client :get 400 (with-new-secret-key (card-url card)))))))))
+               (client/client :get 400 (with-new-secret-key! (card-url card)))))))))
 
 (deftest check-that-only-enabled-params-that-are-not-present-in-the-jwt-come-back
   (testing "check that only ENABLED params that ARE NOT PRESENT IN THE JWT come back"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-card [card {:enable_embedding true
                              :dataset_query    {:database (mt/id)
                                                 :type     :native
@@ -234,7 +234,7 @@
      ;; because doing such migration is costly.
      ;; so there are cards where some parameters in template-tags does not exist in card.parameters
      ;; that why we need to keep concat both of them then dedupe by id
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-card [card (public-test/card-with-embedded-params)]
         (is (= [;; the parameter with id = "c" exists in both card.parameters and tempalte-tags should have info
                 ;; merge of both places
@@ -262,7 +262,7 @@
 
 (deftest parameters-should-include-relevant-template-tags-only
   (testing "should work with non-parameter template tags"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-card [card (public-test/card-with-snippet-and-card-template-tags)]
         (is (= [{:type "date/single",
                  :name "a",
@@ -308,7 +308,7 @@
       (do-response-formats [response-format _request-options]
         (testing "check that the endpoint doesn't work if embedding isn't enabled"
           (mt/with-temporary-setting-values [enable-embedding false]
-            (with-new-secret-key
+            (with-new-secret-key!
               (with-temp-card [card]
                 (is (= "Embedding is not enabled."
                        (client/real-client :get 400 (card-query-url card response-format))))))))))))
@@ -317,7 +317,7 @@
   (testing "GET /api/embed/card/:token/query and GET /api/embed/card/:token/query/:export-format"
     (mt/test-helpers-set-global-values!
       (do-response-formats [response-format request-options]
-        (with-embedding-enabled-and-new-secret-key
+        (with-embedding-enabled-and-new-secret-key!
           (let [expected-status (response-format->status-code response-format)]
             (testing "it should be possible to run a Card successfully if you jump through the right hoops..."
               (with-temp-card [card {:enable_embedding true}]
@@ -331,7 +331,7 @@
   (testing "GET /api/embed/card/:token/query and GET /api/embed/card/:token/query/:export-format"
     (mt/test-helpers-set-global-values!
       (do-response-formats [response-format _request-options]
-        (with-embedding-enabled-and-new-secret-key
+        (with-embedding-enabled-and-new-secret-key!
           (let [expected-status (response-format->status-code response-format)]
             (testing (str "If the card has an invalid query we should just get a generic \"query failed\" "
                           "exception (rather than leaking query info)")
@@ -347,7 +347,7 @@
   (testing "GET /api/embed/card/:token/query and GET /api/embed/card/:token/query/:export-format"
     (mt/test-helpers-set-global-values!
       (do-response-formats [response-format _request-options]
-        (with-embedding-enabled-and-new-secret-key
+        (with-embedding-enabled-and-new-secret-key!
           (testing "check that if embedding *is* enabled globally but not for the Card the request fails"
             (with-temp-card [card]
               (is (= "Embedding is not enabled for this object."
@@ -357,19 +357,19 @@
   (testing "GET /api/embed/card/:token/query and GET /api/embed/card/:token/query/:export-format"
     (mt/test-helpers-set-global-values!
       (do-response-formats [response-format _request-options]
-        (with-embedding-enabled-and-new-secret-key
+        (with-embedding-enabled-and-new-secret-key!
           (testing (str "check that if embedding is enabled globally and for the object that requests fail if they are "
                         "signed with the wrong key")
             (with-temp-card [card {:enable_embedding true}]
               (is (= "Message seems corrupt or manipulated"
-                     (client/real-client :get 400 (with-new-secret-key (card-query-url card response-format))))))))))))
+                     (client/real-client :get 400 (with-new-secret-key! (card-query-url card response-format))))))))))))
 
 (deftest download-formatted-without-constraints-test
   (testing (str "Downloading CSV/JSON/XLSX results shouldn't be subject to the default query constraints -- even if "
                 "the query comes in with `add-default-userland-constraints` (as will be the case if the query gets "
                 "saved from one that had it -- see #9831 and #10399)")
     (with-redefs [qp.constraints/default-query-constraints (constantly {:max-results 10, :max-results-bare-rows 10})]
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-card [card {:enable_embedding true
                                :dataset_query    (assoc (mt/mbql-query venues)
                                                         :middleware
@@ -381,7 +381,7 @@
 
 (deftest card-locked-params-test
   (mt/test-helpers-set-global-values!
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-card [card {:enable_embedding true, :embedding_params {:venue_id "locked"}}]
         (do-response-formats [response-format request-options]
                              (testing (str "check that if embedding is enabled globally and for the object requests fail if the token is "
@@ -402,7 +402,7 @@
                                       (client/client :get 400 (str (card-query-url card response-format {:params {:venue_id 100}}) "?venue_id=100"))))))))))
 
 (deftest card-disabled-params-test
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-card [card {:enable_embedding true, :embedding_params {:venue_id "disabled"}}]
       (do-response-formats [response-format _request-options]
         (testing (str "check that if embedding is enabled globally and for the object requests fail if they pass a "
@@ -416,7 +416,7 @@
 
 (deftest card-enabled-params-test
   (mt/test-helpers-set-global-values!
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-card [card {:enable_embedding true, :embedding_params {:venue_id "enabled"}}]
         (do-response-formats [response-format request-options]
           (testing "If `:enabled` param is present in both JWT and the URL, the request should fail"
@@ -455,7 +455,7 @@
 
 (deftest default-value-card-query-test
   (testing "GET /api/embed/card/:token/query with default values for params"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (testing "if the param is enabled"
         (t2.with-temp/with-temp
           [Card card (assoc (card-with-date-field-filter-default) :embedding_params {:date :enabled})]
@@ -507,14 +507,14 @@
 
 (deftest csv-reports-count
   (testing "make sure CSV (etc.) downloads take editable params into account (#6407)"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Card card (card-with-date-field-filter)]
         (is (= "count\n107\n"
                (client/client :get 200 (str (card-query-url card "/csv") "?date=Q1-2014"))))))))
 
 (deftest csv-forward-url-test
   (mt/test-helpers-set-global-values!
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (mt/with-temp [Card card (card-with-date-field-filter)]
         ;; make sure the URL doesn't include /api/ at the beginning like it normally would
         (binding [client/*url-prefix* ""]
@@ -529,34 +529,34 @@
   (str "embed/dashboard/" (dash-token dashboard additional-token-params)))
 
 (deftest it-should-be-possible-to-call-this-endpoint-successfully
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (t2.with-temp/with-temp [Dashboard dash {:enable_embedding true}]
       (is (= successful-dashboard-info
              (dissoc-id-and-name
               (client/client :get 200 (dashboard-url dash))))))))
 
 (deftest bad-dashboard-id-fails
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (let [dashboard-url (str "embed/dashboard/" (sign {:resource {:dashboard "8"}
                                                        :params   {}}))]
       (is (= "Dashboard id should be a positive integer."
              (client/client :get 400 dashboard-url))))))
 
 (deftest we-should-fail-when-attempting-to-use-an-expired-token-2
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (t2.with-temp/with-temp [Dashboard dash {:enable_embedding true}]
       (is (re= #"^Token is expired.*"
                (client/client :get 400 (dashboard-url dash {:exp (buddy-util/to-timestamp yesterday)})))))))
 
 (deftest check-that-the-dashboard-endpoint-doesn-t-work-if-embedding-isn-t-enabled
   (mt/with-temporary-setting-values [enable-embedding false]
-    (with-new-secret-key
+    (with-new-secret-key!
       (t2.with-temp/with-temp [Dashboard dash]
         (is (= "Embedding is not enabled."
                (client/client :get 400 (dashboard-url dash))))))))
 
 (deftest check-that-if-embedding--is--enabled-globally-but-not-for-the-dashboard-the-request-fails
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (t2.with-temp/with-temp [Dashboard dash]
       (is (= "Embedding is not enabled for this object."
              (client/client :get 400 (dashboard-url dash)))))))
@@ -564,14 +564,14 @@
 (deftest global-embedding-check-key
   (testing (str "check that if embedding is enabled globally and for the object that requests fail if they are signed "
                 "with the wrong key")
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard dash {:enable_embedding true}]
         (is (= "Message seems corrupt or manipulated"
-               (client/client :get 400 (with-new-secret-key (dashboard-url dash)))))))))
+               (client/client :get 400 (with-new-secret-key! (dashboard-url dash)))))))))
 
 (deftest only-enabled-params-that-are-not-present-in-the-jwt-come-back
   (testing "check that only ENABLED params that ARE NOT PRESENT IN THE JWT come back"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard dash {:enable_embedding true
                                                :embedding_params {:a "locked", :b "disabled", :c "enabled", :d "enabled"}
                                                :parameters       [{:id "_a", :slug "a", :name "a", :type "date"}
@@ -583,7 +583,7 @@
 
 (deftest locked-params-are-substituted-into-text-cards
   (testing "check that locked params are substituted into text cards with mapped variables on the backend"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (mt/with-temp [Dashboard     dash {:enable_embedding true
                                          :parameters       [{:id "_a" :slug "a" :name "a" :type :string/=}]}
                      DashboardCard _ {:dashboard_id           (:id dash)
@@ -600,7 +600,7 @@
 
 (deftest locked-params-removes-values-fields-and-mappings-test
   (testing "check that locked params are removed in parameter mappings, param_values, and param_fields"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard     dashboard     {:enable_embedding true
                                                             :embedding_params {:venue_name "locked"}
                                                             :name             "Test Dashboard"
@@ -639,7 +639,7 @@
 
 (deftest locked-params-removes-values-fields-when-not-used-in-enabled-params
   (testing "check that locked params are not removed in parameter mappings, param_values, and param_fields when an enabled param uses them (#37914)"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard     dashboard     {:enable_embedding true
                                                             :embedding_params {:venue_name   "locked"
                                                                                :venue_name_2 "enabled"}
@@ -685,7 +685,7 @@
 
 (deftest linked-param-to-locked-removes-param-values-test
   (testing "Check that a linked parameter to a locked params we remove the param_values."
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard     dashboard     {:enable_embedding true
                                                             :embedding_params {:venue_name "locked" :category_name "enabled"}
                                                             :name             "Test Dashboard"
@@ -731,7 +731,7 @@
 
 (deftest it-should-be-possible-to-run-a-card-successfully-if-you-jump-through-the-right-hoops---
   (testing "it should be possible to run a Card successfully if you jump through the right hoops..."
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-dashcard [dashcard {:dash {:enable_embedding true}}]
         #_{:clj-kondo/ignore [:deprecated-var]}
         (test-query-results (client/client :get 202 (dashcard-url dashcard)))))))
@@ -740,7 +740,7 @@
   (testing (str "Downloading CSV/JSON/XLSX results from the dashcard endpoint shouldn't be subject to the default "
                 "query constraints (#10399)")
     (with-redefs [qp.constraints/default-query-constraints (constantly {:max-results 10, :max-results-bare-rows 10})]
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash {:enable_embedding true}
                                        :card {:dataset_query (assoc (mt/mbql-query venues)
                                                                     :middleware
@@ -755,7 +755,7 @@
     ;; Clear out the query execution log so that test doesn't read stale state
     (t2/delete! :model/QueryExecution)
     (mt/test-helpers-set-global-values!
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash {:enable_embedding true}
                                        :card {:dataset_query (mt/mbql-query venues)}}]
           (let [query (assoc
@@ -768,17 +768,17 @@
                        :viz-settings {}
                        :async? true
                        :cache-strategy nil)]
-            (process-userland-query-test/with-query-execution [qe query]
+            (process-userland-query-test/with-query-execution! [qe query]
               (client/client :get 200 (str (dashcard-url dashcard) "/csv"))
               (is (= :embedded-csv-download
                      (:context
                       (qe)))))
-            (process-userland-query-test/with-query-execution [qe query]
+            (process-userland-query-test/with-query-execution! [qe query]
               (client/client :get 200 (str (dashcard-url dashcard) "/json"))
               (is (= :embedded-json-download
                      (:context
                       (qe)))))
-            (process-userland-query-test/with-query-execution [qe query]
+            (process-userland-query-test/with-query-execution! [qe query]
               (client/client :get 200 (str (dashcard-url dashcard) "/xlsx"))
               (is (= :embedded-xlsx-download
                      (:context
@@ -787,7 +787,7 @@
 (deftest downloading-csv-json-xlsx-results-from-the-dashcard-endpoint-respects-column-settings
   (testing "Downloading CSV/JSON/XLSX results should respect the column settings of the dashcard, such as column order and hidden/shown setting. (#33727)"
     (with-redefs [qp.constraints/default-query-constraints (constantly {:max-results 10, :max-results-bare-rows 10})]
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash     {:enable_embedding true}
                                        :card     {:dataset_query (assoc (mt/mbql-query venues)
                                                                         :limit 1
@@ -811,7 +811,7 @@
 (deftest generic-query-failed-exception-test
   (testing (str "...but if the card has an invalid query we should just get a generic \"query failed\" exception "
                 "(rather than leaking query info)")
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-dashcard [dashcard {:dash {:enable_embedding true}
                                      :card {:dataset_query (mt/native-query {:query "SELECT * FROM XYZ"})}}]
         (is (= {:status     "failed"
@@ -821,13 +821,13 @@
 
 (deftest check-that-the-dashcard-endpoint-doesn-t-work-if-embedding-isn-t-enabled
   (mt/with-temporary-setting-values [enable-embedding false]
-    (with-new-secret-key
+    (with-new-secret-key!
       (with-temp-dashcard [dashcard]
         (is (= "Embedding is not enabled."
                (client/client :get 400 (dashcard-url dashcard))))))))
 
 (deftest dashcard-check-that-if-embedding--is--enabled-globally-but-not-for-the-dashboard-the-request-fails
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-dashcard [dashcard]
       (is (= "Embedding is not enabled for this object."
              (client/client :get 400 (dashcard-url dashcard)))))))
@@ -835,13 +835,13 @@
 (deftest dashcard-global-embedding-check-key
   (testing (str "check that if embedding is enabled globally and for the object that requests fail if they are signed "
                 "with the wrong key")
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-dashcard [dashcard {:dash {:enable_embedding true}}]
         (is (= "Message seems corrupt or manipulated"
-               (client/client :get 400 (with-new-secret-key (dashcard-url dashcard)))))))))
+               (client/client :get 400 (with-new-secret-key! (dashcard-url dashcard)))))))))
 
 (deftest dashboard-locked-params-test
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-dashcard [dashcard {:dash {:enable_embedding true, :embedding_params {:venue_id "locked"}}}]
       (testing (str "check that if embedding is enabled globally and for the object requests fail if the token is "
                     "missing a `:locked` parameter")
@@ -858,7 +858,7 @@
                (client/client :get 400 (str (dashcard-url dashcard) "?venue_id=100"))))))))
 
 (deftest dashboard-disabled-params-test
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-dashcard [dashcard {:dash {:enable_embedding true, :embedding_params {:venue_id "disabled"}}}]
       (testing (str "check that if embedding is enabled globally and for the object requests fail if they pass a "
                     "`:disabled` parameter")
@@ -870,7 +870,7 @@
                (client/client :get 400 (str (dashcard-url dashcard) "?venue_id=200"))))))))
 
 (deftest dashboard-enabled-params-test
-  (with-embedding-enabled-and-new-secret-key
+  (with-embedding-enabled-and-new-secret-key!
     (with-temp-dashcard [dashcard {:dash {:enable_embedding true, :embedding_params {:venue_id "enabled"}}}]
       (testing "If `:enabled` param is present in both JWT and the URL, the request should fail"
         (is (= "You can't specify a value for :venue_id if it's already set in the JWT."
@@ -888,7 +888,7 @@
 
 (deftest dashboard-native-query-params-with-default-test
   (testing "GET api/embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id with default values for params"
-   (with-embedding-enabled-and-new-secret-key
+   (with-embedding-enabled-and-new-secret-key!
      (t2.with-temp/with-temp
        [Card      card      (card-with-date-field-filter-default)
         Dashboard dashboard {:enable_embedding true
@@ -947,7 +947,7 @@
 
 (deftest make-sure-that-multiline-series-word-as-expected---4768-
   (testing "make sure that multiline series word as expected (#4768)"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Card series-card {:dataset_query {:database (mt/id)
                                                                  :type     :query
                                                                  :query    {:source-table (mt/id :venues)}}}]
@@ -970,16 +970,16 @@
    (u/the-id field-or-id)
    "/values"))
 
-(defn- do-with-embedding-enabled-and-temp-card-referencing {:style/indent 2} [table-kw field-kw f]
-  (with-embedding-enabled-and-new-secret-key
+(defn- do-with-embedding-enabled-and-temp-card-referencing! {:style/indent 2} [table-kw field-kw f]
+  (with-embedding-enabled-and-new-secret-key!
     (t2.with-temp/with-temp [Card card (assoc (public-test/mbql-card-referencing table-kw field-kw)
                                         :enable_embedding true)]
       (f card))))
 
-(defmacro ^:private with-embedding-enabled-and-temp-card-referencing
+(defmacro ^:private with-embedding-enabled-and-temp-card-referencing!
   {:style/indent 3}
   [table-kw field-kw [card-binding] & body]
-  `(do-with-embedding-enabled-and-temp-card-referencing ~table-kw ~field-kw
+  `(do-with-embedding-enabled-and-temp-card-referencing! ~table-kw ~field-kw
      (fn [~(or card-binding '_)]
        ~@body)))
 
@@ -993,26 +993,26 @@
                             ["BCD Tofu House"]]
           :field_id        (mt/id :venues :name)
           :has_more_values false}
-         (with-embedding-enabled-and-temp-card-referencing :venues :name [card]
+         (with-embedding-enabled-and-temp-card-referencing! :venues :name [card]
            (-> (client/client :get 200 (field-values-url card (mt/id :venues :name)))
                (update :values (partial take 5)))))))
 
 ;; but for Fields that are not referenced we should get an Exception
 (deftest but-for-fields-that-are-not-referenced-we-should-get-an-exception
   (is (= "Not found."
-         (with-embedding-enabled-and-temp-card-referencing :venues :name [card]
+         (with-embedding-enabled-and-temp-card-referencing! :venues :name [card]
            (client/client :get 400 (field-values-url card (mt/id :venues :price)))))))
 
 ;; Endpoint should fail if embedding is disabled
 (deftest endpoint-should-fail-if-embedding-is-disabled
   (is (= "Embedding is not enabled."
-         (with-embedding-enabled-and-temp-card-referencing :venues :name [card]
+         (with-embedding-enabled-and-temp-card-referencing! :venues :name [card]
            (mt/with-temporary-setting-values [enable-embedding false]
              (client/client :get 400 (field-values-url card (mt/id :venues :name))))))))
 
 (deftest embedding-not-enabled-message
   (is (= "Embedding is not enabled for this object."
-         (with-embedding-enabled-and-temp-card-referencing :venues :name [card]
+         (with-embedding-enabled-and-temp-card-referencing! :venues :name [card]
            (t2/update! Card (u/the-id card) {:enable_embedding false})
            (client/client :get 400 (field-values-url card (mt/id :venues :name)))))))
 
@@ -1024,7 +1024,7 @@
             (client/client :get 200 (format "embed/card/%s/params/%s/values"
                                             (card-token card) param-key)))]
     (mt/with-temporary-setting-values [enable-embedding true]
-      (with-new-secret-key
+      (with-new-secret-key!
         (api.card-test/with-card-param-values-fixtures [{:keys [card field-filter-card param-keys]}]
           (t2/update! Card (:id field-filter-card)
                       {:enable_embedding true
@@ -1065,8 +1065,8 @@
 
 ;;; ----------------------------- GET /api/embed/dashboard/:token/field/:field/values nil -----------------------------
 
-(defn- do-with-embedding-enabled-and-temp-dashcard-referencing {:style/indent 2} [table-kw field-kw f]
-  (with-embedding-enabled-and-new-secret-key
+(defn- do-with-embedding-enabled-and-temp-dashcard-referencing! {:style/indent 2} [table-kw field-kw f]
+  (with-embedding-enabled-and-new-secret-key!
     (mt/with-temp [Dashboard     dashboard {:enable_embedding true}
                    Card          card      (public-test/mbql-card-referencing table-kw field-kw)
                    DashboardCard dashcard  {:dashboard_id       (u/the-id dashboard)
@@ -1078,10 +1078,10 @@
       (f dashboard card dashcard))))
 
 
-(defmacro ^:private with-embedding-enabled-and-temp-dashcard-referencing
+(defmacro ^:private with-embedding-enabled-and-temp-dashcard-referencing!
   {:style/indent 3}
   [table-kw field-kw [dash-binding card-binding dashcard-binding] & body]
-  `(do-with-embedding-enabled-and-temp-dashcard-referencing ~table-kw ~field-kw
+  `(do-with-embedding-enabled-and-temp-dashcard-referencing! ~table-kw ~field-kw
      (fn [~(or dash-binding '_) ~(or card-binding '_) ~(or dashcard-binding '_)]
        ~@body)))
 
@@ -1094,20 +1094,20 @@
                             ["BCD Tofu House"]]
           :field_id        (mt/id :venues :name)
           :has_more_values false}
-         (with-embedding-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+         (with-embedding-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
            (-> (client/client :get 200 (field-values-url dashboard (mt/id :venues :name)))
                (update :values (partial take 5)))))))
 
 ;; shound NOT be able to use the endpoint with a Field not referenced by the Dashboard
 (deftest shound-not-be-able-to-use-the-endpoint-with-a-field-not-referenced-by-the-dashboard
   (is (= "Not found."
-         (with-embedding-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+         (with-embedding-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
            (client/client :get 400 (field-values-url dashboard (mt/id :venues :price)))))))
 
 ;; Endpoint should fail if embedding is disabled
 (deftest field-values-endpoint-should-fail-if-embedding-is-disabled
   (is (= "Embedding is not enabled."
-         (with-embedding-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+         (with-embedding-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
            (mt/with-temporary-setting-values [enable-embedding false]
              (client/client :get 400 (field-values-url dashboard (mt/id :venues :name))))))))
 
@@ -1115,7 +1115,7 @@
 ;; Endpoint should fail if embedding is disabled for the Dashboard
 (deftest endpoint-should-fail-if-embedding-is-disabled-for-the-dashboard
   (is (= "Embedding is not enabled for this object."
-         (with-embedding-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+         (with-embedding-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
            (t2/update! Dashboard (u/the-id dashboard) {:enable_embedding false})
            (client/client :get 400 (field-values-url dashboard (mt/id :venues :name)))))))
 
@@ -1155,11 +1155,11 @@
                                       :value "33 T")))))]
       (testing "GET /api/embed/card/:token/field/:field/search/:search-field-id nil"
         (testing "Search for Field values for a Card"
-          (with-embedding-enabled-and-temp-card-referencing :venues :id [card]
+          (with-embedding-enabled-and-temp-card-referencing! :venues :id [card]
             (tests Card card))))
       (testing "GET /api/embed/dashboard/:token/field/:field/search/:search-field-id nil"
         (testing "Search for Field values for a Dashboard"
-          (with-embedding-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+          (with-embedding-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
             (tests Dashboard dashboard)))))))
 
 
@@ -1199,28 +1199,28 @@
 
     (testing "GET /api/embed/card/:token/field/:field/remapping/:remapped-id nil"
       (testing "Get remapped Field values for a Card"
-        (with-embedding-enabled-and-temp-card-referencing :venues :id [card]
+        (with-embedding-enabled-and-temp-card-referencing! :venues :id [card]
           (tests Card card)))
       (testing "Shouldn't work if Card doesn't reference the Field in question"
-        (with-embedding-enabled-and-temp-card-referencing :venues :price [card]
+        (with-embedding-enabled-and-temp-card-referencing! :venues :price [card]
           (is (= "Not found."
                  (client/client :get 400 (field-remapping-url card (mt/id :venues :id) (mt/id :venues :name))
                                 :value "10"))))))
 
     (testing "GET /api/embed/dashboard/:token/field/:field/remapping/:remapped-id nil"
       (testing "Get remapped Field values for a Dashboard"
-        (with-embedding-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+        (with-embedding-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
           (tests Dashboard dashboard)))
       (testing "Shouldn't work if Dashboard doesn't reference the Field in question"
-        (with-embedding-enabled-and-temp-dashcard-referencing :venues :price [dashboard]
+        (with-embedding-enabled-and-temp-dashcard-referencing! :venues :price [dashboard]
           (is (= "Not found."
                  (client/client :get 400 (field-remapping-url dashboard (mt/id :venues :id) (mt/id :venues :name))
                                 :value "10"))))))))
 
 ;;; ------------------------------------------------ Chain filtering -------------------------------------------------
 
-(defn- do-with-chain-filter-fixtures [f]
-  (with-embedding-enabled-and-new-secret-key
+(defn- do-with-chain-filter-fixtures! [f]
+  (with-embedding-enabled-and-new-secret-key!
     (api.dashboard-test/with-chain-filter-fixtures [{:keys [dashboard], :as m}]
       (t2/update! Dashboard (u/the-id dashboard) {:enable_embedding true})
       (letfn [(token [params]
@@ -1236,11 +1236,11 @@
                   :values-url values-url
                   :search-url search-url))))))
 
-(defmacro ^:private with-chain-filter-fixtures [[binding] & body]
-  `(do-with-chain-filter-fixtures (fn [~binding] ~@body)))
+(defmacro ^:private with-chain-filter-fixtures! [[binding] & body]
+  `(do-with-chain-filter-fixtures! (fn [~binding] ~@body)))
 
 (deftest chain-filter-embedding-disabled-test
-  (with-chain-filter-fixtures [{:keys [dashboard values-url search-url]}]
+  (with-chain-filter-fixtures! [{:keys [dashboard values-url search-url]}]
     (testing "without embedding enabled for dashboard"
       (t2/update! Dashboard (u/the-id dashboard) {:enable_embedding false})
       (testing "GET /api/embed/dashboard/:token/params/:param-key/values"
@@ -1251,7 +1251,7 @@
                (client/client :get 400 (search-url))))))))
 
 (deftest chain-filter-random-params-test
-  (with-chain-filter-fixtures [{:keys [values-url search-url]}]
+  (with-chain-filter-fixtures! [{:keys [values-url search-url]}]
     (testing "Requests should fail if parameter is not explicitly enabled"
       (testing "\nGET /api/embed/dashboard/:token/params/:param-key/values"
         (is (= "Cannot search for values: \"category_id\" is not an enabled parameter."
@@ -1262,7 +1262,7 @@
 
 (deftest params-with-static-list-test
   (testing "embedding with parameter that has source is a static list"
-    (with-chain-filter-fixtures [{:keys [dashboard values-url search-url]}]
+    (with-chain-filter-fixtures! [{:keys [dashboard values-url search-url]}]
       (t2/update! Dashboard (:id dashboard)
         {:embedding_params {"static_category" "enabled", "static_category_label" "enabled"}})
       (testing "Should work if the param we're fetching values for is enabled"
@@ -1276,7 +1276,7 @@
                  (client/client :get 200 (search-url {} "_STATIC_CATEGORY_LABEL_" "AF")))))))))
 
 (deftest chain-filter-enabled-params-test
-  (with-chain-filter-fixtures [{:keys [dashboard values-url search-url]}]
+  (with-chain-filter-fixtures! [{:keys [dashboard values-url search-url]}]
     (t2/update! Dashboard (:id dashboard)
       {:embedding_params {"category_id" "enabled", "category_name" "enabled", "price" "enabled"}})
     (testing "Should work if the param we're fetching values for is enabled"
@@ -1320,7 +1320,7 @@
   (testing "Should not fail if request is authenticated but current user does not have data permissions"
     (mt/with-temp-copy-of-db
       (mt/with-no-data-perms-for-all-users!
-        (with-chain-filter-fixtures [{:keys [dashboard values-url search-url]}]
+        (with-chain-filter-fixtures! [{:keys [dashboard values-url search-url]}]
           (t2/update! Dashboard (:id dashboard)
                       {:embedding_params {"category_id" "enabled", "category_name" "enabled", "price" "enabled"}})
           (testing "Should work if the param we're fetching values for is enabled"
@@ -1334,7 +1334,7 @@
                      (chain-filer-test/take-n-values 3 (mt/user-http-request :rasta :get 200 (search-url))))))))))))
 
 (deftest chain-filter-locked-params-test
-  (with-chain-filter-fixtures [{:keys [dashboard values-url search-url]}]
+  (with-chain-filter-fixtures! [{:keys [dashboard values-url search-url]}]
     (testing "Requests should fail if searched param is locked"
       (t2/update! Dashboard (:id dashboard)
                   {:embedding_params {"category_id" "locked", "category_name" "locked"}})
@@ -1371,7 +1371,7 @@
                    (client/client :get 400 (str url "?_PRICE_=4"))))))))))
 
 (deftest chain-filter-disabled-params-test
-  (with-chain-filter-fixtures [{:keys [dashboard values-url search-url]}]
+  (with-chain-filter-fixtures! [{:keys [dashboard values-url search-url]}]
     (testing "Requests should fail if searched param is disabled"
       (t2/update! Dashboard (:id dashboard)
         {:embedding_params {"category_id" "disabled", "category_name" "disabled"}})
@@ -1412,12 +1412,12 @@
       (testing "GET /api/embed/pivot/card/:token/query"
         (testing "check that the endpoint doesn't work if embedding isn't enabled"
           (mt/with-temporary-setting-values [enable-embedding false]
-            (with-new-secret-key
+            (with-new-secret-key!
               (with-temp-card [card (api.pivots/pivot-card)]
                 (is (= "Embedding is not enabled."
                        (client/client :get 400 (pivot-card-query-url card ""))))))))
 
-        (with-embedding-enabled-and-new-secret-key
+        (with-embedding-enabled-and-new-secret-key!
           (let [expected-status 202]
             (testing "it should be possible to run a Card successfully if you jump through the right hoops..."
               (with-temp-card [card (merge {:enable_embedding true} (api.pivots/pivot-card))]
@@ -1437,7 +1437,7 @@
                         "signed with the wrong key")
             (with-temp-card [card (merge {:enable_embedding true} (api.pivots/pivot-card))]
               (is (= "Message seems corrupt or manipulated"
-                     (client/client :get 400 (with-new-secret-key (pivot-card-query-url card ""))))))))))))
+                     (client/client :get 400 (with-new-secret-key! (pivot-card-query-url card ""))))))))))))
 
 (defn- pivot-dashcard-url [dashcard & [additional-token-params]]
   (str "embed/pivot/dashboard/" (dash-token (:dashboard_id dashcard) additional-token-params)
@@ -1447,7 +1447,7 @@
 (deftest pivot-dashcard-success-test
   (mt/test-drivers (api.pivots/applicable-drivers)
     (mt/dataset test-data
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash     {:enable_embedding true, :parameters []}
                                        :card     (api.pivots/pivot-card)
                                        :dashcard {:parameter_mappings []}}]
@@ -1461,7 +1461,7 @@
 (deftest pivot-dashcard-embedding-disabled-test
   (mt/dataset test-data
     (mt/with-temporary-setting-values [enable-embedding false]
-      (with-new-secret-key
+      (with-new-secret-key!
         (with-temp-dashcard [dashcard {:dash     {:parameters []}
                                        :card     (api.pivots/pivot-card)
                                        :dashcard {:parameter_mappings []}}]
@@ -1470,7 +1470,7 @@
 
 (deftest pivot-dashcard-embedding-disabled-for-card-test
   (mt/dataset test-data
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-dashcard [dashcard {:dash     {:parameters []}
                                      :card     (api.pivots/pivot-card)
                                      :dashcard {:parameter_mappings []}}]
@@ -1481,17 +1481,17 @@
   (mt/dataset test-data
     (testing (str "check that if embedding is enabled globally and for the object that requests fail if they are signed "
                   "with the wrong key")
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash     {:enable_embedding true, :parameters []}
                                        :card     (api.pivots/pivot-card)
                                        :dashcard {:parameter_mappings []}}]
           (is (= "Message seems corrupt or manipulated"
-                 (client/client :get 400 (with-new-secret-key (pivot-dashcard-url dashcard))))))))))
+                 (client/client :get 400 (with-new-secret-key! (pivot-dashcard-url dashcard))))))))))
 
 (deftest pivot-dashcard-locked-params-test
   (mt/dataset test-data
     (mt/test-helpers-set-global-values!
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash     {:enable_embedding true
                                                   :embedding_params {:abc "locked"}
                                                   :parameters       [{:id     "_ORDER_ID_"
@@ -1520,7 +1520,7 @@
 
 (deftest pivot-dashcard-disabled-params-test
   (mt/dataset test-data
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-dashcard [dashcard {:dash     {:enable_embedding true
                                                 :embedding_params {:abc "disabled"}
                                                 :parameters       []}
@@ -1537,7 +1537,7 @@
 
 (deftest pivot-dashcard-enabled-params-test
   (mt/dataset test-data
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (with-temp-dashcard [dashcard {:dash     {:enable_embedding true
                                                 :embedding_params {:abc "enabled"}
                                                 :parameters       [{:id      "_ORDER_ID_"
@@ -1585,7 +1585,7 @@
 (deftest handle-single-params-for-operator-filters-test
   (testing "Query endpoints should work with a single URL parameter for an operator filter (#20438)"
     (mt/dataset test-data
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (t2.with-temp/with-temp [Card {card-id :id, :as card} {:dataset_query    (mt/native-query
                                                                                   {:query         "SELECT count(*) AS count FROM PUBLIC.PEOPLE WHERE true [[AND {{NAME}}]]"
                                                                                    :template-tags {"NAME"
@@ -1623,7 +1623,7 @@
 (deftest pass-numeric-param-as-number-test
   (testing "Embedded numeric params should work with numeric (as opposed to string) values in the JWT (#20845)"
     (mt/dataset test-data
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (t2.with-temp/with-temp [Card card {:dataset_query    (mt/native-query
                                                                {:query         "SELECT count(*) FROM orders WHERE quantity = {{qty_locked}}"
                                                                 :template-tags {"qty_locked" {:name         "qty_locked"
@@ -1641,7 +1641,7 @@
                          :native   {:query "SELECT 2000 AS number, '2024-03-26'::DATE AS date;"}}
           output-helper {:csv  (fn [output] (->> output csv/read-csv last))
                          :json (fn [output] (->> output (map (juxt :NUMBER :DATE)) last))}]
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (t2.with-temp/with-temp [Card {card-id :id} {:enable_embedding true
                                                      :display :table :dataset_query q}
                                  Dashboard {dashboard-id :id} {:enable_embedding true
@@ -1669,7 +1669,7 @@
 (deftest filter-linked-to-locked-filter-test
   (testing "Filter linked to locked filter works in various common configurations."
     (mt/dataset test-data
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (t2.with-temp/with-temp [Card {card-id :id} {:enable_embedding true
                                                      :display          :table
                                                      :dataset_query    {:database (mt/id)
@@ -1739,7 +1739,7 @@
 (deftest querying-a-dashboard-dashcard-updates-last-viewed-at
   (mt/test-helpers-set-global-values!
     (mt/dataset test-data
-      (with-embedding-enabled-and-new-secret-key
+      (with-embedding-enabled-and-new-secret-key!
         (with-temp-dashcard [dashcard {:dash {:enable_embedding true
                                               :last_viewed_at #t "2000-01-01"}}]
           (let [dashboard-id (t2/select-one-fn :id :model/Dashboard :id (:dashboard_id dashcard))
diff --git a/test/metabase/api/ldap_test.clj b/test/metabase/api/ldap_test.clj
index 99e17ab6ac3c151a58d823d48a20050d84457e12..cd47e76df482f40ac21752e2a506cd8029042d78 100644
--- a/test/metabase/api/ldap_test.clj
+++ b/test/metabase/api/ldap_test.clj
@@ -17,7 +17,7 @@
 
 (deftest ldap-settings-test
   (testing "PUT /api/ldap/settings"
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "Valid LDAP settings can be saved via an API call"
         (mt/user-http-request :crowberto :put 200 "ldap/settings" (ldap-test-details)))
 
@@ -54,7 +54,7 @@
                                      (assoc (ldap-test-details) :ldap-port "" :ldap-enabled false))))))))
 
 (deftest ldap-enabled-test
-  (ldap.test/with-ldap-server
+  (ldap.test/with-ldap-server!
     (testing "`ldap-enabled` setting validates currently saved LDAP settings"
       (mt/with-temporary-setting-values [ldap-enabled false]
         (with-redefs [ldap/test-current-ldap-details (constantly {:status :ERROR :message "test error"})]
diff --git a/test/metabase/api/persist_test.clj b/test/metabase/api/persist_test.clj
index 775ac2784b86cdfaa0319835d6371670ad504962..c4bc5a44792f6e33a94d844a339b27ad76221c37 100644
--- a/test/metabase/api/persist_test.clj
+++ b/test/metabase/api/persist_test.clj
@@ -11,22 +11,22 @@
 
 (def ^:private default-cron "0 0 0/12 * * ? *")
 
-(defn- do-with-setup [f]
-  (mt/with-temp-scheduler
+(defn- do-with-setup! [f]
+  (mt/with-temp-scheduler!
     (#'task.persist-refresh/job-init!)
     (mt/with-temporary-setting-values [:persisted-models-enabled true]
       (mt/with-temp [Database db {:settings {:persist-models-enabled true}}]
         (task.persist-refresh/schedule-persistence-for-database! db default-cron)
         (f db)))))
 
-(defmacro ^:private with-setup
+(defmacro ^:private with-setup!
   "Sets up a temp scheduler, a temp database and enabled persistence"
   [db-binding & body]
-  `(do-with-setup (fn [~db-binding] ~@body)))
+  `(do-with-setup! (fn [~db-binding] ~@body)))
 
 (deftest set-refresh-schedule-test
   (testing "Setting new cron schedule reschedules refresh tasks"
-    (with-setup db
+    (with-setup! db
       (is (= default-cron (get-in (task.persist-refresh/job-info-by-db-id)
                                   [(:id db) :schedule])))
       (let [new-schedule "0 0 0/12 * * ? *"]
@@ -36,7 +36,7 @@
                (get-in (task.persist-refresh/job-info-by-db-id)
                        [(:id db) :schedule]))))))
   (testing "Prevents setting a year value"
-    (with-setup db
+    (with-setup! db
       (let [bad-schedule "0 0 0/12 * * ? 1995"]
         (is (= "Must be a valid cron string not specifying a year"
                (mt/user-http-request :crowberto :post 400 "persist/set-refresh-schedule"
@@ -46,7 +46,7 @@
                        [(:id db) :schedule])))))))
 
 (deftest persisted-info-by-id-test
-  (with-setup db
+  (with-setup! db
     (mt/with-temp
       [:model/Card          model {:database_id (u/the-id db), :type :model}
        :model/PersistedInfo pinfo {:database_id (u/the-id db), :card_id (u/the-id model)}]
@@ -64,7 +64,7 @@
                 (mt/user-http-request :crowberto :get 200 (format "persist/%d" (u/the-id pinfo)))))))))
 
 (deftest persisted-info-by-card-id-test
-  (with-setup db
+  (with-setup! db
     (mt/with-temp
       [:model/Card          model {:database_id (u/the-id db), :type :model}
        :model/PersistedInfo pinfo {:database_id (u/the-id db), :card_id (u/the-id model)}]
diff --git a/test/metabase/api/preview_embed_test.clj b/test/metabase/api/preview_embed_test.clj
index 9e17391a860140d7fa5cf1fbc4cbd4fc6b1e95bc..79a74041c12c6c3d03422cc0436abdbd0bbf533e 100644
--- a/test/metabase/api/preview_embed_test.clj
+++ b/test/metabase/api/preview_embed_test.clj
@@ -23,7 +23,7 @@
 
 (deftest card-test
   (testing "GET /api/preview_embed/card/:token"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (embed-test/with-temp-card [card]
         (testing "it should be possible to use this endpoint successfully if all the conditions are met"
           (is (= embed-test/successful-card-info
@@ -42,7 +42,7 @@
 
         (testing "check that if embedding is enabled globally requests fail if they are signed with the wrong key"
           (is (= "Message seems corrupt or manipulated"
-                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key (card-url card))))))
+                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key! (card-url card))))))
 
         (testing "Check that only ENABLED params that ARE NOT PRESENT IN THE JWT come back"
           (embed-test/with-temp-card [card {:dataset_query
@@ -75,7 +75,7 @@
 
 (deftest query-test
   (testing "GET /api/preview_embed/card/:token/query"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (embed-test/with-temp-card [card]
         (testing "It should be possible to run a Card successfully if you jump through the right hoops..."
           #_{:clj-kondo/ignore [:deprecated-var]}
@@ -93,12 +93,12 @@
 
         (testing "check that if embedding is enabled globally requests fail if they are signed with the wrong key"
           (is (= "Message seems corrupt or manipulated"
-                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key (card-query-url card))))))))))
+                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key! (card-query-url card))))))))))
 
 (deftest query-locked-params-test
   (testing "GET /api/preview_embed/card/:token/query"
     (testing "LOCKED params"
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (embed-test/with-temp-card [card]
           (testing "check that if embedding is enabled globally fail if the token is missing a `:locked` parameter"
             (is (= "You must specify a value for :venue_id in the JWT."
@@ -119,7 +119,7 @@
 (deftest query-disabled-params-test
   (testing "GET /api/preview_embed/card/:token/query"
     (testing "DISABLED params"
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (embed-test/with-temp-card [card]
           (testing "check that if embedding is enabled globally and for the object requests fail if they pass a `:disabled` parameter"
             (is (= "You're not allowed to specify a value for :venue_id."
@@ -134,7 +134,7 @@
 (deftest query-enabled-params-test
   (testing "GET /api/preview_embed/card/:token/query"
     (testing "ENABLED params"
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (embed-test/with-temp-card [card]
           (testing "If `:enabled` param is present in both JWT and the URL, the request should fail"
             (is (= "You can't specify a value for :venue_id if it's already set in the JWT."
@@ -154,7 +154,7 @@
                                                             "?venue_id=200")))))))))
 (deftest default-value-card-query-test
   (testing "GET /api/preview_embed/card/:token/query with default values for params"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (testing "if the param is enabled"
         (t2.with-temp/with-temp
           [Card card (assoc (embed-test/card-with-date-field-filter-default) :embedding_params {:date "enabled"})]
@@ -209,7 +209,7 @@
             expected-row-count 1]
         (with-redefs [api.preview-embed/max-results expected-row-count]
           (mt/dataset test-data
-            (embed-test/with-embedding-enabled-and-new-secret-key
+            (embed-test/with-embedding-enabled-and-new-secret-key!
               (let [sample-db-orders-question (mt/query orders)]
                 (embed-test/with-temp-card [card {:dataset_query sample-db-orders-question}]
                   (let [limited (count
@@ -226,7 +226,7 @@
 
 (deftest dashboard-test
   (testing "GET /api/preview_embed/dashboard/:token"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard dash]
         (testing "it should be possible to call this endpoint successfully..."
           (is (= embed-test/successful-dashboard-info
@@ -244,11 +244,11 @@
 
         (testing "check that if embedding is enabled globally requests fail if they are signed with the wrong key"
           (is (= "Message seems corrupt or manipulated"
-                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key (dashboard-url dash))))))))))
+                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key! (dashboard-url dash))))))))))
 
 (deftest only-enabled-params-not-in-jwt-test
   (testing "Check that only ENABLED params that ARE NOT PRESENT IN THE JWT come back"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Dashboard dash {:parameters [{:id "_a", :slug "a", :name "a", :type "date"}
                                                             {:id "_b", :slug "b", :name "b", :type "date"}
                                                             {:id "_c", :slug "c", :name "c", :type "date"}
@@ -271,7 +271,7 @@
 
 (deftest dashcard-test
   (testing "/api/preview_embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (embed-test/with-temp-dashcard [dashcard]
         (testing "It should be possible to run a Card successfully if you jump through the right hoops..."
           #_{:clj-kondo/ignore [:deprecated-var]}
@@ -289,12 +289,12 @@
 
         (testing "check that if embedding is enabled globally requests fail if they are signed with the wrong key"
           (is (= "Message seems corrupt or manipulated"
-                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key (dashcard-url dashcard))))))))))
+                 (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key! (dashcard-url dashcard))))))))))
 
 (deftest dashcard-locked-params-test
   (testing "/api/preview_embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id"
     (testing "LOCKED params"
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (embed-test/with-temp-dashcard [dashcard]
           (testing "check that if embedding is enabled globally fail if the token is missing a `:locked` parameter"
             (is (= "You must specify a value for :venue_id in the JWT."
@@ -316,7 +316,7 @@
 (deftest dashcard-disabled-params-test
   (testing "/api/preview_embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id"
     (testing "DISABLED params"
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (embed-test/with-temp-dashcard [dashcard]
           (testing "check that if embedding is enabled globally and for the object requests fail if they pass a `:disabled` parameter"
             (is (= "You're not allowed to specify a value for :venue_id."
@@ -331,7 +331,7 @@
 (deftest dashcard-disabled-params-test-2
   (testing "/api/preview_embed/dashboard/:token/dashcard/:dashcard-id/card/:card-id"
     (testing "ENABLED params"
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (embed-test/with-temp-dashcard [dashcard]
           (testing "If `:enabled` param is present in both JWT and the URL, the request should fail"
             (is (= "You can't specify a value for :venue_id if it's already set in the JWT."
@@ -355,7 +355,7 @@
   (testing (str "Check that editable query params work correctly and keys get coverted from strings to keywords, even "
                 "if they're something that our middleware doesn't normally assume is implicitly convertable to a "
                 "keyword. See `ring.middleware.keyword-params/keyword-syntax?` (#6783)")
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (embed-test/with-temp-dashcard [dashcard {:dash {:enable_embedding true
                                                        :parameters       [{:id   "_SECOND_DATE_SEEN_"
                                                                            :slug "2nd_date_seen"
@@ -374,7 +374,7 @@
 
 (deftest editable-params-should-not-be-invalid-test
   (testing "Make sure that editable params do not result in \"Invalid Parameter\" exceptions (#7212)"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (t2.with-temp/with-temp [Card card {:dataset_query {:database (mt/id)
                                                           :type     :native
                                                           :native   {:query         "SELECT {{num}} AS num"
@@ -400,7 +400,7 @@
 (deftest postgres-convert-parameters-to-numbers-test
   (mt/test-driver :postgres
     (testing "Make sure that ID params correctly get converted to numbers as needed (Postgres-specific)..."
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (t2.with-temp/with-temp [Card card {:dataset_query {:database (mt/id)
                                                             :type     :query
                                                             :query    {:source-table (mt/id :venues)
@@ -432,7 +432,7 @@
     (mt/dataset test-data
       (testing "GET /api/preview_embed/pivot/card/:token/query"
         (testing "successful preview"
-          (let [result (embed-test/with-embedding-enabled-and-new-secret-key
+          (let [result (embed-test/with-embedding-enabled-and-new-secret-key!
                          (embed-test/with-temp-card [card (api.pivots/pivot-card)]
                            (mt/user-http-request :crowberto :get 202 (pivot-card-query-url card))))
                 rows   (mt/rows result)]
@@ -443,22 +443,22 @@
 
         (testing "should fail if user is not an admin"
           (is (= "You don't have permissions to do that."
-                 (embed-test/with-embedding-enabled-and-new-secret-key
+                 (embed-test/with-embedding-enabled-and-new-secret-key!
                    (embed-test/with-temp-card [card (api.pivots/pivot-card)]
                      (mt/user-http-request :rasta :get 403 (pivot-card-query-url card)))))))
 
         (testing "should fail if embedding is disabled"
           (is (= "Embedding is not enabled."
                  (mt/with-temporary-setting-values [enable-embedding false]
-                   (embed-test/with-new-secret-key
+                   (embed-test/with-new-secret-key!
                      (embed-test/with-temp-card [card (api.pivots/pivot-card)]
                        (mt/user-http-request :crowberto :get 400 (pivot-card-query-url card))))))))
 
         (testing "should fail if embedding is enabled and the wrong key is used"
           (is (= "Message seems corrupt or manipulated"
-                 (embed-test/with-embedding-enabled-and-new-secret-key
+                 (embed-test/with-embedding-enabled-and-new-secret-key!
                    (embed-test/with-temp-card [card (api.pivots/pivot-card)]
-                     (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key (pivot-card-query-url card))))))))))))
+                     (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key! (pivot-card-query-url card))))))))))))
 
 (defn- pivot-dashcard-url {:style/indent 1} [dashcard & [additional-token-params]]
   (str "preview_embed/pivot/dashboard/"
@@ -471,7 +471,7 @@
   (mt/test-drivers (api.pivots/applicable-drivers)
     (mt/dataset test-data
       (testing "GET /api/preview_embed/pivot/dashboard/:token/dashcard/:dashcard-id/card/:card-id"
-        (embed-test/with-embedding-enabled-and-new-secret-key
+        (embed-test/with-embedding-enabled-and-new-secret-key!
           (embed-test/with-temp-dashcard [dashcard {:dash     {:parameters []}
                                                     :card     (api.pivots/pivot-card)
                                                     :dashcard {:parameter_mappings []}}]
@@ -490,17 +490,17 @@
             (testing "should fail if embedding is disabled"
               (is (= "Embedding is not enabled."
                      (mt/with-temporary-setting-values [enable-embedding false]
-                       (embed-test/with-new-secret-key
+                       (embed-test/with-new-secret-key!
                          (mt/user-http-request :crowberto :get 400 (pivot-dashcard-url dashcard)))))))
 
             (testing "should fail if embedding is enabled and the wrong key is used"
               (is (= "Message seems corrupt or manipulated"
-                     (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key (pivot-dashcard-url dashcard))))))))))))
+                     (mt/user-http-request :crowberto :get 400 (embed-test/with-new-secret-key! (pivot-dashcard-url dashcard))))))))))))
 
 (deftest handle-single-params-for-operator-filters-test
   (testing "Query endpoints should work with a single URL parameter for an operator filter (#20438)"
     (mt/dataset test-data
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (t2.with-temp/with-temp [Card {card-id :id, :as card} {:dataset_query    (mt/native-query
                                                                                    {:query         "SELECT count(*) AS count FROM PUBLIC.PEOPLE WHERE true [[AND {{NAME}}]]"
                                                                                     :template-tags {"NAME"
@@ -545,17 +545,17 @@
 
 (defn sign [claims] (jwt/sign claims *secret-key*))
 
-(defn do-with-new-secret-key [f]
+(defn do-with-new-secret-key! [f]
   (binding [*secret-key* (random-embedding-secret-key)]
     (mt/with-temporary-setting-values [embedding-secret-key *secret-key*]
       (f))))
 
-(defmacro with-new-secret-key {:style/indent 0} [& body]
-  `(do-with-new-secret-key (fn [] ~@body)))
+(defmacro with-new-secret-key! {:style/indent 0} [& body]
+  `(do-with-new-secret-key! (fn [] ~@body)))
 
-(defmacro with-embedding-enabled-and-new-secret-key {:style/indent 0} [& body]
+(defmacro with-embedding-enabled-and-new-secret-key! {:style/indent 0} [& body]
   `(mt/with-temporary-setting-values [~'enable-embedding true]
-     (with-new-secret-key
+     (with-new-secret-key!
        ~@body)))
 
 (defn dash-token
@@ -566,7 +566,7 @@
 
 (deftest params-with-static-list-test
   (testing "embedding with parameter that has source is a static list"
-    (with-embedding-enabled-and-new-secret-key
+    (with-embedding-enabled-and-new-secret-key!
       (api.dashboard-test/with-chain-filter-fixtures [{:keys [dashboard]}]
         (t2/update! Dashboard (u/the-id dashboard) {:enable_embedding false ;; works without enabling embedding on the dashboard (#44962)
                                                     :embedding_params {"static_category"       "enabled"
@@ -581,7 +581,7 @@
 
 (deftest boolean-parameter-values-test
   (testing "embedding endpoint supports boolean parameter values (#27643)"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (mt/dataset places-cam-likes
         (mt/with-temp [:model/Card {card-id :id :as card} {:dataset_query
                                                            {:database (mt/id)
@@ -642,7 +642,7 @@
 
 (deftest string-parameter-values-test
   (testing "embedding endpoint should not parse string values into numbers (#46240)"
-    (embed-test/with-embedding-enabled-and-new-secret-key
+    (embed-test/with-embedding-enabled-and-new-secret-key!
       (mt/dataset airports
         (mt/with-temp [:model/Card {card-id :id} {:dataset_query
                                                            {:database (mt/id)
diff --git a/test/metabase/api/public_test.clj b/test/metabase/api/public_test.clj
index 97d8ba369525b52a1401520c4924fdd90d53fb0d..9247b952f3b2222ae1cd23c8a7b9efd9ed4e6ac1 100644
--- a/test/metabase/api/public_test.clj
+++ b/test/metabase/api/public_test.clj
@@ -421,7 +421,7 @@
                                                                     :value nil}]))))))))))
 
 ;; Cards with required params
-(defn- do-with-required-param-card [f]
+(defn- do-with-required-param-card! [f]
   (mt/with-temporary-setting-values [enable-public-sharing true]
     (with-temp-public-card [{uuid :public_uuid}
                             {:dataset_query
@@ -434,11 +434,11 @@
                                                                   :required     true}}}}}]
       (f uuid))))
 
-(defmacro ^:private with-required-param-card [[uuid-binding] & body]
-  `(do-with-required-param-card (fn [~uuid-binding] ~@body)))
+(defmacro ^:private with-required-param-card! [[uuid-binding] & body]
+  `(do-with-required-param-card! (fn [~uuid-binding] ~@body)))
 
 (deftest should-be-able-to-run-a-card-with-a-required-param
-  (with-required-param-card [uuid]
+  (with-required-param-card! [uuid]
     (is (= [[22]]
            (mt/rows
              (client/client :get 202 (str "public/card/" uuid "/query")
@@ -449,7 +449,7 @@
 (deftest missing-required-param-error-message-test
   (testing (str "If you're missing a required param, the error message should get passed thru, rather than the normal "
                 "generic 'Query Failed' message that we show for most embedding errors")
-    (with-required-param-card [uuid]
+    (with-required-param-card! [uuid]
       (is (= {:status     "failed"
               :error      "You'll need to pick a value for 'Price' before this query can run."
               :error_type "missing-required-parameter"}
@@ -903,7 +903,7 @@
   (t2/update! DashboardCard (u/the-id dashcard) {:parameter_mappings [{:card_id (u/the-id card)
                                                                        :target  ["dimension" dimension]}]}))
 
-(defn- GET-param-values [dashboard]
+(defn- GET-param-values! [dashboard]
   (mt/with-temporary-setting-values [enable-public-sharing true]
     (:param_values (client/client :get 200 (str "public/dashboard/" (:public_uuid dashboard))))))
 
@@ -919,21 +919,21 @@
     (add-price-param-to-dashboard! dash)
     (add-dimension-param-mapping-to-dashcard! dashcard card ["template-tag" "price"])
     (is (= (price-param-values)
-           (GET-param-values dash)))))
+           (GET-param-values! dash)))))
 
 (deftest check-that-param-info-comes-back-for-mbql-cards--field-id-
   (with-temp-public-dashboard-and-card [dash card dashcard]
     (add-price-param-to-dashboard! dash)
     (add-dimension-param-mapping-to-dashcard! dashcard card ["field" (mt/id :venues :price) nil])
     (is (= (price-param-values)
-           (GET-param-values dash)))))
+           (GET-param-values! dash)))))
 
 (deftest check-that-param-info-comes-back-for-mbql-cards--fk---
   (with-temp-public-dashboard-and-card [dash card dashcard]
     (add-price-param-to-dashboard! dash)
     (add-dimension-param-mapping-to-dashcard! dashcard card [:field (mt/id :venues :price) {:source-field (mt/id :checkins :venue_id)}])
     (is (= (price-param-values)
-           (GET-param-values dash)))))
+           (GET-param-values! dash)))))
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
 ;;; |                                        New FieldValues search endpoints                                        |
@@ -1151,15 +1151,15 @@
        "/field/" (u/the-id field-or-id)
        "/values"))
 
-(defn- do-with-sharing-enabled-and-temp-card-referencing {:style/indent 2} [table-kw field-kw f]
+(defn- do-with-sharing-enabled-and-temp-card-referencing! {:style/indent 2} [table-kw field-kw f]
   (mt/with-temporary-setting-values [enable-public-sharing true]
     (t2.with-temp/with-temp [Card card (merge (shared-obj) (mbql-card-referencing table-kw field-kw))]
       (f card))))
 
-(defmacro ^:private with-sharing-enabled-and-temp-card-referencing
+(defmacro ^:private with-sharing-enabled-and-temp-card-referencing!
   {:style/indent 3}
   [table-kw field-kw [card-binding] & body]
-  `(do-with-sharing-enabled-and-temp-card-referencing ~table-kw ~field-kw
+  `(do-with-sharing-enabled-and-temp-card-referencing! ~table-kw ~field-kw
      (fn [~card-binding]
        ~@body)))
 
@@ -1171,24 +1171,24 @@
                             ["BCD Tofu House"]]
           :field_id        (mt/id :venues :name)
           :has_more_values false}
-         (with-sharing-enabled-and-temp-card-referencing :venues :name [card]
+         (with-sharing-enabled-and-temp-card-referencing! :venues :name [card]
            (-> (client/client :get 200 (field-values-url card (mt/id :venues :name)))
                (update :values (partial take 5)))))))
 
 (deftest but-for-fields-that-are-not-referenced-we-should-get-an-exception
   (is (= "Not found."
-         (with-sharing-enabled-and-temp-card-referencing :venues :name [card]
+         (with-sharing-enabled-and-temp-card-referencing! :venues :name [card]
            (client/client :get 404 (field-values-url card (mt/id :venues :price)))))))
 
 (deftest field-value-endpoint-should-fail-if-public-sharing-is-disabled
   (is (= "An error occurred."
-         (with-sharing-enabled-and-temp-card-referencing :venues :name [card]
+         (with-sharing-enabled-and-temp-card-referencing! :venues :name [card]
            (mt/with-temporary-setting-values [enable-public-sharing false]
              (client/client :get 400 (field-values-url card (mt/id :venues :name))))))))
 
 ;;; ----------------------------- GET /api/public/dashboard/:uuid/field/:field/values nil -----------------------------
 
-(defn do-with-sharing-enabled-and-temp-dashcard-referencing {:style/indent 2} [table-kw field-kw f]
+(defn do-with-sharing-enabled-and-temp-dashcard-referencing! {:style/indent 2} [table-kw field-kw f]
   (mt/with-temporary-setting-values [enable-public-sharing true]
     (mt/with-temp [Dashboard     dashboard (shared-obj)
                    Card          card      (mbql-card-referencing table-kw field-kw)
@@ -1200,15 +1200,15 @@
                                                                              (mt/id table-kw field-kw) nil]]}]}]
       (f dashboard card dashcard))))
 
-(defmacro with-sharing-enabled-and-temp-dashcard-referencing
+(defmacro with-sharing-enabled-and-temp-dashcard-referencing!
   {:style/indent 3}
   [table-kw field-kw [dashboard-binding card-binding dashcard-binding] & body]
-  `(do-with-sharing-enabled-and-temp-dashcard-referencing ~table-kw ~field-kw
+  `(do-with-sharing-enabled-and-temp-dashcard-referencing! ~table-kw ~field-kw
      (fn [~(or dashboard-binding '_) ~(or card-binding '_) ~(or dashcard-binding '_)]
        ~@body)))
 
 (deftest should-be-able-to-use-it-when-everything-is-g2g
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
     (is (= {:values          [["20th Century Cafe"]
                               ["25°"]
                               ["33 Taps"]
@@ -1220,12 +1220,12 @@
                (update :values (partial take 5)))))))
 
 (deftest shound-not-be-able-to-use-the-endpoint-with-a-field-not-referenced-by-the-dashboard
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
     (is (= "Not found."
            (client/client :get 404 (field-values-url dashboard (mt/id :venues :price)))))))
 
 (deftest endpoint-should-fail-if-public-sharing-is-disabled
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :name [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :name [dashboard]
     (mt/with-temporary-setting-values [enable-public-sharing false]
       (is (= "An error occurred."
              (client/client :get 400 (field-values-url dashboard (mt/id :venues :name))))))))
@@ -1234,18 +1234,18 @@
 ;;; ----------------------------------------------- search-card-fields -----------------------------------------------
 
 (deftest search-card-fields
-  (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
     (is (= [[93 "33 Taps"]]
            (api.public/search-card-fields (u/the-id card) (mt/id :venues :id) (mt/id :venues :name) "33 T" 10)))))
 
 (deftest shouldn-t-work-if-the-search-field-isn-t-allowed-to-be-used-in-combination-with-the-other-field
-  (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
     (is (thrown?
          Exception
          (api.public/search-card-fields (u/the-id card) (mt/id :venues :id) (mt/id :venues :price) "33 T" 10)))))
 
 (deftest shouldn-t-work-if-the-field-isn-t-referenced-by-card
-  (with-sharing-enabled-and-temp-card-referencing :venues :name [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :name [card]
     (is (thrown?
          Exception
          (api.public/search-card-fields (u/the-id card) (mt/id :venues :id) (mt/id :venues :id) "33 T" 10)))))
@@ -1264,19 +1264,19 @@
 
 (deftest field-search-with-venue
   (is (= [[93 "33 Taps"]]
-         (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+         (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
            (client/client :get 200 (field-search-url card (mt/id :venues :id) (mt/id :venues :name))
                           :value "33 T")))))
 
 (deftest if-search-field-isn-t-allowed-to-be-used-with-the-other-field-endpoint-should-return-exception
   (is (= "An error occurred."
-         (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+         (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
            (client/client :get 400 (field-search-url card (mt/id :venues :id) (mt/id :venues :price))
                           :value "33 T")))))
 
 (deftest search-endpoint-should-fail-if-public-sharing-is-disabled
   (is (= "An error occurred."
-         (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+         (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
            (mt/with-temporary-setting-values [enable-public-sharing false]
              (client/client :get 400 (field-search-url card (mt/id :venues :id) (mt/id :venues :name))
                             :value "33 T"))))))
@@ -1285,19 +1285,19 @@
 ;;; -------------------- GET /api/public/dashboard/:uuid/field/:field/search/:search-field-id nil ---------------------
 
 (deftest dashboard
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
     (is (= [[93 "33 Taps"]]
            (client/client :get (field-search-url dashboard (mt/id :venues :id) (mt/id :venues :name))
                           :value "33 T")))))
 
 (deftest dashboard-if-search-field-isn-t-allowed-to-be-used-with-the-other-field-endpoint-should-return-exception
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
     (is (= "An error occurred."
            (client/client :get 400 (field-search-url dashboard (mt/id :venues :id) (mt/id :venues :price))
                           :value "33 T")))))
 
 (deftest dashboard-endpoint-should-fail-if-public-sharing-is-disabled
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
     (mt/with-temporary-setting-values [enable-public-sharing false]
       (is (= "An error occurred."
              (client/client :get 400 (field-search-url dashboard (mt/id :venues :name) (mt/id :venues :name))
@@ -1330,26 +1330,26 @@
 
 
 (deftest we-should-be-able-to-use-the-api-endpoint-and-get-the-same-results-we-get-by-calling-the-function-above-directly
-  (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
     (is (= [10 "Fred 62"]
            (client/client :get 200 (field-remapping-url card (mt/id :venues :id) (mt/id :venues :name))
                           :value "10")))))
 
 (deftest shouldn-t-work-if-card-doesn-t-reference-the-field-in-question
-  (with-sharing-enabled-and-temp-card-referencing :venues :price [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :price [card]
     (is (= "Not found."
            (client/client :get 404 (field-remapping-url card (mt/id :venues :id) (mt/id :venues :name))
                           :value "10")))))
 
 
 (deftest ---or-if-the-remapping-field-isn-t-allowed-to-be-used-with-the-other-field
-  (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
     (is (= "An error occurred."
            (client/client :get 400 (field-remapping-url card (mt/id :venues :id) (mt/id :venues :price))
                           :value "10")))))
 
 (deftest ---or-if-public-sharing-is-disabled
-  (with-sharing-enabled-and-temp-card-referencing :venues :id [card]
+  (with-sharing-enabled-and-temp-card-referencing! :venues :id [card]
     (mt/with-temporary-setting-values [enable-public-sharing false]
       (is (= "An error occurred."
              (client/client :get 400 (field-remapping-url card (mt/id :venues :id) (mt/id :venues :name))
@@ -1359,25 +1359,25 @@
 
 
 (deftest api-endpoint-should-return-same-results-as-function
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
     (is (= [10 "Fred 62"]
            (client/client :get 200 (field-remapping-url dashboard (mt/id :venues :id) (mt/id :venues :name))
                           :value "10")))))
 
 (deftest field-remapping-shouldn-t-work-if-card-doesn-t-reference-the-field-in-question
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :price [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :price [dashboard]
     (is (= "Not found."
            (client/client :get 404 (field-remapping-url dashboard (mt/id :venues :id) (mt/id :venues :name))
                           :value "10")))))
 
 (deftest remapping-or-if-the-remapping-field-isn-t-allowed-to-be-used-with-the-other-field
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
     (is (= "An error occurred."
            (client/client :get 400 (field-remapping-url dashboard (mt/id :venues :id) (mt/id :venues :price))
                           :value "10")))))
 
 (deftest remapping-or-if-public-sharing-is-disabled
-  (with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+  (with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
     (mt/with-temporary-setting-values [enable-public-sharing false]
       (is (= "An error occurred."
              (client/client :get 400 (field-remapping-url dashboard (mt/id :venues :id) (mt/id :venues :name))
diff --git a/test/metabase/api/pulse_test.clj b/test/metabase/api/pulse_test.clj
index fbedd7d1a74f251d91799108575b6b7e7fa638cf..8247fb318b97051298f1e485d642e8617f15c3d6 100644
--- a/test/metabase/api/pulse_test.clj
+++ b/test/metabase/api/pulse_test.clj
@@ -71,7 +71,7 @@
       (update :cards #(for [card %]
                         (update card :collection_id boolean)))))
 
-(defn- do-with-pulses-in-a-collection [grant-collection-perms-fn! pulses-or-ids f]
+(defn- do-with-pulses-in-a-collection! [grant-collection-perms-fn! pulses-or-ids f]
   (mt/with-non-admin-groups-no-root-collection-perms
     (t2.with-temp/with-temp [Collection collection]
       (grant-collection-perms-fn! (perms-group/all-users) collection)
@@ -82,14 +82,14 @@
                        :where  [:in :id (set (map u/the-id pulses-or-ids))]}))
       (f))))
 
-(defmacro ^:private with-pulses-in-nonreadable-collection [pulses-or-ids & body]
-  `(do-with-pulses-in-a-collection (constantly nil) ~pulses-or-ids (fn [] ~@body)))
+(defmacro ^:private with-pulses-in-nonreadable-collection! [pulses-or-ids & body]
+  `(do-with-pulses-in-a-collection! (constantly nil) ~pulses-or-ids (fn [] ~@body)))
 
-(defmacro ^:private with-pulses-in-readable-collection [pulses-or-ids & body]
-  `(do-with-pulses-in-a-collection perms/grant-collection-read-permissions! ~pulses-or-ids (fn [] ~@body)))
+(defmacro ^:private with-pulses-in-readable-collection! [pulses-or-ids & body]
+  `(do-with-pulses-in-a-collection! perms/grant-collection-read-permissions! ~pulses-or-ids (fn [] ~@body)))
 
-(defmacro ^:private with-pulses-in-writeable-collection [pulses-or-ids & body]
-  `(do-with-pulses-in-a-collection perms/grant-collection-readwrite-permissions! ~pulses-or-ids (fn [] ~@body)))
+(defmacro ^:private with-pulses-in-writeable-collection! [pulses-or-ids & body]
+  `(do-with-pulses-in-a-collection! perms/grant-collection-readwrite-permissions! ~pulses-or-ids (fn [] ~@body)))
 
 
 ;;; +----------------------------------------------------------------------------------------------------------------+
@@ -184,7 +184,7 @@
                      Card card-2 {}
                      Dashboard _ {:name "Birdcage KPIs"}
                      Collection collection {}]
-        (api.card-test/with-cards-in-readable-collection [card-1 card-2]
+        (api.card-test/with-cards-in-readable-collection! [card-1 card-2]
           (mt/with-model-cleanup [Pulse]
             (is (= (merge
                     pulse-defaults
@@ -236,7 +236,7 @@
                              :dashboard_id  permitted-dashboard-id
                              :skip_if_empty false
                              :parameters filter-params}]
-          (api.card-test/with-cards-in-readable-collection [card-1 card-2]
+          (api.card-test/with-cards-in-readable-collection! [card-1 card-2]
             (mt/with-model-cleanup [Pulse]
               (testing "successful creation"
                 (is (= (merge
@@ -269,7 +269,7 @@
                      Card card-2 {:name        "The card"
                                   :description "Info"
                                   :display     :table}]
-        (api.card-test/with-cards-in-readable-collection [card-1 card-2]
+        (api.card-test/with-cards-in-readable-collection! [card-1 card-2]
           (t2.with-temp/with-temp [Collection collection]
             (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
             (mt/with-model-cleanup [Pulse]
@@ -311,7 +311,7 @@
           (t2.with-temp/with-temp [Collection collection]
             (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
             (mt/with-model-cleanup [Pulse]
-              (api.card-test/with-cards-in-readable-collection [card-1 card-2]
+              (api.card-test/with-cards-in-readable-collection! [card-1 card-2]
                 (is (= (merge
                         pulse-defaults
                         {:name          "A Pulse"
@@ -363,7 +363,7 @@
           (let [pulse-name (mt/random-name)]
             (mt/with-temp [Card       card {}
                            Collection collection] {}
-              (api.card-test/with-cards-in-readable-collection [card]
+              (api.card-test/with-cards-in-readable-collection! [card]
                 (create-pulse! 200 pulse-name card collection)
                 (is (= {:collection_id (u/the-id collection), :collection_position 1}
                        (mt/derecordize (t2/select-one [Pulse :collection_id :collection_position] :name pulse-name)))))))
@@ -424,8 +424,8 @@
                    PulseChannelRecipient _     {:pulse_channel_id (u/the-id pc) :user_id (mt/user->id :rasta)}
                    Card                  card  {}]
       (let [filter-params [{:id "123abc", :name "species", :type "string"}]]
-        (with-pulses-in-writeable-collection [pulse]
-          (api.card-test/with-cards-in-readable-collection [card]
+        (with-pulses-in-writeable-collection! [pulse]
+          (api.card-test/with-cards-in-readable-collection! [card]
             (is (= (merge
                     pulse-defaults
                     {:name          "Updated Pulse"
@@ -470,8 +470,8 @@
                                                    :pulse_id (u/the-id pulse)}
                      Card                  card-2 {:name        "Test2"
                                                    :description "Just Testing2"}]
-        (with-pulses-in-writeable-collection [pulse]
-          (api.card-test/with-cards-in-readable-collection [card-1 card-2]
+        (with-pulses-in-writeable-collection! [pulse]
+          (api.card-test/with-cards-in-readable-collection! [card-1 card-2]
             ;; The FE will include the original HybridPulseCard, similar to how the API returns the card via GET
             (let [pulse-cards (:cards (mt/user-http-request :rasta :get 200 (format "pulse/%d" (u/the-id pulse))))]
               (is (= (merge
@@ -502,7 +502,7 @@
 
 (deftest change-collection-test
   (testing "Can we change the Collection a Pulse is in (assuming we have the permissions to do so)?"
-    (pulse-test/with-pulse-in-collection [_db collection pulse]
+    (pulse-test/with-pulse-in-collection! [_db collection pulse]
       (t2.with-temp/with-temp [Collection new-collection]
         ;; grant Permissions for both new and old collections
         (doseq [coll [collection new-collection]]
@@ -514,7 +514,7 @@
                (u/the-id new-collection)))))
 
     (testing "...but if we don't have the Permissions for the old collection, we should get an Exception"
-      (pulse-test/with-pulse-in-collection [_db _collection pulse]
+      (pulse-test/with-pulse-in-collection! [_db _collection pulse]
         (t2.with-temp/with-temp [Collection new-collection]
           ;; grant Permissions for only the *new* collection
           (perms/grant-collection-readwrite-permissions! (perms-group/all-users) new-collection)
@@ -523,7 +523,7 @@
                  (mt/user-http-request :rasta :put 403 (str "pulse/" (u/the-id pulse)) {:collection_id (u/the-id new-collection)}))))))
 
     (testing "...and if we don't have the Permissions for the new collection, we should get an Exception"
-      (pulse-test/with-pulse-in-collection [_db collection pulse]
+      (pulse-test/with-pulse-in-collection! [_db collection pulse]
         (t2.with-temp/with-temp [Collection new-collection]
           ;; grant Permissions for only the *old* collection
           (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
@@ -533,7 +533,7 @@
 
 (deftest update-collection-position-test
   (testing "Can we change the Collection position of a Pulse?"
-    (pulse-test/with-pulse-in-collection [_ collection pulse]
+    (pulse-test/with-pulse-in-collection! [_ collection pulse]
       (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
       (mt/user-http-request :rasta :put 200 (str "pulse/" (u/the-id pulse))
                             {:collection_position 1})
@@ -541,7 +541,7 @@
              (t2/select-one-fn :collection_position Pulse :id (u/the-id pulse)))))
 
     (testing "...and unset (unpin) it as well?"
-      (pulse-test/with-pulse-in-collection [_ collection pulse]
+      (pulse-test/with-pulse-in-collection! [_ collection pulse]
         (t2/update! Pulse (u/the-id pulse) {:collection_position 1})
         (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
         (mt/user-http-request :rasta :put 200 (str "pulse/" (u/the-id pulse))
@@ -550,7 +550,7 @@
                (t2/select-one-fn :collection_position Pulse :id (u/the-id pulse))))))
 
     (testing "...we shouldn't be able to if we don't have permissions for the Collection"
-      (pulse-test/with-pulse-in-collection [_db _collection pulse]
+      (pulse-test/with-pulse-in-collection! [_db _collection pulse]
         (mt/user-http-request :rasta :put 403 (str "pulse/" (u/the-id pulse))
                               {:collection_position 1})
         (is (= nil
@@ -565,7 +565,7 @@
 
 (deftest archive-test
   (testing "Can we archive a Pulse?"
-    (pulse-test/with-pulse-in-collection [_ collection pulse]
+    (pulse-test/with-pulse-in-collection! [_ collection pulse]
       (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
       (mt/user-http-request :rasta :put 200 (str "pulse/" (u/the-id pulse))
                             {:archived true})
@@ -574,7 +574,7 @@
 
 (deftest unarchive-test
   (testing "Can we unarchive a Pulse?"
-    (pulse-test/with-pulse-in-collection [_ collection pulse]
+    (pulse-test/with-pulse-in-collection! [_ collection pulse]
       (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
       (t2/update! Pulse (u/the-id pulse) {:archived true})
       (mt/user-http-request :rasta :put 200 (str "pulse/" (u/the-id pulse))
@@ -768,7 +768,7 @@
                    PulseChannel          pc {:pulse_id pulse-3-id}
                    PulseChannelRecipient _  {:pulse_channel_id (u/the-id pc)
                                              :user_id          (mt/user->id :rasta)}]
-      (with-pulses-in-writeable-collection [pulse-1 pulse-2 pulse-3]
+      (with-pulses-in-writeable-collection! [pulse-1 pulse-2 pulse-3]
         (testing "admins can see all pulses"
           (let [results (-> (mt/user-http-request :crowberto :get 200 "pulse")
                             (filter-pulse-results :id #{pulse-1-id pulse-2-id pulse-3-id}))]
@@ -807,7 +807,7 @@
                     (assoc (expected-pulse-shape pulse-3) :can_write false)]
                    (map #(update % :collection_id boolean) results)))))))
 
-      (with-pulses-in-nonreadable-collection [pulse-3]
+      (with-pulses-in-nonreadable-collection! [pulse-3]
         (testing "when `creator_or_recipient=true`, cards and recipients are not included in results if the user
                  does not have collection perms"
           (let [result (-> (mt/user-http-request :rasta :get 200 "pulse?creator_or_recipient=true")
@@ -821,7 +821,7 @@
                      Pulse pulse-2 {:name "GHIJKL"}
                      Pulse pulse-3 {:name            "AAAAAA"
                                     :alert_condition "rows"}]
-        (with-pulses-in-readable-collection [pulse-1 pulse-2 pulse-3]
+        (with-pulses-in-readable-collection! [pulse-1 pulse-2 pulse-3]
           (is (= [(assoc (pulse-details pulse-1) :can_write true, :collection_id true)
                   (assoc (pulse-details pulse-2) :can_write true, :collection_id true)]
                  (for [pulse (-> (mt/user-http-request :rasta :get 200 "pulse")
@@ -831,7 +831,7 @@
     (testing "by default, archived Pulses should be excluded"
       (mt/with-temp [Pulse not-archived-pulse {:name "Not Archived"}
                      Pulse archived-pulse     {:name "Archived" :archived true}]
-        (with-pulses-in-readable-collection [not-archived-pulse archived-pulse]
+        (with-pulses-in-readable-collection! [not-archived-pulse archived-pulse]
           (is (= #{"Not Archived"}
                  (set (map :name (-> (mt/user-http-request :rasta :get 200 "pulse")
                                      (filter-pulse-results :name #{"Not Archived" "Archived"})))))))))
@@ -839,7 +839,7 @@
     (testing "can we fetch archived Pulses?"
       (mt/with-temp [Pulse not-archived-pulse {:name "Not Archived"}
                      Pulse archived-pulse     {:name "Archived" :archived true}]
-        (with-pulses-in-readable-collection [not-archived-pulse archived-pulse]
+        (with-pulses-in-readable-collection! [not-archived-pulse archived-pulse]
           (is (= #{"Archived"}
                  (set (map :name (-> (mt/user-http-request :rasta :get 200 "pulse?archived=true")
                                      (filter-pulse-results :name #{"Not Archived" "Archived"})))))))))
@@ -853,7 +853,7 @@
 (deftest get-pulse-test
   (testing "GET /api/pulse/:id"
     (t2.with-temp/with-temp [Pulse pulse]
-      (with-pulses-in-readable-collection [pulse]
+      (with-pulses-in-readable-collection! [pulse]
         (is (= (assoc (pulse-details pulse)
                       :can_write     true
                       :collection_id true)
@@ -862,19 +862,19 @@
 
     (testing "cannot normally fetch a pulse without collection permissions"
       (t2.with-temp/with-temp [Pulse pulse {:creator_id (mt/user->id :crowberto)}]
-        (with-pulses-in-nonreadable-collection [pulse]
+        (with-pulses-in-nonreadable-collection! [pulse]
           (mt/user-http-request :rasta :get 403 (str "pulse/" (u/the-id pulse))))))
 
     (testing "can fetch a pulse without collection permissions if you are the creator or a recipient"
       (t2.with-temp/with-temp [Pulse pulse {:creator_id (mt/user->id :rasta)}]
-        (with-pulses-in-nonreadable-collection [pulse]
+        (with-pulses-in-nonreadable-collection! [pulse]
           (mt/user-http-request :rasta :get 200 (str "pulse/" (u/the-id pulse)))))
 
       (mt/with-temp [Pulse                 pulse {:creator_id (mt/user->id :crowberto)}
                      PulseChannel          pc    {:pulse_id (u/the-id pulse)}
                      PulseChannelRecipient _     {:pulse_channel_id (u/the-id pc)
                                                   :user_id          (mt/user->id :rasta)}]
-        (with-pulses-in-nonreadable-collection [pulse]
+        (with-pulses-in-nonreadable-collection! [pulse]
           (mt/user-http-request :rasta :get 200 (str "pulse/" (u/the-id pulse))))))))
 
 (deftest send-test-pulse-test
@@ -893,7 +893,7 @@
                                                                      :default 3}]}
                          Card       card  {:dataset_query (mt/mbql-query incidents {:aggregation [[:count]]})}]
             (perms/grant-collection-readwrite-permissions! (perms-group/all-users) collection)
-            (api.card-test/with-cards-in-readable-collection [card]
+            (api.card-test/with-cards-in-readable-collection! [card]
               (let [channel-messages (pulse.test-util/with-captured-channel-send-messages!
                                       (is (= {:ok true}
                                              (mt/user-http-request :rasta :post 200 "pulse/test"
diff --git a/test/metabase/api/revision_test.clj b/test/metabase/api/revision_test.clj
index 30eeb638b75a7ad870d5542778ec295d3c7cd6f9..45660b0089835209ec25d145e32ac126df4e5cb2 100644
--- a/test/metabase/api/revision_test.clj
+++ b/test/metabase/api/revision_test.clj
@@ -431,7 +431,7 @@
                   (mt/user-http-request :crowberto :get 200 "revision" :entity "card" :id card-id)))))))
 
 (deftest revision-descriptions-are-i18ned-test
-  (mt/with-mock-i18n-bundles {"fr" {:messages {"created this" "créé ceci"
+  (mt/with-mock-i18n-bundles! {"fr" {:messages {"created this" "créé ceci"
                                                "added a description" "ajouté une description"
                                                "renamed {0} from \"{1}\" to \"{2}\"" "renommé {0} de {1} à {2}"
                                                "this {0}" "ce {0}"
diff --git a/test/metabase/api/session_test.clj b/test/metabase/api/session_test.clj
index 0d3e1bbb3c5f8f6769cb0caa1f7da0244dd026a3..e33e31529eeea10f54184467f220e36baab70a93 100644
--- a/test/metabase/api/session_test.clj
+++ b/test/metabase/api/session_test.clj
@@ -466,7 +466,7 @@
   (reset-throttlers!)
   (testing "GET /session/properties"
     (testing "Setting the X-Metabase-Locale header should result give you properties in that locale"
-      (mt/with-mock-i18n-bundles {"es" {:messages {"Connection String" "Cadena de conexión !"}}}
+      (mt/with-mock-i18n-bundles! {"es" {:messages {"Connection String" "Cadena de conexión !"}}}
         (is (= "Cadena de conexión !"
                (-> (mt/client :get 200 "session/properties" {:request-options {:headers {"x-metabase-locale" "es"}}})
                    :engines :h2 :details-fields first :display-name)))))))
@@ -516,7 +516,7 @@
 
 (deftest ldap-login-test
   (reset-throttlers!)
-  (ldap.test/with-ldap-server
+  (ldap.test/with-ldap-server!
     (testing "Test that we can login with LDAP"
       (t2.with-temp/with-temp [User _ {:email    "ngoc@metabase.com"
                                        :password "securedpassword"}]
diff --git a/test/metabase/api/setting_test.clj b/test/metabase/api/setting_test.clj
index c55cd069821ec7841a1cb8d2d5f5915a6808e6f0..79e5e7b909c66298083883fd63dce18d0183d29e 100644
--- a/test/metabase/api/setting_test.clj
+++ b/test/metabase/api/setting_test.clj
@@ -55,16 +55,16 @@
   ([user setting-name status]
    (mt/user-http-request user :get status (format "setting/%s" (name setting-name)))))
 
-(defn- do-with-mocked-settings-manager-access
+(defn- do-with-mocked-settings-manager-access!
   [f]
   (with-redefs [setting/has-advanced-setting-access?        (constantly true)
                 validation/check-has-application-permission (constantly true)]
     (f)))
 
-(defmacro ^:private with-mocked-settings-manager-access
+(defmacro ^:private with-mocked-settings-manager-access!
   "Runs `body` with the approrpiate functions redefined to give the current user settings manager permissions."
   [& body]
-  `(do-with-mocked-settings-manager-access (fn [] ~@body)))
+  `(do-with-mocked-settings-manager-access! (fn [] ~@body)))
 
 (deftest fetch-setting-test
   (testing "GET /api/setting"
@@ -88,7 +88,7 @@
 
     (testing "Check that non-admin setting managers can fetch Settings with `:visibility :settings-manager`"
       (test-settings-manager-visibility! nil)
-      (with-mocked-settings-manager-access
+      (with-mocked-settings-manager-access!
         (is (= [{:key "test-settings-manager-visibility",
                  :value nil,
                  :is_env_setting false,
@@ -109,7 +109,7 @@
 
     (testing "Test that non-admin setting managers can fetch a single Setting if it has `:visibility :settings-manager`."
       (test-settings-manager-visibility! "OK!")
-      (with-mocked-settings-manager-access
+      (with-mocked-settings-manager-access!
         (is (= "OK!" (fetch-setting :test-settings-manager-visibility 200)))))
 
     (testing "Check that non-superusers cannot fetch a single Setting if it is not user-local"
@@ -166,7 +166,7 @@
         "Updated setting should be visible from API endpoint")
 
     (testing "Check that non-admin setting managers can only update Settings with `:visibility :settings-manager`."
-      (with-mocked-settings-manager-access
+      (with-mocked-settings-manager-access!
         (mt/user-http-request :rasta :put 204 "setting/test-settings-manager-visibility" {:value "NICE!"})
         (is (= "NICE!" (fetch-setting :test-settings-manager-visibility 200)))
 
@@ -304,7 +304,7 @@
              (models.setting-test/test-setting-2))))
 
     (testing "non-admin setting managers should only be able to update multiple settings at once if they have `:visibility :settings-manager`"
-      (with-mocked-settings-manager-access
+      (with-mocked-settings-manager-access!
        (is (= nil
               (mt/user-http-request :rasta :put 204 "setting" {:test-settings-manager-visibility "ABC"})))
        (is (= "ABC"
diff --git a/test/metabase/api/user_test.clj b/test/metabase/api/user_test.clj
index 7b3c6c9b1c49bbe823cf6a21b2d44fba5119c5b8..bea3ff0fb35747cc6317798dd628d715433dd75f 100644
--- a/test/metabase/api/user_test.clj
+++ b/test/metabase/api/user_test.clj
@@ -918,16 +918,16 @@
                  (client/client creds :put 403 (format "user/%d" (u/the-id user))
                                 {:email "adifferentemail@metabase.com"}))))))))
 
-(defn- do-with-preserved-rasta-personal-collection-name [thunk]
+(defn- do-with-preserved-rasta-personal-collection-name! [thunk]
   (let [{collection-name :name, :keys [slug id]} (collection/user->personal-collection (mt/user->id :rasta))]
     (mt/with-temp-vals-in-db Collection id {:name collection-name, :slug slug}
       (thunk))))
 
-(defmacro ^:private with-preserved-rasta-personal-collection-name
+(defmacro ^:private with-preserved-rasta-personal-collection-name!
   "Preserve the name of Rasta's personal collection inside a body that might cause it to change (e.g. changing user name
   via the API.)"
   [& body]
-  `(do-with-preserved-rasta-personal-collection-name (fn [] ~@body)))
+  `(do-with-preserved-rasta-personal-collection-name! (fn [] ~@body)))
 
 (deftest update-groups-test
   (testing "PUT /api/user/:id"
@@ -943,7 +943,7 @@
       ;; By wrapping the test in this macro even if the test fails it will restore the original values
       (mt/with-temp-vals-in-db User (mt/user->id :rasta) {:first_name "Rasta"}
         (mt/test-helpers-set-global-values!
-          (with-preserved-rasta-personal-collection-name
+          (with-preserved-rasta-personal-collection-name!
             (t2.with-temp/with-temp [PermissionsGroup group {:name "Blue Man Group"}]
               (mt/user-http-request :rasta :put 403 (str "user/" (mt/user->id :rasta))
                                     {:user_group_memberships (group-or-ids->user-group-memberships [(perms-group/all-users) group])
@@ -957,7 +957,7 @@
 
     (testing "if we pass user_group_memberships as a non-superuser the call should succeed, so long as the value doesn't change"
       (mt/with-temp-vals-in-db User (mt/user->id :rasta) {:first_name "Rasta"}
-        (with-preserved-rasta-personal-collection-name
+        (with-preserved-rasta-personal-collection-name!
           (mt/user-http-request :rasta :put 200 (str "user/" (mt/user->id :rasta))
                                 {:user_group_memberships (group-or-ids->user-group-memberships [(perms-group/all-users)])
                                  :first_name             "Reggae"}))
diff --git a/test/metabase/async/streaming_response_test.clj b/test/metabase/async/streaming_response_test.clj
index a2b3fb251dd2d42486c0c48502272e579b15611a..c75d6f070a43e6bc37a6597e8c32ed55930f2118 100644
--- a/test/metabase/async/streaming_response_test.clj
+++ b/test/metabase/async/streaming_response_test.clj
@@ -27,7 +27,7 @@
 
 (def ^:private thread-pool-size 5)
 
-(defn- do-with-streaming-response-thread-pool [thunk]
+(defn- do-with-streaming-response-thread-pool! [thunk]
   (let [pool (Executors/newFixedThreadPool thread-pool-size
                                            (.build
                                             (doto (BasicThreadFactory$Builder.)
@@ -40,13 +40,13 @@
         (finally
           (.shutdownNow pool))))))
 
-(defmacro ^:private with-streaming-response-thread-pool {:style/indent 0} [& body]
-  `(do-with-streaming-response-thread-pool (fn [] ~@body)))
+(defmacro ^:private with-streaming-response-thread-pool! {:style/indent 0} [& body]
+  `(do-with-streaming-response-thread-pool! (fn [] ~@body)))
 
 (defmacro ^:private with-test-driver-db! {:style/indent 0} [& body]
   `(t2.with-temp/with-temp [Database db# {:engine ::test-driver}]
      (mt/with-db db#
-       (with-streaming-response-thread-pool
+       (with-streaming-response-thread-pool!
          ~@body))))
 
 (def ^:private start-execution-chan
diff --git a/test/metabase/db/custom_migrations_test.clj b/test/metabase/db/custom_migrations_test.clj
index f5d0946ce001fa4d10e4c3b2aef9eea12c40f062..8aca5dbdfd67c9dbd02550a5b70ca3cb71a7e4f7 100644
--- a/test/metabase/db/custom_migrations_test.clj
+++ b/test/metabase/db/custom_migrations_test.clj
@@ -1466,7 +1466,7 @@
   [setting-k]
   (json/parse-string (t2/select-one-fn :value :setting :key (name setting-k))))
 
-(defn- call-with-ldap-and-sso-configured [ldap-group-mappings sso-group-mappings f]
+(defn- call-with-ldap-and-sso-configured! [ldap-group-mappings sso-group-mappings f]
   (mt/with-temporary-raw-setting-values
     [ldap-group-mappings    (json/generate-string ldap-group-mappings)
      saml-group-mappings    (json/generate-string sso-group-mappings)
@@ -1476,11 +1476,11 @@
      jwt-enabled            "true"]
     (f)))
 
-(defmacro ^:private with-ldap-and-sso-configured
+(defmacro ^:private with-ldap-and-sso-configured!
   "Run body with ldap and SSO configured, in which SSO will only be configured if enterprise is available"
   [ldap-group-mappings sso-group-mappings & body]
   (binding [setting/*allow-retired-setting-names* true]
-    `(call-with-ldap-and-sso-configured ~ldap-group-mappings ~sso-group-mappings (fn [] ~@body))))
+    `(call-with-ldap-and-sso-configured! ~ldap-group-mappings ~sso-group-mappings (fn [] ~@body))))
 
 ;; The `remove-admin-from-group-mapping-if-needed` migration is written to run in OSS version
 ;; even though it might make changes to some enterprise-only settings.
@@ -1498,14 +1498,14 @@
         ldap-expected-mapping {"dc=metabase,dc=com" [(+ 1 admin-group-id)]}]
 
     (testing "Remove admin from group mapping for LDAP, SAML, JWT if they are enabled"
-      (with-ldap-and-sso-configured ldap-group-mappings sso-group-mappings
+      (with-ldap-and-sso-configured! ldap-group-mappings sso-group-mappings
         (#'custom-migrations/migrate-remove-admin-from-group-mapping-if-needed)
         (is (= ldap-expected-mapping (get-json-setting :ldap-group-mappings)))
         (is (= sso-expected-mapping (get-json-setting :jwt-group-mappings)))
         (is (= sso-expected-mapping (get-json-setting :saml-group-mappings)))))
 
     (testing "remove admin from group mapping for LDAP, SAML, JWT even if they are disabled"
-      (with-ldap-and-sso-configured ldap-group-mappings sso-group-mappings
+      (with-ldap-and-sso-configured! ldap-group-mappings sso-group-mappings
         (mt/with-temporary-raw-setting-values
           [ldap-enabled "false"
            saml-enabled "false"
@@ -1516,7 +1516,7 @@
           (is (= sso-expected-mapping (get-json-setting :saml-group-mappings))))))
 
     (testing "Don't remove admin group if `ldap-sync-admin-group` is enabled"
-      (with-ldap-and-sso-configured ldap-group-mappings sso-group-mappings
+      (with-ldap-and-sso-configured! ldap-group-mappings sso-group-mappings
         (mt/with-temporary-raw-setting-values
           [ldap-sync-admin-group "true"]
           (#'custom-migrations/migrate-remove-admin-from-group-mapping-if-needed)
@@ -1678,7 +1678,7 @@
   (testing "We should delete the triggers for DBs that are configured not to scan their field values\n"
     (impl/test-migrations "v49.2024-04-09T10:00:03" [migrate!]
       (letfn [(do-test []
-                (api.database-test/with-db-scheduler-setup
+                (api.database-test/with-db-scheduler-setup!
                   (let [db-with-full-schedules (new-instance-with-default :metabase_database
                                                                           {:metadata_sync_schedule      "0 0 * * * ? *"
                                                                            :cache_field_values_schedule "0 0 1 * * ? *"
diff --git a/test/metabase/driver/common/parameters/values_test.clj b/test/metabase/driver/common/parameters/values_test.clj
index 76f6300e6256fc444e26e2ff09d802eb70917148..b32f1d7e923d5dbc194abe11a1722cbc16706e13 100644
--- a/test/metabase/driver/common/parameters/values_test.clj
+++ b/test/metabase/driver/common/parameters/values_test.clj
@@ -383,7 +383,7 @@
     (testing "Persisted Models are substituted"
       (mt/test-driver :postgres
         (mt/dataset test-data
-          (mt/with-persistence-enabled [persist-models!]
+          (mt/with-persistence-enabled! [persist-models!]
             (let [mbql-query (mt/mbql-query categories)]
               (mt/with-temp [Card model {:name "model"
                                          :type :model
diff --git a/test/metabase/driver/common_test.clj b/test/metabase/driver/common_test.clj
index 940ac5f77e85f46886c6f9b9bcaa180f2822ebdf..7c7a8723556825a537e33cd12aec97448ab1ab5c 100644
--- a/test/metabase/driver/common_test.clj
+++ b/test/metabase/driver/common_test.clj
@@ -40,17 +40,17 @@
                                                                                 [4 5 6])))
               @realized-lazy-seq?])))))
 
-(defn- test-start-of-week-offset
+(defn- test-start-of-week-offset!
   [db-start-of-week target-start-of-week]
   (with-redefs [driver/db-start-of-week   (constantly db-start-of-week)
                 setting/get-value-of-type (constantly target-start-of-week)]
     (driver.common/start-of-week-offset :sql)))
 
 (deftest start-of-week-offset-test
-  (is (= 0 (test-start-of-week-offset :sunday :sunday)))
-  (is (= -1 (test-start-of-week-offset :sunday :monday)))
-  (is (= 1 (test-start-of-week-offset :monday :sunday)))
-  (is (= 5 (test-start-of-week-offset :monday :wednesday))))
+  (is (= 0 (test-start-of-week-offset! :sunday :sunday)))
+  (is (= -1 (test-start-of-week-offset! :sunday :monday)))
+  (is (= 1 (test-start-of-week-offset! :monday :sunday)))
+  (is (= 5 (test-start-of-week-offset! :monday :wednesday))))
 
 (deftest cloud-ip-address-info-test
   (testing "The cloud-ip-address-info field is correctly resolved when fetching driver connection properties"
diff --git a/test/metabase/driver/postgres_test.clj b/test/metabase/driver/postgres_test.clj
index 6049268ae7db00bc51d3831b197f6b619ea52a10..9304c19d4cef31ed26764c8e6148786afd8e672a 100644
--- a/test/metabase/driver/postgres_test.clj
+++ b/test/metabase/driver/postgres_test.clj
@@ -1346,7 +1346,7 @@
                (driver/syncable-schemas driver/*driver* (mt/db))))))
     (testing "metabase_cache schemas should be excluded"
       (mt/dataset test-data
-        (mt/with-persistence-enabled [persist-models!]
+        (mt/with-persistence-enabled! [persist-models!]
           (let [conn-spec (sql-jdbc.conn/db->pooled-connection-spec (mt/db))]
             (mt/with-temp [:model/Card _ {:name "model"
                                           :type :model
diff --git a/test/metabase/driver/sql_jdbc/sync/describe_database_test.clj b/test/metabase/driver/sql_jdbc/sync/describe_database_test.clj
index 4560132b5e06345a84a8ce89e95ea0ade4fbb604..f668f2d9725b41d38082d2d0c57734393ea4f664 100644
--- a/test/metabase/driver/sql_jdbc/sync/describe_database_test.clj
+++ b/test/metabase/driver/sql_jdbc/sync/describe_database_test.clj
@@ -93,7 +93,7 @@
                     {:name "REVIEWS", :schema "PUBLIC", :description nil}}}
          (sql-jdbc.describe-database/describe-database :h2 (mt/id)))))
 
-(defn- describe-database-with-open-resultset-count
+(defn- describe-database-with-open-resultset-count!
   "Just like `describe-database`, but instead of returning the database description returns the number of ResultSet
   objects the sync process left open. Make sure you wrap ResultSets with `with-open`! Otherwise some JDBC drivers like
   Oracle and Redshift will keep open cursors indefinitely."
@@ -142,7 +142,7 @@
     (testing (str "make sure that running the sync process doesn't leak cursors because it's not closing the ResultSets. "
                   "See issues #4389, #6028, and #6467 (Oracle) and #7609 (Redshift)")
       (is (= 0
-             (describe-database-with-open-resultset-count driver/*driver* (mt/db)))))))
+             (describe-database-with-open-resultset-count! driver/*driver* (mt/db)))))))
 
 (defn- sync-and-assert-filtered-tables [database assert-table-fn]
   (t2.with-temp/with-temp [Database db-filtered database]
diff --git a/test/metabase/email/messages_test.clj b/test/metabase/email/messages_test.clj
index 54b849da621d1781ab191e0b13198be885996142..acc7c184ede85561d12583e35cd0963fcc461557 100644
--- a/test/metabase/email/messages_test.clj
+++ b/test/metabase/email/messages_test.clj
@@ -60,7 +60,7 @@
               (get-in [0 :body 0 :content])
               (str/includes? "deactivated"))))))
 
-(defmacro ^:private with-create-temp-failure [& body]
+(defmacro ^:private with-create-temp-failure! [& body]
   `(with-redefs [messages/create-temp-file (fn [~'_]
                                              (throw (IOException. "Failed to write file")))]
      ~@body))
@@ -70,7 +70,7 @@
   (is (thrown-with-msg?
         IOException
         (re-pattern (format "Unable to create temp file in `%s`" (System/getProperty "java.io.tmpdir")))
-        (with-create-temp-failure
+        (with-create-temp-failure!
           (#'messages/create-temp-file-or-throw "txt")))))
 
 (deftest alert-schedule-text-test
diff --git a/test/metabase/email_test.clj b/test/metabase/email_test.clj
index b4ba1917014fb5f82f2bef426cf5ac291940dca2..44004c81b9754dbcfd6a283b9cfe7acdf667dd60 100644
--- a/test/metabase/email_test.clj
+++ b/test/metabase/email_test.clj
@@ -69,7 +69,7 @@
   [n & body]
   `(do-with-expected-messages ~n (fn [] ~@body)))
 
-(defn do-with-fake-inbox
+(defn do-with-fake-inbox!
   "Impl for `with-fake-inbox` macro; prefer using that rather than calling this directly."
   [f]
   (with-redefs [email/send-email! fake-inbox-email-fn]
@@ -78,6 +78,8 @@
                                        email-smtp-port 587]
       (f))))
 
+;;; TODO -- rename to `with-fake-inbox!` since it's not thread-safe and remove the Kondo ignore below.
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-fake-inbox
   "Clear `inbox`, bind `send-email!` to `fake-inbox-email-fn`, set temporary settings for `email-smtp-username`
    and `email-smtp-password` (which will cause `metabase.email/email-configured?` to return `true`, and execute `body`.
@@ -89,7 +91,7 @@
        @inbox)"
   [& body]
   {:style/indent 0}
-  `(do-with-fake-inbox (fn [] ~@body)))
+  `(do-with-fake-inbox! (fn [] ~@body)))
 
 (defn- create-email-body->regex-fn
   "Returns a function expecting the email body structure. It will apply the regexes in `regex-seq` over the body and
diff --git a/test/metabase/events/view_log_test.clj b/test/metabase/events/view_log_test.clj
index 93e86de5449086d8079fab31ce6cd4b6eb0c935b..106660a83481dfe7bc51aa71e1ae5ea9b531c9d9 100644
--- a/test/metabase/events/view_log_test.clj
+++ b/test/metabase/events/view_log_test.clj
@@ -265,7 +265,7 @@
 (deftest get-embedded-card-embedding-logs-view-test
   (mt/with-premium-features #{:audit-app}
     (testing "Viewing an embedding logs the correct view log event."
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (mt/with-temp [:model/Card card {:enable_embedding true}]
           (testing "GET /api/embed/card/:token"
             (client/client :get 200 (embed-test/card-url card))
@@ -275,7 +275,7 @@
 (deftest embedded-dashboard-card-query-view-log-test
   (mt/with-premium-features #{:audit-app}
     (testing "Running a query for a card in a public dashboard logs the correct view log event."
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (mt/with-temp [:model/Dashboard dash {:enable_embedding true}
                        :model/Card          card     {}
                        :model/DashboardCard dashcard {:dashboard_id (:id dash)
@@ -288,7 +288,7 @@
 (deftest get-embedded-dashboard-logs-view-test
   (mt/with-premium-features #{:audit-app}
     (testing "Viewing an embedding logs the correct view log event."
-      (embed-test/with-embedding-enabled-and-new-secret-key
+      (embed-test/with-embedding-enabled-and-new-secret-key!
         (mt/with-temp [:model/Dashboard dash {:enable_embedding true}]
           (testing "GET /api/embed/dashboard/:token"
             (client/client :get 200 (embed-test/dashboard-url dash))
diff --git a/test/metabase/integrations/google_test.clj b/test/metabase/integrations/google_test.clj
index c2c999a63b618db143757a610bfa150cd6596b56..d92e439124cf502f9a86cb82609d87283f000008 100644
--- a/test/metabase/integrations/google_test.clj
+++ b/test/metabase/integrations/google_test.clj
@@ -39,12 +39,12 @@
 
 ;;; --------------------------------------------- account autocreation -----------------------------------------------
 
-(defmacro ^:private with-no-sso-google-token [& body]
+(defmacro ^:private with-no-sso-google-token! [& body]
   `(with-redefs [premium-features/enable-sso-google? (constantly false)]
      ~@body))
 
 (deftest allow-autocreation-test
-  (with-no-sso-google-token
+  (with-no-sso-google-token!
     (mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "metabase.com"]
       (are [allowed? email] (= allowed?
                                (#'google/autocreate-user-allowed-for-email? email))
@@ -53,14 +53,14 @@
 
 (deftest google-auth-auto-create-accounts-domain-test
   (testing "multiple domains cannot be set if EE `:sso-google` feature flag is not enabled"
-    (with-no-sso-google-token
+    (with-no-sso-google-token!
       (is (thrown?
            clojure.lang.ExceptionInfo
            (google.i/google-auth-auto-create-accounts-domain! "metabase.com, example.com"))))))
 
 (deftest google-auth-create-new-user!-test
   (mt/with-model-cleanup [User]
-    (with-no-sso-google-token
+    (with-no-sso-google-token!
       (testing "shouldn't be allowed to create a new user via Google Auth if their email doesn't match the auto-create accounts domain"
         (mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "sf-toucannery.com"]
           (is (thrown?
@@ -136,7 +136,7 @@
 
 (deftest google-auth-fetch-or-create-user!-test
   (mt/with-model-cleanup [User]
-    (with-no-sso-google-token
+    (with-no-sso-google-token!
       (testing "test that an existing user can log in with Google auth even if the auto-create accounts domain is different from"
         (t2.with-temp/with-temp [User _ {:email "cam@sf-toucannery.com"}]
           (mt/with-temporary-setting-values [google-auth-auto-create-accounts-domain "metabase.com"]
diff --git a/test/metabase/integrations/ldap_test.clj b/test/metabase/integrations/ldap_test.clj
index 8b773e071a24137a166910880cf43a81c9cf1708..cfc1653047bf3244f7e46a509c3dd32fe3f0d995 100644
--- a/test/metabase/integrations/ldap_test.clj
+++ b/test/metabase/integrations/ldap_test.clj
@@ -16,7 +16,7 @@
 
 ;; The connection test should pass with valid settings
 (deftest connection-test
-  (ldap.test/with-ldap-server
+  (ldap.test/with-ldap-server!
     (testing "anonymous binds"
       (testing "successfully connect to IPv4 host"
         (is (= {:status :SUCCESS}
@@ -70,7 +70,7 @@
 (deftest find-test
   ;; there are EE-specific versions of this test in [[metabase-enterprise.enhancements.integrations.ldap-test]]
   (mt/with-premium-features #{}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "find by username"
         (is (= {:dn         "cn=John Smith,ou=People,dc=metabase,dc=com"
                 :first-name "John"
@@ -104,7 +104,7 @@
                (ldap/find-user "jane.miller@metabase.com")))))
 
     ;; Test group lookups for directory servers that use the memberOf attribute overlay, such as Active Directory
-    (ldap.test/with-active-directory-ldap-server
+    (ldap.test/with-active-directory-ldap-server!
       (testing "find user with one group using memberOf attribute"
         (is (= {:dn         "cn=John Smith,ou=People,dc=metabase,dc=com"
                 :first-name "John"
@@ -125,7 +125,7 @@
 (deftest fetch-or-create-user-test
   ;; there are EE-specific versions of this test in [[metabase-enterprise.enhancements.integrations.ldap-test]]
   (mt/with-premium-features #{}
-    (ldap.test/with-ldap-server
+    (ldap.test/with-ldap-server!
       (testing "a new user is created when they don't already exist"
         (try
           (ldap/fetch-or-create-user! (ldap/find-user "jsmith1"))
@@ -182,7 +182,7 @@
 ;; This isn't a failure of the code, it's a failure of the host.
 (deftest ipv6-test
   (testing "successfully connect to IPv6 host"
-    (let [actual (ldap.test/with-ldap-server
+    (let [actual (ldap.test/with-ldap-server!
                    (ldap/test-ldap-connection (assoc (ldap.test/get-ldap-details)
                                                      :host "[::1]")))]
       (if (= (:status actual) :ERROR)
diff --git a/test/metabase/integrations/slack_test.clj b/test/metabase/integrations/slack_test.clj
index f812e882488d18f6a4d2a3c2646072385e87fa7d..16e406cdd2b5785dda66bbd365065926ff8f7efc 100644
--- a/test/metabase/integrations/slack_test.clj
+++ b/test/metabase/integrations/slack_test.clj
@@ -43,7 +43,7 @@
              body
              (json/generate-string body))})
 
-(defn- test-no-auth-token
+(defn- test-no-auth-token!
   "Test that a Slack API endpoint function returns `nil` if a Slack API token isn't configured."
   [endpoint thunk]
   (http-fake/with-fake-routes {endpoint (fn [_]
@@ -54,7 +54,7 @@
         (is (= nil
                (not-empty (thunk))))))))
 
-(defn- test-invalid-auth-token
+(defn- test-invalid-auth-token!
   "Test that a Slack API endpoint function throws an Exception if an invalid Slack API token is set."
   [endpoint thunk]
   (testing "should throw Exception if auth token is invalid"
@@ -72,10 +72,10 @@
             (is (= {:slack-token "Invalid token"}
                    (:errors (ex-data e))))))))))
 
-(defn- test-auth
+(defn- test-auth!
   "Test that a Slack API `endpoint` function works as expected when Slack token is missing or invalid."
   [endpoint thunk]
-  (doseq [f [test-no-auth-token test-invalid-auth-token]]
+  (doseq [f [test-no-auth-token! test-invalid-auth-token!]]
     (f endpoint thunk)))
 
 (deftest slack-app-token-truncation-test
@@ -86,7 +86,7 @@
 
 (deftest conversations-list-test
   (testing "conversations-list"
-    (test-auth conversations-endpoint slack/conversations-list)
+    (test-auth! conversations-endpoint slack/conversations-list)
 
     (testing "should be able to fetch channels and paginate"
       (http-fake/with-fake-routes {conversations-endpoint (comp mock-200-response mock-conversations-response-body)}
@@ -138,7 +138,7 @@
 
 (deftest users-list-test
   (testing "users-list"
-    (test-auth users-endpoint slack/users-list)
+    (test-auth! users-endpoint slack/users-list)
 
     (testing "should be able to fetch list of users and page"
       (http-fake/with-fake-routes {users-endpoint (comp mock-200-response mock-users-response-body)}
diff --git a/test/metabase/lib/drill_thru/fk_details_test.cljc b/test/metabase/lib/drill_thru/fk_details_test.cljc
index c3276568fd63795c395af343da8ff54bc9eb34a9..061c83f715735eff8d54ececaf61ddb830b466b2 100644
--- a/test/metabase/lib/drill_thru/fk_details_test.cljc
+++ b/test/metabase/lib/drill_thru/fk_details_test.cljc
@@ -144,6 +144,7 @@
       (is (not (m/find-first #(= (:type %) :drill-thru/fk-details)
                              (lib/available-drill-thrus query -1 context)))))))
 
+`preserve-filters-for-other-fks-forming-multi-column-pk-test
 (deftest ^:parallel preserve-filters-for-other-fks-forming-multi-column-pk-test
   (testing "with multiple FKs forming a multi-column PK on another table"
     (let [provider (merged-mock/merged-mock-metadata-provider
diff --git a/test/metabase/models/collection_test.clj b/test/metabase/models/collection_test.clj
index 369c29383fad1149f8319c67f402ad121689cb53..86b541a0a3e12e75a8c7926ba4c010458af03ef3 100644
--- a/test/metabase/models/collection_test.clj
+++ b/test/metabase/models/collection_test.clj
@@ -144,7 +144,7 @@
 ;;; |                                     Nested Collections Helper Fns & Macros                                     |
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
-(defn do-with-collection-hierarchy [options a-fn]
+(defn do-with-collection-hierarchy! [options a-fn]
   (mt/with-non-admin-groups-no-root-collection-perms
     (t2.with-temp/with-temp [Collection a (merge options {:name "A"})
                              Collection b (merge options {:name "B", :location (collection/location-path a)})
@@ -155,7 +155,7 @@
                              Collection g (merge options {:name "G", :location (collection/location-path a c f)})]
       (a-fn {:a a, :b b, :c c, :d d, :e e, :f f, :g g}))))
 
-(defmacro with-collection-hierarchy
+(defmacro with-collection-hierarchy!
   "Run `body` with a hierarchy of Collections that looks like:
 
         +-> B
@@ -170,7 +170,7 @@
        ...)"
   {:style/indent 1}
   [[collections-binding options] & body]
-  `(do-with-collection-hierarchy ~options (fn [~collections-binding] ~@body)))
+  `(do-with-collection-hierarchy! ~options (fn [~collections-binding] ~@body)))
 
 (defmacro with-current-user-perms-for-collections
   "Run `body` with the current User permissions for `collections-or-ids`.
@@ -495,7 +495,7 @@
     ;; x -+-> C -+-> D -> E     ===>     x
     ;;           |
     ;;           +-> F -> G
-    (with-collection-hierarchy [{:keys [a b c d e f g]}]
+    (with-collection-hierarchy! [{:keys [a b c d e f g]}]
       (is (= 1
              (t2/delete! Collection :id (u/the-id a))))
       (is (= 0
@@ -509,7 +509,7 @@
     ;; A -+-> x -+-> D -> E     ===>     A -+
     ;;           |
     ;;           +-> F -> G
-    (with-collection-hierarchy [{:keys [a b c d e f g]}]
+    (with-collection-hierarchy! [{:keys [a b c d e f g]}]
       (t2/delete! Collection :id (u/the-id c))
       (is (= 2
              (t2/count Collection :id [:in (map u/the-id [a b c d e f g])]))))))
@@ -525,7 +525,7 @@
   (map :name (:effective_ancestors (t2/hydrate collection :effective_ancestors))))
 
 (deftest effective-ancestors-test
-  (with-collection-hierarchy [{:keys [a c d]}]
+  (with-collection-hierarchy! [{:keys [a c d]}]
     (testing "For D: if we don't have permissions for C, we should only see A"
       (with-current-user-perms-for-collections [a d]
         (is (= ["A"]
@@ -573,7 +573,7 @@
       format-collections))
 
 (deftest descendants-test
-  (with-collection-hierarchy [{:keys [a b c d]}]
+  (with-collection-hierarchy! [{:keys [a b c d]}]
     (testing "make sure we can fetch the descendants of a Collection in the hierarchy we'd expect"
       (is (= #{{:name "B", :id true, :location "/A/", :children #{}, :description nil}
                {:name        "C"
@@ -615,7 +615,7 @@
 
 (deftest root-collection-descendants-test
   (testing "For the *Root* Collection, can we get top-level Collections?"
-    (with-collection-hierarchy [_]
+    (with-collection-hierarchy! [_]
       (is (contains? (descendants collection/root-collection)
                      {:name        "A"
                       :id          true
@@ -666,7 +666,7 @@
   (set (map :name (collection/effective-children collection))))
 
 (deftest effective-children-test
-  (with-collection-hierarchy [{:keys [a b c d e f g]}]
+  (with-collection-hierarchy! [{:keys [a b c d e f g]}]
     (testing "If we *have* perms for everything we should just see B and C."
       (with-current-user-perms-for-collections [a b c d e f g]
         (is (= #{"B" "C"}
@@ -739,7 +739,7 @@
                (effective-children collection/root-collection)))))
 
     (testing "For the Root Collection: if we remove A and C we should get B, D and F"
-      (with-collection-hierarchy [{:keys [b d e f g]}]
+      (with-collection-hierarchy! [{:keys [b d e f g]}]
         (is (= #{"B" "D" "F"}
                (with-current-user-perms-for-collections [b d e f g]
                  (effective-children collection/root-collection))))))))
@@ -776,7 +776,7 @@
 ;;; ---------------------------------------------- Perms for Archiving -----------------------------------------------
 
 (deftest perms-for-archiving-test
-  (with-collection-hierarchy [{:keys [a b c d], :as collections}]
+  (with-collection-hierarchy! [{:keys [a b c d], :as collections}]
     (testing "To Archive A, you should need *write* perms for A and all of its descendants, and also the Root Collection..."
       (is (= #{"/collection/root/"
                "/collection/A/"
@@ -847,7 +847,7 @@
 ;; `*` marks the things that require permissions in charts below!
 
 (deftest perms-for-moving-test
-  (with-collection-hierarchy [{:keys [b c], :as collections}]
+  (with-collection-hierarchy! [{:keys [b c], :as collections}]
     (testing "If we want to move B into C, we should need perms for A, B, and C."
       ;; B because it is being moved; C we are moving
       ;; something into it, A because we are moving something out of it
@@ -912,7 +912,7 @@
                   (perms-path-ids->names collections)))))))
 
 (deftest perms-for-moving-exceptions-test
-  (with-collection-hierarchy [{:keys [a b], :as _collections}]
+  (with-collection-hierarchy! [{:keys [a b], :as _collections}]
     (testing "If you try to calculate permissions to move or archive the Root Collection, throw an Exception!"
       (is (thrown?
            Exception
@@ -980,7 +980,7 @@
     ;; A -+-> C -+-> D -> E
     ;;           |
     ;;           +-> F -> G
-    (with-collection-hierarchy [collections]
+    (with-collection-hierarchy! [collections]
       (is (= {"A" {"B" {}
                    "C" {"D" {"E" {}}
                         "F" {"G" {}}}}}
@@ -993,7 +993,7 @@
     ;; A -+-> C -+-> D -> E   ===>  A -+-> C -+-> D
     ;;           |                            |
     ;;           +-> F -> G                   +-> F -> G
-    (with-collection-hierarchy [{:keys [b e], :as collections}]
+    (with-collection-hierarchy! [{:keys [b e], :as collections}]
       (collection/move-collection! e (collection/children-location b))
       (is (= {"A" {"B" {"E" {}}
                    "C" {"D" {}
@@ -1007,7 +1007,7 @@
     ;; A -+-> C -+-> D -> E  ===>  A -+-> C -+
     ;;           |                           |
     ;;           +-> F -> G                  +-> F -> G
-    (with-collection-hierarchy [{:keys [b d], :as collections}]
+    (with-collection-hierarchy! [{:keys [b d], :as collections}]
       (collection/move-collection! d (collection/children-location b))
       (is (= {"A" {"B" {"D" {"E" {}}}
                    "C" {"F" {"G" {}}}}}
@@ -1020,7 +1020,7 @@
     ;; A -+-> C -+-> D -> E   ===>  A -+-> C -> D -> E
     ;;           |
     ;;           +-> F -> G         F -> G
-    (with-collection-hierarchy [{:keys [f], :as collections}]
+    (with-collection-hierarchy! [{:keys [f], :as collections}]
       (collection/move-collection! f (collection/children-location collection/root-collection))
       (is (= {"A" {"B" {}
                    "C" {"D" {"E" {}}}}
@@ -1034,7 +1034,7 @@
     ;; A -+-> C -+-> D -> E   ===>  F -+-> A -+-> C -+-> D -> E
     ;;           |                     |
     ;;           +-> F -> G            +-> G
-    (with-collection-hierarchy [{:keys [a f], :as collections}]
+    (with-collection-hierarchy! [{:keys [a f], :as collections}]
       (collection/move-collection! f (collection/children-location collection/root-collection))
       (collection/move-collection! a (collection/children-location (t2/select-one Collection :id (u/the-id f))))
       (is (= {"F" {"A" {"B" {}
@@ -1049,7 +1049,7 @@
 
 (deftest nested-collections-archiving-test
   (testing "Make sure the 'additional-conditions' for collection-locations is working normally"
-    (with-collection-hierarchy [collections]
+    (with-collection-hierarchy! [collections]
       (is (= {"A" {"B" {}
                    "C" {"D" {"E" {}}
                         "F" {"G" {}}}}}
@@ -1061,7 +1061,7 @@
     ;; A -+-> C -+-> D -> E   ===>  A -+-> C -+-> D
     ;;           |                            |
     ;;           +-> F -> G                   +-> F -> G
-    (with-collection-hierarchy [{:keys [e], :as collections}]
+    (with-collection-hierarchy! [{:keys [e], :as collections}]
       (t2/update! Collection (u/the-id e) {:archived true})
       (is (= {"A" {"B" {}
                    "C" {"D" {}
@@ -1074,7 +1074,7 @@
     ;; A -+-> C -+-> D -> E   ===>  A -+
     ;;           |
     ;;           +-> F -> G
-    (with-collection-hierarchy [{:keys [c], :as collections}]
+    (with-collection-hierarchy! [{:keys [c], :as collections}]
       (archive-collection! c)
       (is (= {"A" {"B" {}}}
              (collection-locations (vals collections) :archived false))))))
@@ -1086,7 +1086,7 @@
     ;; A -+-> C -+-> D        ===>  A -+-> C -+-> D -> E
     ;;           |                            |
     ;;           +-> F -> G                   +-> F -> G
-    (with-collection-hierarchy [{:keys [e], :as collections}]
+    (with-collection-hierarchy! [{:keys [e], :as collections}]
       (archive-collection! e)
       (unarchive-collection! (t2/select-one :model/Collection :id (u/the-id e)))
       (is (= {"A" {"B" {}
@@ -1100,7 +1100,7 @@
     ;; A -+                   ===>  A -+-> C -+-> D -> E
     ;;                                        |
     ;;                                        +-> F -> G
-    (with-collection-hierarchy [{:keys [c], :as collections}]
+    (with-collection-hierarchy! [{:keys [c], :as collections}]
       (archive-collection! c)
       (unarchive-collection! (t2/select-one :model/Collection :id (u/the-id c)))
       (is (= {"A" {"B" {}
@@ -1112,7 +1112,7 @@
   (doseq [model [Card Dashboard NativeQuerySnippet Pulse]]
     (testing (format "Test that archiving applies to %ss" (name model))
       ;; object is in E; archiving E should cause object to be archived
-      (with-collection-hierarchy [{:keys [e], :as _collections} (when (= model NativeQuerySnippet)
+      (with-collection-hierarchy! [{:keys [e], :as _collections} (when (= model NativeQuerySnippet)
                                                                   {:namespace "snippets"})]
         (t2.with-temp/with-temp [model object {:collection_id (u/the-id e)}]
           (archive-collection! e)
@@ -1121,7 +1121,7 @@
 
     (testing (format "Test that archiving applies to %ss belonging to descendant Collections" (name model))
       ;; object is in E, a descendant of C; archiving C should cause object to be archived
-      (with-collection-hierarchy [{:keys [c e], :as _collections} (when (= model NativeQuerySnippet)
+      (with-collection-hierarchy! [{:keys [c e], :as _collections} (when (= model NativeQuerySnippet)
                                                                     {:namespace "snippets"})]
         (t2.with-temp/with-temp [model object {:collection_id (u/the-id e)}]
           (archive-collection! c)
@@ -1132,7 +1132,7 @@
   (doseq [model [Card Dashboard NativeQuerySnippet Pulse]]
     (testing (format "Test that unarchiving applies to %ss" (name model))
       ;; object is in E; unarchiving E should cause object to be unarchived
-      (with-collection-hierarchy [{:keys [e], :as _collections} (when (= model NativeQuerySnippet)
+      (with-collection-hierarchy! [{:keys [e], :as _collections} (when (= model NativeQuerySnippet)
                                                                   {:namespace "snippets"})]
         (archive-collection! e)
         (t2.with-temp/with-temp [model object {:collection_id (u/the-id e), :archived true}]
@@ -1142,7 +1142,7 @@
 
     (testing (format "Test that unarchiving applies to %ss belonging to descendant Collections" (name model))
       ;; object is in E, a descendant of C; unarchiving C should cause object to be unarchived
-      (with-collection-hierarchy [{:keys [c e], :as _collections} (when (= model NativeQuerySnippet)
+      (with-collection-hierarchy! [{:keys [c e], :as _collections} (when (= model NativeQuerySnippet)
                                                                     {:namespace "snippets"})]
         (archive-collection! c)
         (t2.with-temp/with-temp [model object {:collection_id (u/the-id e), :archived true}]
diff --git a/test/metabase/models/dashboard_test.clj b/test/metabase/models/dashboard_test.clj
index 564cfcc01b859d6390576b88cee3d12d0e66e91d..423152c005550c7c3ed6f2dcc2830e60d12d49d3 100644
--- a/test/metabase/models/dashboard_test.clj
+++ b/test/metabase/models/dashboard_test.clj
@@ -855,7 +855,7 @@
 ;;; |                                         Collections Permissions Tests                                          |
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
-(defn do-with-dash-in-collection [f]
+(defn do-with-dash-in-collection! [f]
   (tu/with-non-admin-groups-no-root-collection-perms
     (t2.with-temp/with-temp [Collection    collection {}
                              Dashboard     dash       {:collection_id (u/the-id collection)}
@@ -867,16 +867,16 @@
                              DashboardCard _          {:dashboard_id (u/the-id dash), :card_id (u/the-id card)}]
       (f db collection dash))))
 
-(defmacro with-dash-in-collection
+(defmacro with-dash-in-collection!
   "Execute `body` with a Dashboard in a Collection. Dashboard will contain one Card in a Database."
   {:style/indent :defn}
   [[db-binding collection-binding dash-binding] & body]
-  `(do-with-dash-in-collection
+  `(do-with-dash-in-collection!
     (fn [~(or db-binding '_) ~(or collection-binding '_) ~(or dash-binding '_)]
       ~@body)))
 
 (deftest perms-test
-  (with-dash-in-collection [_db collection dash]
+  (with-dash-in-collection! [_db collection dash]
     (testing (str "Check that if a Dashboard is in a Collection, someone who would not be able to see it under the old "
                   "artifact-permissions regime will be able to see it if they have permissions for that Collection")
       (binding [api/*current-user-permissions-set* (atom #{(perms/collection-read-path collection)})]
diff --git a/test/metabase/models/database_test.clj b/test/metabase/models/database_test.clj
index 8dacb83e5b664da1aa2078ef78c475a26888b4b2..d738350104719ac4788108631d4807d26f07a1b4 100644
--- a/test/metabase/models/database_test.clj
+++ b/test/metabase/models/database_test.clj
@@ -41,7 +41,7 @@
 
 (deftest tasks-test
   (testing "Sync tasks should get scheduled for a newly created Database"
-    (mt/with-temp-scheduler
+    (mt/with-temp-scheduler!
       (task/init! ::task.sync-databases/SyncDatabases)
       (t2.with-temp/with-temp [Database {db-id :id}]
         (is (=? {:description         (format "sync-and-analyze Database %d" db-id)
diff --git a/test/metabase/models/humanization_test.clj b/test/metabase/models/humanization_test.clj
index 3b274c4f179a2e671a8016f5319b3cce1106d45b..ebc4547133fc3c19e4185067b8796b9900732f20 100644
--- a/test/metabase/models/humanization_test.clj
+++ b/test/metabase/models/humanization_test.clj
@@ -7,7 +7,7 @@
    [toucan2.core :as t2]
    [toucan2.tools.with-temp :as t2.with-temp]))
 
-(defn- get-humanized-display-name [actual-name strategy]
+(defn- get-humanized-display-name! [actual-name strategy]
   (with-redefs [humanization/humanization-strategy (constantly strategy)]
     (t2.with-temp/with-temp [Table {table-id :id} {:name actual-name}]
       (t2/select-one-fn :display_name Table, :id table-id))))
@@ -21,7 +21,7 @@
             [strategy expected]        strategy->expected]
       (testing (pr-str (list 'get-humanized-display-name input strategy))
         (is (= expected
-               (get-humanized-display-name input strategy)))))))
+               (get-humanized-display-name! input strategy)))))))
 
 (deftest rehumanize-test
   (testing "check that existing tables have their :display_names updated appropriately when strategy is changed"
diff --git a/test/metabase/models/model_index_test.clj b/test/metabase/models/model_index_test.clj
index d33fbe58c34119419d688eb92fe65d60003349b8..fc20a248170ba9b2a65d1c352a4959aa8a5f6fb1 100644
--- a/test/metabase/models/model_index_test.clj
+++ b/test/metabase/models/model_index_test.clj
@@ -21,7 +21,7 @@
    [toucan2.core :as t2]
    [toucan2.tools.with-temp :as t2.with-temp]))
 
-(defmacro with-scheduler-setup [& body]
+(defmacro with-scheduler-setup! [& body]
   `(let [scheduler# (#'tu/in-memory-scheduler)]
      ;; need cross thread rebinding from with-redefs not a binding
      (with-redefs [task/scheduler (constantly scheduler#)]
@@ -37,7 +37,7 @@
          (finally (qs/shutdown scheduler#))))))
 
 (deftest quick-run-through
-  (with-scheduler-setup
+  (with-scheduler-setup!
     (mt/dataset test-data
       (let [query     (mt/mbql-query products
                                      {:filter [:and
diff --git a/test/metabase/models/params/chain_filter_test.clj b/test/metabase/models/params/chain_filter_test.clj
index e934cd5446c699885471a31e7fa2d53aefac0e6d..4b231edac315501b8855018027b27c7af553a70d 100644
--- a/test/metabase/models/params/chain_filter_test.clj
+++ b/test/metabase/models/params/chain_filter_test.clj
@@ -596,7 +596,7 @@
                   (is (#'chain-filter/use-cached-field-values? %myfield)))
                 (thunk)))))))))
 
-(defn- do-with-clean-field-values-for-field
+(defn- do-with-clean-field-values-for-field!
   [field-or-field-id thunk]
   (mt/with-model-cleanup [FieldValues]
     (let [field-id         (u/the-id field-or-field-id)
@@ -612,18 +612,18 @@
          (t2/update! Field field-id {:has_field_values has_field_values})
          (t2/insert! FieldValues fvs))))))
 
-(defmacro ^:private with-clean-field-values-for-field
+(defmacro ^:private with-clean-field-values-for-field!
   "Run `body` with all FieldValues for `field-id` deleted.
   Restores the deleted FieldValues when we're done."
   {:style/indent 1}
   [field-or-field-id & body]
-  `(do-with-clean-field-values-for-field ~field-or-field-id (fn [] ~@body)))
+  `(do-with-clean-field-values-for-field! ~field-or-field-id (fn [] ~@body)))
 
 (deftest chain-filter-has-more-values-test
   (testing "the `has_more_values` property should be correct\n"
     (testing "for cached fields"
       (testing "without contraints"
-        (with-clean-field-values-for-field (mt/id :categories :name)
+        (with-clean-field-values-for-field! (mt/id :categories :name)
           (testing "`false` for field has values less than [[field-values/*total-max-length*]] threshold"
             (is (= false
                    (:has_more_values (chain-filter categories.name {})))))
@@ -636,13 +636,13 @@
                    (:has_more_values (chain-filter categories.name {} :limit Integer/MAX_VALUE))))))
 
         (testing "`true` if the values of a field exceeds our [[field-values/*total-max-length*]] limit"
-          (with-clean-field-values-for-field (mt/id :categories :name)
+          (with-clean-field-values-for-field! (mt/id :categories :name)
             (binding [field-values/*total-max-length* 10]
               (is (= true
                      (:has_more_values (chain-filter categories.name {}))))))))
 
       (testing "with contraints"
-        (with-clean-field-values-for-field (mt/id :categories :name)
+        (with-clean-field-values-for-field! (mt/id :categories :name)
           (testing "`false` for field has values less than [[field-values/*total-max-length*]] threshold"
             (is (= false
                    (:has_more_values (chain-filter categories.name {venues.price 4})))))
@@ -654,7 +654,7 @@
             (is (= false
                    (:has_more_values (chain-filter categories.name {venues.price 4} :limit Integer/MAX_VALUE))))))
 
-        (with-clean-field-values-for-field (mt/id :categories :name)
+        (with-clean-field-values-for-field! (mt/id :categories :name)
           (testing "`true` if the values of a field exceeds our [[field-values/*total-max-length*]] limit"
               (binding [field-values/*total-max-length* 10]
                 (is (= true
@@ -662,7 +662,7 @@
 
     (testing "for non-cached fields"
       (testing "with contraints"
-        (with-clean-field-values-for-field (mt/id :venues :latitude)
+        (with-clean-field-values-for-field! (mt/id :venues :latitude)
           (testing "`false` if we don't specify limit"
             (is (= false
                    (:has_more_values (chain-filter venues.latitude {venues.price 4})))))
diff --git a/test/metabase/models/params_test.clj b/test/metabase/models/params_test.clj
index 1259fad991c76b44144e2af5fc073f11a6248d99..5f983b0abf2e1dc798724ecdb0eb2677f46ae641 100644
--- a/test/metabase/models/params_test.clj
+++ b/test/metabase/models/params_test.clj
@@ -100,7 +100,7 @@
 
 (deftest hydate-param-fields-for-dashboard-test
   (testing "check that we can hydrate param_fields for a Dashboard"
-    (public-test/with-sharing-enabled-and-temp-dashcard-referencing :venues :id [dashboard]
+    (public-test/with-sharing-enabled-and-temp-dashcard-referencing! :venues :id [dashboard]
       (is (= {(mt/id :venues :id) {:id                 (mt/id :venues :id)
                                    :table_id           (mt/id :venues)
                                    :display_name       "ID"
diff --git a/test/metabase/models/pulse_channel_test.clj b/test/metabase/models/pulse_channel_test.clj
index 2a345a89997c3aa288d1892168829acfee71f3c3..6fadbdd55efd3730e2804fbeb3a429ab334a9093 100644
--- a/test/metabase/models/pulse_channel_test.clj
+++ b/test/metabase/models/pulse_channel_test.clj
@@ -431,7 +431,7 @@
 
 (defmacro with-send-pulse-setup!
   [& body]
-  `(mt/with-temp-scheduler
+  `(mt/with-temp-scheduler!
      (task/init! ::task.send-pulses/SendPulses)
      ~@body))
 
diff --git a/test/metabase/models/pulse_test.clj b/test/metabase/models/pulse_test.clj
index f1a4a71b95c42508ba6df366d0d540dcc1be9246..9cc57a65d1a2258aa1fddf0c6c1dd31d70018787 100644
--- a/test/metabase/models/pulse_test.clj
+++ b/test/metabase/models/pulse_test.clj
@@ -434,7 +434,7 @@
 ;;; |                                   Pulse Collections Permissions Tests                                          |
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
-(defn do-with-pulse-in-collection [f]
+(defn do-with-pulse-in-collection! [f]
   (mt/with-non-admin-groups-no-root-collection-perms
     (mt/with-temp [Collection collection {}
                    Pulse      pulse {:collection_id (u/the-id collection)}
@@ -446,11 +446,11 @@
                    PulseCard  _ {:pulse_id (u/the-id pulse) :card_id (u/the-id card)}]
       (f db collection pulse card))))
 
-(defmacro with-pulse-in-collection
+(defmacro with-pulse-in-collection!
   "Execute `body` with a temporary Pulse, in a Collection, containing a single Card."
   {:style/indent :defn}
   [[db-binding collection-binding pulse-binding card-binding] & body]
-  `(do-with-pulse-in-collection
+  `(do-with-pulse-in-collection!
     (fn [~(or db-binding '_) ~(or collection-binding '_) ~(or pulse-binding '_) ~(or card-binding '_)]
       ~@body)))
 
@@ -477,7 +477,7 @@
 ;;; |                         Dashboard Subscription Collections Permissions Tests                                   |
 ;;; +----------------------------------------------------------------------------------------------------------------+
 
-(defn- do-with-dashboard-subscription-in-collection [f]
+(defn- do-with-dashboard-subscription-in-collection! [f]
   (mt/with-non-admin-groups-no-root-collection-perms
     (mt/with-temp [Collection collection {}
                    Dashboard  dashboard {:collection_id (u/the-id collection)}
@@ -487,16 +487,16 @@
                    Database   db        {:engine :h2}]
       (f db collection dashboard pulse))))
 
-(defmacro with-dashboard-subscription-in-collection
+(defmacro with-dashboard-subscription-in-collection!
   "Execute `body` with a temporary Dashboard Subscription created by :rasta (a non-admin) for a Dashboard in a Collection"
   {:style/indent 1}
   [[db-binding collection-binding dashboard-binding subscription-binding] & body]
-  `(do-with-dashboard-subscription-in-collection
+  `(do-with-dashboard-subscription-in-collection!
     (fn [~(or db-binding '_) ~(or collection-binding '_) ~(or dashboard-binding '_) ~(or subscription-binding '_)]
       ~@body)))
 
 (deftest dashboard-subscription-permissions-test
-  (with-dashboard-subscription-in-collection [_ collection dashboard subscription]
+  (with-dashboard-subscription-in-collection! [_ collection dashboard subscription]
     (testing "An admin has read and write access to any dashboard subscription"
       (binding [api/*is-superuser?* true]
         (is (mi/can-read? subscription))
diff --git a/test/metabase/models/setting_test.clj b/test/metabase/models/setting_test.clj
index 9a080233cc3fb72cdecc97bceab48b35f5f07c89..908957afa5614000cecfee3b50776748ace14d57 100644
--- a/test/metabase/models/setting_test.clj
+++ b/test/metabase/models/setting_test.clj
@@ -317,8 +317,8 @@
 ;; these tests are to check that settings get returned with the correct information; these functions are what feed
 ;; into the API
 
-(defn- user-facing-info-with-db-and-env-var-values [setting db-value env-var-value]
-  (tu/do-with-temporary-setting-value setting db-value
+(defn- user-facing-info-with-db-and-env-var-values! [setting db-value env-var-value]
+  (tu/do-with-temporary-setting-value! setting db-value
     (fn []
       (tu/do-with-temp-env-var-value!
        (setting/setting-env-map-name (keyword setting))
@@ -330,35 +330,35 @@
 (deftest user-facing-info-test
   (testing "user-facing info w/ no db value, no env var value, no default value"
     (is (= {:value nil, :is_env_setting false, :env_name "MB_TEST_SETTING_1", :default nil}
-           (user-facing-info-with-db-and-env-var-values :test-setting-1 nil nil))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-1 nil nil))))
 
   (testing "user-facing info w/ no db value, no env var value, default value"
     (is (= {:value nil, :is_env_setting false, :env_name "MB_TEST_SETTING_2", :default "[Default Value]"}
-           (user-facing-info-with-db-and-env-var-values :test-setting-2 nil nil))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-2 nil nil))))
 
   (testing "user-facing info w/ no db value, env var value, no default value -- shouldn't leak env var value"
     (is (= {:value nil, :is_env_setting true, :env_name "MB_TEST_SETTING_1", :default "Using value of env var $MB_TEST_SETTING_1"}
-           (user-facing-info-with-db-and-env-var-values :test-setting-1 nil "TOUCANS"))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-1 nil "TOUCANS"))))
 
   (testing "user-facing info w/ no db value, env var value, default value"
     (is (= {:value nil, :is_env_setting true, :env_name "MB_TEST_SETTING_2", :default "Using value of env var $MB_TEST_SETTING_2"}
-           (user-facing-info-with-db-and-env-var-values :test-setting-2 nil "TOUCANS"))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-2 nil "TOUCANS"))))
 
   (testing "user-facing info w/ db value, no env var value, no default value"
     (is (= {:value "WOW", :is_env_setting false, :env_name "MB_TEST_SETTING_1", :default nil}
-           (user-facing-info-with-db-and-env-var-values :test-setting-1 "WOW" nil))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-1 "WOW" nil))))
 
   (testing "user-facing info w/ db value, no env var value, default value"
     (is (= {:value "WOW", :is_env_setting false, :env_name "MB_TEST_SETTING_2", :default "[Default Value]"}
-           (user-facing-info-with-db-and-env-var-values :test-setting-2 "WOW" nil))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-2 "WOW" nil))))
 
   (testing "user-facing info w/ db value, env var value, no default value -- the env var should take precedence over the db value, but should be obfuscated"
     (is (= {:value nil, :is_env_setting true, :env_name "MB_TEST_SETTING_1", :default "Using value of env var $MB_TEST_SETTING_1"}
-           (user-facing-info-with-db-and-env-var-values :test-setting-1 "WOW" "ENV VAR"))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-1 "WOW" "ENV VAR"))))
 
   (testing "user-facing info w/ db value, env var value, default value -- env var should take precedence over default, but should be obfuscated"
     (is (= {:value nil, :is_env_setting true, :env_name "MB_TEST_SETTING_2", :default "Using value of env var $MB_TEST_SETTING_2"}
-           (user-facing-info-with-db-and-env-var-values :test-setting-2 "WOW" "ENV VAR")))))
+           (user-facing-info-with-db-and-env-var-values! :test-setting-2 "WOW" "ENV VAR")))))
 
 (deftest writable-settings-test
   (testing `setting/writable-settings
@@ -416,7 +416,7 @@
 (deftest validate-description-test
   (testing "Validate setting description with i18n string"
     (mt/with-test-user :crowberto
-      (mt/with-mock-i18n-bundles {"zz" {:messages {"Test setting - with i18n" "TEST SETTING - WITH I18N"}}}
+      (mt/with-mock-i18n-bundles! {"zz" {:messages {"Test setting - with i18n" "TEST SETTING - WITH I18N"}}}
         (letfn [(description []
                   (some (fn [{:keys [key description]}]
                           (when (= :test-i18n-setting key)
@@ -434,7 +434,7 @@
 (deftest dynamic-description-test
   (testing "Descriptions with i18n string should update if it depends on another setting's value."
     (mt/with-test-user :crowberto
-      (mt/with-mock-i18n-bundles {"zz" {:messages {"Test setting - with i18n: {0}" "TEST SETTING - WITH I18N: {0}"}}}
+      (mt/with-mock-i18n-bundles! {"zz" {:messages {"Test setting - with i18n: {0}" "TEST SETTING - WITH I18N: {0}"}}}
         (letfn [(description []
                   (some (fn [{:keys [key description]}]
                           (when (= :test-dynamic-i18n-setting key)
@@ -457,7 +457,7 @@
 
 (deftest boolean-setting-user-facing-info-test
   (is (= {:value nil, :is_env_setting false, :env_name "MB_TEST_BOOLEAN_SETTING", :default nil}
-         (user-facing-info-with-db-and-env-var-values :test-boolean-setting nil nil))))
+         (user-facing-info-with-db-and-env-var-values! :test-boolean-setting nil nil))))
 
 (deftest boolean-setting-env-vars-test
   (testing "values set by env vars should never be shown to the User"
@@ -466,11 +466,11 @@
                     :env_name       "MB_TEST_BOOLEAN_SETTING"
                     :default        "Using value of env var $MB_TEST_BOOLEAN_SETTING"}]
       (is (= expected
-             (user-facing-info-with-db-and-env-var-values :test-boolean-setting nil "true")))
+             (user-facing-info-with-db-and-env-var-values! :test-boolean-setting nil "true")))
 
       (testing "env var values should be case-insensitive"
         (is (= expected
-               (user-facing-info-with-db-and-env-var-values :test-boolean-setting nil "TRUE"))))))
+               (user-facing-info-with-db-and-env-var-values! :test-boolean-setting nil "TRUE"))))))
 
   (testing "if value isn't true / false"
     (testing "getter should throw exception"
@@ -484,7 +484,7 @@
               :is_env_setting true
               :env_name       "MB_TEST_BOOLEAN_SETTING"
               :default        "Using value of env var $MB_TEST_BOOLEAN_SETTING"}
-             (user-facing-info-with-db-and-env-var-values :test-boolean-setting nil "X"))))))
+             (user-facing-info-with-db-and-env-var-values! :test-boolean-setting nil "X"))))))
 
 (deftest set-boolean-setting-test
   (testing "should be able to set value with a string..."
@@ -511,18 +511,18 @@
 
 ;;; -------------------------------------------------- CSV Settings --------------------------------------------------
 
-(defn- fetch-csv-setting-value [v]
+(defn- fetch-csv-setting-value! [v]
   (with-redefs [setting/db-or-cache-value (constantly v)]
     (test-csv-setting)))
 
 (deftest get-csv-setting-test
   (testing "should be able to fetch a simple CSV setting"
     (is (= ["A" "B" "C"]
-           (fetch-csv-setting-value "A,B,C"))))
+           (fetch-csv-setting-value! "A,B,C"))))
 
   (testing "should also work if there are quoted values that include commas in them"
     (is  (= ["A" "B" "C1,C2" "ddd"]
-            (fetch-csv-setting-value "A,B,\"C1,C2\",ddd")))))
+            (fetch-csv-setting-value! "A,B,\"C1,C2\",ddd")))))
 
 (defn- set-and-fetch-csv-setting-value! [v]
   (test-csv-setting! v)
diff --git a/test/metabase/models/user_test.clj b/test/metabase/models/user_test.clj
index ee0faedc14167087c260dc66334e73a325a1a6de..a43833866a40e978dc3fb72a43148e02ff93f5bf 100644
--- a/test/metabase/models/user_test.clj
+++ b/test/metabase/models/user_test.clj
@@ -195,7 +195,7 @@
  (testing "if sso enabled and password login is disabled, email should send a link to sso login"
    (mt/with-premium-features #{:disable-password-login}
      (mt/with-temporary-setting-values [enable-password-login false]
-       (ldap.test/with-ldap-server
+       (ldap.test/with-ldap-server!
          (invite-user-accept-and-check-inboxes! :invitor default-invitor , :accept-invite? false)
          (is (seq (mt/regex-email-bodies #"/auth/login"))))))))
 
diff --git a/test/metabase/public_settings_test.clj b/test/metabase/public_settings_test.clj
index 1d819f140f480aa7373381d2d2e62c14b9bd8e41..ea8a55be7acccc5e519fcddcb4ef93145f0edb6c 100644
--- a/test/metabase/public_settings_test.clj
+++ b/test/metabase/public_settings_test.clj
@@ -96,14 +96,14 @@
              (public-settings/redirect-all-requests-to-https))))))
 
 (deftest translate-public-setting
-  (mt/with-mock-i18n-bundles {"zz" {:messages {"Host" "HOST"}}}
+  (mt/with-mock-i18n-bundles! {"zz" {:messages {"Host" "HOST"}}}
     (mt/with-user-locale "zz"
       (is (= "HOST"
              (str (get-in (setting/user-readable-values-map #{:public})
                           [:engines :postgres :details-fields 0 :display-name])))))))
 
 (deftest tru-translates
-  (mt/with-mock-i18n-bundles {"zz" {:messages {"Host" "HOST"}}}
+  (mt/with-mock-i18n-bundles! {"zz" {:messages {"Host" "HOST"}}}
     (mt/with-user-locale "zz"
       (is (= true
              (= (i18n/locale "zz")
diff --git a/test/metabase/pulse/pulse_integration_test.clj b/test/metabase/pulse/pulse_integration_test.clj
index 6bea4d617696b81e140b845eab0b76339ae2e365..be7c80b13e1b0009bbae22b56f6e9681f8fa4285 100644
--- a/test/metabase/pulse/pulse_integration_test.clj
+++ b/test/metabase/pulse/pulse_integration_test.clj
@@ -595,7 +595,7 @@
               (is (= ["IDENTIFIER" "Tax" "Grand Total" "Amount of Discount ($)" "Count" "Tax Rate"]
                      (attachment-name->cols (format "%s.csv" question-card-name)))))))))))
 
-(defn- run-pulse-and-return-scalars
+(defn- run-pulse-and-return-scalars!
   "Simulate sending the pulse email, get the html body of the response and return the scalar value of the card."
   [pulse]
   (mt/with-fake-inbox
@@ -654,9 +654,9 @@
           ;; First value is the scalar returned from card1 (specified "TAX" field directly in the query)
           ;; Second value is the scalar returned from card2 (scalar field specified only in viz-settings, not the query)
           (is (= ["2.07" "2.07"]
-                 (run-pulse-and-return-scalars pulse))))))))
+                 (run-pulse-and-return-scalars! pulse))))))))
 
-(defn- run-pulse-and-return-data-tables
+(defn- run-pulse-and-return-data-tables!
   "Run the pulse and return the sequence of inlined html tables as data. Empty tables will be [].
   If not pulse is sent, return `nil`."
   [pulse]
@@ -679,7 +679,7 @@
                  (mapv (comp (partial mapv (comp first :content)) :content))))
           data-tables)))))
 
-(defmacro with-skip-if-empty-pulse-result
+(defmacro ^:private with-skip-if-empty-pulse-result!
   "Provide a fixture that runs body using the provided pulse results (symbol), the value of `:skip_if_empty` for the
   pulse, and the queries for two cards. This enables a variety of cases to test the behavior of `:skip_if_empty` based
   on the presence or absence of card data."
@@ -715,7 +715,7 @@
                                                          :enabled      true}
                   PulseChannelRecipient ~'_ {:pulse_channel_id ~'pulse-channel-id
                                              :user_id          (mt/user->id :rasta)}]
-     (let [~result (run-pulse-and-return-data-tables ~'pulse)]
+     (let [~result (run-pulse-and-return-data-tables! ~'pulse)]
        ~@body)))
 
 (deftest skip-if-empty-test
@@ -732,23 +732,23 @@
         (testing "Cases for when 'Don't send if there aren't results is enabled' is false"
           (let [skip-if-empty? false]
             (testing "Everything has results"
-              (with-skip-if-empty-pulse-result [result skip-if-empty? query query2]
+              (with-skip-if-empty-pulse-result! [result skip-if-empty? query query2]
                 (testing "Show all the data"
                   (is (= [[["1" "2.07"] ["2" "6.1"]]
                           [["1" "2.07"] ["2" "6.1"] ["3" "2.9"]]]
                          result)))))
             (testing "Not everything has results"
-              (with-skip-if-empty-pulse-result [result skip-if-empty? query empty-query]
+              (with-skip-if-empty-pulse-result! [result skip-if-empty? query empty-query]
                 (testing "The second table is empty since there are no results"
                   (is (= [[["1" "2.07"] ["2" "6.1"]] []] result)))))
             (testing "No results"
-              (with-skip-if-empty-pulse-result [result skip-if-empty? empty-query empty-query]
+              (with-skip-if-empty-pulse-result! [result skip-if-empty? empty-query empty-query]
                 (testing "We send the email anyways, despite everything being empty due to no results"
                   (is (= [[] []] result)))))))
         (testing "Cases for when 'Don't send if there aren't results is enabled' is true"
           (let [skip-if-empty? true]
             (testing "Everything has results"
-              (with-skip-if-empty-pulse-result [result skip-if-empty? query query2]
+              (with-skip-if-empty-pulse-result! [result skip-if-empty? query query2]
                 (testing "When everything has results, we see everything"
                   (is (= 2 (count result))))
                 (testing "Show all the data"
@@ -756,13 +756,13 @@
                           [["1" "2.07"] ["2" "6.1"] ["3" "2.9"]]]
                          result)))))
             (testing "Not everything has results"
-              (with-skip-if-empty-pulse-result [result skip-if-empty? query empty-query]
+              (with-skip-if-empty-pulse-result! [result skip-if-empty? query empty-query]
                 (testing "We should only see a single data table in the result"
                   (is (= 1 (count result))))
                 (testing "The single result should contain the card with data in it"
                   (is (= [[["1" "2.07"] ["2" "6.1"]]] result)))))
             (testing "No results"
-              (with-skip-if-empty-pulse-result [result skip-if-empty? empty-query empty-query]
+              (with-skip-if-empty-pulse-result! [result skip-if-empty? empty-query empty-query]
                 (testing "Don't send a pulse if no results at all"
                   (is (nil? result)))))))))))
 
@@ -907,7 +907,7 @@
                      ["3" "2.19777989° W" "57.20190048° N"]
                      ["4" "89.67790222° W" "39.84410095° N"]
                      ["5" "54.65110016° E" "24.43300056° N"]]]
-                   (run-pulse-and-return-data-tables pulse)))))))))
+                   (run-pulse-and-return-data-tables! pulse)))))))))
 
 (deftest empty-dashboard-test
   (testing "A completely empty dashboard should still send an email"
diff --git a/test/metabase/pulse/render/body_test.clj b/test/metabase/pulse/render/body_test.clj
index 55f6f6d95d60e1f31bc796c2f02738013dfcc594..feab51385f70fff4a3c1ad467c710e71d7c6650d 100644
--- a/test/metabase/pulse/render/body_test.clj
+++ b/test/metabase/pulse/render/body_test.clj
@@ -480,7 +480,7 @@
                             {:key "January", :name "January", :enabled true}],
                            :funnel.order_dimension "CREATED_AT"}}]
         (mt/with-temp [Card {card-id :id} funnel-card]
-          (let [doc        (render.tu/render-card-as-hickory card-id)
+          (let [doc        (render.tu/render-card-as-hickory! card-id)
                 pulse-body (hik.s/select
                             (hik.s/class "pulse-body")
                             doc)]
@@ -522,7 +522,7 @@
                             {:key "purchase" :name "purchase" :enabled true}]}}]
         (mt/with-temp [:model/Card {card-id :id} funnel-card]
           (let [row-names      (into #{} (map first funnel-rows))
-                doc            (render.tu/render-card-as-hickory card-id)
+                doc            (render.tu/render-card-as-hickory! card-id)
                 section-labels (->> doc
                                     (hik.s/select (hik.s/tag :tspan))
                                     (mapv (comp first :content))
@@ -553,8 +553,8 @@
                                                                              :pie.show_total  false
                                                                              :pie.colors      colours}
                                                     :dataset_query          q}]
-          (let [card-a-doc (render.tu/render-card-as-hickory card-a-id)
-                card-b-doc (render.tu/render-card-as-hickory card-b-id)]
+          (let [card-a-doc (render.tu/render-card-as-hickory! card-a-id)
+                card-b-doc (render.tu/render-card-as-hickory! card-b-id)]
             ;; The test asserts that all 4 slices exist by seeing that each path element has the colour assigned to that category
             ;; we should expect to see each of the 4 (and only those 4) colours.
             ;; This is also true of the colours for the legend circle elements.
@@ -665,7 +665,7 @@
                                                              :dataset_query          q
                                                              :visualization_settings viz}]
             (testing "the render succeeds with unknown column settings keys"
-              (is (seq (render.tu/render-card-as-hickory card-id))))))))))
+              (is (seq (render.tu/render-card-as-hickory! card-id))))))))))
 
 (deftest trend-chart-renders-in-alerts-test
   (testing "Trend charts render successfully in Alerts. (#39854)"
@@ -682,7 +682,7 @@
         ;; Here, we simulate an Alert (NOT a subscription) by only providing a card and not mocking a DashCard.
         (mt/with-temp [:model/Card {card-id :id} {:display       :smartscalar
                                                   :dataset_query q}]
-          (let [doc       (render.tu/render-card-as-hickory card-id)
+          (let [doc       (render.tu/render-card-as-hickory! card-id)
                 span-text (->> doc
                                (hik.s/select (hik.s/tag :span))
                                (mapv (comp first :content))
@@ -731,7 +731,7 @@
                                                         :visualization_settings (viz "right")
                                                         :dataset_query          q}]
           (testing "Every series on the left correctly only renders left axis."
-            (let [doc                (render.tu/render-card-as-hickory left-card-id)
+            (let [doc                (render.tu/render-card-as-hickory! left-card-id)
                   axis-label-element (hik.s/select (content-selector ["Count"]) doc)
                   ;; the axis label has a :transform property like this: "matrix(0,1,-1,0,520,162.3245)"
                   ;; which is explained here: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform
@@ -747,7 +747,7 @@
               (is (= 1 (count axis-label-element)))
               (is (> 200 axis-y-transform))))
           (testing "Every series on the right correctly only renders right axis."
-            (let [doc                (render.tu/render-card-as-hickory right-card-id)
+            (let [doc                (render.tu/render-card-as-hickory! right-card-id)
                   axis-label-element (hik.s/select (content-selector ["Count"]) doc)
                   axis-y-transform   (-> axis-label-element
                                          (get-in [0 :attrs :transform])
@@ -776,8 +776,8 @@
                        :model/DashboardCardSeries _ {:dashboardcard_id dashcard-id
                                                      :card_id          card-b-id}]
           (mt/with-current-user (mt/user->id :rasta)
-            (let [card-doc               (render.tu/render-card-as-hickory card-a-id)
-                  dashcard-doc           (render.tu/render-dashcard-as-hickory dashcard-id)
+            (let [card-doc               (render.tu/render-card-as-hickory! card-a-id)
+                  dashcard-doc           (render.tu/render-dashcard-as-hickory! dashcard-id)
                   card-path-elements     (hik.s/select (hik.s/tag :path) card-doc)
                   card-paths-count       (count card-path-elements)
                   dashcard-path-elements (hik.s/select (hik.s/tag :path) dashcard-doc)
@@ -827,7 +827,7 @@
                        :model/DashboardCardSeries _ {:dashboardcard_id dashcard-id
                                                      :card_id          card-b-id}]
           (mt/with-current-user (mt/user->id :rasta)
-            (let [dashcard-doc           (render.tu/render-dashcard-as-hickory
+            (let [dashcard-doc           (render.tu/render-dashcard-as-hickory!
                                           dashcard-id
                                           [{:value     "2019-05"
                                             :id        "944bba5f"
@@ -885,9 +885,9 @@
                                                                :column_settings   {(format "[\"ref\",[\"field\",%d,null]]" (mt/id :orders :total))
                                                                                    {:column_title "CASH MONEY"}}}}]
        (mt/with-current-user (mt/user->id :rasta)
-         (let [card-doc        (render.tu/render-card-as-hickory card-id)
+         (let [card-doc        (render.tu/render-card-as-hickory! card-id)
                card-header-els (hik.s/select (hik.s/tag :th) card-doc)
-               dashcard-doc    (render.tu/render-dashcard-as-hickory dashcard-id)
+               dashcard-doc    (render.tu/render-dashcard-as-hickory! dashcard-id)
                dash-header-els (hik.s/select (hik.s/tag :th) dashcard-doc)
                card-header     ["ID" "User ID" "Product ID" "SUB CASH MONEY" "Tax"
                                 "Total" "Discount ($)" "Created At" "Quantity"]
@@ -920,7 +920,7 @@
                                                              :id            idx})
                                                           ids-to-colour))}}]
           (mt/with-current-user (mt/user->id :rasta)
-            (let [card-doc     (render.tu/render-card-as-hickory card-id)
+            (let [card-doc     (render.tu/render-card-as-hickory! card-id)
                   card-row-els (hik.s/select (hik.s/tag :tr) card-doc)]
               (is (= (mapv str ids-to-colour)
                      (keep
@@ -962,7 +962,7 @@
                                                              :id            idx})
                                                           ids-to-colour))}}]
           (mt/with-current-user (mt/user->id :rasta)
-            (let [card-doc     (render.tu/render-card-as-hickory card-id)
+            (let [card-doc     (render.tu/render-card-as-hickory! card-id)
                   card-row-els (hik.s/select (hik.s/tag :tr) card-doc)]
               (is (=  ids-to-colour
                      (keep
diff --git a/test/metabase/pulse/render/color_test.clj b/test/metabase/pulse/render/color_test.clj
index d5a9d617ef2862f64f19fc941d16d2f89d522a60..4f686d6a1f777e911841625eb6e534f213d9d70f 100644
--- a/test/metabase/pulse/render/color_test.clj
+++ b/test/metabase/pulse/render/color_test.clj
@@ -22,7 +22,7 @@
     }
    }")
 
-(defmacro ^:private with-test-js-engine
+(defmacro ^:private with-test-js-engine!
   "Setup a javascript engine with a stubbed script useful making sure `get-background-color` works independently from
   the real color picking script"
   [script & body]
@@ -33,7 +33,7 @@
 
 (deftest color-test
   (testing "The test script above should return red on even rows, green on odd rows"
-    (with-test-js-engine test-script
+    (with-test-js-engine! test-script
       (let [color-selector (color/make-color-selector {:cols [{:name "test"}]
                                                        :rows [[1] [2] [3] [4]]}
                                                       {"even" red, "odd" green})]
@@ -44,7 +44,7 @@
 (deftest convert-keywords-test
   (testing (str "Same test as above, but make sure we convert any keywords as keywords don't get converted to "
                 "strings automatically when passed to a JavaScript function")
-    (with-test-js-engine test-script
+    (with-test-js-engine! test-script
       (let [color-selector (color/make-color-selector {:cols [{:name "test"}]
                                                        :rows [[1] [2] [3] [4]]}
                                                       {:even red, :odd  green})]
diff --git a/test/metabase/pulse/render/table_test.clj b/test/metabase/pulse/render/table_test.clj
index be6609df2d725ec88a3c69844aa1cbec2d494c98..ef57cc335910d50012bade8e7363976c4e303b3f 100644
--- a/test/metabase/pulse/render/table_test.clj
+++ b/test/metabase/pulse/render/table_test.clj
@@ -129,7 +129,7 @@
                                                                                   :native   {:query q}}
                                                          :visualization_settings formatting-viz}]
         (testing "Custom column titles and column format settings are respected in render."
-          (let [doc     (render.tu/render-card-as-hickory card-id)
+          (let [doc     (render.tu/render-card-as-hickory! card-id)
                 row-els (hik.s/select (hik.s/tag :tr) doc)]
             (is (= [["Eh" "Bee" "Sea" "D" "E"]
                     ["10%" "9E3" "12/10/2022" "---0.12___" "0.667"]]
@@ -139,7 +139,7 @@
                                                                                 :date_separator  "-"
                                                                                 :date_abbreviate false}
                                                                 :type/Number   {:number_separators ",."}}]
-            (let [doc     (render.tu/render-card-as-hickory card-id)
+            (let [doc     (render.tu/render-card-as-hickory! card-id)
                   row-els (hik.s/select (hik.s/tag :tr) doc)]
               (is (= [["Eh" "Bee" "Sea" "D" "E"]
                       ["10%" "9E3" "12-10-2022" "---0,12___" "0,667"]]
@@ -165,7 +165,7 @@
                                                                            :type     :native
                                                                            :native   {:query q}}
                                                   :visualization_settings disabled-cols-viz}]
-          (let [doc     (render.tu/render-card-as-hickory card-id)
+          (let [doc     (render.tu/render-card-as-hickory! card-id)
                 row-els (hik.s/select (hik.s/tag :tr) doc)]
             (is (= [["B" "A"]
                     ["9,000" "0.1"]]
diff --git a/test/metabase/pulse/render/test_util.clj b/test/metabase/pulse/render/test_util.clj
index 35906cb5c0bb8800065ee9daac57bc7bf1472b8b..f67fd31dfaf50770704ffa9179ae70f01ba15696 100644
--- a/test/metabase/pulse/render/test_util.clj
+++ b/test/metabase/pulse/render/test_util.clj
@@ -10,7 +10,6 @@
    [hiccup.core :as hiccup]
    [hickory.core :as hik]
    [metabase.pulse.render :as render]
-   [metabase.pulse.render.body :as body]
    [metabase.pulse.render.image-bundle :as image-bundle]
    [metabase.pulse.render.js-svg :as js-svg]
    [metabase.pulse.util :as pu]
@@ -43,10 +42,6 @@
                                :max_value     9
                                :colors        ["#00ff00" "#0000ff"]}]}})
 
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;    render-as-hiccup
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
 (defn- node-attrs->map
   [^AbstractElement$ExtendedNamedNodeHashMap attrs]
   (when attrs
@@ -81,10 +76,10 @@
 
 (defn- edit-nodes
   "Returns a tree of nodes where any node that matches the `matcher` predicate is modified by the `edit-fn`.
-  A `matcher` function takes a zipper location `loc`, and should return `true` or `false`.
-  An `edit-fn` function takes a location `loc`, and returns a `loc`, which is easiest to modify with `zip/replace` or `zip/edit`.
+  A `matcher` function takes a zipper location `loc`, and should return `true` or `false`. An `edit-fn` function takes
+  a location `loc`, and returns a `loc`, which is easiest to modify with `zip/replace` or `zip/edit`.
 
-  See the `render-as-hiccup` function for an example usage of this function."
+  See the [[render-card-as-hickory!]] function for an example usage of this function."
   [tree matcher edit-fn]
   (loop [loc (hiccup-zip tree)]
     (if (zip/end? loc)
@@ -100,90 +95,18 @@
      (= tag :img)
      (str/starts-with? src "<svg"))))
 
-(defn- wrapped-children?
-  [loc]
-  (let [children (remove #(or (map? %) (string? %) (nil? %)) (rest (zip/node loc)))]
-    (and (every? seq? children)
-         (seq children))))
-
-(defn- wrapped-node?
-  [loc]
-  (let [node (zip/node loc)]
-    (and (= 1 (count node))
-         (seqable? node))))
-
 (def ^:private parse-svg #'js-svg/parse-svg-string)
 
 (defn- img-node->svg-node
-  "Modifies an intentionally malformed [:img {:src \"<svg>...</svg>\"}] node by parsing the svg string and
-  replacing the entire :img node with the `svg-content` hiccup tree. The malformed node is a result of the
-  `render-as-hiccup` function which redefines some functionality of the static-viz rendering pipeline. See
-  `render-as-hiccup` in this namespace for details."
+  "Modifies an intentionally malformed [:img {:src \"<svg>...</svg>\"}] node by parsing the svg string and replacing the
+  entire :img node with the `svg-content` hiccup tree. The malformed node is a result of the
+  [[render-card-as-hickory!]] function which redefines some functionality of the static-viz rendering pipeline. See
+  [[render-card-as-hickory!]] in this namespace for details."
   [loc]
   (let [[_ attrs] (zip/node loc)
         svg-content (-> attrs :src parse-svg document-tag-hiccup)]
     (zip/replace loc svg-content)))
 
-(defn- unwrap-children
-  [loc]
-  (let [node (zip/node loc)
-        k (first node)
-        attrs (if (map? (second node)) (second node) {})
-        children (remove #(or (map? %) (nil? %)) (rest (zip/node loc)))]
-    (zip/replace loc (into [k attrs] (first children)))))
-
-(defn- unwrap-node
-  [loc]
-  (zip/replace loc (first (zip/node loc))))
-
-(defn render-as-hiccup
-  "Renders a card-and-data map using the static-viz rendering pipeline, returning a hiccup tree from the html/SVG.
-  The input map requires:
-  `:card` which contains a map with the necessary keys to configure a visualization.
-  `:data` which is map that mimics the shape and settings returned by executing a card's :dataset_query with
-  [[metabase.query-processor/process-query]] + [[metabase.query-processor/userland-query]], and
-  the :process-viz-settings? middleware. For example:
-
-  ```
-  (let [card-id 1
-      {:keys [dataset_query] :as card} (t2/select-one card/Card :id card-id)
-      user                             (t2/select-one user/User)
-      query-results                    (binding [qp.perms/*card-id* nil]
-                                         (qp/process-query
-                                           (qp/userland-query
-                                            (-> dataset_query
-                                               (assoc-in [:middleware :process-viz-settings?] true))
-                                            {:executed-by (:id user)
-                                             :context     :pulse
-                                             :card-id     card-id})))]
-  {:data query-results})
-  ```
-
-  The intent of these test utils, however, is to avoid the need to run the query processor like this, and just
-  work with the data directly.
-
-  Rendering the result as a hiccup tree is acheived by redefining 2 functions:
-
-  [[metabase.pulse.render.js-svg/svg-string->bytes]] normally takes an svg-string from the static-viz js (via gaalvm)
-  and returns PNG bytes. It is redefined to pass the svg-string without any encoding.
-
-  [[metabase.pulse.render.image-bundle/make-image-bundle]] normally takes a render-type (:inline :attachment) and
-  image-bytes, and returns a map containing the image as a base64 encoded string, suitable for an inline src string
-  to embed the PNG in an html img tag. It is redefined to pass the string unmodified.
-
-  This does result in a malformed img tag, because the src string ends up being an svg-string, but we immediately
-  extract and replace this tag with the `img-node->svg-node` function."
-  [{:keys [card data]}]
-  (with-redefs [js-svg/svg-string->bytes       identity
-                image-bundle/make-image-bundle (fn [_ s]
-                                                 {:image-src   s
-                                                  :render-type :inline})]
-    (let [content (-> (body/render (render/detect-pulse-chart-type card nil data) :inline "UTC" card nil data)
-                      :content)]
-      (-> content
-          (edit-nodes img-node-with-svg? img-node->svg-node)          ;; replace the :img tag with its parsed SVG.
-          (edit-nodes wrapped-node? unwrap-node)             ;; eg: ([:div "content"]) -> [:div "content"]
-          (edit-nodes wrapped-children? unwrap-children))))) ;; eg: [:tr ([:td 1] [:td 2])] -> [:tr [:td 1] [:td 2]]
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;   verification-utils
@@ -199,19 +122,10 @@
        (tree-seq #(and (seqable? %) (not (map? %))) (fn [s] (remove #(or (map? %) (string? %) (keyword? %)) s)))
        (filter #(and (string? (last %)) (str/includes? (last %) text)))))
 
-(defn nodes-with-exact-text
-  "Returns a list of nodes from the `tree` that exactly matches text `text` as the last entry of the node.
-  The tree is assumed to be a valid hiccup-style tree.
-
-  `(nodes-with-text \"the text\" [:svg [:tspan [:text \"the text\"]]]) -> ([:text \"the text\"])`"
-  [tree text]
-  (->> tree
-       (tree-seq #(and (seqable? %) (not (map? %))) (fn [s] (remove #(or (map? %) (string? %) (keyword? %)) s)))
-       (filter #(and (string? (last %)) (= (last %) text)))))
-
 (defn nodes-with-tag
-  "Returns a list of nodes from the `tree` that contain an exact match of `tag` as the first entry of the node.
-  The tag can be any valid hiccup key, but will often be a keyword or a string. The tree is assumed to be a valid hiccup-style tree.
+  "Returns a list of nodes from the `tree` that contain an exact match of `tag` as the first entry of the node. The tag
+  can be any valid hiccup key, but will often be a keyword or a string. The tree is assumed to be a valid hiccup-style
+  tree.
 
   `(nodes-with-tag :tspan [:svg [:tspan [:text \"the text\"]]]) -> ([:tspan [:text \"the text\"]])`"
   [tree tag]
@@ -219,18 +133,10 @@
        (tree-seq #(and (seqable? %) (not (map? %))) (fn [s] (remove #(or (map? %) (string? %) (keyword? %)) s)))
        (filter #(#{tag} (first %)))))
 
-(defn remove-attrs
-  [tree]
-  (let [matcher (fn [loc] (map? (second (zip/node loc))))
-        edit-fn (fn [loc]
-                  (let [[k _m & c] (zip/node loc)]
-                    (zip/replace loc (into [k] c))))]
-    (edit-nodes tree matcher edit-fn)))
-
-(defn render-card-as-hickory
-  "Render the card with `card-id` using the static-viz rendering pipeline as a hickory data structure.
-  Redefines some internal rendering functions to keep svg from being rendered into a png.
-  Functions from `hickory.select` can be used on the output of this function and are particularly useful for writing test assertions."
+(defn render-card-as-hickory!
+  "Render the card with `card-id` using the static-viz rendering pipeline as a hickory data structure. Redefines some
+  internal rendering functions to keep svg from being rendered into a png. Functions from `hickory.select` can be used
+  on the output of this function and are particularly useful for writing test assertions."
   [card-id]
   (let [{:keys [visualization_settings] :as card} (t2/select-one :model/Card :id card-id)
         query                                     (qp.card/query-for-card card [] nil {:process-viz-settings? true} nil)
@@ -247,11 +153,11 @@
             hik/parse
             hik/as-hickory)))))
 
-(defn render-dashcard-as-hickory
-  "Render the dashcard with `dashcard-id` using the static-viz rendering pipeline as a hickory data structure.
-  Redefines some internal rendering functions to keep svg from being rendered into a png.
-  Functions from `hickory.select` can be used on the output of this function and are particularly useful for writing test assertions."
-  ([dashcard-id] (render-dashcard-as-hickory dashcard-id []))
+(defn render-dashcard-as-hickory!
+  "Render the dashcard with `dashcard-id` using the static-viz rendering pipeline as a hickory data structure. Redefines
+  some internal rendering functions to keep svg from being rendered into a png. Functions from `hickory.select` can be
+  used on the output of this function and are particularly useful for writing test assertions."
+  ([dashcard-id] (render-dashcard-as-hickory! dashcard-id []))
   ([dashcard-id parameters]
    (let [dashcard                  (t2/select-one :model/DashboardCard :id dashcard-id)
          card                      (t2/select-one :model/Card :id (:card_id dashcard))
diff --git a/test/metabase/pulse/test_util.clj b/test/metabase/pulse/test_util.clj
index a75bc38862b217f9b068d2d6d4e2547ea7d141a4..d5725589f9db22fde8654be0de75ed208775dc95 100644
--- a/test/metabase/pulse/test_util.clj
+++ b/test/metabase/pulse/test_util.clj
@@ -61,26 +61,23 @@
   [data]
   (walk/postwalk identity data))
 
-(defn do-with-site-url
+(defn do-with-site-url!
   [f]
   (mt/with-temporary-setting-values [site-url "https://metabase.com/testmb"]
     (f)))
 
-(defmacro email-test-setup
+(defmacro email-test-setup!
   "Macro that ensures test-data is present and will use a fake inbox for emails"
   [& body]
   `(mt/with-fake-inbox
-     (do-with-site-url (fn [] ~@body))))
+     (do-with-site-url! (fn [] ~@body))))
 
 (defmacro slack-test-setup!
   "Macro that ensures test-data is present and disables sending of all notifications"
   [& body]
-  `(with-redefs [channel/send!       (fn [& _args#]
-                                       :noop)
+  `(with-redefs [channel/send!       (constantly :noop)
                  slack/files-channel (constantly "FOO")]
-     (do-with-site-url (fn [] ~@body))))
-
-(def ^:dynamic *channel-messages* nil)
+     (do-with-site-url! (fn [] ~@body))))
 
 (defn do-with-captured-channel-send-messages!
   [thunk]
diff --git a/test/metabase/pulse_test.clj b/test/metabase/pulse_test.clj
index 724a065a35918857ec908ac13656755b765c7fd3..7698ca629eaeb32af41b6e327d58791bf390a0cb 100644
--- a/test/metabase/pulse_test.clj
+++ b/test/metabase/pulse_test.clj
@@ -691,7 +691,7 @@
                                                       :details  {:emails ["nonuser@metabase.com"]}}
                    PulseChannelRecipient _ {:user_id          (pulse.test-util/rasta-id)
                                             :pulse_channel_id pc-id}]
-      (pulse.test-util/email-test-setup
+      (pulse.test-util/email-test-setup!
        (metabase.pulse/send-pulse! (pulse/retrieve-notification pulse-id))
        (is (mt/received-email-body? :rasta #"Manage your subscriptions"))
        (is (mt/received-email-body? "nonuser@metabase.com" #"Unsubscribe"))))))
diff --git a/test/metabase/query_processor/middleware/cache_test.clj b/test/metabase/query_processor/middleware/cache_test.clj
index 73f5115667219c07b4d95e86dc771cb70ace19c2..f47713def73cab57f475d78656add4b7af1a749e 100644
--- a/test/metabase/query_processor/middleware/cache_test.clj
+++ b/test/metabase/query_processor/middleware/cache_test.clj
@@ -89,7 +89,7 @@
         (log/tracef "Purge old entries --> store: %s" (pretty/pretty this))
         (a/>!! purge-chan ::purge)))))
 
-(defn do-with-mock-cache [f]
+(defn do-with-mock-cache! [f]
   (mt/with-open-channels [save-chan  (a/chan 10)
                           purge-chan (a/chan 10)]
     (mt/with-temporary-setting-values [query-caching-max-ttl 60]
@@ -108,8 +108,8 @@
                                                      (throw e))))]
             (f {:save-chan save-chan, :purge-chan purge-chan})))))))
 
-(defmacro with-mock-cache [[& bindings] & body]
-  `(do-with-mock-cache (fn [{:keys [~@bindings]}] ~@body)))
+(defmacro with-mock-cache! [[& bindings] & body]
+  `(do-with-mock-cache! (fn [{:keys [~@bindings]}] ~@body)))
 
 (def ^:private ^:dynamic ^Long *query-execution-delay-ms* 10)
 
@@ -160,7 +160,7 @@
 
 (deftest is-cacheable-test
   (testing "something is-cacheable? if it includes `:cache-strategy` and it is not `:nocache`"
-    (with-mock-cache []
+    (with-mock-cache! []
       (doseq [[cache-strategy expected] {(ttl-strategy)   true
                                          {:type :nocache} false
                                          nil              false}]
@@ -174,13 +174,13 @@
 
 (deftest empty-cache-test
   (testing "if there's nothing in the cache, cached results should *not* be returned"
-    (with-mock-cache []
+    (with-mock-cache! []
       (is (= :not-cached
              (run-query))))))
 
 (deftest return-cached-results-test
   (testing "if we run the query twice, the second run should return cached results"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (is (= true
              (cacheable?)))
       (run-query)
@@ -190,7 +190,7 @@
 
 (deftest expired-results-test
   (testing "If cached resutls are past their TTL, the cached results shouldn't be returned"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (run-query :cache-strategy (assoc (ttl-strategy) :multiplier 0.1))
       (mt/wait-for-result save-chan)
       (Thread/sleep 200)
@@ -199,7 +199,7 @@
 
 (deftest ignore-valid-results-when-caching-is-disabled-test
   (testing "if caching is disabled then cache shouldn't be used even if there's something valid in there"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (run-query)
       (mt/wait-for-result save-chan)
       (is (= false
@@ -209,7 +209,7 @@
 
 (deftest max-kb-test
   (testing "check that `query-caching-max-kb` is respected and queries aren't cached if they're past the threshold"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (mt/with-temporary-setting-values [query-caching-max-kb 0]
         (run-query)
         (let [result (mt/wait-for-result save-chan)]
@@ -225,7 +225,7 @@
                 "then wait 200 ms, and run `:def`. This should trigger the cache flush for entries past "
                 "`:max-ttl`; and the cached entry for `:abc` should be deleted. Running `:abc` a subsequent time "
                 "should not return cached results")
-    (with-mock-cache [purge-chan]
+    (with-mock-cache! [purge-chan]
       (mt/with-temporary-setting-values [query-caching-max-ttl 0.1]
         (run-query)
         (mt/wait-for-result purge-chan)
@@ -237,7 +237,7 @@
 
 (deftest ignore-cached-results-test
   (testing "check that :ignore-cached-results? in middleware is respected when returning results..."
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (run-query :middleware {:ignore-cached-results? false})
       (mt/wait-for-result save-chan)
       (is (= :not-cached
@@ -245,7 +245,7 @@
 
 (deftest ignore-cached-results-should-still-save-test
   (testing "...but if it's set those results should still be cached for next time."
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (is (= true (cacheable?)))
       (run-query :middleware {:ignore-cached-results? true})
       (mt/wait-for-result save-chan)
@@ -253,7 +253,7 @@
 
 (deftest min-ttl-test
   (testing "if the cache takes less than the min TTL to execute, it shouldn't be cached"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (binding [*query-caching-min-ttl* 1000]
         (run-query)
         (is (= :metabase.test.util.async/timed-out
@@ -262,7 +262,7 @@
                (run-query))))))
 
   (testing "...but if it takes *longer* than the min TTL, it should be cached"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (binding [*query-caching-min-ttl* 0.1]
         (run-query)
         (mt/wait-for-result save-chan)
@@ -271,7 +271,7 @@
 
 (deftest invalid-cache-entry-test
   (testing "We should handle invalid cache entries gracefully"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (run-query)
       (mt/wait-for-result save-chan)
       (let [query-hash (qp.util/query-hash (test-query nil))]
@@ -286,7 +286,7 @@
 
 (deftest metadata-test
   (testing "Verify that correct metadata about caching such as `:updated_at` and `:cached` come back with cached results."
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (mt/with-clock #t "2020-02-19T02:31:07.798Z[UTC]"
         (run-query)
         (mt/wait-for-result save-chan)
@@ -303,7 +303,7 @@
   (testing "Test that the caching middleware actually working in the context of the entire QP"
     (doseq [query [(mt/mbql-query venues {:order-by [[:asc $id]], :limit 5})
                    (mt/native-query {:query "SELECT * FROM VENUES ORDER BY ID ASC LIMIT 5;"})]]
-      (with-mock-cache [save-chan]
+      (with-mock-cache! [save-chan]
         (let [query (assoc query :cache-strategy (ttl-strategy))]
           (testing (format "query = %s" (pr-str query))
             (is (= true
@@ -346,7 +346,7 @@
         (let [query  (assoc (mt/mbql-query venues {:order-by [[:asc $id]] :limit 42})
                             :cache-strategy (assoc (ttl-strategy) :multiplier 5000))
               q-hash (qp.util/query-hash query)]
-          (with-mock-cache [save-chan]
+          (with-mock-cache! [save-chan]
             (t2/delete! Query :query_hash q-hash)
             (is (not (:cached (qp/process-query (qp/userland-query query)))))
             (a/alts!! [save-chan (a/timeout 200)]) ;; wait-for-result closes the channel
@@ -367,7 +367,7 @@
 
 (deftest insights-from-cache-test
   (testing "Insights should work on cached results (#12556)"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (let [query (-> checkins
                       (mt/mbql-query {:breakout    [!month.date]
                                       :aggregation [[:count]]})
@@ -391,7 +391,7 @@
 
 (deftest export-test
   (testing "Should be able to cache results streaming as an alternate download format, e.g. csv"
-    (with-mock-cache [save-chan]
+    (with-mock-cache! [save-chan]
       (let [query (assoc (mt/mbql-query venues {:order-by [[:asc $id]], :limit 6})
                          :cache-strategy (ttl-strategy))]
         (with-open [os (java.io.ByteArrayOutputStream.)]
@@ -431,7 +431,7 @@
       (is (= false
              (boolean (:cached normal-results)))
           "Query shouldn't be cached when running without mock cache in place")
-      (with-mock-cache [save-chan]
+      (with-mock-cache! [save-chan]
         (let [query (assoc query :cache-strategy (ttl-strategy))]
           (with-open [os (java.io.ByteArrayOutputStream.)]
             (qp.streaming/do-with-streaming-rff
@@ -468,7 +468,7 @@
     (mt/with-temp-copy-of-db
       (mt/with-no-data-perms-for-all-users!
        (mt/with-test-user :rasta
-         (with-mock-cache [save-chan]
+         (with-mock-cache! [save-chan]
            (letfn [(run-forbidden-query []
                      (qp/process-query (assoc (mt/mbql-query checkins {:aggregation [[:count]]})
                                               :cache-strategy (ttl-strategy))))]
diff --git a/test/metabase/query_processor/middleware/limit_test.clj b/test/metabase/query_processor/middleware/limit_test.clj
index e70f4a925dabe1e4538aeb8316f78e17283d6648..5f2b017e0278d28ef1d03fd96a161ebfdafb2b6b 100644
--- a/test/metabase/query_processor/middleware/limit_test.clj
+++ b/test/metabase/query_processor/middleware/limit_test.clj
@@ -9,7 +9,7 @@
 
 (def ^:private test-max-results 10000)
 
-(defn- limit [query]
+(defn- limit! [query]
   (with-redefs [qp.i/absolute-max-results test-max-results]
     (let [rff (limit/limit-result-rows query qp.reducible/default-rff)
           rf  (rff {})]
@@ -18,7 +18,7 @@
 (deftest limit-results-rows-test
   (testing "Apply to an infinite sequence and make sure it gets capped at `qp.i/absolute-max-results`"
     (is (= test-max-results
-           (-> (limit {:type :native}) mt/rows count)))))
+           (-> (limit! {:type :native}) mt/rows count)))))
 
 (deftest ^:parallel disable-max-results-test
   (testing "Apply `absolute-max-results` limit in the default case"
@@ -37,7 +37,7 @@
 (deftest max-results-constraint-test
   (testing "Apply an arbitrary max-results on the query and ensure our results size is appropriately constrained"
     (is (= 1234
-           (-> (limit {:constraints {:max-results 1234}
+           (-> (limit! {:constraints {:max-results 1234}
                        :type        :query
                        :query       {:aggregation [[:count]]}})
                mt/rows count)))))
@@ -47,7 +47,7 @@
     (let [query  {:constraints {:max-results 46}
                   :type        :query
                   :query       {}}
-          result (limit query)]
+          result (limit! query)]
       (is (= 46
              (-> result mt/rows count))
           "number of rows in results should match limit added by middleware")
diff --git a/test/metabase/query_processor/middleware/process_userland_query_test.clj b/test/metabase/query_processor/middleware/process_userland_query_test.clj
index bc3cbe1c0d813358cb1303664f75d4e1f592fd9f..2af35c2f3645327f91c5f2aebdf2ec6a4731d15d 100644
--- a/test/metabase/query_processor/middleware/process_userland_query_test.clj
+++ b/test/metabase/query_processor/middleware/process_userland_query_test.clj
@@ -22,7 +22,7 @@
 
 (set! *warn-on-reflection* true)
 
-(defn do-with-query-execution [query run]
+(defn do-with-query-execution! [query run]
   (mt/with-clock #t "2020-02-04T12:22-08:00[US/Pacific]"
     (let [original-hash (qp.util/query-hash query)
           result        (promise)]
@@ -37,7 +37,7 @@
                            ;; bug that is causing query hashes to get
                            ;; calculated in an inconsistent manner; check
                            ;; `:query` vs `:query-execution-query`
-                           (ex-info (format "%s: Query hashes are not equal!" `do-with-query-execution)
+                           (ex-info (format "%s: Query hashes are not equal!" `do-with-query-execution!)
                                     {:query                 query
                                      :original-hash         (some-> original-hash codecs/bytes->hex)
                                      :query-execution       query-execution
@@ -51,8 +51,8 @@
                (:hash qe)         (update :hash (fn [^bytes a-hash]
                                                   (some-> a-hash codecs/bytes->hex)))))))))))
 
-(defmacro with-query-execution {:style/indent 1} [[qe-result-binding query] & body]
-  `(do-with-query-execution ~query (fn [~qe-result-binding] ~@body)))
+(defmacro with-query-execution! {:style/indent 1} [[qe-result-binding query] & body]
+  `(do-with-query-execution! ~query (fn [~qe-result-binding] ~@body)))
 
 (defn- process-userland-query
   [query]
@@ -71,7 +71,7 @@
 
 (deftest success-test
   (let [query {:database 2, :type :query, :query {:source-table 26}}]
-    (with-query-execution [qe query]
+    (with-query-execution! [qe query]
       (is (= #t "2020-02-04T12:22:00.000-08:00[US/Pacific]"
              (t/zoned-date-time))
           "sanity check")
@@ -108,7 +108,7 @@
 
 (deftest failure-test
   (let [query {:database 2, :type :query, :query {:source-table 26}}]
-    (with-query-execution [qe query]
+    (with-query-execution! [qe query]
       (binding [qp.pipeline/*run* (fn [_query _rff]
                                     (throw (ex-info "Oops!" {:type qp.error-type/qp})))]
         (is (thrown-with-msg?
diff --git a/test/metabase/query_processor/persistence_test.clj b/test/metabase/query_processor/persistence_test.clj
index d9a957b4a697f3dc0cda01f8330e0fc662f104bd..37627a56427d9ad6973bdb5b3f0b213681ad9013 100644
--- a/test/metabase/query_processor/persistence_test.clj
+++ b/test/metabase/query_processor/persistence_test.clj
@@ -70,7 +70,7 @@
     (with-redefs [qp.i/absolute-max-results 3]
       (mt/test-drivers (mt/normal-drivers-with-feature :persist-models)
         (mt/dataset daily-bird-counts
-          (mt/with-persistence-enabled [persist-models!]
+          (mt/with-persistence-enabled! [persist-models!]
             (mt/with-temp [Card model {:type          :model
                                        :database_id   (mt/id)
                                        :query_type    :query
@@ -111,7 +111,7 @@
                                     [:native (mt/native-query
                                               (qp.compile/compile
                                                (mt/mbql-query products)))]]]
-          (mt/with-persistence-enabled [persist-models!]
+          (mt/with-persistence-enabled! [persist-models!]
             (mt/with-temp [Card model {:type          :model
                                        :database_id   (mt/id)
                                        :query_type    query-type
@@ -153,7 +153,7 @@
   (testing "Can use joins with persisted models (#28902)"
     (mt/test-drivers (mt/normal-drivers-with-feature :persist-models)
       (mt/dataset test-data
-        (mt/with-persistence-enabled [persist-models!]
+        (mt/with-persistence-enabled! [persist-models!]
           (mt/with-temp [Card model {:type        :model
                                      :database_id (mt/id)
                                      :query_type  :query
diff --git a/test/metabase/query_processor/streaming_test.clj b/test/metabase/query_processor/streaming_test.clj
index 2ce7d709d527b0b53438aec098d33e4d5f69cbb2..f80c72416139a9b3806dd986db260225fbc9bd6d 100644
--- a/test/metabase/query_processor/streaming_test.clj
+++ b/test/metabase/query_processor/streaming_test.clj
@@ -320,7 +320,7 @@
           user              (or user :rasta)]
       (mt/with-temporary-setting-values [enable-public-sharing true
                                          enable-embedding      true]
-        (embed-test/with-new-secret-key
+        (embed-test/with-new-secret-key!
           (t2.with-temp/with-temp [Card          card      (if viz-settings
                                                              (assoc card-defaults :visualization_settings viz-settings)
                                                              card-defaults)
diff --git a/test/metabase/query_processor/util/relative_datetime_test.clj b/test/metabase/query_processor/util/relative_datetime_test.clj
index 5b764637467ebf855853ef86dc07551324f2de25..63b6e3dc127f7996f5cad8d93f21fb6faab0f786 100644
--- a/test/metabase/query_processor/util/relative_datetime_test.clj
+++ b/test/metabase/query_processor/util/relative_datetime_test.clj
@@ -16,7 +16,7 @@
                         :params params})
       qp/process-query))
 
-(defn- getdate-vs-ss-ts-test-thunk-generator
+(defn- getdate-vs-ss-ts-test-thunk-generator!
   [unit value]
   (fn []
     ;; `with-redefs` forces use of `gettime()` in :relative-datetime transformation even for units gte or eq to :day.
@@ -45,7 +45,7 @@
   (mt/test-drivers (mt/normal-drivers-with-feature ::server-side-relative-datetime)
     (testing "Values of getdate() and server side generated timestamp are equal"
       (mt/with-metadata-provider (mt/id)
-        (let [test-thunk (getdate-vs-ss-ts-test-thunk-generator :week -1)]
+        (let [test-thunk (getdate-vs-ss-ts-test-thunk-generator! :week -1)]
           (doseq [tz-setter [qp.test-util/do-with-report-timezone-id!
                              test.tz/do-with-system-timezone-id!
                              qp.test-util/do-with-database-timezone-id
@@ -64,7 +64,7 @@
           (mt/with-database-timezone-id "America/Los_Angeles"
             (mt/with-report-timezone-id! "America/Los_Angeles"
               (mt/with-system-timezone-id! "Europe/Prague"
-                (let [test-thunk (getdate-vs-ss-ts-test-thunk-generator :week -1)]
+                (let [test-thunk (getdate-vs-ss-ts-test-thunk-generator! :week -1)]
                   (test-thunk))))))))))
 
 (deftest server-side-relative-datetime-various-units-test
@@ -73,7 +73,7 @@
       (testing "Value of server side generated timestamp matches the one from getdate() with multiple timezone settings"
         (doseq [unit [:day :week :month :quarter :year]
                 value [-30 0 7]
-                :let [test-thunk (getdate-vs-ss-ts-test-thunk-generator unit value)]]
+                :let [test-thunk (getdate-vs-ss-ts-test-thunk-generator! unit value)]]
           (test-thunk))))))
 
 (deftest server-side-relative-datetime-truncation-test
diff --git a/test/metabase/sample_data_test.clj b/test/metabase/sample_data_test.clj
index 5a65e2a378e07c587776331531fdaa80d839beab..fae4ac53efe9270b0f1fd8914a297b9206043f95 100644
--- a/test/metabase/sample_data_test.clj
+++ b/test/metabase/sample_data_test.clj
@@ -171,21 +171,21 @@
             (is (not (contains? (get-tables) "NEW_TABLE")))
             (jdbc/execute! conn-spec "CREATE TABLE NEW_TABLE (id INTEGER);")
             (is (contains? (get-tables) "NEW_TABLE"))
-           (testing "add column"
-             (is (not (contains? (show-columns-from "NEW_TABLE") "NEW_COLUMN")))
-             (jdbc/execute! conn-spec "ALTER TABLE NEW_TABLE ADD COLUMN NEW_COLUMN VARCHAR(255);")
-             (is (contains? (show-columns-from "NEW_TABLE") "NEW_COLUMN"))
-            (testing "remove column"
-              (jdbc/execute! conn-spec "ALTER TABLE NEW_TABLE DROP COLUMN NEW_COLUMN;")
+            (testing "add column"
               (is (not (contains? (show-columns-from "NEW_TABLE") "NEW_COLUMN")))
-             (testing "drop table"
-                 (jdbc/execute! conn-spec "DROP TABLE NEW_TABLE;")
-                 (is (not (contains? (get-tables) "NEW_TABLE"))))))))))))
+              (jdbc/execute! conn-spec "ALTER TABLE NEW_TABLE ADD COLUMN NEW_COLUMN VARCHAR(255);")
+              (is (contains? (show-columns-from "NEW_TABLE") "NEW_COLUMN"))
+              (testing "remove column"
+                (jdbc/execute! conn-spec "ALTER TABLE NEW_TABLE DROP COLUMN NEW_COLUMN;")
+                (is (not (contains? (show-columns-from "NEW_TABLE") "NEW_COLUMN")))
+                (testing "drop table"
+                  (jdbc/execute! conn-spec "DROP TABLE NEW_TABLE;")
+                  (is (not (contains? (get-tables) "NEW_TABLE"))))))))))))
 
 (deftest sample-database-schedule-sync-test
   (testing "Check that the sample database has scheduled sync jobs, just like a newly created database"
     (mt/with-temp-empty-app-db [_conn :h2]
-      (api.database-test/with-db-scheduler-setup
+      (api.database-test/with-db-scheduler-setup!
         (mdb/setup-db! :create-sample-content? true)
         (sample-data/extract-and-sync-sample-database!)
         (testing "Sense check: a newly created database should have sync jobs scheduled"
diff --git a/test/metabase/sync/analyze_test.clj b/test/metabase/sync/analyze_test.clj
index b0fb162c9cbfdb4f48c496ed7fc0cbd2ee27c77b..2ee9c05a93d9fdc81f7f7548bdb68e74efc06b52 100644
--- a/test/metabase/sync/analyze_test.clj
+++ b/test/metabase/sync/analyze_test.clj
@@ -18,7 +18,7 @@
    [metabase.sync.sync-metadata :as sync-metadata]
    [metabase.test :as mt]
    [metabase.test.data :as data]
-   [metabase.test.sync :as test.sync :refer [sync-survives-crash?]]
+   [metabase.test.sync :as test.sync :refer [sync-survives-crash?!]]
    [metabase.util :as u]
    [toucan2.core :as t2]
    [toucan2.tools.with-temp :as t2.with-temp]))
@@ -88,18 +88,18 @@
 
 (deftest survive-fingerprinting-errors
   (testing "Make sure we survive fingerprinting failing"
-    (sync-survives-crash? fingerprinters/fingerprinter)))
+    (sync-survives-crash?! fingerprinters/fingerprinter)))
 
 (deftest survive-classify-fields-errors
   (testing "Make sure we survive field classification failing"
-    (sync-survives-crash? classifiers.name/semantic-type-for-name-and-base-type)
-    (sync-survives-crash? classifiers.category/infer-is-category-or-list)
-    (sync-survives-crash? classifiers.no-preview-display/infer-no-preview-display)
-    (sync-survives-crash? classifiers.text-fingerprint/infer-semantic-type)))
+    (sync-survives-crash?! classifiers.name/semantic-type-for-name-and-base-type)
+    (sync-survives-crash?! classifiers.category/infer-is-category-or-list)
+    (sync-survives-crash?! classifiers.no-preview-display/infer-no-preview-display)
+    (sync-survives-crash?! classifiers.text-fingerprint/infer-semantic-type)))
 
 (deftest survive-classify-table-errors
   (testing "Make sure we survive table classification failing"
-    (sync-survives-crash? classifiers.name/infer-entity-type-by-name)))
+    (sync-survives-crash?! classifiers.name/infer-entity-type-by-name)))
 
 (defn- classified-semantic-type [values]
   (let [field (mi/instance Field {:base_type :type/Text})]
diff --git a/test/metabase/sync/sync_metadata/fields/sync_metadata_test.clj b/test/metabase/sync/sync_metadata/fields/sync_metadata_test.clj
index cec27b0f6aee197af6c58c8d497004531dd31c04..65b860ce4810a13a5c506287da38498cf063f16b 100644
--- a/test/metabase/sync/sync_metadata/fields/sync_metadata_test.clj
+++ b/test/metabase/sync/sync_metadata/fields/sync_metadata_test.clj
@@ -10,10 +10,10 @@
    [toucan2.tools.with-temp :as t2.with-temp]))
 
 
-(defn- updates-that-will-be-performed
+(defn- updates-that-will-be-performed!
   ([new-metadata-from-sync metadata-in-application-db]
    ;; use alphabetical field_order by default because the default, database, will update the position
-   (updates-that-will-be-performed new-metadata-from-sync metadata-in-application-db {:field_order :alphabetical}))
+   (updates-that-will-be-performed! new-metadata-from-sync metadata-in-application-db {:field_order :alphabetical}))
   ([new-metadata-from-sync metadata-in-application-db table]
    (t2.with-temp/with-temp [:model/Table table table]
      (let [update-operations (atom [])]
@@ -29,7 +29,7 @@
 (deftest database-type-changed-test
   (testing "test that if database-type changes we will update it in the DB"
     (is (= [["Field" 1 {:database_type "Integer"}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              "Integer"
              :base-type                  :type/Integer
@@ -57,7 +57,7 @@
   (testing "test that if database-position changes and table.field_order=database we will update the position too"
     (is (= [["Field" 1 {:database_position 1
                         :position          1}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             (merge default-metadata {:database-position 1})
             (merge default-metadata {:database-position 0
                                      :position          0
@@ -65,7 +65,7 @@
             {:field_order :database})))
     (testing "but not if the table's fields should not be sorted according to the database"
       (is (= [["Field" 1 {:database_position 1}]]
-             (updates-that-will-be-performed
+             (updates-that-will-be-performed!
               (merge default-metadata {:database-position 1})
               (merge default-metadata {:database-position 0
                                        :position          0
@@ -75,7 +75,7 @@
 (deftest database-required-changed-test
   (testing "test that if database-required changes we will update it in the DB"
     (is (= [["Field" 1 {:database_required false}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              "Integer"
              :base-type                  :type/Integer
@@ -94,7 +94,7 @@
 (deftest database-is-auto-increment-changed-test
   (testing "test that if database-required changes we will update it in the DB"
     (is (= [["Field" 1 {:database_is_auto_increment true}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              "Integer"
              :base-type                  :type/Integer
@@ -109,7 +109,7 @@
              :database-required          false
              :database-is-auto-increment false})))
     (is (= [["Field" 1 {:database_is_auto_increment false}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name              "My Field"
              :database-type     "Integer"
              :base-type         :type/Integer
@@ -127,7 +127,7 @@
 (deftest json-unfolding-test
   (testing "test that if json-unfolding changes the DB doesn't get updated"
     (is (= []
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              "Integer"
              :base-type                  :type/Integer
@@ -147,7 +147,7 @@
 (deftest no-op-test
   (testing "no changes should be made (i.e., no calls to `update!`) if nothing changes"
     (is (= []
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              "Integer"
              :base-type                  :type/Integer
@@ -167,13 +167,13 @@
 (deftest update-database-partitioned-test
   (testing "update from nil -> boolean"
     (is (= [["Field" 1 {:database_partitioned false}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             (merge default-metadata {:database-partitioned false})
             (merge default-metadata {:database-partitioned nil :id 1})))))
 
   (testing "flip the state"
     (is (= [["Field" 1 {:database_partitioned false}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             (merge default-metadata {:database-partitioned false})
             (merge default-metadata {:database-partitioned true :id 1}))))))
 
@@ -182,7 +182,7 @@
                 "to set a `nil` value in the DB -- this is against the rules -- we should set `NULL` instead. See "
                 "`TableMetadataField` schema.")
     (is (= [["Field" 1 {:database_type "NULL"}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              nil
              :base-type                  :type/Integer
@@ -202,7 +202,7 @@
   (testing (str "if `database-type` comes back as `nil` and was already saved in application DB as `NULL` no changes "
                 "should be made")
     (is (= []
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name                       "My Field"
              :database-type              nil
              :base-type                  :type/Integer
@@ -222,7 +222,7 @@
 (deftest dont-overwrite-semantic-type-test
   (testing "We should not override non-nil `semantic_type`s"
     (is (= []
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             {:name              "My Field"
              :database-type     "Integer"
              :base-type         :type/Integer
@@ -252,7 +252,7 @@
               :fingerprint_version 0
               :fingerprint         nil
               :semantic_type       nil}]]
-           (updates-that-will-be-performed
+           (updates-that-will-be-performed!
             (merge default-metadata
                    {:id             1
                     :base-type      :type/Text
diff --git a/test/metabase/sync/sync_metadata_test.clj b/test/metabase/sync/sync_metadata_test.clj
index f3f9d9928eb9508dad71348fbf6ddc884876f99c..517d22f01fa6ea0a1b41a704d3c64d5d03d36b9b 100644
--- a/test/metabase/sync/sync_metadata_test.clj
+++ b/test/metabase/sync/sync_metadata_test.clj
@@ -6,26 +6,26 @@
    [metabase.sync.sync-metadata.metabase-metadata :as metabase-metadata]
    [metabase.sync.sync-metadata.sync-timezone :as sync-tz]
    [metabase.sync.sync-metadata.tables :as sync-tables]
-   [metabase.test.sync :refer [sync-survives-crash?]]))
+   [metabase.test.sync :refer [sync-survives-crash?!]]))
 
 (deftest survive-metadata-errors
   (testing "Make sure we survive metadata sync failing"
-    (sync-survives-crash? metabase-metadata/sync-metabase-metadata!)))
+    (sync-survives-crash?! metabase-metadata/sync-metabase-metadata!)))
 
 (deftest survive-tz-errors
   (testing "Make sure we survive metadataDB timezone sync failing"
-    (sync-survives-crash? sync-tz/sync-timezone!)))
+    (sync-survives-crash?! sync-tz/sync-timezone!)))
 
 (deftest survive-fields-errors
   (testing "Make sure we survive field sync failing"
-    (sync-survives-crash? sync-fields/sync-and-update!)))
+    (sync-survives-crash?! sync-fields/sync-and-update!)))
 
 (deftest survive-table-errors
   (testing "Make sure we survive table sync failing"
-    (sync-survives-crash? sync-tables/create-or-reactivate-tables!)
-    (sync-survives-crash? sync-tables/retire-tables!)
-    (sync-survives-crash? sync-tables/update-tables-metadata-if-needed!)))
+    (sync-survives-crash?! sync-tables/create-or-reactivate-tables!)
+    (sync-survives-crash?! sync-tables/retire-tables!)
+    (sync-survives-crash?! sync-tables/update-tables-metadata-if-needed!)))
 
 (deftest survive-fk-errors
   (testing "Make sure we survive FK sync failing"
-    (sync-survives-crash? sync-fks/mark-fk!)))
+    (sync-survives-crash?! sync-fks/mark-fk!)))
diff --git a/test/metabase/task/persist_refresh_test.clj b/test/metabase/task/persist_refresh_test.clj
index 6f647afab7e6cdcd160a7392e2b209aff8c52173..1039734e1b2142da50c3bcf4b183473db34243a4 100644
--- a/test/metabase/task/persist_refresh_test.clj
+++ b/test/metabase/task/persist_refresh_test.clj
@@ -82,7 +82,7 @@
      (select-keys (task.persist-refresh/job-info-by-db-id) ids))))
 
 (deftest reschedule-refresh-test
-  (mt/with-temp-scheduler
+  (mt/with-temp-scheduler!
     (mt/with-temp [Database db-1 {:settings {:persist-models-enabled true}}
                    Database db-2 {:settings {:persist-models-enabled true}}]
       (#'task.persist-refresh/job-init!)
diff --git a/test/metabase/task/sync_databases_test.clj b/test/metabase/task/sync_databases_test.clj
index 7ec9d1d990ae0bc225acc5b517750d6912c9ba0a..3047b51659d492a56622e41305add34331d298ba 100644
--- a/test/metabase/task/sync_databases_test.clj
+++ b/test/metabase/task/sync_databases_test.clj
@@ -69,8 +69,8 @@
          (update :triggers (partial filter #(str/ends-with? (:key %) (str \. (u/the-id db-or-id)))))
          (dissoc :class)))))
 
-(defmacro with-scheduler-setup [& body]
-  `(tu/with-temp-scheduler
+(defmacro ^:private with-scheduler-setup! [& body]
+  `(tu/with-temp-scheduler!
      (#'task.sync-databases/job-init)
      ~@body))
 
@@ -93,7 +93,7 @@
 ;; Check that a newly created database automatically gets scheduled
 (deftest new-db-jobs-scheduled-test
   (is (= [sync-job fv-job]
-         (with-scheduler-setup
+         (with-scheduler-setup!
            (t2.with-temp/with-temp [Database database {:details {:let-user-control-scheduling true}}]
              (current-tasks-for-db database))))))
 
@@ -101,7 +101,7 @@
 (deftest custom-schedule-test
   (is (= [(assoc-in sync-job [:triggers 0 :cron-schedule] "0 30 4,16 * * ? *")
           (assoc-in fv-job   [:triggers 0 :cron-schedule] "0 15 10 ? * 6#3")]
-         (with-scheduler-setup
+         (with-scheduler-setup!
            (t2.with-temp/with-temp [Database database {:details                     {:let-user-control-scheduling true}
                                                        :metadata_sync_schedule      "0 30 4,16 * * ? *" ; 4:30 AM and PM daily
                                                        :cache_field_values_schedule "0 15 10 ? * 6#3"}] ; 10:15 on the 3rd Friday of the Month
@@ -111,7 +111,7 @@
 (deftest unschedule-deleted-database-test
   (is (= [(update sync-job :triggers empty)
           (update fv-job   :triggers empty)]
-         (with-scheduler-setup
+         (with-scheduler-setup!
            (t2.with-temp/with-temp [Database database {:details {:let-user-control-scheduling true}}]
              (t2/delete! Database :id (u/the-id database))
              (current-tasks-for-db database))))))
@@ -120,7 +120,7 @@
 (deftest schedule-change-test
   (is (= [(assoc-in sync-job [:triggers 0 :cron-schedule] "0 15 10 ? * MON-FRI")
           (assoc-in fv-job   [:triggers 0 :cron-schedule] "0 11 11 11 11 ?")]
-         (with-scheduler-setup
+         (with-scheduler-setup!
            (t2.with-temp/with-temp [Database database {:details {:let-user-control-scheduling true}}]
              (t2/update! Database (u/the-id database)
                          {:metadata_sync_schedule      "0 15 10 ? * MON-FRI" ; 10:15 AM every weekday
@@ -131,7 +131,7 @@
 (deftest schedule-changes-only-expected-test
   (is (= [sync-job
           (assoc-in fv-job [:triggers 0 :cron-schedule] "0 15 10 ? * MON-FRI")]
-         (with-scheduler-setup
+         (with-scheduler-setup!
            (t2.with-temp/with-temp [Database database {:details {:let-user-control-scheduling true}}]
              (t2/update! Database (u/the-id database)
                          {:cache_field_values_schedule "0 15 10 ? * MON-FRI"})
@@ -139,7 +139,7 @@
 
   (is (= [(assoc-in sync-job [:triggers 0 :cron-schedule] "0 15 10 ? * MON-FRI")
           fv-job]
-         (with-scheduler-setup
+         (with-scheduler-setup!
            (t2.with-temp/with-temp [Database database {:details {:let-user-control-scheduling true}}]
              (t2/update! Database (u/the-id database)
                          {:metadata_sync_schedule "0 15 10 ? * MON-FRI"})
@@ -177,7 +177,7 @@
 
 (deftest check-orphaned-jobs-removed-test
   (testing "jobs for orphaned databases are removed during sync run"
-    (with-scheduler-setup
+    (with-scheduler-setup!
       (doseq [sync-fn [#'task.sync-databases/update-field-values! #'task.sync-databases/sync-and-analyze-database!]]
         (testing (str sync-fn)
           (t2.with-temp/with-temp [Database database {:details {:let-user-control-scheduling true}}]
diff --git a/test/metabase/task_test.clj b/test/metabase/task_test.clj
index 76fbea1734de298438e862552739d7e29850a26c..528161ea747bb560388207b9bd10774efba4d359 100644
--- a/test/metabase/task_test.clj
+++ b/test/metabase/task_test.clj
@@ -47,15 +47,15 @@
       (cron/cron-schedule "0 0 6 * * ? *") ; at 6 AM every day
       (cron/with-misfire-handling-instruction-ignore-misfires)))))
 
-(defn- do-with-temp-scheduler-and-cleanup [f]
-  (mt/with-temp-scheduler
+(defn- do-with-temp-scheduler-and-cleanup! [f]
+  (mt/with-temp-scheduler!
     (try
       (f)
       (finally
         (task/delete-task! (.getKey (job)) (.getKey (trigger-1)))))))
 
-(defmacro ^:private with-temp-scheduler-and-cleanup [& body]
-  `(do-with-temp-scheduler-and-cleanup (fn [] ~@body)))
+(defmacro ^:private with-temp-scheduler-and-cleanup! [& body]
+  `(do-with-temp-scheduler-and-cleanup! (fn [] ~@body)))
 
 (defn- triggers []
   (set
@@ -65,7 +65,7 @@
 
 (deftest schedule-job-test
   (testing "can we schedule a job?"
-    (with-temp-scheduler-and-cleanup
+    (with-temp-scheduler-and-cleanup!
       (task/schedule-task! (job) (trigger-1))
       (is (= #{{:cron-expression     "0 0 * * * ? *"
                 :misfire-instruction CronTrigger/MISFIRE_INSTRUCTION_DO_NOTHING}}
@@ -73,7 +73,7 @@
 
 (deftest reschedule-job-test
   (testing "does scheduling a job a second time work without throwing errors?"
-    (with-temp-scheduler-and-cleanup
+    (with-temp-scheduler-and-cleanup!
       (task/schedule-task! (job) (trigger-1))
       (task/schedule-task! (job) (trigger-1))
       (is (= #{{:cron-expression     "0 0 * * * ? *"
@@ -82,7 +82,7 @@
 
 (deftest reschedule-and-replace-job-test
   (testing "does scheduling a job with a *new* trigger replace the original? (can we reschedule a job?)"
-    (with-temp-scheduler-and-cleanup
+    (with-temp-scheduler-and-cleanup!
       (task/schedule-task! (job) (trigger-1))
       (task/schedule-task! (job) (trigger-2))
       (is (= #{{:cron-expression     "0 0 6 * * ? *"
@@ -91,7 +91,7 @@
 
 (deftest scheduler-info-test
   (testing "Make sure scheduler-info doesn't explode and returns info in the general shape we expect"
-    (mt/with-temp-scheduler
+    (mt/with-temp-scheduler!
       (is (malli= [:map {:closed true}
                    [:scheduler [:+ :string]]
                    [:jobs      [:sequential
@@ -111,7 +111,7 @@
                   (task/scheduler-info))))))
 
 (deftest start-scheduler-no-op-with-env-var-test
-  (tu/do-with-unstarted-temp-scheduler
+  (tu/do-with-unstarted-temp-scheduler!
    (^:once fn* []
     (testing (format "task/start-scheduler! should no-op When MB_DISABLE_SCHEDULER is set")
       (testing "Sanity check"
diff --git a/test/metabase/test.clj b/test/metabase/test.clj
index ace9084b425030959c81bf720303a8fbdf572bba..4351db67c9b21933fcdc10d550f2c0af7b25560b 100644
--- a/test/metabase/test.clj
+++ b/test/metabase/test.clj
@@ -154,7 +154,7 @@
   client-real-response]
 
  [i18n.tu
-  with-mock-i18n-bundles
+  with-mock-i18n-bundles!
   with-user-locale]
 
  [initialize
@@ -214,7 +214,7 @@
   derecordize]
 
  [test.persistence
-  with-persistence-enabled]
+  with-persistence-enabled!]
 
  [test.users
   fetch-user
@@ -266,7 +266,7 @@
   with-temp-env-var-value!
   with-temp-dir
   with-temp-file
-  with-temp-scheduler
+  with-temp-scheduler!
   with-temp-vals-in-db
   with-temporary-setting-values
   with-temporary-raw-setting-values
diff --git a/test/metabase/test/data.clj b/test/metabase/test/data.clj
index 9874dd1356aa22f3358f921f094c2765732fd201..14d1f7c03de4d5a8f0ec0e3540ee1f6bf2e73487 100644
--- a/test/metabase/test/data.clj
+++ b/test/metabase/test/data.clj
@@ -266,6 +266,8 @@
   [& body]
   `(data.impl/do-with-temp-copy-of-db (^:once fn* [] ~@body)))
 
+;;; TODO FIXME -- rename this to `with-empty-h2-app-db`
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-empty-h2-app-db
   "Runs `body` under a new, blank, H2 application database (randomly named), in which all model tables have been
   created via Liquibase schema migrations. After `body` is finished, the original app DB bindings are restored.
diff --git a/test/metabase/test/data/impl/get_or_create.clj b/test/metabase/test/data/impl/get_or_create.clj
index 0369c8adb301f582d18295877fe0d3f256f9fbbd..fa702ab7c61ed660641b6c6936b35596e1841338 100644
--- a/test/metabase/test/data/impl/get_or_create.clj
+++ b/test/metabase/test/data/impl/get_or_create.clj
@@ -289,7 +289,7 @@
     ;;
     ;; require/resolve used here to avoid circular refs
     (if (driver/report-timezone)
-      ((requiring-resolve 'metabase.test.util/do-with-temporary-setting-value)
+      ((requiring-resolve 'metabase.test.util/do-with-temporary-setting-value!)
        :report-timezone nil
        thunk)
       (thunk))))
diff --git a/test/metabase/test/integrations/ldap.clj b/test/metabase/test/integrations/ldap.clj
index b9f76d03037276ff374b582ae93df6b67ad882ac..15a98c7caa355da1aac476c013ed877160d5106a 100644
--- a/test/metabase/test/integrations/ldap.clj
+++ b/test/metabase/test/integrations/ldap.clj
@@ -53,7 +53,7 @@
    (u/varargs Schema [(Schema/getDefaultStandardSchema)
                       (Schema/getSchema (u/varargs File [(io/file "test_resources/posixGroup.schema.ldif")]))])))
 
-(defn do-with-ldap-server
+(defn do-with-ldap-server!
   "Bind `*ldap-server*` and the relevant settings to an in-memory LDAP testing server and executes `f`."
   [f options]
   (binding [*ldap-server* (start-ldap-server! options)]
@@ -69,17 +69,17 @@
           (f)))
       (finally (.shutDown *ldap-server* true)))))
 
-(defmacro with-ldap-server
+(defmacro with-ldap-server!
   "Bind `*ldap-server*` and the relevant settings to an in-memory LDAP testing server and executes `body`."
   [& body]
-  `(do-with-ldap-server (fn [] ~@body)
-                        {:ldif-resource "ldap.ldif"
-                         :schema        (get-default-schema)}))
+  `(do-with-ldap-server! (fn [] ~@body)
+                         {:ldif-resource "ldap.ldif"
+                          :schema        (get-default-schema)}))
 
-(defmacro with-active-directory-ldap-server
+(defmacro with-active-directory-ldap-server!
   "Bind `*ldap-server*` and the relevant settings to an in-memory LDAP testing server and executes `body`.
   This version of the macro uses options that simulate an Active Directory server with memberOf attributes."
   [& body]
-  `(do-with-ldap-server (fn [] ~@body)
-                        {:ldif-resource "active_directory.ldif"
-                         :schema        nil}))
+  `(do-with-ldap-server! (fn [] ~@body)
+                         {:ldif-resource "active_directory.ldif"
+                          :schema        nil}))
diff --git a/test/metabase/test/persistence.clj b/test/metabase/test/persistence.clj
index d9e4e57ae1eaa98ee77b5ab4463791c38d06780e..6a61e072ebe3d2d5e389e5e48c04c3c17feb65a9 100644
--- a/test/metabase/test/persistence.clj
+++ b/test/metabase/test/persistence.clj
@@ -6,7 +6,7 @@
    [metabase.test.data :as data]
    [metabase.test.util :as tu]))
 
-(defn with-persistence-enabled*
+(defn do-with-persistence-enabled!
   [f]
   (tu/with-temporary-setting-values [:persisted-models-enabled true]
     (ddl.i/check-can-persist (data/db))
@@ -17,7 +17,7 @@
                         (var-get #'task.persist-refresh/dispatching-refresher)))]
       (f persist-fn))))
 
-(defmacro with-persistence-enabled
+(defmacro with-persistence-enabled!
   "Does the necessary setup to enable persistence on the current db. Provide a binding for a function to persist
   everything.
 
@@ -30,4 +30,4 @@
         (persist-models!))
         ...))"
   [[persist-fn-binding] & body]
-  `(with-persistence-enabled* (fn [~persist-fn-binding] ~@body)))
+  `(do-with-persistence-enabled! (fn [~persist-fn-binding] ~@body)))
diff --git a/test/metabase/test/sync.clj b/test/metabase/test/sync.clj
index 9e31e50c9ccaa35d71a79e66cffb3a099b7c34b9..efb2c9f87db5558827fd89bb6c24119bb2cdcc14 100644
--- a/test/metabase/test/sync.clj
+++ b/test/metabase/test/sync.clj
@@ -20,7 +20,7 @@
   [& _]
   (throw (Exception. "simulated exception")))
 
-(defmacro sync-survives-crash?
+(defmacro sync-survives-crash?!
   "Can sync process survive `f` crashing?"
   [f]
   `(is (= (sync-steps-run-to-completion)
diff --git a/test/metabase/test/util.clj b/test/metabase/test/util.clj
index 683ba02f43ed16f6fab041abefcb36f2b29608b6..a39fb311271016c7ae70280db9ab422b41015613 100644
--- a/test/metabase/test/util.clj
+++ b/test/metabase/test/util.clj
@@ -403,7 +403,7 @@
     (t2/delete! Setting :key setting-k))
   (setting.cache/restore-cache!))
 
-(defn do-with-temporary-setting-value
+(defn do-with-temporary-setting-value!
   "Temporarily set the value of the Setting named by keyword `setting-k` to `value` and execute `f`, then re-establish
   the original value. This works much the same way as [[binding]].
 
@@ -462,6 +462,8 @@
                                  :original-value original-value}
                                 e))))))))))
 
+;;; TODO FIXME -- either rename this to `with-temporary-setting-values!` or fix it and make it thread-safe
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-temporary-setting-values
   "Temporarily bind the site-wide values of one or more `Settings`, execute body, and re-establish the original values.
   This works much the same way as `binding`.
@@ -475,11 +477,13 @@
   (assert (even? (count bindings)) "mismatched setting/value pairs: is each setting name followed by a value?")
   (if (empty? bindings)
     `(do ~@body)
-    `(do-with-temporary-setting-value ~(keyword setting-k) ~value
+    `(do-with-temporary-setting-value! ~(keyword setting-k) ~value
        (fn []
          (with-temporary-setting-values ~more
            ~@body)))))
 
+;;; TODO FIXME -- either rename this to `with-temporary-raw-setting-values!` or fix it and make it thread-safe
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-temporary-raw-setting-values
   "Like [[with-temporary-setting-values]] but works with raw value and it allows settings that are not defined
   using [[metabase.models.setting/defsetting]]."
@@ -487,22 +491,24 @@
   (assert (even? (count bindings)) "mismatched setting/value pairs: is each setting name followed by a value?")
   (if (empty? bindings)
     `(do ~@body)
-    `(do-with-temporary-setting-value ~(keyword setting-k) ~value
+    `(do-with-temporary-setting-value! ~(keyword setting-k) ~value
        (fn []
          (with-temporary-raw-setting-values ~more
            ~@body))
        :raw-setting? true)))
 
-(defn do-with-discarded-setting-changes [settings thunk]
+(defn do-with-discarded-setting-changes! [settings thunk]
   (initialize/initialize-if-needed! :db :plugins)
   ((reduce
     (fn [thunk setting-k]
       (fn []
         (let [value (setting/read-setting setting-k)]
-          (do-with-temporary-setting-value setting-k value thunk :skip-init? true))))
+          (do-with-temporary-setting-value! setting-k value thunk :skip-init? true))))
     thunk
     settings)))
 
+;;; TODO FIXME -- either rename this to `with-discarded-setting-changes!` or fix it and make it thread-safe
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro discard-setting-changes
   "Execute `body` in a try-finally block, restoring any changes to listed `settings` to their original values at its
   conclusion.
@@ -511,7 +517,7 @@
       ...)"
   {:style/indent 1}
   [settings & body]
-  `(do-with-discarded-setting-changes ~(mapv keyword settings) (fn [] ~@body)))
+  `(do-with-discarded-setting-changes! ~(mapv keyword settings) (fn [] ~@body)))
 
 (defn- maybe-merge-original-values
   "For some map columns like `Database.settings` or `User.settings`, merge the original values with the temp ones to
@@ -630,7 +636,7 @@
       (.setProperty StdSchedulerFactory/PROP_JOB_STORE_CLASS (.getCanonicalName org.quartz.simpl.RAMJobStore))
       (.setProperty (str StdSchedulerFactory/PROP_THREAD_POOL_PREFIX ".threadCount") (str in-memory-scheduler-thread-count))))))
 
-(defn do-with-unstarted-temp-scheduler [thunk]
+(defn do-with-unstarted-temp-scheduler! [thunk]
   (let [temp-scheduler (in-memory-scheduler)
         already-bound? (identical? @task/*quartz-scheduler* temp-scheduler)]
     (if already-bound?
@@ -647,16 +653,16 @@
        (finally
          (qs/shutdown temp-scheduler))))))
 
-(defn do-with-temp-scheduler [thunk]
+(defn do-with-temp-scheduler! [thunk]
   ;; not 100% sure we need to initialize the DB anymore since the temp scheduler is in-memory-only now.
   (classloader/the-classloader)
   (initialize/initialize-if-needed! :db)
-  (do-with-unstarted-temp-scheduler
+  (do-with-unstarted-temp-scheduler!
    (^:once fn* []
     (qs/start @task/*quartz-scheduler*)
     (thunk))))
 
-(defmacro with-temp-scheduler
+(defmacro with-temp-scheduler!
   "Execute `body` with a temporary scheduler in place.
   This does not initialize the all the jobs for performance reasons, so make sure you init it yourself!
 
@@ -667,7 +673,7 @@
       (scheduler-current-tasks))"
   {:style/indent 0}
   [& body]
-  `(do-with-temp-scheduler (fn [] ~@body)))
+  `(do-with-temp-scheduler! (fn [] ~@body)))
 
 (defn scheduler-current-tasks
   "Return information about the currently scheduled tasks (jobs+triggers) for the current scheduler. Intended so we
@@ -1097,7 +1103,9 @@
   [locale-tag & body]
   `(call-with-locale ~locale-tag (fn [] ~@body)))
 
-(defn do-with-column-remappings [orig->remapped thunk]
+;;; TODO -- this could be made thread-safe if we made [[with-temp-vals-in-db]] thread-safe which I think is pretty
+;;; doable (just do it in a transaction?)
+(defn do-with-column-remappings! [orig->remapped thunk]
   (transduce
    identity
    (fn
@@ -1160,6 +1168,8 @@
     :else
     x))
 
+;;; TODO FIXME -- either rename this to `with-column-remappings!` or fix it and make it thread-safe.
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-column-remappings
   "Execute `body` with column remappings in place. Can create either FK \"external\" or human-readable-values
   \"internal\" remappings:
@@ -1191,7 +1201,7 @@
       ...)"
   {:arglists '([[original-col source-col & more-remappings] & body])}
   [cols & body]
-  `(do-with-column-remappings
+  `(do-with-column-remappings!
     ~(into {} (comp (map col-remappings-arg)
                     (partition-all 2))
            cols)
@@ -1205,7 +1215,8 @@
   (with-open [socket (ServerSocket. 0)]
     (.getLocalPort socket)))
 
-(defn do-with-env-keys-renamed-by
+;;; TODO -- we could make this thread-safe if we introduced a new dynamic variable to replace [[env/env]]
+(defn do-with-env-keys-renamed-by!
   "Evaluates the thunk with the current core.environ/env being redefined, its keys having been renamed by the given
   rename-fn. Prefer to use the with-env-keys-renamed-by macro version instead."
   [rename-fn thunk]
@@ -1222,12 +1233,14 @@
       (with-redefs [env/env new-e]
         (thunk)))))
 
+;;; TODO FIXME -- either rename this to `with-env-keys-renamed-by!` or fix it and make it thread-safe
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defmacro with-env-keys-renamed-by
   "Evaluates body with the current core.environ/env being redefined, its keys having been renamed by the given
   rename-fn."
   {:arglists '([rename-fn & body])}
   [rename-fn & body]
-  `(do-with-env-keys-renamed-by ~rename-fn (fn [] ~@body)))
+  `(do-with-env-keys-renamed-by! ~rename-fn (fn [] ~@body)))
 
 (defn do-with-temp-file
   "Impl for `with-temp-file` macro."
diff --git a/test/metabase/test/util/i18n.clj b/test/metabase/test/util/i18n.clj
index fd721f52327018a48fee854a2188707c765611fe..adcbe01fee33fad50c32dd3a154c5bc8b583357a 100644
--- a/test/metabase/test/util/i18n.clj
+++ b/test/metabase/test/util/i18n.clj
@@ -4,24 +4,25 @@
    [metabase.util.i18n :as i18n]
    [metabase.util.i18n.impl :as i18n.impl]))
 
-(defn do-with-mock-i18n-bundles [bundles thunk]
+;;; TODO -- this could be made thread-safe pretty easily if we made [[i18n.impl/translations]] dynamic
+(defn do-with-mock-i18n-bundles! [bundles thunk]
   (t/testing (format "\nwith mock i18n bundles %s\n" (pr-str bundles))
     (let [locale->bundle (into {} (for [[locale-name bundle] bundles]
                                     [(i18n/locale locale-name) bundle]))]
       (with-redefs [i18n.impl/translations (comp locale->bundle i18n/locale)]
         (thunk)))))
 
-(defmacro with-mock-i18n-bundles
+(defmacro with-mock-i18n-bundles!
   "Mock the i18n resource bundles for the duration of `body`.
 
-    (with-mock-i18n-bundles {\"es\"    {:messages {\"Your database has been added!\"
+    (with-mock-i18n-bundles! {\"es\"    {:messages {\"Your database has been added!\"
                                                    [\"¡Tu base de datos ha sido añadida!\"]}}
                              \"es-MX\" {:messages {\"I''m good thanks\"
                                                    [\"Está bien, gracias\"]}}}
       (translate \"es-MX\" \"Your database has been added!\"))
     ;; -> \"¡Tu base de datos ha sido añadida!\""
   [bundles & body]
-  `(do-with-mock-i18n-bundles ~bundles (fn [] ~@body)))
+  `(do-with-mock-i18n-bundles! ~bundles (fn [] ~@body)))
 
 (defmacro with-user-locale
   [user-locale & body]
diff --git a/test/metabase/test/util/public_settings.clj b/test/metabase/test/util/public_settings.clj
index 1fd7a10539a2cc785a7fd6da207ddde0769c84c1..4a5637d67fd33ebb9d91add4c0c23c0384c4b383 100644
--- a/test/metabase/test/util/public_settings.clj
+++ b/test/metabase/test/util/public_settings.clj
@@ -5,6 +5,8 @@
    [metabase.public-settings.premium-features :as premium-features]
    [metabase.test.util.thread-local :as tu.thread-local]))
 
+;;; This is actually thread-safe by default unless you're using [[metabase.test/test-helpers-set-global-values!]]
+#_{:clj-kondo/ignore [:metabase/test-helpers-use-non-thread-safe-functions]}
 (defn do-with-premium-features
   [features thunk]
   (let [features (set (map name features))]
diff --git a/test/metabase/upload_test.clj b/test/metabase/upload_test.clj
index 9230bbb74968cd7533fb3a40aaaef413c57d6e6e..a7d538010a5a2c978cf9747c13f1a17bb8ac82b4 100644
--- a/test/metabase/upload_test.clj
+++ b/test/metabase/upload_test.clj
@@ -1787,7 +1787,7 @@
               (is (= #{question-id model-id complex-model-id}
                      (into #{} (map :id) (t2/select :model/Card :table_id table-id :archived false))))
 
-              (mt/with-persistence-enabled [persist-models!]
+              (mt/with-persistence-enabled! [persist-models!]
                 (persist-models!)
 
                 (let [cached-before (cached-model-ids)
diff --git a/test/metabase/util/i18n/impl_test.clj b/test/metabase/util/i18n/impl_test.clj
index 97f2f2287817506593680190bc528aa36cc10b36..c3ee80df6a3328d993f1c747604c62619b81b967 100644
--- a/test/metabase/util/i18n/impl_test.clj
+++ b/test/metabase/util/i18n/impl_test.clj
@@ -87,7 +87,7 @@
            (i18n.impl/translate "zz" "Translate me {0}" [100])))))
 
 (deftest translate-test
-  (mt/with-mock-i18n-bundles  {"es"    {:messages
+  (mt/with-mock-i18n-bundles!  {"es"    {:messages
                                         {"Your database has been added!"  "¡Tu base de datos ha sido añadida!"
                                          "I''m good thanks"               "Está bien, gracias"
                                          "must be {0} characters or less" "deben tener {0} caracteres o menos"}}
@@ -115,7 +115,7 @@
              (i18n.impl/translate "es" "must be {0} characters or less" [140]))))))
 
 (deftest translate-error-handling-test
-  (mt/with-mock-i18n-bundles {"ba-DD" {"Bad translation {0}" "BaD TrAnSlAtIoN {a}"}}
+  (mt/with-mock-i18n-bundles! {"ba-DD" {"Bad translation {0}" "BaD TrAnSlAtIoN {a}"}}
     (testing "Should fall back to original format string if translated one is busted"
       (is (= "Bad translation 100"
              (i18n.impl/translate "ba-DD" "Bad translation {0}" [100]))))
diff --git a/test/metabase/util/i18n_test.clj b/test/metabase/util/i18n_test.clj
index 1e5d0c53486c82e33f0169e5e2e93da63f5dfb8a..3cce07605ee6ff4485ae607d9f6feef6163e8673 100644
--- a/test/metabase/util/i18n_test.clj
+++ b/test/metabase/util/i18n_test.clj
@@ -11,7 +11,7 @@
                    ["pt_BR", "Portuguese (Brazil)"]))))
 
 (deftest tru-test
-  (mt/with-mock-i18n-bundles {"es" {:messages {"must be {0} characters or less"
+  (mt/with-mock-i18n-bundles! {"es" {:messages {"must be {0} characters or less"
                                                "deben tener {0} caracteres o menos"}}}
     (doseq [[message f] {"tru"
                          (fn [] (i18n/tru "must be {0} characters or less" 140))
@@ -43,7 +43,7 @@
                        (f)))))))))))
 
 (deftest trs-test
-  (mt/with-mock-i18n-bundles {"es" {:messages {"must be {0} characters or less"
+  (mt/with-mock-i18n-bundles! {"es" {:messages {"must be {0} characters or less"
                                                "deben tener {0} caracteres o menos"}}}
     (doseq [[message f] {"trs"
                          (fn [] (i18n/trs "must be {0} characters or less" 140))
@@ -70,7 +70,7 @@
                        (f)))))))))))
 
 (deftest trun-test
-  (mt/with-mock-i18n-bundles {"es" {:headers {"Plural-Forms" "nplurals=2; plural=(n != 1);\n"}
+  (mt/with-mock-i18n-bundles! {"es" {:headers {"Plural-Forms" "nplurals=2; plural=(n != 1);\n"}
                                     :messages {"{0} table" ["{0} tabla" "{0} tablas"]}}}
     (doseq [[message f]
             {"trun"
@@ -102,7 +102,7 @@
 
 
 (deftest trsn-test
-  (mt/with-mock-i18n-bundles {"es" {:headers {"Plural-Forms" "nplurals=2; plural=(n != 1);\n"}
+  (mt/with-mock-i18n-bundles! {"es" {:headers {"Plural-Forms" "nplurals=2; plural=(n != 1);\n"}
                                     :messages {"{0} table" ["{0} tabla" "{0} tablas"]}}}
     (doseq [[message f]
             {"trsn - singular"
diff --git a/test/metabase/util/malli_test.clj b/test/metabase/util/malli_test.clj
index 2be87ea2e4240cd10dcb3fa8f342d1dca0c63554..e1c01532699575a68d278941abafa69f42631e4c 100644
--- a/test/metabase/util/malli_test.clj
+++ b/test/metabase/util/malli_test.clj
@@ -27,7 +27,7 @@
           (is (= "Special Number that has to be less than four description"
                  (umd/describe special-lt-4-schema)))
 
-          (mt/with-mock-i18n-bundles {"es" {:messages {"Special Number that has to be less than four description"
+          (mt/with-mock-i18n-bundles! {"es" {:messages {"Special Number that has to be less than four description"
                                                        "Número especial que tiene que ser menos de cuatro descripción"
 
                                                        "Special Number that has to be less than four error"