mirror of
https://github.com/penpot/penpot.git
synced 2025-03-20 19:51:23 -05:00
🐛 Fix db table tagged thumbnails
This commit is contained in:
parent
3448259c60
commit
7951350762
8 changed files with 123 additions and 299 deletions
|
@ -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")}
|
||||
|
|
|
@ -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)
|
||||
);
|
|
@ -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);
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)))))
|
||||
))
|
||||
|
||||
|
||||
|
|
|
@ -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"))))))
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue