penpot/common/test/common_tests/logic/comp_remote_synced_test.cljc
alonso.torres cc6edd1032 🐛 Cascade structural edits through deleted component mains
Add, delete and move changes inside a deleted main carry a component
container ID. The change scanner ignored that destination, so it never
synced the deleted component's surviving copies after a structural edit.
Return the container's component ID for all three change kinds.

The integration regression failed with dangling refs before the fix.
It now removes the child from both the stored main and its copies and
checks undo/redo. Focused common suites pass: 66 tests, 11263 assertions.
Common lint passes.

Sync benchmark ratios against the 1e baseline (lower quantile):
main 10/100/1000 copies 0.55/0.65/0.61; three levels 0.52; chain 0.62;
library 0.58; many shapes 0.69; variant switch 0.79. No regression flags.

AI-assisted-by: GPT-6
2026-10-30 09:50:08 +01:00

51 lines
2.3 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 common-tests.logic.comp-remote-synced-test
(:require
[app.common.test-helpers.composable.comp.nodes :as n]
[app.common.test-helpers.composable.comp.runner :as r]
[app.common.test-helpers.composable.comp.setups :as setup]
[app.common.test-helpers.composable.comp.undo-check :as uc]
[app.common.test-helpers.composable.core :as tm]
[app.common.test-helpers.ids-map :as thi]
[clojure.test :as t]))
(t/use-fixtures :each thi/test-fixture)
(t/deftest updating-main-keeps-overrides-authored-since-the-previous-update
(let [middle-copy (fn [s]
(:parent-id (tm/shape-by-id s ((n/nested-head-of "a" 1) s))))
nested-main-rect (fn [s] (n/level-rect s "a" 0))
situation
(r/run-variant
{:setup setup/empty-situation
:operation
(tm/in-sequence
[(n/create-component "a" "#abcdef" :size 100)
(n/make-nested-component "a" 2)
(n/change-property middle-copy :fills "#ff0000")
(n/update-main middle-copy)
;; Push a nested override, then update again for another edit.
(n/change-property (n/main-rect-of "a") :name "Authored name")
(n/update-main middle-copy)
(n/change-property middle-copy :opacity 0.4)
(n/update-main middle-copy)])})
main (tm/shape-by-id situation (nested-main-rect situation))]
(t/is (= "Authored name" (:name main)))
(t/is (contains? (:touched main) :name-group))))
(t/deftest inner-child-removal-propagates-through-a-deleted-outer-main
(let [situation (r/run-variant
{:setup setup/nested-component-with-copy
:operation (tm/in-sequence [(n/delete-component :main2-root)
(n/remove-child :main1-child)])})
copy (tm/resolve-shape situation :copy2-child)
stored (get-in (tm/file situation) [:data :components (thi/id :component2) :objects])]
(t/is (empty? (:shapes copy)))
(t/is (= 2 (count stored)))
(t/is (empty? (uc/failures situation)))))