penpot/frontend/test/frontend_tests/data/exports_assets_test.cljs
Andrey Antukh 040080749b
🐛 Fix shape export failures when export name is nil or empty (#10852)
Use cuerdas blank-name handling directly when normalizing frontend export
payloads. Replace nil or blank export names with the object-id string in
request-simple-export, request-multiple-export, clipboard export, and plugin
direct export payloads so that the backend always receives a valid name. Add
focused frontend tests for nil/blank name normalization and normalized request
params.

AI-assisted-by: nex-n2-pro
2026-07-30 12:49:19 +02:00

100 lines
4.0 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 Sucursal en España SL
(ns frontend-tests.data.exports-assets-test
(:require
[app.common.uuid :as uuid]
[app.main.data.exports.assets :as de]
[app.main.data.persistence :as dwp]
[app.main.repo :as repo]
[app.main.store :as st]
[app.util.dom :as dom]
[app.util.websocket :as ws]
[beicon.v2.core :as rx]
[cljs.test :as t :include-macros true]
[frontend-tests.helpers.events :as the]
[frontend-tests.helpers.mock :as mock]
[potok.v2.core :as ptk]))
(def ^:private export {:id (uuid/next)
:object-id (uuid/next)
:type :png
:suffix ""
:scale 1})
(defn- export-with-name
[name]
(merge export {:name name}))
(defn- test-state
[]
{:profile-id (:id export)
:ws-conn nil})
(t/deftest normalize-export-preserves-existing-name
(t/is (= (export-with-name "Layer 1")
(de/normalize-export (export-with-name "Layer 1")))))
(t/deftest normalize-export-replaces-nil-name-with-object-id
(t/is (= (export-with-name (str (:object-id export)))
(de/normalize-export (assoc export :name nil)))))
(t/deftest normalize-export-replaces-empty-name-with-object-id
(t/is (= (export-with-name (str (:object-id export)))
(de/normalize-export (assoc export :name "")))))
(t/deftest request-simple-export-sends-normalized-export
(t/async done
(let [export (export-with-name "")
observed (atom nil)]
(mock/with-mocks {repo/cmd! (mock/stub (fn [_ params]
(reset! observed params)
(rx/of {:filename "export.png"
:mtype "image/png"
:uri "blob:export"})))
dwp/force-persist-and-wait (mock/stub (fn [_] (rx/of ::force-persisted)))
dom/trigger-download-uri (mock/stub (fn [& _] nil))}
(fn [done']
(let [completed (fn [_state]
(t/is (= (export-with-name (str (:object-id export)))
(-> @observed :exports first))))]
(ptk/emit! (the/prepare-store (test-state) done' completed)
(de/request-simple-export {:export export})
:the/end)))
done))))
(t/deftest request-multiple-export-sends-normalized-enabled-exports
(t/async done
(let [exports [{:id "enabled-1"
:object-id "enabled-1"
:shape {:id "enabled-1"}
:type :png
:suffix ""
:scale 1
:enabled true
:name ""}]
observed (atom nil)]
(mock/with-mocks {repo/cmd! (mock/stub (fn [_ params]
(reset! observed params)
(rx/of {:id (:id export)})))
ws/get-rcv-stream (mock/stub (fn [_] (rx/empty)))
st/ongoing-tasks (atom #{})}
(fn [done']
(let [completed (fn [_state]
(t/is (= [{:id "enabled-1"
:object-id "enabled-1"
:shape {:id "enabled-1"}
:type :png
:suffix ""
:scale 1
:enabled true
:name "enabled-1"}]
(:exports @observed))))]
(ptk/emit! (the/prepare-store (test-state) done' completed)
(de/request-multiple-export {:exports exports})
:the/end)))
done))))