Files
penpot/frontend/test/frontend_tests/tokens/token_errors_test.cljs
Andrey Antukh a2672a598c 🐛 Fix TypeError when token error map lacks :error/fn key (#8767)
* 🐛 Fix TypeError when token error map lacks :error/fn key

Guard against missing :error/fn in token form control resolve streams.
When schema validation errors are produced they may not carry an
:error/fn key; calling nil as a function caused a TypeError crash.
Apply an if-let guard at all 7 affected sites across input.cljs,
color_input.cljs and fonts_combobox.cljs, falling back to :message
or returning the error map unchanged.

* ♻️ Extract token error helpers and add unit tests

Extract resolve-error-message and resolve-error-assoc-message helpers
into errors.cljs, replacing the seven duplicated inline lambdas in
input.cljs, color_input.cljs and fonts_combobox.cljs with named
function references.  Add frontend-tests.tokens.token-errors-test
covering both helpers for the normal path (:error/fn present) and the
fallback path (schema-validation errors that lack :error/fn).

Signed-off-by: Penpot Dev <dev@penpot.app>

---------

Signed-off-by: Penpot Dev <dev@penpot.app>
2026-03-25 12:12:18 +01:00

54 lines
2.5 KiB
Clojure

;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns frontend-tests.tokens.token-errors-test
(:require
[app.main.data.workspace.tokens.errors :as wte]
[cljs.test :as t :include-macros true]))
;; ---------------------------------------------------------------------------
;; resolve-error-message
;; ---------------------------------------------------------------------------
(t/deftest resolve-error-message-with-error-fn
(t/testing "calls :error/fn with :error/value when both keys are present"
(let [error {:error/fn (fn [v] (str "bad value: " v))
:error/value "abc"}]
(t/is (= "bad value: abc" (wte/resolve-error-message error))))))
(t/deftest resolve-error-message-without-error-fn
(t/testing "returns :message when :error/fn is absent (schema-validation error)"
(let [error {:message "This field is required"}]
(t/is (= "This field is required" (wte/resolve-error-message error))))))
(t/deftest resolve-error-message-nil-error-fn
(t/testing "returns :message when :error/fn is explicitly nil"
(let [error {:error/fn nil :message "fallback message"}]
(t/is (= "fallback message" (wte/resolve-error-message error))))))
;; ---------------------------------------------------------------------------
;; resolve-error-assoc-message
;; ---------------------------------------------------------------------------
(t/deftest resolve-error-assoc-message-with-error-fn
(t/testing "assocs :message produced by :error/fn into the error map"
(let [error {:error/fn (fn [v] (str "invalid: " v))
:error/value "42"
:error/code :error.token/invalid-color}]
(let [result (wte/resolve-error-assoc-message error)]
(t/is (= "invalid: 42" (:message result)))
(t/is (= :error.token/invalid-color (:error/code result)))))))
(t/deftest resolve-error-assoc-message-without-error-fn
(t/testing "returns the error map unchanged when :error/fn is absent"
(let [error {:message "This field is required"}]
(t/is (= error (wte/resolve-error-assoc-message error))))))
(t/deftest resolve-error-assoc-message-nil-error-fn
(t/testing "returns the error map unchanged when :error/fn is explicitly nil"
(let [error {:error/fn nil :message "fallback"}]
(t/is (= error (wte/resolve-error-assoc-message error))))))