🔧 Fix integration tests

This commit is contained in:
Andrés Moya 2026-07-30 09:43:16 +02:00
parent 12fc08d7f5
commit d56a460b3c
7 changed files with 124 additions and 52 deletions

View File

@ -694,7 +694,8 @@
(defn sync-tokens-status-with-lib (defn sync-tokens-status-with-lib
"Synchronizes tokens status with the current tokens lib: "Synchronizes tokens status with the current tokens lib:
- Delete any theme or set that no longer exists in the lib." - Delete any theme or set that no longer exists in the lib.
- Recalculate the list of active sets from the new themes."
[tokens-status tokens-lib] [tokens-status tokens-lib]
(assert (ctos/tokens-status? tokens-status) "expected valid tokens-status") (assert (ctos/tokens-status? tokens-status) "expected valid tokens-status")
(assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib") (assert (ctob/tokens-lib? tokens-lib) "expected valid tokens-lib")
@ -703,9 +704,11 @@
(filter #(some? (ctob/get-theme tokens-lib %))) (filter #(some? (ctob/get-theme tokens-lib %)))
active-theme-ids) active-theme-ids)
active-set-ids (ctos/get-active-set-ids tokens-status) active-set-ids (ctos/get-active-set-ids tokens-status)
valid-set-ids (into #{} valid-set-ids (if (empty? valid-theme-ids)
(filter #(some? (ctob/get-set tokens-lib %))) (into #{}
active-set-ids)] (filter #(some? (ctob/get-set tokens-lib %)))
active-set-ids)
(calculate-active-sets valid-theme-ids tokens-lib))]
(if (or (not= active-theme-ids valid-theme-ids) (if (or (not= active-theme-ids valid-theme-ids)
(not= active-set-ids valid-set-ids)) (not= active-set-ids valid-set-ids))

View File

@ -6,6 +6,7 @@
(ns app.common.logic.tokens (ns app.common.logic.tokens
(:require (:require
[app.common.files.changes :as ch]
[app.common.files.changes-builder :as pcb] [app.common.files.changes-builder :as pcb]
[app.common.files.tokens :as cfo] [app.common.files.tokens :as cfo]
[app.common.types.tokens-lib :as ctob])) [app.common.types.tokens-lib :as ctob]))
@ -84,6 +85,22 @@
prev-before (assoc :prev-before-path (:path prev-before) prev-before (assoc :prev-before-path (:path prev-before)
:prev-before-group? (:group? prev-before)))))) :prev-before-group? (:group? prev-before))))))
(declare generate-sync-tokens-status-with-lib)
(defn generate-update-token-theme
"Create changes for updating a token theme and regenerating the activation status
of the sets inside it."
[changes token-theme]
(let [changes' (pcb/set-token-theme changes (ctob/get-id token-theme) token-theme)
data (pcb/get-library-data changes')
tokens-status (cfo/get-tokens-status data)
tokens-lib' (-> data
(ch/process-changes (:redo-changes changes'))
(cfo/get-tokens-lib))]
(generate-sync-tokens-status-with-lib changes'
tokens-status
tokens-lib')))
(defn generate-move-token-set (defn generate-move-token-set
"Create changes for dropping a token set or token set. "Create changes for dropping a token set or token set.
Throws for impossible moves." Throws for impossible moves."

View File

@ -1184,7 +1184,7 @@
(t/is (= #{theme-1-id} (ctos/get-active-theme-ids tokens-status'))) (t/is (= #{theme-1-id} (ctos/get-active-theme-ids tokens-status')))
(t/is (ctos/theme-active? tokens-status' theme-1-id)))) (t/is (ctos/theme-active? tokens-status' theme-1-id))))
(t/testing "removes set ids that no longer exist in the lib" (t/testing "removes set ids that no longer exist in the lib (active themes)"
(let [theme-1-id (thi/new-id! :theme-1) (let [theme-1-id (thi/new-id! :theme-1)
set-a-id (thi/new-id! :set-a) set-a-id (thi/new-id! :set-a)
tokens-lib (-> (ctob/make-tokens-lib) tokens-lib (-> (ctob/make-tokens-lib)
@ -1198,6 +1198,36 @@
tokens-status' (cfo/sync-tokens-status-with-lib tokens-status tokens-lib)] tokens-status' (cfo/sync-tokens-status-with-lib tokens-status tokens-lib)]
(t/is (= #{set-a-id} (ctos/get-active-set-ids tokens-status'))))) (t/is (= #{set-a-id} (ctos/get-active-set-ids tokens-status')))))
(t/testing "removes set ids that no longer exist in the lib (no active themes)"
(let [theme-1-id (thi/new-id! :theme-1)
set-a-id (thi/new-id! :set-a)
tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a"))
(ctob/add-theme (ctob/make-token-theme :id theme-1-id
:name "theme-1"
:group ""
:sets #{"set-a"})))
tokens-status (ctos/make-tokens-status :active-theme-ids #{}
:active-set-ids #{set-a-id (thi/new-id! :removed-set)})
tokens-status' (cfo/sync-tokens-status-with-lib tokens-status tokens-lib)]
(t/is (= #{set-a-id} (ctos/get-active-set-ids tokens-status')))))
(t/testing "updates active sets when theme changes"
(let [theme-1-id (thi/new-id! :theme-1)
set-a-id (thi/new-id! :set-a)
set-b-id (thi/new-id! :set-b)
tokens-lib (-> (ctob/make-tokens-lib)
(ctob/add-set (ctob/make-token-set :id set-a-id :name "set-a"))
(ctob/add-set (ctob/make-token-set :id set-b-id :name "set-b"))
(ctob/add-theme (ctob/make-token-theme :id theme-1-id
:name "theme-1"
:group ""
:sets #{"set-b"})))
tokens-status (ctos/make-tokens-status :active-theme-ids #{theme-1-id}
:active-set-ids #{set-a-id (thi/new-id! :removed-set)})
tokens-status' (cfo/sync-tokens-status-with-lib tokens-status tokens-lib)]
(t/is (= #{set-b-id} (ctos/get-active-set-ids tokens-status')))))
(t/testing "returns same status object when everything is valid" (t/testing "returns same status object when everything is valid"
(let [theme-1-id (thi/new-id! :theme-1) (let [theme-1-id (thi/new-id! :theme-1)
set-a-id (thi/new-id! :set-a) set-a-id (thi/new-id! :set-a)

View File

@ -42,10 +42,24 @@
] ]
} }
}, },
"~:id": "~u51e13852-1a8e-8037-8005-9e9413a1f1f6", "~:id": "~uc7ce0794-0992-8105-8004-38f280443849",
"~:options": { "~:options": {
"~:components-v2": true "~:components-v2": true
}, },
"~:tokens-status": {
"~#penpot/tokens-status": {
"~:active-theme-ids": {
"~#set": ["~u66697432-c33d-8055-8006-2c62de27d738"]
},
"~:active-set-ids": {
"~#set": [
"~u66697432-c33d-8055-8006-2c62de27d709",
"~u51e13852-1a8e-8037-8005-9e9413a1f1f6",
"~u66697432-c33d-8055-8006-2c62de27d731"
]
}
}
},
"~:tokens-lib": { "~:tokens-lib": {
"~#penpot/tokens-lib": { "~#penpot/tokens-lib": {
"~:sets": { "~:sets": {

View File

@ -10,7 +10,7 @@
[app.common.files.changes-builder :as pcb] [app.common.files.changes-builder :as pcb]
[app.common.files.helpers :as cfh] [app.common.files.helpers :as cfh]
[app.common.geom.point :as gpt] [app.common.geom.point :as gpt]
[app.common.logic.tokens :as clt] [app.common.logic.tokens :as clo]
[app.common.path-names :as cpn] [app.common.path-names :as cpn]
[app.common.test-helpers.ids-map :as cthi] [app.common.test-helpers.ids-map :as cthi]
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
@ -252,7 +252,7 @@
:timeout 9000})) :timeout 9000}))
(let [changes (-> (pcb/empty-changes it) (let [changes (-> (pcb/empty-changes it)
(pcb/with-library-data data) (pcb/with-library-data data)
(pcb/set-token-theme (ctob/get-id token-theme) token-theme))] (clo/generate-update-token-theme token-theme))]
(rx/of (dch/commit-changes changes)))))))) (rx/of (dch/commit-changes changes))))))))
(defn set-token-theme-active (defn set-token-theme-active
@ -267,7 +267,7 @@
tokens-lib (dsh/lookup-tokens-lib state) tokens-lib (dsh/lookup-tokens-lib state)
changes (-> (pcb/empty-changes) changes (-> (pcb/empty-changes)
(pcb/with-library-data data) (pcb/with-library-data data)
(clt/generate-set-theme-status tokens-status tokens-lib id active?))] (clo/generate-set-theme-status tokens-status tokens-lib id active?))]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens)))))) (dwtp/propagate-workspace-tokens))))))
@ -283,7 +283,7 @@
tokens-lib (dsh/lookup-tokens-lib state) tokens-lib (dsh/lookup-tokens-lib state)
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(pcb/with-library-data data) (pcb/with-library-data data)
(clt/generate-toggle-theme tokens-status tokens-lib id))] (clo/generate-toggle-theme tokens-status tokens-lib id))]
(rx/of (rx/of
(dch/commit-changes changes) (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens)))))) (dwtp/propagate-workspace-tokens))))))
@ -370,7 +370,7 @@
tokens-status (dsh/lookup-tokens-status state) tokens-status (dsh/lookup-tokens-status state)
changes (-> (pcb/empty-changes) changes (-> (pcb/empty-changes)
(pcb/with-library-data data) (pcb/with-library-data data)
(clt/generate-set-enabled-token-set tokens-status tokens-lib id enabled?))] (clo/generate-set-enabled-token-set tokens-status tokens-lib id enabled?))]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens)))))) (dwtp/propagate-workspace-tokens))))))
@ -386,7 +386,7 @@
tokens-status (dsh/lookup-tokens-status state) tokens-status (dsh/lookup-tokens-status state)
changes (-> (pcb/empty-changes) changes (-> (pcb/empty-changes)
(pcb/with-library-data data) (pcb/with-library-data data)
(clt/generate-toggle-token-set tokens-status tokens-lib id))] (clo/generate-toggle-token-set tokens-status tokens-lib id))]
(rx/of (rx/of
(dch/commit-changes changes) (dch/commit-changes changes)
@ -402,7 +402,7 @@
tokens-status (dsh/lookup-tokens-status state) tokens-status (dsh/lookup-tokens-status state)
changes (-> (pcb/empty-changes) changes (-> (pcb/empty-changes)
(pcb/with-library-data data) (pcb/with-library-data data)
(clt/generate-toggle-token-set-group tokens-status tokens-lib group-path))] (clo/generate-toggle-token-set-group tokens-status tokens-lib group-path))]
(rx/of (rx/of
(dch/commit-changes changes) (dch/commit-changes changes)
@ -451,7 +451,7 @@
(let [data (dsh/lookup-file-data state) (let [data (dsh/lookup-file-data state)
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(pcb/with-library-data data) (pcb/with-library-data data)
(clt/generate-delete-token-set-group (dsh/lookup-tokens-lib state) path))] (clo/generate-delete-token-set-group (dsh/lookup-tokens-lib state) path))]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens)))))) (dwtp/propagate-workspace-tokens))))))
@ -479,7 +479,7 @@
ptk/WatchEvent ptk/WatchEvent
(watch [it state _] (watch [it state _]
(try (try
(when-let [changes (clt/generate-move-token-set-group (pcb/empty-changes it) (dsh/lookup-tokens-lib state) drop-opts)] (when-let [changes (clo/generate-move-token-set-group (pcb/empty-changes it) (dsh/lookup-tokens-lib state) drop-opts)]
(rx/of (rx/of
(dch/commit-changes changes) (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens))) (dwtp/propagate-workspace-tokens)))
@ -497,7 +497,7 @@
(try (try
(let [tokens-lib (dsh/lookup-tokens-lib state) (let [tokens-lib (dsh/lookup-tokens-lib state)
changes (-> (pcb/empty-changes it) changes (-> (pcb/empty-changes it)
(clt/generate-move-token-set tokens-lib params))] (clo/generate-move-token-set tokens-lib params))]
(rx/of (dch/commit-changes changes) (rx/of (dch/commit-changes changes)
(dwtp/propagate-workspace-tokens))) (dwtp/propagate-workspace-tokens)))
(catch :default cause (catch :default cause

View File

@ -251,7 +251,7 @@
(fn [event] (fn [event]
(dom/stop-propagation event) (dom/stop-propagation event)
(when (fn? on-toggle) (when (fn? on-toggle)
(on-toggle (ctob/get-id set))))) (on-toggle (ctob/get-name set)))))
on-edit-submit' on-edit-submit'
(mf/use-fn (mf/use-fn

View File

@ -238,15 +238,16 @@
(t/deftest token-set-duplicate-returns-the-duplicated-set (t/deftest token-set-duplicate-returns-the-duplicated-set
(let [file-id (cthi/new-id! :file) (let [file-id (cthi/new-id! :file)
set-id (cthi/new-id! :set) set-id (cthi/new-id! :set)
dup-id (cthi/new-id! :dup) dup-id (cthi/new-id! :dup)]
proxy (ptok/token-set-proxy "plugin-id" file-id set-id)] (with-redefs [u/locate-tokens-lib (constantly nil)
(with-redefs [dwtl/duplicate-token-set dwtl/duplicate-token-set
(mock/stub (fn [id {:keys [id-ref]}] (mock/stub (fn [id {:keys [id-ref]}]
(t/is (= set-id id)) (t/is (= set-id id))
(reset! id-ref dup-id) (reset! id-ref dup-id)
:duplicate-token-set)) :duplicate-token-set))
st/emit! mock/noop] st/emit! mock/noop]
(let [dup (.duplicate proxy)] (let [proxy (ptok/token-set-proxy "plugin-id" file-id set-id)
dup (.duplicate proxy)]
(t/is (ptok/token-set-proxy? dup)) (t/is (ptok/token-set-proxy? dup))
(t/is (= (str dup-id) (.-id dup))))))) (t/is (= (str dup-id) (.-id dup)))))))
@ -254,10 +255,9 @@
(let [file-id (cthi/new-id! :file) (let [file-id (cthi/new-id! :file)
theme-id (cthi/new-id! :theme) theme-id (cthi/new-id! :theme)
set-id (cthi/new-id! :set) set-id (cthi/new-id! :set)
set (ptok/token-set-proxy "plugin-id" file-id set-id "Primitives")
theme (ptok/token-theme-proxy "plugin-id" file-id theme-id)
captured (atom [])] captured (atom [])]
(with-redefs [u/locate-token-theme (with-redefs [u/locate-tokens-lib (constantly nil)
u/locate-token-theme
(fn [_file _theme] (fn [_file _theme]
(ctob/make-token-theme :id theme-id (ctob/make-token-theme :id theme-id
:name "Theme" :name "Theme"
@ -267,18 +267,21 @@
(swap! captured conj {:id id :theme theme}) (swap! captured conj {:id id :theme theme})
:update-token-theme) :update-token-theme)
st/emit! mock/noop] st/emit! mock/noop]
(.addSet theme set) (let [set (ptok/token-set-proxy "plugin-id" file-id set-id "Primitives")
(.removeSet theme set) theme (ptok/token-theme-proxy "plugin-id" file-id theme-id)]
(t/is (= [theme-id theme-id] (mapv :id @captured))) (.addSet theme set)
(t/is (contains? (-> @captured first :theme :sets) "Primitives")) (.removeSet theme set)
(t/is (not (contains? (-> @captured second :theme :sets) "Primitives")))))) (t/is (= [theme-id theme-id] (mapv :id @captured)))
(t/is (contains? (-> @captured first :theme :sets) "Primitives"))
(t/is (not (contains? (-> @captured second :theme :sets) "Primitives")))))))
(t/deftest font-family-token-value-accepts-a-string (t/deftest font-family-token-value-accepts-a-string
(let [file-id (cthi/new-id! :file) (let [file-id (cthi/new-id! :file)
set-id (cthi/new-id! :set) set-id (cthi/new-id! :set)
token-id (cthi/new-id! :token) token-id (cthi/new-id! :token)
captured (atom nil)] captured (atom nil)]
(with-redefs [u/locate-token (constantly {:id token-id (with-redefs [u/locate-tokens-lib (constantly nil)
u/locate-token (constantly {:id token-id
:name "font.primary" :name "font.primary"
:type :font-family :type :font-family
:value ["Inter"]}) :value ["Inter"]})
@ -351,12 +354,13 @@
theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light") theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light")
emitted (atom []) emitted (atom [])
invalid (atom [])] invalid (atom [])]
(with-redefs [u/locate-token-set (fn [_ id] (when (= id set-id) token-set)) (with-redefs [u/locate-tokens-lib (constantly nil)
u/locate-token-theme (fn [_ id] (when (= id theme-id) theme)) u/locate-token-set (fn [_ id] (when (= id set-id) token-set))
u/not-valid (fn [_ code value] (swap! invalid conj [code value])) u/locate-token-theme (fn [_ id] (when (= id theme-id) theme))
u/not-valid (fn [_ code value] (swap! invalid conj [code value]))
dwtl/update-token-theme (fn [id theme] {:id id :theme theme}) dwtl/update-token-theme (fn [id theme] {:id id :theme theme})
st/emit! (fn ([event] (swap! emitted conj event) nil) st/emit! (fn ([event] (swap! emitted conj event) nil)
([event & _] (swap! emitted conj event) nil))] ([event & _] (swap! emitted conj event) nil))]
(let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)] (let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)]
(.addSet theme-proxy (str set-id)) (.addSet theme-proxy (str set-id))
(t/is (= #{"Core"} (-> @emitted first :theme :sets))) (t/is (= #{"Core"} (-> @emitted first :theme :sets)))
@ -371,12 +375,13 @@
theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light") theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light")
emitted (atom []) emitted (atom [])
invalid (atom [])] invalid (atom [])]
(with-redefs [u/locate-token-set (fn [_ id] (when (= id set-id) token-set)) (with-redefs [u/locate-tokens-lib (constantly nil)
u/locate-token-theme (fn [_ id] (when (= id theme-id) theme)) u/locate-token-set (fn [_ id] (when (= id set-id) token-set))
u/not-valid (fn [_ code value] (swap! invalid conj [code value])) u/locate-token-theme (fn [_ id] (when (= id theme-id) theme))
u/not-valid (fn [_ code value] (swap! invalid conj [code value]))
dwtl/update-token-theme (fn [id theme] {:id id :theme theme}) dwtl/update-token-theme (fn [id theme] {:id id :theme theme})
st/emit! (fn ([event] (swap! emitted conj event) nil) st/emit! (fn ([event] (swap! emitted conj event) nil)
([event & _] (swap! emitted conj event) nil))] ([event & _] (swap! emitted conj event) nil))]
(let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id) (let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)
set-proxy (ptok/token-set-proxy plugin-id file-id set-id "Core")] set-proxy (ptok/token-set-proxy plugin-id file-id set-id "Core")]
(.addSet theme-proxy set-proxy) (.addSet theme-proxy set-proxy)
@ -389,18 +394,21 @@
theme-id (uuid/next) theme-id (uuid/next)
theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light") theme (ctob/make-token-theme :id theme-id :group "mode" :name "Light")
emitted (atom []) emitted (atom [])
errors (atom [])] invalid (atom [])]
(with-redefs [u/locate-token-set (constantly nil) (with-redefs [u/locate-tokens-lib (constantly nil)
u/locate-token-theme (fn [_ id] (when (= id theme-id) theme)) u/locate-token-set (constantly nil)
u/throw-validation-errors? (constantly true) u/locate-token-theme (fn [_ id] (when (= id theme-id) theme))
dwtl/update-token-theme (fn [id theme] {:id id :theme theme}) u/not-valid (fn [_ code value] (swap! invalid conj [code value]))
st/emit! (fn ([event] (swap! emitted conj event) nil) u/handle-error (fn [plugin-id]
([event & _] (swap! emitted conj event) nil))] (fn [cause]
(u/not-valid plugin-id :error (str cause))))
dwtl/update-token-theme (fn [id theme] {:id id :theme theme})
st/emit! (fn ([event] (swap! emitted conj event) nil)
([event & _] (swap! emitted conj event) nil))]
(let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)] (let [theme-proxy (ptok/token-theme-proxy plugin-id file-id theme-id)]
;; Non-id, non-proxy arguments are rejected by the schema coercer. (try (.addSet theme-proxy 42) (catch :default e (swap! invalid conj e)))
(try (.addSet theme-proxy 42) (catch :default e (swap! errors conj e))) (try (.removeSet theme-proxy nil) (catch :default e (swap! invalid conj e)))
(try (.removeSet theme-proxy nil) (catch :default e (swap! errors conj e)))
(t/is (empty? @emitted)) (t/is (empty? @emitted))
(t/is (= 2 (count @errors))) (t/is (= 2 (count @invalid)))
(t/is (every? #(instance? js/Error %) @errors)))))) (t/is (every? #(instance? js/Error %) @invalid))))))