mirror of
https://github.com/penpot/penpot.git
synced 2026-10-29 05:50:35 +00:00
🐛 Store the fragments a library absorption changes
Absorbing a library into a file that uses it (unpublishing or deleting the library) saved the file without its features. Saving stores the changed pointer-map fragments only when the features name fdata/pointer-map, so with that feature the file pointed at a fragment of components that was never written, and loading it failed with :fragment-not-found. The file's features now go with the save. rpc-file-test/unpublish-library-absorbs-it-into-the-files-using-it unpublishes a library with a copy in another file, then loads that file. The existing absorption test turns fdata/pointer-map off, so it missed this. AI-assisted-by: claude-opus-5-5
This commit is contained in:
parent
5fdf0c036f
commit
9c701da24a
@ -1008,6 +1008,8 @@
|
||||
:library-id (str (:id ldata))
|
||||
:file-id (str file-id))
|
||||
|
||||
;; the features say how to store the data: with fdata/pointer-map, the
|
||||
;; fragments the absorption changed
|
||||
(bfc/update-file! cfg {:id file-id
|
||||
:features (:features file)
|
||||
:migrations (:migrations file)
|
||||
|
||||
@ -2132,6 +2132,93 @@
|
||||
(t/is (= (:id file-2) (:file-id (get rows 0))))
|
||||
(t/is (nil? (:deleted-at (get rows 0)))))))
|
||||
|
||||
(defn- create-library-copy!
|
||||
"Create a shared library with a component and a file using it with a copy
|
||||
of it. Returns the profile, both files and the ids involved."
|
||||
[]
|
||||
(let [profile (th/create-profile* 1)
|
||||
params {:profile-id (:id profile)
|
||||
:project-id (:default-project-id profile)}
|
||||
library (th/create-file* 1 (assoc params :is-shared true))
|
||||
file (th/create-file* 2 params)
|
||||
c-id (uuid/random)
|
||||
main-id (uuid/random)
|
||||
inst-id (uuid/random)
|
||||
l-page (first (get-in library [:data :pages]))
|
||||
f-page (first (get-in file [:data :pages]))]
|
||||
(th/link-file-to-library* {:file-id (:id file)
|
||||
:library-id (:id library)})
|
||||
|
||||
(update-file!
|
||||
:file-id (:id library)
|
||||
:profile-id (:id profile)
|
||||
:changes
|
||||
[{:type :add-obj
|
||||
:page-id l-page
|
||||
:id main-id
|
||||
:parent-id uuid/zero
|
||||
:frame-id uuid/zero
|
||||
:obj (cts/setup-shape
|
||||
{:id main-id
|
||||
:name "Board"
|
||||
:frame-id uuid/zero
|
||||
:parent-id uuid/zero
|
||||
:type :frame
|
||||
:main-instance true
|
||||
:component-root true
|
||||
:component-file (:id library)
|
||||
:component-id c-id})}
|
||||
{:type :add-component
|
||||
:path ""
|
||||
:name "Board"
|
||||
:main-instance-id main-id
|
||||
:main-instance-page l-page
|
||||
:id c-id
|
||||
:anotation nil}])
|
||||
|
||||
(update-file!
|
||||
:file-id (:id file)
|
||||
:profile-id (:id profile)
|
||||
:changes
|
||||
[{:type :add-obj
|
||||
:page-id f-page
|
||||
:id inst-id
|
||||
:parent-id uuid/zero
|
||||
:frame-id uuid/zero
|
||||
:obj (cts/setup-shape
|
||||
{:id inst-id
|
||||
:name "Board"
|
||||
:frame-id uuid/zero
|
||||
:parent-id uuid/zero
|
||||
:type :frame
|
||||
:main-instance false
|
||||
:component-root true
|
||||
:component-file (:id library)
|
||||
:component-id c-id})}])
|
||||
|
||||
{:profile profile :library library :file file
|
||||
:c-id c-id :inst-id inst-id :f-page f-page}))
|
||||
|
||||
(defn- check-absorbed!
|
||||
"Check that the file of `setup` holds the library component, with its copy
|
||||
pointing at it."
|
||||
[{:keys [profile file c-id inst-id f-page]}]
|
||||
(let [out (th/command! {::th/type :get-file
|
||||
::rpc/profile-id (:id profile)
|
||||
:id (:id file)})]
|
||||
(t/is (th/success? out))
|
||||
(t/is (some? (get-in out [:result :data :components c-id])))
|
||||
(t/is (= (:id file)
|
||||
(get-in out [:result :data :pages-index f-page :objects inst-id :component-file])))))
|
||||
|
||||
(t/deftest unpublish-library-absorbs-it-into-the-files-using-it
|
||||
(let [{:keys [profile library] :as setup} (create-library-copy!)]
|
||||
(t/is (th/success? (th/command! {::th/type :set-file-shared
|
||||
::rpc/profile-id (:id profile)
|
||||
:id (:id library)
|
||||
:is-shared false})))
|
||||
(check-absorbed! setup)))
|
||||
|
||||
(t/deftest delete-shared-library-with-storage-file-data
|
||||
(binding [cf/config (assoc cf/config :file-data-backend "storage")]
|
||||
;; Keep this test focused on the storage-backed file-data fix: create
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user