mirror of
https://github.com/penpot/penpot.git
synced 2025-05-23 01:36:11 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
cba62c0172
14 changed files with 296 additions and 39 deletions
|
@ -114,7 +114,7 @@
|
||||||
(partial not-found-handler request)))
|
(partial not-found-handler request)))
|
||||||
|
|
||||||
(on-error [cause request]
|
(on-error [cause request]
|
||||||
(let [{:keys [body] :as response} (errors/handle cause request)]
|
(let [{:keys [::rres/body] :as response} (errors/handle cause request)]
|
||||||
(cond-> response
|
(cond-> response
|
||||||
(map? body)
|
(map? body)
|
||||||
(-> (update ::rres/headers assoc "content-type" "application/transit+json")
|
(-> (update ::rres/headers assoc "content-type" "application/transit+json")
|
||||||
|
@ -150,10 +150,10 @@
|
||||||
[["" {:middleware [[mw/server-timing]
|
[["" {:middleware [[mw/server-timing]
|
||||||
[mw/params]
|
[mw/params]
|
||||||
[mw/format-response]
|
[mw/format-response]
|
||||||
|
[mw/errors errors/handle]
|
||||||
[mw/parse-request]
|
[mw/parse-request]
|
||||||
[session/soft-auth cfg]
|
[session/soft-auth cfg]
|
||||||
[actoken/soft-auth cfg]
|
[actoken/soft-auth cfg]
|
||||||
[mw/errors errors/handle]
|
|
||||||
[mw/restrict-methods]]}
|
[mw/restrict-methods]]}
|
||||||
|
|
||||||
(::mtx/routes cfg)
|
(::mtx/routes cfg)
|
||||||
|
|
|
@ -10,16 +10,13 @@
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.config :as cf]
|
[app.config :as cf]
|
||||||
[app.util.json :as json]
|
[clojure.data.json :as json]
|
||||||
[cuerdas.core :as str]
|
[cuerdas.core :as str]
|
||||||
[ring.request :as rreq]
|
[ring.request :as rreq]
|
||||||
[ring.response :as rres]
|
[ring.response :as rres]
|
||||||
[yetti.adapter :as yt]
|
[yetti.adapter :as yt]
|
||||||
[yetti.middleware :as ymw])
|
[yetti.middleware :as ymw])
|
||||||
(:import
|
(:import
|
||||||
com.fasterxml.jackson.core.JsonParseException
|
|
||||||
com.fasterxml.jackson.core.io.JsonEOFException
|
|
||||||
com.fasterxml.jackson.databind.exc.MismatchedInputException
|
|
||||||
io.undertow.server.RequestTooBigException
|
io.undertow.server.RequestTooBigException
|
||||||
java.io.InputStream
|
java.io.InputStream
|
||||||
java.io.OutputStream))
|
java.io.OutputStream))
|
||||||
|
@ -34,11 +31,22 @@
|
||||||
{:name ::params
|
{:name ::params
|
||||||
:compile (constantly ymw/wrap-params)})
|
:compile (constantly ymw/wrap-params)})
|
||||||
|
|
||||||
(def ^:private json-mapper
|
(defn- get-reader
|
||||||
(json/mapper
|
^java.io.BufferedReader
|
||||||
{:encode-key-fn str/camel
|
[request]
|
||||||
:decode-key-fn (comp keyword str/kebab)
|
(let [^InputStream body (rreq/body request)]
|
||||||
:pretty true}))
|
(java.io.BufferedReader.
|
||||||
|
(java.io.InputStreamReader. body))))
|
||||||
|
|
||||||
|
(defn- read-json-key
|
||||||
|
[k]
|
||||||
|
(-> k str/kebab keyword))
|
||||||
|
|
||||||
|
(defn- write-json-key
|
||||||
|
[k]
|
||||||
|
(if (or (keyword? k) (symbol? k))
|
||||||
|
(str/camel k)
|
||||||
|
(str k)))
|
||||||
|
|
||||||
(defn wrap-parse-request
|
(defn wrap-parse-request
|
||||||
[handler]
|
[handler]
|
||||||
|
@ -53,8 +61,8 @@
|
||||||
(update :params merge params))))
|
(update :params merge params))))
|
||||||
|
|
||||||
(str/starts-with? header "application/json")
|
(str/starts-with? header "application/json")
|
||||||
(with-open [^InputStream is (rreq/body request)]
|
(with-open [reader (get-reader request)]
|
||||||
(let [params (json/decode is json-mapper)]
|
(let [params (json/read reader :key-fn read-json-key)]
|
||||||
(-> request
|
(-> request
|
||||||
(assoc :body-params params)
|
(assoc :body-params params)
|
||||||
(update :params merge params))))
|
(update :params merge params))))
|
||||||
|
@ -74,9 +82,7 @@
|
||||||
:code :request-body-too-large
|
:code :request-body-too-large
|
||||||
:hint (ex-message cause))
|
:hint (ex-message cause))
|
||||||
|
|
||||||
(or (instance? JsonEOFException cause)
|
(instance? java.io.EOFException cause)
|
||||||
(instance? JsonParseException cause)
|
|
||||||
(instance? MismatchedInputException cause))
|
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :malformed-json
|
:code :malformed-json
|
||||||
:hint (ex-message cause)
|
:hint (ex-message cause)
|
||||||
|
@ -128,7 +134,8 @@
|
||||||
(-write-body-to-stream [_ _ output-stream]
|
(-write-body-to-stream [_ _ output-stream]
|
||||||
(try
|
(try
|
||||||
(with-open [^OutputStream bos (buffered-output-stream output-stream buffer-size)]
|
(with-open [^OutputStream bos (buffered-output-stream output-stream buffer-size)]
|
||||||
(json/write! bos data json-mapper))
|
(with-open [^java.io.OutputStreamWriter writer (java.io.OutputStreamWriter. bos)]
|
||||||
|
(json/write data writer :key-fn write-json-key)))
|
||||||
|
|
||||||
(catch java.io.IOException _)
|
(catch java.io.IOException _)
|
||||||
(catch Throwable cause
|
(catch Throwable cause
|
||||||
|
|
|
@ -140,6 +140,7 @@
|
||||||
(::rpc/profile-id params)
|
(::rpc/profile-id params)
|
||||||
uuid/zero)
|
uuid/zero)
|
||||||
|
|
||||||
|
session-id (rreq/get-header request "x-external-session-id")
|
||||||
props (-> (or (::replace-props resultm)
|
props (-> (or (::replace-props resultm)
|
||||||
(-> params
|
(-> params
|
||||||
(merge (::props resultm))
|
(merge (::props resultm))
|
||||||
|
@ -150,6 +151,7 @@
|
||||||
|
|
||||||
token-id (::actoken/id request)
|
token-id (::actoken/id request)
|
||||||
context (-> (::context resultm)
|
context (-> (::context resultm)
|
||||||
|
(assoc :external-session-id session-id)
|
||||||
(assoc :access-token-id (some-> token-id str))
|
(assoc :access-token-id (some-> token-id str))
|
||||||
(d/without-nils))]
|
(d/without-nils))]
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
[app.common.fressian :as fres]
|
[app.common.fressian :as fres]
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[clojure.core :as c])
|
[clojure.core :as c]
|
||||||
|
[clojure.data.json :as json])
|
||||||
(:import
|
(:import
|
||||||
clojure.lang.Counted
|
clojure.lang.Counted
|
||||||
clojure.lang.IHashEq
|
clojure.lang.IHashEq
|
||||||
|
@ -83,6 +84,10 @@
|
||||||
^:unsynchronized-mutable loaded?
|
^:unsynchronized-mutable loaded?
|
||||||
^:unsynchronized-mutable modified?]
|
^:unsynchronized-mutable modified?]
|
||||||
|
|
||||||
|
json/JSONWriter
|
||||||
|
(-write [this writter options]
|
||||||
|
(json/-write (into {} this) writter options))
|
||||||
|
|
||||||
IHashEq
|
IHashEq
|
||||||
(hasheq [this]
|
(hasheq [this]
|
||||||
(when-not hash
|
(when-not hash
|
||||||
|
|
|
@ -40,7 +40,8 @@
|
||||||
[app.common.transit :as t]
|
[app.common.transit :as t]
|
||||||
[app.common.uuid :as uuid]
|
[app.common.uuid :as uuid]
|
||||||
[app.util.time :as dt]
|
[app.util.time :as dt]
|
||||||
[clojure.core :as c])
|
[clojure.core :as c]
|
||||||
|
[clojure.data.json :as json])
|
||||||
(:import
|
(:import
|
||||||
clojure.lang.Counted
|
clojure.lang.Counted
|
||||||
clojure.lang.IDeref
|
clojure.lang.IDeref
|
||||||
|
@ -75,6 +76,14 @@
|
||||||
^:unsynchronized-mutable modified?
|
^:unsynchronized-mutable modified?
|
||||||
^:unsynchronized-mutable loaded?]
|
^:unsynchronized-mutable loaded?]
|
||||||
|
|
||||||
|
json/JSONWriter
|
||||||
|
(-write [this writter options]
|
||||||
|
(json/-write {:type "pointer"
|
||||||
|
:id (get-id this)
|
||||||
|
:meta (meta this)}
|
||||||
|
writter
|
||||||
|
options))
|
||||||
|
|
||||||
IPointerMap
|
IPointerMap
|
||||||
(load! [_]
|
(load! [_]
|
||||||
(when-not *load-fn*
|
(when-not *load-fn*
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
(ns app.common.test-helpers.components
|
(ns app.common.test-helpers.components
|
||||||
(:require
|
(:require
|
||||||
|
[app.common.data :as d]
|
||||||
[app.common.data.macros :as dm]
|
[app.common.data.macros :as dm]
|
||||||
[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]
|
||||||
|
@ -64,13 +65,12 @@
|
||||||
[file id]
|
[file id]
|
||||||
(ctkl/get-component (:data file) id))
|
(ctkl/get-component (:data file) id))
|
||||||
|
|
||||||
(defn set-child-label
|
(defn- set-children-labels!
|
||||||
[file shape-label child-idx label]
|
[file shape-label children-labels]
|
||||||
(let [id (-> (ths/get-shape file shape-label)
|
(doseq [[label id]
|
||||||
:shapes
|
(d/zip children-labels (cfh/get-children-ids (-> (thf/current-page file) :objects)
|
||||||
(nth child-idx))]
|
(thi/id shape-label)))]
|
||||||
(when id
|
(thi/set-id! label id)))
|
||||||
(thi/set-id! label id))))
|
|
||||||
|
|
||||||
(defn instantiate-component
|
(defn instantiate-component
|
||||||
[file component-label copy-root-label & {:keys [parent-label library children-labels] :as params}]
|
[file component-label copy-root-label & {:keys [parent-label library children-labels] :as params}]
|
||||||
|
@ -103,6 +103,7 @@
|
||||||
|
|
||||||
(and (some? parent) (ctn/in-any-component? (:objects page) parent))
|
(and (some? parent) (ctn/in-any-component? (:objects page) parent))
|
||||||
(dissoc :component-root))
|
(dissoc :component-root))
|
||||||
|
|
||||||
file' (ctf/update-file-data
|
file' (ctf/update-file-data
|
||||||
file
|
file
|
||||||
(fn [file-data]
|
(fn [file-data]
|
||||||
|
@ -128,14 +129,14 @@
|
||||||
true)))
|
true)))
|
||||||
$
|
$
|
||||||
(remove #(= (:id %) (:id copy-root')) copy-shapes)))))]
|
(remove #(= (:id %) (:id copy-root')) copy-shapes)))))]
|
||||||
|
|
||||||
(when children-labels
|
(when children-labels
|
||||||
(dotimes [idx (count children-labels)]
|
(set-children-labels! file' copy-root-label children-labels))
|
||||||
(set-child-label file' copy-root-label idx (nth children-labels idx))))
|
|
||||||
|
|
||||||
file'))
|
file'))
|
||||||
|
|
||||||
(defn component-swap
|
(defn component-swap
|
||||||
[file shape-label new-component-label new-shape-label & {:keys [library] :as params}]
|
[file shape-label new-component-label new-shape-label & {:keys [library children-labels] :as params}]
|
||||||
(let [shape (ths/get-shape file shape-label)
|
(let [shape (ths/get-shape file shape-label)
|
||||||
library (or library file)
|
library (or library file)
|
||||||
libraries {(:id library) library}
|
libraries {(:id library) library}
|
||||||
|
@ -147,10 +148,15 @@
|
||||||
;; Store the properties that need to be maintained when the component is swapped
|
;; Store the properties that need to be maintained when the component is swapped
|
||||||
keep-props-values (select-keys shape ctk/swap-keep-attrs)
|
keep-props-values (select-keys shape ctk/swap-keep-attrs)
|
||||||
|
|
||||||
|
|
||||||
[new_shape _ changes]
|
[new_shape _ changes]
|
||||||
(-> (pcb/empty-changes nil (:id page))
|
(-> (pcb/empty-changes nil (:id page))
|
||||||
(cll/generate-component-swap objects shape (:data file) page libraries id-new-component 0 nil keep-props-values))]
|
(cll/generate-component-swap objects shape (:data file) page libraries id-new-component 0 nil keep-props-values))
|
||||||
|
|
||||||
|
file' (thf/apply-changes file changes)]
|
||||||
|
|
||||||
(thi/set-id! new-shape-label (:id new_shape))
|
(thi/set-id! new-shape-label (:id new_shape))
|
||||||
(thf/apply-changes file changes)))
|
|
||||||
|
(when children-labels
|
||||||
|
(set-children-labels! file' new-shape-label children-labels))
|
||||||
|
|
||||||
|
file'))
|
||||||
|
|
|
@ -58,6 +58,28 @@
|
||||||
:parent-label frame-label}
|
:parent-label frame-label}
|
||||||
child-params))))
|
child-params))))
|
||||||
|
|
||||||
|
(defn add-minimal-component
|
||||||
|
[file component-label root-label
|
||||||
|
& {:keys [component-params root-params]}]
|
||||||
|
;; Generated shape tree:
|
||||||
|
;; {:root-label} [:name Frame1] # [Component :component-label]
|
||||||
|
(-> file
|
||||||
|
(add-frame root-label root-params)
|
||||||
|
(thc/make-component component-label root-label component-params)))
|
||||||
|
|
||||||
|
(defn add-minimal-component-with-copy
|
||||||
|
[file component-label main-root-label copy-root-label
|
||||||
|
& {:keys [component-params main-root-params copy-root-params]}]
|
||||||
|
;; Generated shape tree:
|
||||||
|
;; {:main-root-label} [:name Frame1] # [Component :component-label]
|
||||||
|
;; :copy-root-label [:name Frame1] #--> [Component :component-label] :main-root-label
|
||||||
|
(-> file
|
||||||
|
(add-minimal-component component-label
|
||||||
|
main-root-label
|
||||||
|
:component-params component-params
|
||||||
|
:root-params main-root-params)
|
||||||
|
(thc/instantiate-component component-label copy-root-label copy-root-params)))
|
||||||
|
|
||||||
(defn add-simple-component
|
(defn add-simple-component
|
||||||
[file component-label root-label child-label
|
[file component-label root-label child-label
|
||||||
& {:keys [component-params root-params child-params]}]
|
& {:keys [component-params root-params child-params]}]
|
||||||
|
|
BIN
common/test/cases/detach-with-swap.penpot
Normal file
BIN
common/test/cases/detach-with-swap.penpot
Normal file
Binary file not shown.
BIN
common/test/cases/remove-swap-slots.penpot
Normal file
BIN
common/test/cases/remove-swap-slots.penpot
Normal file
Binary file not shown.
197
common/test/common_tests/logic/comp_detach_with_swap_test.cljc
Normal file
197
common/test/common_tests/logic/comp_detach_with_swap_test.cljc
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
;; 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 common-tests.logic.comp-detach-with-swap-test
|
||||||
|
(:require
|
||||||
|
[app.common.files.changes-builder :as pcb]
|
||||||
|
[app.common.logic.libraries :as cll]
|
||||||
|
[app.common.test-helpers.components :as thc]
|
||||||
|
[app.common.test-helpers.compositions :as tho]
|
||||||
|
[app.common.test-helpers.files :as thf]
|
||||||
|
[app.common.test-helpers.ids-map :as thi]
|
||||||
|
[app.common.test-helpers.shapes :as ths]
|
||||||
|
[app.common.types.component :as ctk]
|
||||||
|
[clojure.test :as t]))
|
||||||
|
|
||||||
|
(t/use-fixtures :each thi/test-fixture)
|
||||||
|
|
||||||
|
;; Related .penpot file: common/test/cases/detach-with-swap.penpot
|
||||||
|
(defn- setup-file
|
||||||
|
[]
|
||||||
|
;; {:r-ellipse} [:name Ellipse, :type :frame] # [Component :c-ellipse]
|
||||||
|
;; :ellipse [:name Ellipse, :type :circle]
|
||||||
|
;; {:r-rectangle} [:name Rectangle, :type :frame] # [Component :c-rectangle]
|
||||||
|
;; :rectangle [:name rectangle, :type :rect]
|
||||||
|
;; {:board-with-ellipse} [:name Board with ellipse, :type :frame] # [Component :c-board-with-ellipse]
|
||||||
|
;; :nested-h-ellipse [:name Ellipse, :type :frame] @--> :r-ellipse
|
||||||
|
;; :nested-ellipse [:name Ellipse, :type :circle] ---> :ellipse
|
||||||
|
;; {:board-with-rectangle} [:name Board with rectangle, :type :frame] # [Component :c-board-with-rectangle]
|
||||||
|
;; :nested-h-rectangle [:name Rectangle, :type :frame] @--> :r-rectangle
|
||||||
|
;; :nested-rectangle [:name rectangle, :type :rect] ---> :rectangle
|
||||||
|
;; {:big-board} [:name Big Board, :type :frame] # [Component :c-big-board]
|
||||||
|
;; :h-board-with-ellipse [:name Board with ellipse, :type :frame] @--> :board-with-ellipse
|
||||||
|
;; :nested2-h-ellipse [:name Ellipse, :type :frame] @--> :nested-h-ellipse
|
||||||
|
;; :nested2-ellipse [:name Ellipse, :type :circle] ---> :nested-ellipse
|
||||||
|
(-> (thf/sample-file :file1)
|
||||||
|
|
||||||
|
(tho/add-simple-component :c-ellipse :r-ellipse :ellipse
|
||||||
|
:root-params {:name "Ellipse"}
|
||||||
|
:child-params {:name "Ellipse" :type :circle})
|
||||||
|
|
||||||
|
(tho/add-simple-component :c-rectangle :r-rectangle :rectangle
|
||||||
|
:root-params {:name "Rectangle"}
|
||||||
|
:child-params {:name "rectangle" :type :rect})
|
||||||
|
|
||||||
|
(tho/add-frame :board-with-ellipse :name "Board with ellipse")
|
||||||
|
(thc/instantiate-component :c-ellipse :nested-h-ellipse :parent-label :board-with-ellipse
|
||||||
|
:children-labels [:nested-ellipse])
|
||||||
|
(thc/make-component :c-board-with-ellipse :board-with-ellipse)
|
||||||
|
|
||||||
|
(tho/add-frame :board-with-rectangle :name "Board with rectangle")
|
||||||
|
(thc/instantiate-component :c-rectangle :nested-h-rectangle :parent-label :board-with-rectangle
|
||||||
|
:children-labels [:nested-rectangle])
|
||||||
|
(thc/make-component :c-board-with-rectangle :board-with-rectangle)
|
||||||
|
|
||||||
|
(tho/add-frame :big-board :name "Big Board")
|
||||||
|
(thc/instantiate-component :c-board-with-ellipse
|
||||||
|
:h-board-with-ellipse
|
||||||
|
:parent-label :big-board
|
||||||
|
:children-labels [:nested2-h-ellipse :nested2-ellipse])
|
||||||
|
(thc/make-component :c-big-board :big-board)))
|
||||||
|
|
||||||
|
(t/deftest test-advance-when-not-swapped
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (-> (setup-file)
|
||||||
|
(thc/instantiate-component :c-big-board
|
||||||
|
:copy-big-board
|
||||||
|
:children-labels [:copy-h-board-with-ellipse
|
||||||
|
:copy-nested-h-ellipse
|
||||||
|
:copy-nested-ellipse]))
|
||||||
|
|
||||||
|
page (thf/current-page file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
changes (cll/generate-detach-instance (-> (pcb/empty-changes nil)
|
||||||
|
(pcb/with-page page)
|
||||||
|
(pcb/with-objects (:objects page)))
|
||||||
|
page
|
||||||
|
{(:id file) file}
|
||||||
|
(thi/id :copy-big-board))
|
||||||
|
file' (thf/apply-changes file changes)
|
||||||
|
|
||||||
|
;; ==== Get
|
||||||
|
copy-h-board-with-ellipse (ths/get-shape file' :copy-h-board-with-ellipse)
|
||||||
|
copy-nested-h-ellipse (ths/get-shape file' :copy-nested-h-ellipse)
|
||||||
|
copy-nested-ellipse (ths/get-shape file' :copy-nested-ellipse)]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
|
||||||
|
;; In the normal case, children's ref (that pointed to the near main inside big-board)
|
||||||
|
;; are advanced to point to the new near main inside board-with-ellipse.
|
||||||
|
(t/is (ctk/instance-root? copy-h-board-with-ellipse))
|
||||||
|
(t/is (= (:shape-ref copy-h-board-with-ellipse) (thi/id :board-with-ellipse)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-h-board-with-ellipse)))
|
||||||
|
|
||||||
|
(t/is (ctk/instance-head? copy-nested-h-ellipse))
|
||||||
|
(t/is (= (:shape-ref copy-nested-h-ellipse) (thi/id :nested-h-ellipse)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-nested-h-ellipse)))
|
||||||
|
|
||||||
|
(t/is (not (ctk/instance-head? copy-nested-ellipse)))
|
||||||
|
(t/is (= (:shape-ref copy-nested-ellipse) (thi/id :nested-ellipse)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-nested-ellipse)))))
|
||||||
|
|
||||||
|
(t/deftest test-dont-advance-when-swapped-copy
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (-> (setup-file)
|
||||||
|
(thc/instantiate-component :c-big-board
|
||||||
|
:copy-big-board
|
||||||
|
:children-labels [:copy-h-board-with-ellipse
|
||||||
|
:copy-nested-h-ellipse
|
||||||
|
:copy-nested-ellipse])
|
||||||
|
(thc/component-swap :copy-h-board-with-ellipse
|
||||||
|
:c-board-with-rectangle
|
||||||
|
:copy-h-board-with-rectangle
|
||||||
|
:children-labels [:copy-nested-h-rectangle
|
||||||
|
:copy-nested-rectangle]))
|
||||||
|
|
||||||
|
page (thf/current-page file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
changes (cll/generate-detach-instance (-> (pcb/empty-changes nil)
|
||||||
|
(pcb/with-page page)
|
||||||
|
(pcb/with-objects (:objects page)))
|
||||||
|
page
|
||||||
|
{(:id file) file}
|
||||||
|
(thi/id :copy-big-board))
|
||||||
|
file' (thf/apply-changes file changes)
|
||||||
|
|
||||||
|
;; ==== Get
|
||||||
|
copy-h-board-with-rectangle (ths/get-shape file' :copy-h-board-with-rectangle)
|
||||||
|
copy-nested-h-rectangle (ths/get-shape file' :copy-nested-h-rectangle)
|
||||||
|
copy-nested-rectangle (ths/get-shape file' :copy-nested-rectangle)]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
|
||||||
|
;; If the nested copy was swapped, there is no need to advance shape-refs,
|
||||||
|
;; as they already pointing to the near main inside board-with-rectangle.
|
||||||
|
(t/is (ctk/instance-root? copy-h-board-with-rectangle))
|
||||||
|
(t/is (= (:shape-ref copy-h-board-with-rectangle) (thi/id :board-with-rectangle)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-h-board-with-rectangle)))
|
||||||
|
|
||||||
|
(t/is (ctk/instance-head? copy-nested-h-rectangle))
|
||||||
|
(t/is (= (:shape-ref copy-nested-h-rectangle) (thi/id :nested-h-rectangle)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-nested-h-rectangle)))
|
||||||
|
|
||||||
|
(t/is (not (ctk/instance-head? copy-nested-rectangle)))
|
||||||
|
(t/is (= (:shape-ref copy-nested-rectangle) (thi/id :nested-rectangle)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-nested-rectangle)))))
|
||||||
|
|
||||||
|
(t/deftest test-propagate-slot-when-swapped-main
|
||||||
|
(let [;; ==== Setup
|
||||||
|
file (-> (setup-file)
|
||||||
|
(thc/component-swap :nested2-h-ellipse
|
||||||
|
:c-rectangle
|
||||||
|
:nested2-h-rectangle
|
||||||
|
:children-labels [:nested2-rectangle])
|
||||||
|
(thc/instantiate-component :c-big-board
|
||||||
|
:copy-big-board
|
||||||
|
:children-labels [:copy-h-board-with-ellipse
|
||||||
|
:copy-nested-h-rectangle
|
||||||
|
:copy-nested-rectangle]))
|
||||||
|
|
||||||
|
page (thf/current-page file)
|
||||||
|
|
||||||
|
;; ==== Action
|
||||||
|
changes (cll/generate-detach-instance (-> (pcb/empty-changes nil)
|
||||||
|
(pcb/with-page page)
|
||||||
|
(pcb/with-objects (:objects page)))
|
||||||
|
page
|
||||||
|
{(:id file) file}
|
||||||
|
(thi/id :copy-big-board))
|
||||||
|
file' (thf/apply-changes file changes)
|
||||||
|
|
||||||
|
;; ==== Get
|
||||||
|
copy-h-board-with-ellipse (ths/get-shape file' :copy-h-board-with-ellipse)
|
||||||
|
copy-nested-h-rectangle (ths/get-shape file' :copy-nested-h-rectangle)
|
||||||
|
copy-nested-rectangle (ths/get-shape file' :copy-nested-rectangle)]
|
||||||
|
|
||||||
|
;; ==== Check
|
||||||
|
|
||||||
|
;; This one is advanced normally, as it has not been swapped.
|
||||||
|
(t/is (ctk/instance-root? copy-h-board-with-ellipse))
|
||||||
|
(t/is (= (:shape-ref copy-h-board-with-ellipse) (thi/id :board-with-ellipse)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-h-board-with-ellipse)))
|
||||||
|
|
||||||
|
;; If the nested copy has been swapped in the main, it does advance,
|
||||||
|
;; but the swap slot of the near main is propagated to the copy.
|
||||||
|
(t/is (ctk/instance-head? copy-nested-h-rectangle))
|
||||||
|
(t/is (= (:shape-ref copy-nested-h-rectangle) (thi/id :r-rectangle)))
|
||||||
|
(t/is (= (ctk/get-swap-slot copy-nested-h-rectangle) (thi/id :nested-h-ellipse)))
|
||||||
|
|
||||||
|
(t/is (not (ctk/instance-head? copy-nested-rectangle)))
|
||||||
|
(t/is (= (:shape-ref copy-nested-rectangle) (thi/id :rectangle)))
|
||||||
|
(t/is (nil? (ctk/get-swap-slot copy-nested-rectangle)))))
|
||||||
|
|
|
@ -758,7 +758,6 @@
|
||||||
(t/is (some? blue-copy1'))
|
(t/is (some? blue-copy1'))
|
||||||
(t/is (nil? (ctk/get-swap-slot blue-copy1')))))
|
(t/is (nil? (ctk/get-swap-slot blue-copy1')))))
|
||||||
|
|
||||||
|
|
||||||
(t/deftest test-remove-swap-slot-detach
|
(t/deftest test-remove-swap-slot-detach
|
||||||
(let [;; ==== Setup
|
(let [;; ==== Setup
|
||||||
file (setup-file)
|
file (setup-file)
|
||||||
|
|
|
@ -130,9 +130,16 @@
|
||||||
(def worker-uri
|
(def worker-uri
|
||||||
(obj/get global "penpotWorkerURI" "/js/worker.js"))
|
(obj/get global "penpotWorkerURI" "/js/worker.js"))
|
||||||
|
|
||||||
(defn external-feature-flag [flag value]
|
(defn external-feature-flag
|
||||||
(when-let [fn (obj/get global "externalFeatureFlag")]
|
[flag value]
|
||||||
(fn flag value)))
|
(let [f (obj/get global "externalFeatureFlag")]
|
||||||
|
(when (fn? f)
|
||||||
|
(f flag value))))
|
||||||
|
|
||||||
|
(defn external-session-id
|
||||||
|
[]
|
||||||
|
(let [f (obj/get global "externalSessionId")]
|
||||||
|
(when (fn? f) (f))))
|
||||||
|
|
||||||
;; --- Helper Functions
|
;; --- Helper Functions
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,9 @@
|
||||||
(let [session* (or @session (dt/now))
|
(let [session* (or @session (dt/now))
|
||||||
context (-> @context
|
context (-> @context
|
||||||
(merge (:context event))
|
(merge (:context event))
|
||||||
(assoc :session session*))]
|
(assoc :session session*)
|
||||||
|
(assoc :external-session-id (cf/external-session-id))
|
||||||
|
(d/without-nils))]
|
||||||
(reset! session session*)
|
(reset! session session*)
|
||||||
(-> event
|
(-> event
|
||||||
(assoc :timestamp (dt/now))
|
(assoc :timestamp (dt/now))
|
||||||
|
|
|
@ -97,7 +97,8 @@
|
||||||
request {:method method
|
request {:method method
|
||||||
:uri (u/join cf/public-uri "api/rpc/command/" nid)
|
:uri (u/join cf/public-uri "api/rpc/command/" nid)
|
||||||
:credentials "include"
|
:credentials "include"
|
||||||
:headers {"accept" "application/transit+json,text/event-stream,*/*"}
|
:headers {"accept" "application/transit+json,text/event-stream,*/*"
|
||||||
|
"x-external-session-id" (cf/external-session-id)}
|
||||||
:body (when (= method :post)
|
:body (when (= method :post)
|
||||||
(if form-data?
|
(if form-data?
|
||||||
(http/form-data params)
|
(http/form-data params)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue