0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-01-09 00:10:11 -05:00
penpot/frontend/test/frontend_tests/logic/copying_and_duplicating_test.cljs

396 lines
No EOL
16 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.logic.copying-and-duplicating-test
(:require
[app.common.test-helpers.components :as cthc]
[app.common.test-helpers.compositions :as ctho]
[app.common.test-helpers.files :as cthf]
[app.common.test-helpers.ids-map :as cthi]
[app.common.test-helpers.shapes :as cths]
[app.common.uuid :as uuid]
[app.main.data.workspace :as dw]
[app.main.data.workspace.colors :as dc]
[app.main.data.workspace.libraries :as dwl]
[app.main.data.workspace.selection :as dws]
[cljs.test :as t :include-macros true]
[frontend-tests.helpers.pages :as thp]
[frontend-tests.helpers.state :as ths]))
(t/use-fixtures :each
{:before thp/reset-idmap!})
;; Related .penpot file: common/test/cases/copying-and-duplicating.penpot
(defn- setup-file []
(-> (cthf/sample-file :file1 :page-label :page-1)
(ctho/add-simple-component :simple-1 :frame-simple-1 :rect-simple-1 :child-params {:type :rect :fills (cths/sample-fills-color :fill-color "#2152e5") :name "rect-simple-1"})
(ctho/add-frame :frame-composed-1 :name "frame-composed-1")
(cthc/instantiate-component :simple-1 :copy-simple-1 :parent-label :frame-composed-1 :children-labels [:composed-1-simple-1])
(cths/add-sample-shape :rect-composed-1 :parent-label :frame-composed-1 :fills (cths/sample-fills-color :fill-color "#B1B2B5"))
(cthc/make-component :composed-1 :frame-composed-1)
(ctho/add-frame :frame-composed-2 :name "frame-composed-2")
(cthc/instantiate-component :composed-1 :copy-composed-1-composed-2 :parent-label :frame-composed-2 :children-labels [:composed-1-composed-2])
(cthc/make-component :composed-2 :frame-composed-2)
(cthc/instantiate-component :composed-2 :copy-composed-2)
(ctho/add-frame :frame-composed-3 :name "frame-composed-3")
(ctho/add-group :group-3 :parent-label :frame-composed-3)
(cthc/instantiate-component :composed-2 :copy-composed-1-composed-3 :parent-label :group-3 :children-labels [:composed-1-composed-2])
(cths/add-sample-shape :circle-composed-3 :parent-label :group-3 :fills (cths/sample-fills-color :fill-color "#B1B2B5"))
(cthc/make-component :composed-3 :frame-composed-3)
(cthc/instantiate-component :composed-3 :copy-composed-3 :children-labels [:composed-2-composed-3])
(cthf/add-sample-page :page-2)
(cthf/switch-to-page :page-1)))
(defn- copy-paste-shape
[id file & {:keys [target-page-label target-container-id]}]
(let [features #{"components/v2"}
version 46
page (cthf/current-page file)
target-page-id (cthi/id target-page-label)
shape (if (keyword? id)
(cths/get-shape file id)
(cths/get-shape-by-id file id))
pdata (thp/simulate-copy-shape #{(:id shape)} (:objects page) {(:id file) file} page file features version)
target-container-id (or target-container-id (:parent-id shape))]
(filter some?
[(when target-page-id (dw/initialize-page target-page-id))
(dws/select-shape target-container-id)
(dw/paste-shapes pdata)
(when target-page-id (dw/initialize-page (:id page)))])))
(defn- sync-file [file]
(map (fn [component-tag]
(->> component-tag
(cthc/get-component file)
:component-id
(dwl/sync-file (:id file) (:id file) :components)))
[:simple-1 :composed-1 :composed-2 :composed-3]))
(defn- set-color-bottom-shape [label file color]
(let [shape (ctho/bottom-shape file label)]
(concat
[(dws/select-shape (:id shape))
(dc/apply-color-from-palette color false)]
(sync-file file))))
(defn- count-shapes [file name color]
(let [page (cthf/current-page file)]
(->> (vals (:objects page))
(filter #(and
(= (:name %) name)
(-> (cths/get-shape-by-id file (:id %))
:fills
first
:fill-color
(= color))))
(count))))
(defn- duplicate-each-main-and-first-level-copy [file]
(concat (copy-paste-shape :frame-simple-1 file)
(copy-paste-shape :frame-simple-1 file)
(copy-paste-shape :frame-composed-1 file)
(copy-paste-shape :frame-composed-1 file)
(copy-paste-shape :frame-composed-2 file)
(copy-paste-shape :frame-composed-2 file)
(copy-paste-shape :frame-composed-3 file)
(copy-paste-shape :frame-composed-3 file)
(copy-paste-shape :copy-composed-2 file)
(copy-paste-shape :copy-composed-2 file)
(copy-paste-shape :copy-composed-3 file)
(copy-paste-shape :copy-composed-3 file)))
(defn- duplicate-simple-nested-in-main-and-group [file]
(concat (copy-paste-shape :copy-simple-1 file)
(copy-paste-shape :copy-simple-1 file)
(copy-paste-shape :group-3 file)
(copy-paste-shape :group-3 file)))
(defn- duplicate-copy-nested-and-group-out-of-the-main
[file & {:keys [target-page-label]}]
(let [page (cthf/current-page file)
frame-1-instance-ids (->> (vals (:objects page))
(filter #(and
(or
(= (:name %) "Frame1")
(= (:name %) "Group1"))
(not (:component-root %))))
(map :id))]
(concat
(apply concat (mapv #(copy-paste-shape % file :target-page-label target-page-label :target-container-id uuid/zero) frame-1-instance-ids))
(apply concat (mapv #(copy-paste-shape % file :target-page-label target-page-label :target-container-id uuid/zero) frame-1-instance-ids)))))
(t/deftest main-and-first-level-copy-1
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each main and first level copy:
;; - Duplicate it two times with copy-paste.
events
(concat
(duplicate-each-main-and-first-level-copy file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
(t/is (= (count-shapes file' "rect-simple-1" "#111111") 18)))))))))
(t/deftest main-and-first-level-copy-2
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each main and first level copy:
;; - Duplicate it two times with copy-paste.
events
(concat
(duplicate-each-main-and-first-level-copy file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"})
;; - Change color of the nearest main and check propagation to duplicated.
(set-color-bottom-shape :frame-composed-1 file {:color "#222222"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
(t/is (= (count-shapes file' "rect-simple-1" "#222222") 15)))))))))
(t/deftest main-and-first-level-copy-3
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each main and first level copy:
;; - Duplicate it two times with copy-paste.
events
(concat
(duplicate-each-main-and-first-level-copy file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"})
;; - Change color of the nearest main and check propagation to duplicated.
(set-color-bottom-shape :frame-composed-1 file {:color "#222222"})
(set-color-bottom-shape :frame-composed-2 file {:color "#333333"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
(t/is (= (count-shapes file' "rect-simple-1" "#333333") 12)))))))))
(t/deftest main-and-first-level-copy-4
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each main and first level copy:
;; - Duplicate it two times with copy-paste.
events
(concat
(duplicate-each-main-and-first-level-copy file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"})
;; - Change color of the nearest main and check propagation to duplicated.
(set-color-bottom-shape :frame-composed-1 file {:color "#222222"})
(set-color-bottom-shape :frame-composed-2 file {:color "#333333"})
(set-color-bottom-shape :frame-composed-3 file {:color "#444444"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
(t/is (= (count-shapes file' "rect-simple-1" "#444444") 6)))))))))
(t/deftest copy-nested-in-main-1
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each copy of Simple1 nested in a main, and the group inside Composed3 main:
;; - Duplicate it two times, keeping the duplicated inside the same main.
events
(concat
(duplicate-simple-nested-in-main-and-group file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
;; Check propagation to all copies.
(t/is (= (count-shapes file' "rect-simple-1" "#111111") 28)))))))))
(t/deftest copy-nested-in-main-2
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each copy of Simple1 nested in a main, and the group inside Composed3 main:
;; - Duplicate it two times, keeping the duplicated inside the same main.
events
(concat
(duplicate-simple-nested-in-main-and-group file)
;; - Change color of the nearest main
(set-color-bottom-shape :frame-composed-1 file {:color "#222222"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
;; Check propagation to duplicated.
(t/is (= (count-shapes file' "rect-simple-1" "#222222") 9)))))))))
(t/deftest copy-nested-in-main-3
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each copy of Simple1 nested in a main, and the group inside Composed3 main:
;; - Duplicate it two times, keeping the duplicated inside the same main.
events
(concat
(duplicate-simple-nested-in-main-and-group file)
;; - Change color of the copy you duplicated from.
(set-color-bottom-shape :group-3 file {:color "#333333"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
;; Check that it's NOT PROPAGATED.
(t/is (= (count-shapes file' "rect-simple-1" "#333333") 2)))))))))
(t/deftest copy-nested-1
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each copy of Simple1 nested in a main or other copy, and the group inside Composed3
;; main and copy:
;; - Duplicate it two times, moving the duplicates out of the main.
events
(concat
(duplicate-copy-nested-and-group-out-of-the-main file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
;; Check propagation to all copies.
(t/is (= (count-shapes file' "rect-simple-1" "#111111") 20)))))))))
(t/deftest copy-nested-2
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each copy of Simple1 nested in a main or other copy, and the group inside Composed3
;; main and copy:
;; - Duplicate it two times, moving the duplicates out of the main.
events
(concat
(duplicate-copy-nested-and-group-out-of-the-main file)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"})
;; - Change color of the previous main
(set-color-bottom-shape :frame-composed-1 file {:color "#222222"})
(set-color-bottom-shape :group-3 file {:color "#333333"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (ths/get-file-from-store new-state)]
;; Check that it's NOT PROPAGATED.
(t/is (= (count-shapes file' "rect-simple-1" "#111111") 11))
(t/is (= (count-shapes file' "rect-simple-1" "#222222") 7))
(t/is (= (count-shapes file' "rect-simple-1" "#333333") 2)))))))))
(t/deftest copy-nested-3
(t/async
done
(with-redefs [uuid/next cthi/next-uuid]
(let [;; ==== Setup
file (setup-file)
store (ths/setup-store file)
;; ==== Action
;; For each copy of Simple1 nested in a main or other copy, and the group inside Composed3
;; main and copy:
;; - Duplicate it two times, moving the duplicates to another page
events
(concat
(duplicate-copy-nested-and-group-out-of-the-main file :target-page-label :page-2)
;; - Change color of Simple1
(set-color-bottom-shape :frame-simple-1 file {:color "#111111"})
;; - Change color of the previous main
(set-color-bottom-shape :frame-composed-1 file {:color "#222222"})
(set-color-bottom-shape :group-3 file {:color "#333333"}))]
(ths/run-store
store done events
(fn [new-state]
(let [file' (-> (ths/get-file-from-store new-state)
(cthf/switch-to-page :page-2))]
;; Check that it's NOT PROPAGATED.
(t/is (= (count-shapes file' "rect-simple-1" "#111111") 10))
(t/is (= (count-shapes file' "rect-simple-1" "#222222") 4))
(t/is (= (count-shapes file' "rect-simple-1" "#333333") 0)))))))))