diff --git a/backend/src/app/migrations.clj b/backend/src/app/migrations.clj index 98194b359..9454d5960 100644 --- a/backend/src/app/migrations.clj +++ b/backend/src/app/migrations.clj @@ -330,8 +330,8 @@ {:name "0105-mod-server-error-report-table" :fn (mg/resource "app/migrations/sql/0105-mod-server-error-report-table.sql")} - {:name "0106-mod-file-object-thumbnail-table" - :fn (mg/resource "app/migrations/sql/0106-mod-file-object-thumbnail-table.sql")} + {:name "0106-add-file-tagged-object-thumbnail-table" + :fn (mg/resource "app/migrations/sql/0106-add-file-tagged-object-thumbnail-table.sql")} {:name "0106-mod-team-table" :fn (mg/resource "app/migrations/sql/0106-mod-team-table.sql")} diff --git a/backend/src/app/migrations/sql/0106-add-file-tagged-object-thumbnail-table.sql b/backend/src/app/migrations/sql/0106-add-file-tagged-object-thumbnail-table.sql new file mode 100644 index 000000000..8d2fed8b9 --- /dev/null +++ b/backend/src/app/migrations/sql/0106-add-file-tagged-object-thumbnail-table.sql @@ -0,0 +1,10 @@ +CREATE TABLE file_tagged_object_thumbnail ( + file_id uuid NOT NULL REFERENCES file(id) ON DELETE CASCADE DEFERRABLE, + tag text DEFAULT 'frame', + object_id text NOT NULL, + + media_id uuid NOT NULL REFERENCES storage_object(id) ON DELETE CASCADE DEFERRABLE, + created_at timestamptz NOT NULL DEFAULT now(), + + PRIMARY KEY(file_id, tag, object_id) +); diff --git a/backend/src/app/migrations/sql/0106-mod-file-object-thumbnail-table.sql b/backend/src/app/migrations/sql/0106-mod-file-object-thumbnail-table.sql deleted file mode 100644 index 5b74b4b03..000000000 --- a/backend/src/app/migrations/sql/0106-mod-file-object-thumbnail-table.sql +++ /dev/null @@ -1,5 +0,0 @@ -ALTER TABLE file_object_thumbnail - ADD COLUMN tag text DEFAULT 'frame'; - -ALTER TABLE file_object_thumbnail DROP CONSTRAINT file_object_thumbnail_pkey; -ALTER TABLE file_object_thumbnail ADD PRIMARY KEY (file_id, tag, object_id); \ No newline at end of file diff --git a/backend/src/app/rpc/commands/files_thumbnails.clj b/backend/src/app/rpc/commands/files_thumbnails.clj index d247df3bc..d4475a635 100644 --- a/backend/src/app/rpc/commands/files_thumbnails.clj +++ b/backend/src/app/rpc/commands/files_thumbnails.clj @@ -8,17 +8,14 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] - [app.common.exceptions :as ex] [app.common.features :as cfeat] [app.common.geom.shapes :as gsh] [app.common.pages.helpers :as cph] [app.common.schema :as sm] - [app.common.spec :as us] [app.common.thumbnails :as thc] [app.common.types.shape-tree :as ctt] [app.config :as cf] [app.db :as db] - [app.db.sql :as sql] [app.loggers.audit :as-alias audit] [app.loggers.webhooks :as-alias webhooks] [app.media :as media] @@ -27,7 +24,6 @@ [app.rpc.commands.teams :as teams] [app.rpc.cond :as-alias cond] [app.rpc.doc :as-alias doc] - [app.rpc.helpers :as rph] [app.storage :as sto] [app.util.pointer-map :as pmap] [app.util.services :as sv] @@ -45,41 +41,39 @@ (defn- get-object-thumbnails-by-tag [conn file-id tag] (let [sql (str/concat - "select object_id, data, media_id, tag " - " from file_object_thumbnail" + "select object_id, media_id, tag " + " from file_tagged_object_thumbnail" " where file_id=? and tag=?") res (db/exec! conn [sql file-id tag])] (->> res (d/index-by :object-id (fn [row] - (or (some-> row :media-id files/resolve-public-uri) - (:data row)))) + (files/resolve-public-uri (:media-id row)))) (d/without-nils)))) (defn- get-object-thumbnails ([conn file-id] (let [sql (str/concat - "select object_id, data, media_id, tag " - " from file_object_thumbnail" + "select object_id, media_id, tag " + " from file_tagged_object_thumbnail" " where file_id=?") res (db/exec! conn [sql file-id])] (->> res (d/index-by :object-id (fn [row] - (or (some-> row :media-id files/resolve-public-uri) - (:data row)))) + (files/resolve-public-uri (:media-id row)))) (d/without-nils)))) ([conn file-id object-ids] (let [sql (str/concat - "select object_id, data, media_id, tag " - " from file_object_thumbnail" + "select object_id, media_id, tag " + " from file_tagged_object_thumbnail" " where file_id=? and object_id = ANY(?)") ids (db/create-array conn "text" (seq object-ids)) res (db/exec! conn [sql file-id ids])] - (d/index-by :object-id - (fn [row] - (or (some-> row :media-id files/resolve-public-uri) - (:data row))) - res)))) + + (->> res + (d/index-by :object-id (fn [row] + (files/resolve-public-uri (:media-id row)))) + (d/without-nils))))) (sv/defmethod ::get-file-object-thumbnails "Retrieve a file object thumbnails." @@ -99,48 +93,6 @@ (get-object-thumbnails-by-tag conn file-id tag) (get-object-thumbnails conn file-id)))) -;; --- COMMAND QUERY: get-file-thumbnail - -(defn get-file-thumbnail - [conn file-id revn] - (let [sql (sql/select :file-thumbnail - (cond-> {:file-id file-id} - revn (assoc :revn revn)) - {:limit 1 - :order-by [[:revn :desc]]}) - row (db/exec-one! conn sql)] - - (when-not row - (ex/raise :type :not-found - :code :file-thumbnail-not-found)) - - (when-not (:data row) - (ex/raise :type :not-found - :code :file-thumbnail-not-found)) - - {:data (:data row) - :props (some-> (:props row) db/decode-transit-pgobject) - :revn (:revn row) - :file-id (:file-id row)})) - -(s/def ::revn ::us/integer) -(s/def ::file-id ::us/uuid) - -(s/def ::get-file-thumbnail - (s/keys :req [::rpc/profile-id] - :req-un [::file-id] - :opt-un [::revn])) - -(sv/defmethod ::get-file-thumbnail - {::doc/added "1.17" - ::doc/module :files - ::doc/deprecated "1.19"} - [{:keys [::db/pool]} {:keys [::rpc/profile-id file-id revn]}] - (dm/with-open [conn (db/open pool)] - (files/check-read-permissions! conn profile-id file-id) - (-> (get-file-thumbnail conn file-id revn) - (rph/with-http-cache long-cache-duration)))) - ;; --- COMMAND QUERY: get-file-data-for-thumbnail ;; We need to improve how we set frame for thumbnail in order to avoid @@ -277,47 +229,10 @@ ;; MUTATION COMMANDS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; --- MUTATION COMMAND: upsert-file-object-thumbnail - -(def sql:upsert-object-thumbnail - "insert into file_object_thumbnail(file_id, tag, object_id, data) - values (?, ?, ?, ?) - on conflict(file_id, tag, object_id) do - update set data = ?;") - -(defn upsert-file-object-thumbnail! - [conn {:keys [file-id tag object-id data]}] - (if data - (db/exec-one! conn [sql:upsert-object-thumbnail file-id (or tag "frame") object-id data data]) - (db/delete! conn :file-object-thumbnail {:file-id file-id :object-id object-id}))) - -(s/def ::data (s/nilable ::us/string)) -(s/def ::object-id ::us/string) -(s/def ::tag ::us/string) - -(s/def ::upsert-file-object-thumbnail - (s/keys :req [::rpc/profile-id] - :req-un [::file-id ::object-id] - :opt-un [::data ::tag])) - -(sv/defmethod ::upsert-file-object-thumbnail - {::doc/added "1.17" - ::doc/module :files - ::doc/deprecated "1.19" - ::audit/skip true} - [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}] - (db/with-atomic [conn pool] - (files/check-edition-permissions! conn profile-id file-id) - - (when-not (db/read-only? conn) - (upsert-file-object-thumbnail! conn params) - nil))) - - ;; --- MUTATION COMMAND: create-file-object-thumbnail (def ^:private sql:create-object-thumbnail - "insert into file_object_thumbnail(file_id, object_id, media_id, tag) + "insert into file_tagged_object_thumbnail(file_id, object_id, media_id, tag) values (?, ?, ?, ?) on conflict(file_id, tag, object_id) do update set media_id = ?;") @@ -339,7 +254,6 @@ (db/exec-one! conn [sql:create-object-thumbnail file-id object-id (:id media) tag (:id media)]))) - (def schema:create-file-object-thumbnail [:map {:title "create-file-object-thumbnail"} [:file-id ::sm/uuid] @@ -370,14 +284,14 @@ (defn- delete-file-object-thumbnail! [{:keys [::db/conn ::sto/storage]} file-id object-id] - (when-let [{:keys [media-id]} (db/get* conn :file-object-thumbnail + (when-let [{:keys [media-id]} (db/get* conn :file-tagged-object-thumbnail {:file-id file-id :object-id object-id} {::db/for-update? true})] (when media-id (sto/del-object! storage media-id)) - (db/delete! conn :file-object-thumbnail + (db/delete! conn :file-tagged-object-thumbnail {:file-id file-id :object-id object-id}) nil)) @@ -402,41 +316,6 @@ (delete-file-object-thumbnail! file-id object-id)) nil))) -;; --- MUTATION COMMAND: upsert-file-thumbnail - -(def ^:private sql:upsert-file-thumbnail - "insert into file_thumbnail (file_id, revn, data, props) - values (?, ?, ?, ?::jsonb) - on conflict(file_id, revn) do - update set data = ?, props=?, updated_at=now();") - -(defn- upsert-file-thumbnail! - [conn {:keys [file-id revn data props]}] - (let [props (db/tjson (or props {}))] - (db/exec-one! conn [sql:upsert-file-thumbnail - file-id revn data props data props]))) - -(s/def ::revn ::us/integer) -(s/def ::props map?) - -(s/def ::upsert-file-thumbnail - (s/keys :req [::rpc/profile-id] - :req-un [::file-id ::revn ::props ::data])) - -(sv/defmethod ::upsert-file-thumbnail - "Creates or updates the file thumbnail. Mainly used for paint the - grid thumbnails." - {::doc/added "1.17" - ::doc/module :files - ::doc/deprecated "1.19" - ::audit/skip true} - [{:keys [::db/pool] :as cfg} {:keys [::rpc/profile-id file-id] :as params}] - (db/with-atomic [conn pool] - (files/check-edition-permissions! conn profile-id file-id) - (when-not (db/read-only? conn) - (upsert-file-thumbnail! conn params) - nil))) - ;; --- MUTATION COMMAND: create-file-thumbnail (def ^:private sql:create-file-thumbnail diff --git a/backend/src/app/tasks/file_gc.clj b/backend/src/app/tasks/file_gc.clj index 358dc8da3..81c1f6767 100644 --- a/backend/src/app/tasks/file_gc.clj +++ b/backend/src/app/tasks/file_gc.clj @@ -151,9 +151,9 @@ ;; them. (db/delete! conn :file-media-object {:id (:id mobj)})))) -(defn- clean-file-object-thumbnails! +(defn- clean-file-tagged-object-thumbnails! [{:keys [::db/conn ::sto/storage]} file-id data] - (let [stored (->> (db/query conn :file_object_thumbnail + (let [stored (->> (db/query conn :file_tagged_object_thumbnail {:file-id file-id} {:columns [:object-id]}) (into #{} (map :object-id))) @@ -171,7 +171,7 @@ unused (set/difference stored using)] (when (seq unused) - (let [sql (str "delete from file_object_thumbnail " + (let [sql (str "delete from file_tagged_object_thumbnail " " where file_id=? and object_id=ANY(?)" " returning media_id") res (db/exec! conn [sql file-id (db/create-array conn "text" unused)])] @@ -294,7 +294,7 @@ (pmg/migrate-data))] (clean-file-media! conn id data) - (clean-file-object-thumbnails! cfg id data) + (clean-file-tagged-object-thumbnails! cfg id data) (clean-file-thumbnails! cfg id revn) (clean-deleted-components! conn id data) diff --git a/backend/test/backend_tests/helpers.clj b/backend/test/backend_tests/helpers.clj index d09db68f7..472be811f 100644 --- a/backend/test/backend_tests/helpers.clj +++ b/backend/test/backend_tests/helpers.clj @@ -93,6 +93,7 @@ "alter table file_library_rel set unlogged;\n" "alter table file_thumbnail set unlogged;\n" "alter table file_object_thumbnail set unlogged;\n" + "alter table file_tagged_object_thumbnail set unlogged;\n" "alter table file_media_object set unlogged;\n" "alter table file_data_fragment set unlogged;\n" "alter table file set unlogged;\n" diff --git a/backend/test/backend_tests/rpc_file_test.clj b/backend/test/backend_tests/rpc_file_test.clj index 02a394153..653491c52 100644 --- a/backend/test/backend_tests/rpc_file_test.clj +++ b/backend/test/backend_tests/rpc_file_test.clj @@ -18,7 +18,8 @@ [app.storage :as sto] [app.util.time :as dt] [backend-tests.helpers :as th] - [clojure.test :as t])) + [clojure.test :as t] + [cuerdas.core :as str])) (t/use-fixtures :once th/state-init) (t/use-fixtures :each th/database-reset) @@ -667,12 +668,14 @@ (t/testing "RPC :file-data-for-thumbnail" ;; Insert a thumbnail data for the frame-id - (let [data {::th/type :upsert-file-object-thumbnail + (let [data {::th/type :create-file-object-thumbnail ::rpc/profile-id (:id prof) :file-id (:id file) :object-id (thc/fmt-object-id (:id file) page-id frame1-id "frame") - :data "random-data-1"} - + :media {:filename "sample.jpg" + :size 7923 + :path (th/tempfile "backend_tests/test_files/sample2.jpg") + :mtype "image/jpeg"}} {:keys [error result] :as out} (th/command! data)] (t/is (nil? error)) (t/is (nil? result))) @@ -691,15 +694,15 @@ (t/is (contains? result :file-id)) (t/is (= (:id file) (:file-id result))) - (t/is (= "random-data-1" (get-in result [:page :objects frame1-id :thumbnail]))) + (t/is (str/starts-with? (get-in result [:page :objects frame1-id :thumbnail]) + "http://localhost:3449/assets/by-id/")) (t/is (= [] (get-in result [:page :objects frame1-id :shapes])))) ;; Delete thumbnail data - (let [data {::th/type :upsert-file-object-thumbnail + (let [data {::th/type :delete-file-object-thumbnail ::rpc/profile-id (:id prof) :file-id (:id file) - :object-id (thc/fmt-object-id (:id file) page-id frame1-id "frame") - :data nil} + :object-id (thc/fmt-object-id (:id file) page-id frame1-id "frame")} {:keys [error result] :as out} (th/command! data)] ;; (th/print-result! out) (t/is (nil? error)) @@ -723,11 +726,14 @@ (t/testing "TASK :file-gc" ;; insert object snapshot for known frame - (let [data {::th/type :upsert-file-object-thumbnail + (let [data {::th/type :create-file-object-thumbnail ::rpc/profile-id (:id prof) :file-id (:id file) :object-id (thc/fmt-object-id (:id file) page-id frame1-id "frame") - :data "new-data"} + :media {:filename "sample.jpg" + :size 7923 + :path (th/tempfile "backend_tests/test_files/sample2.jpg") + :mtype "image/jpeg"}} {:keys [error result] :as out} (th/command! data)] (t/is (nil? error)) (t/is (nil? result))) @@ -736,22 +742,23 @@ (th/sleep 300) ;; run the task again - (let [task (:app.tasks.file-gc/handler th/*system*) - res (task {:min-age (dt/duration 0)})] + (let [res (th/run-task! "file-gc" {:min-age 0})] (t/is (= 1 (:processed res)))) ;; check that object thumbnails are still here - (let [res (th/db-exec! ["select * from file_object_thumbnail"])] - (th/print-result! res) - (t/is (= 1 (count res))) - (t/is (= "new-data" (get-in res [0 :data])))) + (let [res (th/db-exec! ["select * from file_tagged_object_thumbnail"])] + ;; (th/print-result! res) + (t/is (= 1 (count res)))) ;; insert object snapshot for for unknown frame - (let [data {::th/type :upsert-file-object-thumbnail + (let [data {::th/type :create-file-object-thumbnail ::rpc/profile-id (:id prof) :file-id (:id file) :object-id (thc/fmt-object-id (:id file) page-id (uuid/next) "frame") - :data "new-data-2"} + :media {:filename "sample.jpg" + :size 7923 + :path (th/tempfile "backend_tests/test_files/sample2.jpg") + :mtype "image/jpeg"}} {:keys [error result] :as out} (th/command! data)] (t/is (nil? error)) (t/is (nil? result))) @@ -760,18 +767,16 @@ (th/db-exec! ["update file set has_media_trimmed=false where id=?" (:id file)]) ;; check that we have all object thumbnails - (let [res (th/db-exec! ["select * from file_object_thumbnail"])] + (let [res (th/db-exec! ["select * from file_tagged_object_thumbnail"])] (t/is (= 2 (count res)))) ;; run the task again - (let [task (:app.tasks.file-gc/handler th/*system*) - res (task {:min-age (dt/duration 0)})] + (let [res (th/run-task! "file-gc" {:min-age 0})] (t/is (= 1 (:processed res)))) ;; check that the unknown frame thumbnail is deleted - (let [res (th/db-exec! ["select * from file_object_thumbnail"])] - (t/is (= 1 (count res))) - (t/is (= "new-data" (get-in res [0 :data]))))) + (let [res (th/db-exec! ["select * from file_tagged_object_thumbnail"])] + (t/is (= 1 (count res))))) )) @@ -781,83 +786,53 @@ file (th/create-file* 1 {:profile-id (:id prof) :project-id (:default-project-id prof) :revn 2 - :is-shared false}) - data {::th/type :get-file-thumbnail - ::rpc/profile-id (:id prof) - :file-id (:id file)}] + :is-shared false})] - (t/testing "query a thumbnail with single revn" - - ;; insert an entry on the database with a test value for the thumbnail of this frame - (th/db-insert! :file-thumbnail - {:file-id (:file-id data) - :revn 1 - :data "testvalue1"}) - - (let [{:keys [result error] :as out} (th/command! data)] - ;; (th/print-result! out) - (t/is (nil? error)) - (t/is (= 4 (count result))) - (t/is (= "testvalue1" (:data result))) - (t/is (= 1 (:revn result))))) - - (t/testing "query thumbnail with two revisions" - ;; insert an entry on the database with a test value for the thumbnail of this frame - (th/db-insert! :file-thumbnail - {:file-id (:file-id data) - :revn 2 - :data "testvalue2"}) - - (let [{:keys [result error] :as out} (th/command! data)] - ;; (th/print-result! out) - (t/is (nil? error)) - (t/is (= 4 (count result))) - (t/is (= "testvalue2" (:data result))) - (t/is (= 2 (:revn result)))) - - ;; Then query the specific revn - (let [{:keys [result error] :as out} (th/command! (assoc data :revn 1))] - ;; (th/print-result! out) - (t/is (nil? error)) - (t/is (= 4 (count result))) - (t/is (= "testvalue1" (:data result))) - (t/is (= 1 (:revn result))))) - - (t/testing "upsert file-thumbnail" - (let [data {::th/type :upsert-file-thumbnail + (t/testing "create a file thumbnail" + ;; insert object snapshot for known frame + (let [data {::th/type :create-file-thumbnail ::rpc/profile-id (:id prof) :file-id (:id file) - :data "foobar" - :props {:baz 1} - :revn 2} - {:keys [result error] :as out} (th/command! data)] - ;; (th/print-result! out) - (t/is (nil? error)) - (t/is (nil? result)))) + :revn 1 + :media {:filename "sample.jpg" + :size 7923 + :path (th/tempfile "backend_tests/test_files/sample2.jpg") + :mtype "image/jpeg"}} + {:keys [error result] :as out} (th/command! data)] - (t/testing "query last result" - (let [{:keys [result error] :as out} (th/command! data)] ;; (th/print-result! out) (t/is (nil? error)) - (t/is (= 4 (count result))) - (t/is (= "foobar" (:data result))) - (t/is (= {:baz 1} (:props result))) - (t/is (= 2 (:revn result))))) + (t/is (map? result))) + + (let [data {::th/type :create-file-thumbnail + ::rpc/profile-id (:id prof) + :file-id (:id file) + :revn 2 + :media {:filename "sample.jpg" + :size 7923 + :path (th/tempfile "backend_tests/test_files/sample2.jpg") + :mtype "image/jpeg"}} + {:keys [error result] :as out} (th/command! data)] + + ;; (th/print-result! out) + (t/is (nil? error)) + (t/is (map? result))) + + (let [rows (th/db-query :file-thumbnail {:file-id (:id file)})] + (t/is (= 2 (count rows)))) + + ) (t/testing "gc task" ;; make the file eligible for GC waiting 300ms (configured ;; timeout for testing) (th/sleep 300) - ;; run the task again - (let [task (:app.tasks.file-gc/handler th/*system*) - res (task {:min-age (dt/duration 0)})] + (let [res (th/run-task! "file-gc" {:min-age 0})] (t/is (= 1 (:processed res)))) - ;; Then query the specific revn - (let [{:keys [result error] :as out} (th/command! (assoc data :revn 1))] - (t/is (th/ex-of-type? error :not-found)) - (t/is (th/ex-of-code? error :file-thumbnail-not-found)))) + (let [rows (th/db-query :file-thumbnail {:file-id (:id file)})] + (t/is (= 1 (count rows))))) )) diff --git a/backend/test/backend_tests/rpc_file_thumbnails_test.clj b/backend/test/backend_tests/rpc_file_thumbnails_test.clj index e846e6bb0..c30bce8e2 100644 --- a/backend/test/backend_tests/rpc_file_thumbnails_test.clj +++ b/backend/test/backend_tests/rpc_file_thumbnails_test.clj @@ -81,7 +81,7 @@ (t/is (nil? (:error out))) (t/is (nil? (:result out)))) - (let [[row1 row2 :as rows] (th/db-query :file-object-thumbnail + (let [[row1 row2 :as rows] (th/db-query :file-tagged-object-thumbnail {:file-id (:id file)} {:order-by [[:created-at :asc]]})] @@ -113,7 +113,7 @@ (t/is (= 1 (:processed result)))) ;; check if row2 related thumbnail row still exists - (let [[row :as rows] (th/db-query :file-object-thumbnail + (let [[row :as rows] (th/db-query :file-tagged-object-thumbnail {:file-id (:id file)} {:order-by [[:created-at :asc]]})] (t/is (= 1 (count rows))) @@ -143,7 +143,6 @@ ))) - (t/deftest create-file-thumbnail (let [storage (::sto/storage th/*system*) profile (th/create-profile* 1) @@ -152,14 +151,7 @@ :is-shared false :revn 3}) - data1 {::th/type :upsert-file-thumbnail - ::rpc/profile-id (:id profile) - :file-id (:id file) - :props {} - :revn 1 - :data "data:base64,1234123124"} - - data2 {::th/type :create-file-thumbnail + data1 {::th/type :create-file-thumbnail ::rpc/profile-id (:id profile) :file-id (:id file) :revn 2 @@ -168,7 +160,7 @@ :path (th/tempfile "backend_tests/test_files/sample2.jpg") :mtype "image/jpeg"}} - data3 {::th/type :create-file-thumbnail + data2 {::th/type :create-file-thumbnail ::rpc/profile-id (:id profile) :file-id (:id file) :revn 3 @@ -178,43 +170,35 @@ :mtype "image/jpeg"}}] (let [out (th/command! data1)] - (t/is (nil? (:error out))) - (t/is (nil? (:result out)))) - - (let [out (th/command! data2)] ;; (th/print-result! out) (t/is (nil? (:error out))) (t/is (contains? (:result out) :uri))) - (let [out (th/command! data3)] + (let [out (th/command! data2)] (t/is (nil? (:error out))) (t/is (contains? (:result out) :uri))) - (let [[row1 row2 row3 :as rows] (th/db-query :file-thumbnail - {:file-id (:id file)} - {:order-by [[:created-at :asc]]})] - (t/is (= 3 (count rows))) + (let [[row1 row2 :as rows] (th/db-query :file-thumbnail + {:file-id (:id file)} + {:order-by [[:created-at :asc]]})] + (t/is (= 2 (count rows))) (t/is (= (:file-id data1) (:file-id row1))) (t/is (= (:revn data1) (:revn row1))) - (t/is (nil? (:media-id row1))) + (t/is (uuid? (:media-id row1))) (t/is (= (:file-id data2) (:file-id row2))) (t/is (= (:revn data2) (:revn row2))) (t/is (uuid? (:media-id row2))) - (t/is (= (:file-id data3) (:file-id row3))) - (t/is (= (:revn data3) (:revn row3))) - (t/is (uuid? (:media-id row3))) - - (let [sobject (sto/get-object storage (:media-id row2)) + (let [sobject (sto/get-object storage (:media-id row1)) mobject (meta sobject)] (t/is (= "blake2b:05870e3f8ee885841ee3799924d80805179ab57e6fde84a605d1068fd3138de9" (:hash mobject))) (t/is (= "file-thumbnail" (:bucket mobject))) (t/is (= "image/jpeg" (:content-type mobject))) (t/is (= 7923 (:size sobject)))) - (let [sobject (sto/get-object storage (:media-id row3)) + (let [sobject (sto/get-object storage (:media-id row2)) mobject (meta sobject)] (t/is (= "blake2b:4fdb63b8f3ffc81256ea79f13e53f366723b188554b5afed91b20897c14a1a8e" (:hash mobject))) (t/is (= "file-thumbnail" (:bucket mobject))) @@ -226,21 +210,20 @@ (let [result (th/run-task! :file-gc {:min-age (dt/duration 0)})] (t/is (= 1 (:processed result)))) - ;; check if row2 related thumbnail row still exists + ;; check if row1 related thumbnail row still exists (let [[row :as rows] (th/db-query :file-thumbnail {:file-id (:id file)} {:order-by [[:created-at :asc]]})] (t/is (= 1 (count rows))) - (t/is (= (:file-id data2) (:file-id row))) - (t/is (= (:object-id data2) (:object-id row))) - (t/is (uuid? (:media-id row2)))) + (t/is (= (:file-id data1) (:file-id row))) + (t/is (= (:object-id data1) (:object-id row))) + (t/is (uuid? (:media-id row1)))) ;; Check if storage objects still exists after file-gc (t/is (nil? (sto/get-object storage (:media-id row1)))) - (t/is (nil? (sto/get-object storage (:media-id row2)))) - (t/is (some? (sto/get-object storage (:media-id row3)))) + (t/is (some? (sto/get-object storage (:media-id row2)))) - (let [row (th/db-get :storage-object {:id (:media-id row2)} {::db/remove-deleted? false})] + (let [row (th/db-get :storage-object {:id (:media-id row1)} {::db/remove-deleted? false})] (t/is (some? (:deleted-at row)))) ;; Run the storage gc deleted task, it should permanently delete @@ -248,11 +231,7 @@ (let [result (th/run-task! :storage-gc-deleted {:min-age (dt/duration 0)})] (t/is (= 1 (:deleted result)))) - ;; check that storage object is still exists but is marked as deleted - (let [row (th/db-get :storage-object {:id (:media-id row1)} {::db/remove-deleted? false})] - (t/is (nil? row))) - - (t/is (some? (sto/get-object storage (:media-id row3))))) + (t/is (some? (sto/get-object storage (:media-id row2))))) )) @@ -264,13 +243,7 @@ :project-id (:default-project-id profile) :is-shared false}) - data1 {::th/type :upsert-file-object-thumbnail - ::rpc/profile-id (:id profile) - :file-id (:id file) - :object-id "test-key-1" - :data "data:base64,1234123124"} - - data2 {::th/type :create-file-object-thumbnail + data {::th/type :create-file-object-thumbnail ::rpc/profile-id (:id profile) :file-id (:id file) :object-id "test-key-2" @@ -279,36 +252,27 @@ :path (th/tempfile "backend_tests/test_files/sample2.jpg") :mtype "image/jpeg"}}] - (let [out (th/command! data1)] + (let [out (th/command! data)] (t/is (nil? (:error out))) (t/is (nil? (:result out)))) - (let [out (th/command! data2)] - (t/is (nil? (:error out))) - (t/is (nil? (:result out)))) - - (let [[row1 row2 :as rows] (th/db-query :file-object-thumbnail + (let [[row :as rows] (th/db-query :file-tagged-object-thumbnail {:file-id (:id file)} {:order-by [[:created-at :asc]]})] - (t/is (= 2 (count rows))) - - (t/is (= (:file-id data1) (:file-id row1))) - (t/is (= (:object-id data1) (:object-id row1))) - (t/is (nil? (:media-id row1))) - (t/is (string? (:data row1))) - - (t/is (= (:file-id data2) (:file-id row2))) - (t/is (= (:object-id data2) (:object-id row2))) - (t/is (uuid? (:media-id row2)))) + (t/is (= 1 (count rows))) + (t/is (= (:file-id data) (:file-id row))) + (t/is (= (:object-id data) (:object-id row))) + (t/is (uuid? (:media-id row)))) (let [params {::th/type :get-file-object-thumbnails ::rpc/profile-id (:id profile) :file-id (:id file)} out (th/command! params)] + ;; (th/print-result! out) + (let [result (:result out)] - (t/is (contains? result "test-key-1")) (t/is (contains? result "test-key-2"))))))