0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-11 07:11:32 -05:00

🐛 Fix errors duplicating objects with deleted relations

This commit is contained in:
Andrés Moya 2021-03-25 08:37:40 +01:00 committed by Andrey Antukh
parent 0a3b244f44
commit 47c58df2a4
3 changed files with 155 additions and 5 deletions

View file

@ -84,10 +84,24 @@
(d/without-nils) (d/without-nils)
(blob/encode)))))) (blob/encode))))))
(def sql:retrieve-used-libraries
"select flr.*
from file_library_rel as flr
inner join file as l on (flr.library_file_id = l.id)
where flr.file_id = ?
and l.deleted_at is null")
(def sql:retrieve-used-media-objects
"select fmo.*
from file_media_object as fmo
inner join storage_object as o on (fmo.media_id = o.id)
where fmo.file_id = ?
and o.deleted_at is null")
(defn duplicate-file (defn duplicate-file
[conn {:keys [profile-id file index project-id name]} {:keys [reset-shared-flag] :as opts}] [conn {:keys [profile-id file index project-id name]} {:keys [reset-shared-flag] :as opts}]
(let [flibs (db/query conn :file-library-rel {:file-id (:id file)}) (let [flibs (db/exec! conn [sql:retrieve-used-libraries (:id file)])
fmeds (db/query conn :file-media-object {:file-id (:id file)}) fmeds (db/exec! conn [sql:retrieve-used-media-objects (:id file)])
;; memo uniform creation/modification date ;; memo uniform creation/modification date
now (dt/now) now (dt/now)
@ -185,7 +199,8 @@
(defn duplicate-project (defn duplicate-project
[conn {:keys [profile-id project name] :as params}] [conn {:keys [profile-id project name] :as params}]
(let [files (db/query conn :file (let [files (db/query conn :file
{:project-id (:id project)} {:project-id (:id project)
:deleted-at nil}
{:columns [:id]}) {:columns [:id]})
project (cond-> project project (cond-> project

View file

@ -145,6 +145,10 @@
:name (str "file" i)} :name (str "file" i)}
params)))) params))))
(defn mark-file-deleted*
([params] (mark-file-deleted* *pool* params))
([conn {:keys [id] :as params}]
(#'files/mark-file-deleted conn {:id id})))
(defn create-team* (defn create-team*
([i params] (create-team* *pool* i params)) ([i params] (create-team* *pool* i params))
@ -160,7 +164,6 @@
:role :owner}) :role :owner})
team))) team)))
(defn create-file-media-object* (defn create-file-media-object*
([params] (create-file-media-object* *pool* params)) ([params] (create-file-media-object* *pool* params))
([conn {:keys [name width height mtype file-id is-local media-id] ([conn {:keys [name width height mtype file-id is-local media-id]

View file

@ -73,7 +73,7 @@
(let [[item :as rows] (db/query th/*pool* :file-media-object {:file-id (:id result)})] (let [[item :as rows] (db/query th/*pool* :file-media-object {:file-id (:id result)})]
(t/is (= 1 (count rows))) (t/is (= 1 (count rows)))
;; Checj that bot items have different ids ;; Check that both items have different ids
(t/is (not= (:id item) (:id mobj))) (t/is (not= (:id item) (:id mobj)))
;; check that both file-media-objects points to the same storage object. ;; check that both file-media-objects points to the same storage object.
@ -92,6 +92,67 @@
)))) ))))
(t/deftest duplicate-file-with-deleted-rels
(let [storage (:app.storage/storage th/*system*)
sobject (sto/put-object storage {:content (sto/content "content")
:content-type "text/plain"
:other "data"})
profile (th/create-profile* 1 {:is-active true})
project (th/create-project* 1 {:team-id (:default-team-id profile)
:profile-id (:id profile)})
file1 (th/create-file* 1 {:profile-id (:id profile)
:project-id (:id project)})
file2 (th/create-file* 2 {:profile-id (:id profile)
:project-id (:id project)
:is-shared true})
libl (th/link-file-to-library* {:file-id (:id file1)
:library-id (:id file2)})
mobj (th/create-file-media-object* {:file-id (:id file1)
:is-local false
:media-id (:id sobject)})
_ (th/mark-file-deleted* {:id (:id file2)})
_ (sto/del-object storage (:id sobject))]
(th/update-file*
{:file-id (:id file1)
:profile-id (:id profile)
:changes [{:type :add-media
:object (select-keys mobj [:id :width :height :mtype :name])}]})
(let [data {::th/type :duplicate-file
:profile-id (:id profile)
:file-id (:id file1)
:name "file 1 (copy)"}
out (th/mutation! data)]
;; (th/print-result! out)
;; Check tha tresult is correct
(t/is (nil? (:error out)))
(let [result (:result out)]
;; Check that the returned result is a file but has different id
;; and different name.
(t/is (= "file 1 (copy)" (:name result)))
(t/is (not= (:id file1) (:id result)))
;; Check that the deleted library is not duplicated
(let [[item :as rows] (db/query th/*pool* :file-library-rel {:file-id (:id result)})]
(t/is (= 0 (count rows))))
;; Check that the new file has no media objects
(let [[item :as rows] (db/query th/*pool* :file-media-object {:file-id (:id result)})]
(t/is (= 0 (count rows))))
;; Check the total number of files
(let [rows (db/query th/*pool* :file {:project-id (:id project)})]
(t/is (= 3 (count rows))))
))))
(t/deftest duplicate-project (t/deftest duplicate-project
(let [storage (:app.storage/storage th/*system*) (let [storage (:app.storage/storage th/*system*)
sobject (sto/put-object storage {:content (sto/content "content") sobject (sto/put-object storage {:content (sto/content "content")
@ -162,6 +223,77 @@
))))) )))))
(t/deftest duplicate-project-with-deleted-files
(let [storage (:app.storage/storage th/*system*)
sobject (sto/put-object storage {:content (sto/content "content")
:content-type "text/plain"
:other "data"})
profile (th/create-profile* 1 {:is-active true})
project (th/create-project* 1 {:team-id (:default-team-id profile)
:profile-id (:id profile)})
file1 (th/create-file* 1 {:profile-id (:id profile)
:project-id (:id project)})
file2 (th/create-file* 2 {:profile-id (:id profile)
:project-id (:id project)
:is-shared true})
libl (th/link-file-to-library* {:file-id (:id file1)
:library-id (:id file2)})
mobj (th/create-file-media-object* {:file-id (:id file1)
:is-local false
:media-id (:id sobject)})]
(th/update-file*
{:file-id (:id file1)
:profile-id (:id profile)
:changes [{:type :add-media
:object (select-keys mobj [:id :width :height :mtype :name])}]})
(th/mark-file-deleted* {:id (:id file1)})
(let [data {::th/type :duplicate-project
:profile-id (:id profile)
:project-id (:id project)
:name "project 1 (copy)"}
out (th/mutation! data)]
;; Check tha tresult is correct
(t/is (nil? (:error out)))
(let [result (:result out)]
;; Check that they are the same project but different id and name
(t/is (= "project 1 (copy)" (:name result)))
(t/is (not= (:id project) (:id result)))
;; Check the total number of projects (previously is 2, now is 3)
(let [rows (db/query th/*pool* :project {:team-id (:default-team-id profile)})]
(t/is (= 3 (count rows))))
;; Check that the new project has only the second file
(let [p1-files (db/query th/*pool* :file
{:project-id (:id project)}
{:order-by [:name]})
p2-files (db/query th/*pool* :file
{:project-id (:id result)}
{:order-by [:name]})]
(t/is (= (count (rest p1-files))
(count p2-files)))
;; check that the both files are equivalent
(doseq [[fa fb] (map vector (rest p1-files) p2-files)]
(t/is (not= (:id fa) (:id fb)))
(t/is (= (:name fa) (:name fb)))
(when (= (:id fa) (:id file1))
(t/is (false? (b/equals? (:data fa)
(:data fb)))))
(when (= (:id fa) (:id file2))
(t/is (false? (b/equals? (:data fa)
(:data fb))))))
)))))
(t/deftest move-file-on-same-team (t/deftest move-file-on-same-team
(let [profile (th/create-profile* 1 {:is-active true}) (let [profile (th/create-profile* 1 {:is-active true})
team (th/create-team* 1 {:profile-id (:id profile)}) team (th/create-team* 1 {:profile-id (:id profile)})