Skip to content
Snippets Groups Projects
Unverified Commit d33d83f4 authored by dpsutton's avatar dpsutton Committed by GitHub
Browse files

Update the keys we consider to unverify a card (#18734)

* Update the keys we consider to unverify a card

Previously when almost anything changed we would unverify a card. But
this was way too aggresive. We really only want to unverify when a query
changes. Far simpler to specify the keys we do want to consider rather
than the keys to ignore.

Was prompted because when we marked a question as a dataset it would
unverify because the `:display` was changed and also `:dataset`. Neither
of these matter for verification purposes

* Update testing context string [ci skip]

* Empty commit to trigger CI

had skipped ci since it was a docstring change but that prevents merging
sad face :(
parent 06c100f4
No related branches found
No related tags found
No related merge requests found
...@@ -425,38 +425,37 @@ ...@@ -425,38 +425,37 @@
(-> card :moderation_reviews first :status #{"verified"} boolean)) (-> card :moderation_reviews first :status #{"verified"} boolean))
(defn- changed? (defn- changed?
"Return whether there were any changes other than ignored values. "Return whether there were any changes in the objects at the keys for `consider`.
returns false because changes to collection_id are ignored: returns false because changes to collection_id are ignored:
(changed? {:collection_id 1 :description \"foo\"} (changed? #{:description}
{:collection_id 2} {:collection_id 1 :description \"foo\"}
{:ignore #{:collection_id}}) {:collection_id 2 :description \"foo\"})
returns true: returns true:
(changed? {:collection_id 1 :description \"foo\"} (changed? #{:description}
{:collection_id 2 :description \"diff\"} {:collection_id 1 :description \"foo\"}
{:ignore #{:collection_id}})" {:collection_id 2 :description \"diff\"})"
[card-before updates {:keys [ignore]}] [consider card-before updates]
;; have to ignore keyword vs strings over api. `{:type :query}` vs `{:type "query"}` ;; have to ignore keyword vs strings over api. `{:type :query}` vs `{:type "query"}`
(let [prepare (fn prepare [card] (walk/prewalk (fn [x] (if (keyword? x) (let [prepare (fn prepare [card] (walk/prewalk (fn [x] (if (keyword? x)
(name x) (name x)
x)) x))
card)) card))
before (apply dissoc card-before ignore) before (prepare (select-keys card-before consider))
after (apply dissoc updates ignore) after (prepare (select-keys updates consider))
[_ changes-in-after] (data/diff (prepare before) (prepare after))] [_ changes-in-after] (data/diff before after)]
(boolean (seq changes-in-after)))) (boolean (seq changes-in-after))))
(def card-compare-ignores (def card-compare-keys
"Keys to ignore when comparing card changes to the existing card." "When comparing a card to possibly unverify, only consider these keys as changing something 'important' about the
#{:result_metadata ;; not interested in changes here query."
;; ignore collection changes, pinning, and public changes #{:table_id
:collection_id :collection_position :database_id
:public_uuid :made_public_by_id :query_type ;; these first three may not even be changeable
;; compares java.time objects vs strings over api :dataset_query})
:created_at :updated_at})
(defn- update-card-async! (defn- update-card-async!
"Update a Card asynchronously. Returns a `core.async` promise channel that will return updated Card." "Update a Card asynchronously. Returns a `core.async` promise channel that will return updated Card."
...@@ -468,8 +467,7 @@ ...@@ -468,8 +467,7 @@
(api/maybe-reconcile-collection-position! card-before-update card-updates) (api/maybe-reconcile-collection-position! card-before-update card-updates)
(when (and (card-is-verified? card-before-update) (when (and (card-is-verified? card-before-update)
(changed? card-before-update card-updates (changed? card-compare-keys card-before-update card-updates))
{:ignore card-compare-ignores}))
;; this is an enterprise feature but we don't care if enterprise is enabled here. If there is a review we need ;; this is an enterprise feature but we don't care if enterprise is enabled here. If there is a review we need
;; to remove it regardless if enterprise edition is present at the moment. ;; to remove it regardless if enterprise edition is present at the moment.
(moderation-review/create-review! {:moderated_item_id id (moderation-review/create-review! {:moderated_item_id id
......
...@@ -1525,21 +1525,23 @@ ...@@ -1525,21 +1525,23 @@
(deftest changed?-test (deftest changed?-test
(letfn [(changed? [before after] (letfn [(changed? [before after]
(#'card-api/changed? before after {:ignore card-api/card-compare-ignores}))] (#'card-api/changed? card-api/card-compare-keys before after))]
(testing "Ignores keyword/string" (testing "Ignores keyword/string"
(is (false? (changed? {:dataset_query {:type :query}} {:dataset_query {:type "query"}})))) (is (false? (changed? {:dataset_query {:type :query}} {:dataset_query {:type "query"}}))))
(testing "Ignores properties passed in `card-api/card-compare-ignores" (testing "Ignores properties not in `card-api/card-compare-keys"
(is (false? (changed? {:collection_id 1 (is (false? (changed? {:collection_id 1
:collection_position 0} :collection_position 0}
{:collection_id 2 {:collection_id 2
:collection_position 1})))) :collection_position 1}))))
(testing "Sees changes" (testing "Sees changes"
(is (true? (changed? {:description "foo"} {:description "diff"}))) (is (true? (changed? {:dataset_query {:type :query}}
(testing "But only when they are different in the after" {:dataset_query {:type :query
(is (false? (changed? {:description "foo" :title "something" :collection_id 1} :query {}}})))
(testing "But only when they are different in the after, not just omitted"
(is (false? (changed? {:dataset_query {} :collection_id 1}
{:collection_id 1}))) {:collection_id 1})))
(is (true? (changed? {:description "foo" :title "something" :collection_id 1} (is (true? (changed? {:dataset_query {} :collection_id 1}
{:description nil :title nil :collection_id 1}))))))) {:dataset_query nil :collection_id 1})))))))
(deftest update-verified-card-test (deftest update-verified-card-test
(tools.macro/macrolet (tools.macro/macrolet
...@@ -1571,7 +1573,7 @@ ...@@ -1571,7 +1573,7 @@
(testing "Changing core attributes un-verifies the card" (testing "Changing core attributes un-verifies the card"
(with-card :verified (with-card :verified
(is (verified? card)) (is (verified? card))
(update-card card {:description "a new description"}) (update-card card (update-in card [:dataset_query :query :source-table] inc))
(is (not (verified? card))) (is (not (verified? card)))
(testing "The unverification edit has explanatory text" (testing "The unverification edit has explanatory text"
(is (= "Unverified due to edit" (is (= "Unverified due to edit"
...@@ -1591,7 +1593,22 @@ ...@@ -1591,7 +1593,22 @@
(testing "making public" (testing "making public"
(remains-verified (remains-verified
(update-card card {:made_public_by_id (mt/user->id :rasta) (update-card card {:made_public_by_id (mt/user->id :rasta)
:public_uuid (UUID/randomUUID)}))))) :public_uuid (UUID/randomUUID)})))
(testing "Changing description"
(remains-verified
(update-card card {:description "foo"})))
(testing "Changing name"
(remains-verified
(update-card card {:name "foo"})))
(testing "Changing archived"
(remains-verified
(update-card card {:archived true})))
(testing "Changing display"
(remains-verified
(update-card card {:display :line})))
(testing "Changing visualization settings"
(remains-verified
(update-card card {:visualization_settings {:table.cell_column "FOO"}})))))
(testing "Does not add a new nil moderation review when not verified" (testing "Does not add a new nil moderation review when not verified"
(with-card :not-verified (with-card :not-verified
(is (empty? (reviews card))) (is (empty? (reviews card)))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment