mirror of
https://github.com/penpot/penpot.git
synced 2026-11-05 19:53:15 -05:00
A rollback reverts the local data with a rebase, which is not a commit, so the parts of the workspace that follow commits missed it: - Comment pins moved in the reverted action stayed where they were, on screen and on the server, and pins on a board the rollback removed kept pointing to it. They go back to the reverted position, and pins on a removed board move to the page root. - Focus mode stayed on with no shape left when the rollback removed the focused ones, and the next shape drawn turned it on again. It ends when its last shape goes, and the selection drops removed shapes. - Component thumbnails kept the rejected look. The thumbnails of the reverted mains are rendered and uploaded again, and an upload whose shapes changed during the render is skipped. - Under WASM, an open text editor reset to the reverted content but the canvas kept the old layout. It is laid out again. - A library sync whose save failed showed no update notice again once the release undid it. The notice is checked again after that rollback.
133 lines
5.4 KiB
Clojure
133 lines
5.4 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 SUBSIDIARY SL
|
|
(ns frontend-tests.logic.comp-watcher-test
|
|
"Automatic propagation of main edits to copies, driven by the real
|
|
`dwl/watch-component-changes` on an isolated store."
|
|
(:require
|
|
[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.main.data.changes :as dch]
|
|
[app.main.data.helpers :as dsh]
|
|
[app.main.data.workspace.libraries :as dwl]
|
|
[app.main.data.workspace.pages :as dwpg]
|
|
[app.main.data.workspace.shapes :as dwsh]
|
|
[app.main.data.workspace.thumbnails-wasm :as dwt.wasm]
|
|
[app.main.refs :as refs]
|
|
[app.main.store :as st]
|
|
[beicon.v2.core :as rx]
|
|
[cljs.test :as t :include-macros true]
|
|
[frontend-tests.helpers.async :as async]
|
|
[frontend-tests.helpers.mock :as mock]
|
|
[frontend-tests.helpers.pages :as thp]
|
|
[frontend-tests.helpers.state :as ths]
|
|
[frontend-tests.helpers.wasm :as thw]
|
|
[okulary.core :as l]
|
|
[potok.v2.core :as ptk]))
|
|
|
|
(t/use-fixtures :each
|
|
{:before (fn []
|
|
(thp/reset-idmap!)
|
|
(thw/setup-wasm-mocks!))
|
|
:after thw/teardown-wasm-mocks!})
|
|
|
|
(defn- setup-file
|
|
[]
|
|
;; {:main-root} [:name Frame1] # [Component :component1]
|
|
;; :main-child [:name Rect1]
|
|
;;
|
|
;; :copy-root [:name Frame1] #--> [Component :component1] :main-root
|
|
;; :copy-child [:name Rect1] ---> :main-child
|
|
;;
|
|
;; :outside [:name Frame1]
|
|
(-> (cthf/sample-file :file1)
|
|
(ctho/add-simple-component-with-copy :component1
|
|
:main-root
|
|
:main-child
|
|
:copy-root
|
|
:copy-root-params {:children-labels [:copy-child]})
|
|
(ctho/add-frame :outside)))
|
|
|
|
(defn- noop-render-thumbnail
|
|
[& _]
|
|
(ptk/reify ::noop-render-thumbnail
|
|
ptk/WatchEvent
|
|
(watch [_ _ _] (rx/empty))))
|
|
|
|
(defn- copy-children
|
|
[store]
|
|
(let [file (ths/get-file-from-state @store)]
|
|
(:shapes (cths/get-shape file :copy-root))))
|
|
|
|
(t/deftest ^:async child-moved-out-of-main-leaves-copy-when-another-edit-follows
|
|
;; The move and the fill change commit in the same tick, so the watcher
|
|
;; inspects both in one batch. The move must be checked against the file
|
|
;; data right before it, where the rect still sits in the main.
|
|
(let [file (setup-file)
|
|
store (ths/setup-store file)]
|
|
(await
|
|
(mock/with-mocks*
|
|
{;; The watcher reads the file data through this lens.
|
|
refs/workspace-data (l/derived dsh/lookup-file-data store)
|
|
;; Thumbnail renders read the global store.
|
|
st/state store
|
|
dwt.wasm/render-thumbnail noop-render-thumbnail}
|
|
|
|
(ptk/emit! store (dwl/watch-component-changes))
|
|
(t/is (= 1 (count (copy-children store)))
|
|
"the copy starts with its rect")
|
|
|
|
(ptk/emit! store
|
|
(dwsh/relocate-shapes #{(cthi/id :main-child)} (cthi/id :outside) 0)
|
|
(dwsh/update-shapes [(cthi/id :outside)]
|
|
#(assoc % :fills [{:fill-color "#ff0000"
|
|
:fill-opacity 1}])))
|
|
|
|
(await (async/wait-for #(empty? (copy-children store))
|
|
"the copy to lose its rect"))
|
|
|
|
(let [file' (ths/get-file-from-state @store)]
|
|
(t/is (= (cthi/id :outside)
|
|
(:parent-id (cths/get-shape file' :main-child)))
|
|
"the rect moved out of the main")
|
|
(t/is (empty? (copy-children store))
|
|
"the copy lost its rect"))
|
|
|
|
(ptk/emit! store (dwpg/finalize-page (:id file) (cthf/current-page-id file)))
|
|
(await (async/settle))))))
|
|
|
|
;; Scenario: a rollback reverts the opacity of the main's child. A rollback
|
|
;; is not a commit, so the change watch sees no component change.
|
|
;; Proves: the component's thumbnail is rendered again and uploaded, so
|
|
;; neither the tab nor the server keeps a thumbnail of the rejected data.
|
|
(t/deftest ^:async a-rollback-of-a-main-renders-and-uploads-its-thumbnail
|
|
(let [file (setup-file)
|
|
store (ths/setup-store file)
|
|
page-id (cthf/current-page-id file)
|
|
renders (atom [])]
|
|
(await
|
|
(mock/with-mocks*
|
|
{refs/workspace-data (l/derived dsh/lookup-file-data store)
|
|
st/state store
|
|
dwt.wasm/render-thumbnail (fn [_ _ frame-id & {:as opts}]
|
|
(swap! renders conj [frame-id opts])
|
|
(noop-render-thumbnail))}
|
|
|
|
(ptk/emit! store (dwl/watch-component-changes))
|
|
(ptk/emit! store (dch/rebase-commits
|
|
(:id file)
|
|
{:undo []
|
|
:remote [{:type :mod-obj :id (cthi/id :main-child) :page-id page-id
|
|
:operations [{:type :set :attr :opacity :val 0.5}]}]
|
|
:redo []}))
|
|
|
|
(await (async/wait-for #(seq @renders) "the thumbnail to render"))
|
|
(t/is (= [[(cthi/id :main-root) {:persist? true}]] @renders))
|
|
|
|
(ptk/emit! store (dwpg/finalize-page (:id file) page-id))
|
|
(await (async/settle))))))
|