diff --git a/backend/src/app/rpc/commands/media.clj b/backend/src/app/rpc/commands/media.clj index 69265c27f..f4913edb2 100644 --- a/backend/src/app/rpc/commands/media.clj +++ b/backend/src/app/rpc/commands/media.clj @@ -60,15 +60,25 @@ (media/validate-media-type! content) (media/validate-media-size! content) - (db/run! cfg (fn [cfg] - (let [object (create-file-media-object cfg params) - props {:name (:name params) - :file-id file-id - :is-local (:is-local params) - :size (:size content) - :mtype (:mtype content)}] - (with-meta object - {::audit/replace-props props}))))) + (db/run! cfg (fn [{:keys [::db/conn] :as cfg}] + ;; We get the minimal file for proper checking if + ;; file is not already deleted + (let [_ (files/get-minimal-file conn file-id) + mobj (create-file-media-object cfg params)] + + (db/update! conn :file + {:modified-at (dt/now) + :has-media-trimmed false} + {:id file-id} + {::db/return-keys false}) + + (with-meta mobj + {::audit/replace-props + {:name (:name params) + :file-id file-id + :is-local (:is-local params) + :size (:size content) + :mtype (:mtype content)}}))))) (defn- big-enough-for-thumbnail? "Checks if the provided image info is big enough for @@ -142,20 +152,14 @@ :always (assoc ::image (process-main-image info))))) -(defn create-file-media-object - [{:keys [::sto/storage ::db/conn ::wrk/executor]} +(defn- create-file-media-object + [{:keys [::sto/storage ::db/conn ::wrk/executor] :as cfg} {:keys [id file-id is-local name content]}] - (let [result (px/invoke! executor (partial process-image content)) image (sto/put-object! storage (::image result)) thumb (when-let [params (::thumb result)] (sto/put-object! storage params))] - (db/update! conn :file - {:modified-at (dt/now) - :has-media-trimmed false} - {:id file-id}) - (db/exec-one! conn [sql:create-file-media-object (or id (uuid/next)) file-id is-local name @@ -182,7 +186,18 @@ ::sm/params schema:create-file-media-object-from-url} [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}] (files/check-edition-permissions! pool profile-id file-id) - (create-file-media-object-from-url cfg (assoc params :profile-id profile-id))) + ;; We get the minimal file for proper checking if file is not + ;; already deleted + (let [_ (files/get-minimal-file cfg file-id) + mobj (create-file-media-object-from-url cfg (assoc params :profile-id profile-id))] + + (db/update! pool :file + {:modified-at (dt/now) + :has-media-trimmed false} + {:id file-id} + {::db/return-keys false}) + + mobj)) (defn download-image [{:keys [::http/client]} uri] diff --git a/backend/test/backend_tests/rpc_media_test.clj b/backend/test/backend_tests/rpc_media_test.clj index 748c72683..3095a5c05 100644 --- a/backend/test/backend_tests/rpc_media_test.clj +++ b/backend/test/backend_tests/rpc_media_test.clj @@ -10,6 +10,7 @@ [app.db :as db] [app.rpc :as-alias rpc] [app.storage :as sto] + [app.util.time :as dt] [backend-tests.helpers :as th] [clojure.test :as t] [datoteka.fs :as fs])) @@ -245,3 +246,35 @@ (t/is (= "image/jpeg" (:mtype result))) (t/is (uuid? (:media-id result))) (t/is (uuid? (:thumbnail-id result)))))) + + +(t/deftest media-object-upload-command-when-file-is-deleted + (let [prof (th/create-profile* 1) + proj (th/create-project* 1 {:profile-id (:id prof) + :team-id (:default-team-id prof)}) + file (th/create-file* 1 {:profile-id (:id prof) + :project-id (:default-project-id prof) + :is-shared false}) + + _ (th/db-update! :file + {:deleted-at (dt/now)} + {:id (:id file)}) + + mfile {:filename "sample.jpg" + :path (th/tempfile "backend_tests/test_files/sample.jpg") + :mtype "image/jpeg" + :size 312043} + + params {::th/type :upload-file-media-object + ::rpc/profile-id (:id prof) + :file-id (:id file) + :is-local true + :name "testfile" + :content mfile} + + out (th/command! params)] + + (let [error (:error out) + error-data (ex-data error)] + (t/is (th/ex-info? error)) + (t/is (= (:type error-data) :not-found)))))