diff --git a/common/src/app/common/types/tokens_lib.cljc b/common/src/app/common/types/tokens_lib.cljc index 3a85391623..84648a2518 100644 --- a/common/src/app/common/types/tokens_lib.cljc +++ b/common/src/app/common/types/tokens_lib.cljc @@ -1160,25 +1160,26 @@ Will return a value that matches this schema: (if-let [theme (get-theme this id)] (let [group (:group theme) name (:name theme) - theme' (-> (make-token-theme (f theme)) - (assoc :modified-at (ct/now))) - group' (:group theme') - name' (:name theme') - same-group? (= group group') - same-name? (= name name') - same-path? (and same-group? same-name?)] - (TokensLib. sets - (if same-path? - (update themes group' assoc name' theme') - (-> themes - (d/oassoc-in-before [group name] [group' name'] theme') - (d/dissoc-in [group name]))) - (if same-path? - active-themes - (disj active-themes (join-theme-path group name))))) + theme' (make-token-theme (f theme))] + (if (= theme theme') + this + (let [theme' (assoc theme' :modified-at (ct/now)) + group' (:group theme') + name' (:name theme') + same-group? (= group group') + same-name? (= name name') + same-path? (and same-group? same-name?)] + (TokensLib. sets + (if same-path? + (update themes group' assoc name' theme') + (-> themes + (d/oassoc-in-before [group name] [group' name'] theme') + (d/dissoc-in [group name]))) + (if same-path? + active-themes + (disj active-themes (join-theme-path group name))))))) this)) - (delete-theme [this id] (let [theme (get-theme this id) [group name] [(:group theme) (:name theme)]] @@ -2183,6 +2184,18 @@ Will return a value that matches this schema: tokens-lib (get-sets tokens-lib)))) +(defn update-all-themes + "Walk through all themes in the library and apply the given function to them. + The function receives the library and the theme as arguments, + and should return the updated theme." + [tokens-lib update-fn] + (reduce (fn [lib theme] + (update-theme lib + (get-id theme) + #(update-fn lib %))) + tokens-lib + (get-themes tokens-lib))) + (defn fix-duplicate-token-set-ids "Given an instance of TokensLib fixes it internal sets data sturcture for ensure each set has unique id; @@ -2233,6 +2246,19 @@ Will return a value that matches this schema: (rename token (generate-name name match)) token)))))) +(defn fix-missing-sets-in-themes + [tokens-lib] + (let [existing-set-names (into #{} (map get-name) (get-sets tokens-lib)) + fix-theme-sets + (fn [_ theme] + (let [current-sets (:sets theme) + valid-sets (clojure.set/intersection current-sets existing-set-names)] + (if-not (= valid-sets current-sets) + (assoc theme :sets valid-sets) + theme)))] + + (update-all-themes tokens-lib fix-theme-sets))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SERIALIZATION (FRESIAN) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/common/test/common_tests/types/tokens_migrations_test.cljc b/common/test/common_tests/types/tokens_migrations_test.cljc index 62e07bef25..aa0c7c5fc8 100644 --- a/common/test/common_tests/types/tokens_migrations_test.cljc +++ b/common/test/common_tests/types/tokens_migrations_test.cljc @@ -209,4 +209,72 @@ (t/is (= "name1-1" (ctob/get-name token1'))) (t/is (= "name2-2" (ctob/get-name token2'))) (t/is (= "name1.subname1" (ctob/get-name token3'))) - (t/is (= "name2.subname2" (ctob/get-name token4')))))) \ No newline at end of file + (t/is (= "name2.subname2" (ctob/get-name token4')))))) + +(t/deftest test-v1-6-fix-token-names + + (t/testing "empty tokens-lib should not need any action" + (let [tokens-lib (ctob/make-tokens-lib) + tokens-lib' (ctob/fix-missing-sets-in-themes tokens-lib)] + (t/is (empty? (d/map-diff (datafy tokens-lib) (datafy tokens-lib')))))) + + (t/testing "library with a valid theme should not need any action" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set + :id (thi/new-id! :set1) + :name "set1")) + (ctob/add-set (ctob/make-token-set + :id (thi/new-id! :set2) + :name "set2")) + (ctob/add-theme (ctob/make-token-theme + :id (thi/new-id! :theme1) + :name "theme1" + :sets #{"set1"}))) + tokens-lib' (ctob/fix-missing-sets-in-themes tokens-lib)] + (t/is (empty? (d/map-diff (datafy tokens-lib) (datafy tokens-lib')))))) + + (t/testing "library with a theme containing a non-existent set should have it removed, and the rest of the library should be unchanged" + (let [tokens-lib (-> (ctob/make-tokens-lib) + (ctob/add-set (ctob/make-token-set + :id (thi/new-id! :set1) + :name "set1")) + (ctob/add-set (ctob/make-token-set + :id (thi/new-id! :set2) + :name "set2")) + (ctob/add-theme (ctob/make-token-theme + :id (thi/new-id! :theme1) + :name "theme1" + :sets #{"set1" "set3"})) ;; "set3" does not exist + (ctob/add-theme (ctob/make-token-theme + :id (thi/new-id! :theme2) + :name "theme2" + :sets #{"set1" "set2"}))) + tokens-lib' (ctob/fix-missing-sets-in-themes tokens-lib) + + set1 (ctob/get-set tokens-lib (thi/id :set1)) + set2 (ctob/get-set tokens-lib (thi/id :set2)) + theme1 (ctob/get-theme tokens-lib (thi/id :theme1)) + theme2 (ctob/get-theme tokens-lib (thi/id :theme2)) + set1' (ctob/get-set tokens-lib' (thi/id :set1)) + set2' (ctob/get-set tokens-lib' (thi/id :set2)) + theme1' (ctob/get-theme tokens-lib' (thi/id :theme1)) + theme2' (ctob/get-theme tokens-lib' (thi/id :theme2))] + + (t/is (= (:sets theme1') #{"set1"})) + (t/is (= (:sets theme2') #{"set1" "set2"})) + + (t/is (= (ctob/get-id set1') (ctob/get-id set1))) + (t/is (= (ctob/get-name set1') (ctob/get-name set1))) + (t/is (= (ctob/get-description set1') (ctob/get-description set1))) + (t/is (= (ctob/get-modified-at set1') (ctob/get-modified-at set1))) + (t/is (= (ctob/get-id set2') (ctob/get-id set2))) + (t/is (= (ctob/get-name set2') (ctob/get-name set2))) + (t/is (= (ctob/get-description set2') (ctob/get-description set2))) + (t/is (= (ctob/get-modified-at set2') (ctob/get-modified-at set2))) + + (t/is (= (ctob/get-id theme1') (ctob/get-id theme1))) + (t/is (= (ctob/get-name theme1') (ctob/get-name theme1))) + (t/is (= (ctob/get-description theme1') (ctob/get-description theme1))) + (t/is (= (ctob/get-id theme2') (ctob/get-id theme2))) + (t/is (= (ctob/get-name theme2') (ctob/get-name theme2))) + (t/is (= (ctob/get-description theme2') (ctob/get-description theme2))))))