mirror of
https://github.com/penpot/penpot.git
synced 2025-08-03 13:08:23 +02:00
Merge remote-tracking branch 'origin/staging'
This commit is contained in:
commit
8d8e4c5e22
478 changed files with 18827 additions and 441795 deletions
|
@ -187,23 +187,18 @@
|
|||
;; freeze because of the deduplication (we have uploaded 2 times
|
||||
;; 2 two same files).
|
||||
(let [task (:app.storage/gc-touched-task th/*system*)
|
||||
res (task {})]
|
||||
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 2 (:freeze res)))
|
||||
(t/is (= 0 (:delete res))))
|
||||
|
||||
;; run the task immediately
|
||||
;; run the file-gc task immediately without forced min-age
|
||||
(let [task (:app.tasks.file-gc/handler th/*system*)
|
||||
res (task {})]
|
||||
(t/is (= 0 (:processed res))))
|
||||
|
||||
;; 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 {})]
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed res))))
|
||||
|
||||
;; retrieve file and check trimmed attribute
|
||||
|
@ -220,22 +215,36 @@
|
|||
(t/is (some? @(sto/get-object storage (:media-id fmo1))))
|
||||
(t/is (some? @(sto/get-object storage (:thumbnail-id fmo1))))
|
||||
|
||||
;; now, we have deleted the unused file-media-object, if we
|
||||
;; execute the touched-gc task, we should see that two of them
|
||||
;; are marked to be deleted.
|
||||
;; proceed to remove usage of the file
|
||||
(update-file {:file-id (:id file)
|
||||
:profile-id (:id profile)
|
||||
:revn 0
|
||||
:changes [{:type :del-obj
|
||||
:page-id (first (get-in file [:data :pages]))
|
||||
:id shid}]})
|
||||
|
||||
;; Now, we have deleted the usag of pointers to the
|
||||
;; file-media-objects, if we pase file-gc, they should be marked
|
||||
;; as deleted.
|
||||
(let [task (:app.tasks.file-gc/handler th/*system*)
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed res))))
|
||||
|
||||
;; Now that file-gc have deleted the file-media-object usage,
|
||||
;; lets execute the touched-gc task, we should see that two of
|
||||
;; them are marked to be deleted.
|
||||
(let [task (:app.storage/gc-touched-task th/*system*)
|
||||
res (task {})]
|
||||
(t/is (= 2 (:freeze res)))
|
||||
(t/is (= 0 (:delete res))))
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 0 (:freeze res)))
|
||||
(t/is (= 2 (:delete res))))
|
||||
|
||||
;; Finally, check that some of the objects that are marked as
|
||||
;; deleted we are unable to retrieve them using standard storage
|
||||
;; public api.
|
||||
(t/is (some? @(sto/get-object storage (:media-id fmo2))))
|
||||
(t/is (some? @(sto/get-object storage (:thumbnail-id fmo2))))
|
||||
(t/is (some? @(sto/get-object storage (:media-id fmo1))))
|
||||
(t/is (some? @(sto/get-object storage (:thumbnail-id fmo1))))
|
||||
|
||||
(t/is (nil? @(sto/get-object storage (:media-id fmo2))))
|
||||
(t/is (nil? @(sto/get-object storage (:thumbnail-id fmo2))))
|
||||
(t/is (nil? @(sto/get-object storage (:media-id fmo1))))
|
||||
(t/is (nil? @(sto/get-object storage (:thumbnail-id fmo1))))
|
||||
)))
|
||||
|
||||
(t/deftest permissions-checks-creating-file
|
||||
|
@ -353,8 +362,8 @@
|
|||
:profile-id (:id profile1)})]
|
||||
;; file is not deleted because it does not meet all
|
||||
;; conditions to be deleted.
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; query the list of files
|
||||
(let [data {::th/type :project-files
|
||||
|
@ -384,8 +393,8 @@
|
|||
(t/is (= 0 (count result)))))
|
||||
|
||||
;; run permanent deletion (should be noop)
|
||||
(let [result (task {:max-age (dt/duration {:minutes 1})})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration {:minutes 1})})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; query the list of file libraries of a after hard deletion
|
||||
(let [data {::th/type :file-libraries
|
||||
|
@ -398,8 +407,8 @@
|
|||
(t/is (= 0 (count result)))))
|
||||
|
||||
;; run permanent deletion
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed result))))
|
||||
|
||||
;; query the list of file libraries of a after hard deletion
|
||||
(let [data {::th/type :file-libraries
|
||||
|
@ -590,7 +599,7 @@
|
|||
|
||||
;; run the task again
|
||||
(let [task (:app.tasks.file-gc/handler th/*system*)
|
||||
res (task {})]
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed res))))
|
||||
|
||||
;; check that object thumbnails are still here
|
||||
|
@ -617,7 +626,7 @@
|
|||
|
||||
;; run the task again
|
||||
(let [task (:app.tasks.file-gc/handler th/*system*)
|
||||
res (task {})]
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed res))))
|
||||
|
||||
;; check that the unknown frame thumbnail is deleted
|
||||
|
@ -701,7 +710,7 @@
|
|||
|
||||
;; run the task again
|
||||
(let [task (:app.tasks.file-gc/handler th/*system*)
|
||||
res (task {})]
|
||||
res (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed res))))
|
||||
|
||||
;; Then query the specific revn
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
[app.http :as http]
|
||||
[app.storage :as sto]
|
||||
[app.test-helpers :as th]
|
||||
[app.util.bytes :as bs]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.test :as t]
|
||||
[datoteka.core :as fs]))
|
||||
|
@ -25,7 +26,8 @@
|
|||
font-id (uuid/custom 10 1)
|
||||
|
||||
ttfdata (-> (io/resource "app/test_files/font-1.ttf")
|
||||
(fs/slurp-bytes))
|
||||
io/input-stream
|
||||
bs/read-as-bytes)
|
||||
|
||||
params {::th/type :create-font-variant
|
||||
:profile-id (:id prof)
|
||||
|
@ -60,7 +62,8 @@
|
|||
font-id (uuid/custom 10 1)
|
||||
|
||||
data (-> (io/resource "app/test_files/font-1.woff")
|
||||
(fs/slurp-bytes))
|
||||
io/input-stream
|
||||
bs/read-as-bytes)
|
||||
|
||||
params {::th/type :create-font-variant
|
||||
:profile-id (:id prof)
|
||||
|
|
|
@ -46,9 +46,11 @@
|
|||
(t/is (sto/storage-object? mobj1))
|
||||
(t/is (sto/storage-object? mobj2))
|
||||
(t/is (= 122785 (:size mobj1)))
|
||||
;; This is because in ubuntu 21.04 generates different
|
||||
;; thumbnail that in ubuntu 22.04. This hack should be removed
|
||||
;; when we all use the ubuntu 22.04 devenv image.
|
||||
(t/is (or (= 3302 (:size mobj2))
|
||||
(= 3303 (:size mobj2))))))
|
||||
))
|
||||
(= 3303 (:size mobj2))))))))
|
||||
|
||||
(t/deftest media-object-upload
|
||||
(let [prof (th/create-profile* 1)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.rpc.mutations.profile :as profile]
|
||||
[app.rpc.commands.auth :as cauth]
|
||||
[app.test-helpers :as th]
|
||||
[app.util.time :as dt]
|
||||
[clojure.java.io :as io]
|
||||
|
@ -27,11 +28,10 @@
|
|||
;; Test with wrong credentials
|
||||
(t/deftest profile-login-failed-1
|
||||
(let [profile (th/create-profile* 1)
|
||||
data {::th/type :login
|
||||
data {::th/type :login-with-password
|
||||
:email "profile1.test@nodomain.com"
|
||||
:password "foobar"
|
||||
:scope "foobar"}
|
||||
out (th/mutation! data)]
|
||||
:password "foobar"}
|
||||
out (th/command! data)]
|
||||
|
||||
#_(th/print-result! out)
|
||||
(let [error (:error out)]
|
||||
|
@ -42,11 +42,10 @@
|
|||
;; Test with good credentials but profile not activated.
|
||||
(t/deftest profile-login-failed-2
|
||||
(let [profile (th/create-profile* 1)
|
||||
data {::th/type :login
|
||||
data {::th/type :login-with-password
|
||||
:email "profile1.test@nodomain.com"
|
||||
:password "123123"
|
||||
:scope "foobar"}
|
||||
out (th/mutation! data)]
|
||||
:password "123123"}
|
||||
out (th/command! data)]
|
||||
;; (th/print-result! out)
|
||||
(let [error (:error out)]
|
||||
(t/is (th/ex-info? error))
|
||||
|
@ -58,8 +57,7 @@
|
|||
(let [profile (th/create-profile* 1 {:is-active true})
|
||||
data {::th/type :login
|
||||
:email "profile1.test@nodomain.com"
|
||||
:password "123123"
|
||||
:scope "foobar"}
|
||||
:password "123123"}
|
||||
out (th/mutation! data)]
|
||||
;; (th/print-result! out)
|
||||
(t/is (nil? (:error out)))
|
||||
|
@ -128,8 +126,8 @@
|
|||
|
||||
;; profile is not deleted because it does not meet all
|
||||
;; conditions to be deleted.
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; Request profile to be deleted
|
||||
(let [params {::th/type :delete-profile
|
||||
|
@ -147,8 +145,8 @@
|
|||
(t/is (= 1 (count (:result out)))))
|
||||
|
||||
;; execute permanent deletion task
|
||||
(let [result (task {:max-age (dt/duration "-1m")})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration "-1m")})]
|
||||
(t/is (= 1 (:processed result))))
|
||||
|
||||
;; query profile after delete
|
||||
(let [params {::th/type :profile
|
||||
|
@ -161,11 +159,11 @@
|
|||
(t/deftest registration-domain-whitelist
|
||||
(let [whitelist #{"gmail.com" "hey.com" "ya.ru"}]
|
||||
(t/testing "allowed email domain"
|
||||
(t/is (true? (profile/email-domain-in-whitelist? whitelist "username@ya.ru")))
|
||||
(t/is (true? (profile/email-domain-in-whitelist? #{} "username@somedomain.com"))))
|
||||
(t/is (true? (cauth/email-domain-in-whitelist? whitelist "username@ya.ru")))
|
||||
(t/is (true? (cauth/email-domain-in-whitelist? #{} "username@somedomain.com"))))
|
||||
|
||||
(t/testing "not allowed email domain"
|
||||
(t/is (false? (profile/email-domain-in-whitelist? whitelist "username@somedomain.com"))))))
|
||||
(t/is (false? (cauth/email-domain-in-whitelist? whitelist "username@somedomain.com"))))))
|
||||
|
||||
(t/deftest prepare-register-and-register-profile
|
||||
(let [data {::th/type :prepare-register-profile
|
||||
|
|
|
@ -179,8 +179,8 @@
|
|||
|
||||
;; project is not deleted because it does not meet all
|
||||
;; conditions to be deleted.
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; query the list of projects
|
||||
(let [data {::th/type :projects
|
||||
|
@ -210,8 +210,8 @@
|
|||
(t/is (= 1 (count result)))))
|
||||
|
||||
;; run permanent deletion (should be noop)
|
||||
(let [result (task {:max-age (dt/duration {:minutes 1})})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration {:minutes 1})})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; query the list of files of a after soft deletion
|
||||
(let [data {::th/type :project-files
|
||||
|
@ -224,8 +224,8 @@
|
|||
(t/is (= 0 (count result)))))
|
||||
|
||||
;; run permanent deletion
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed result))))
|
||||
|
||||
;; query the list of files of a after hard deletion
|
||||
(let [data {::th/type :project-files
|
||||
|
|
|
@ -99,8 +99,8 @@
|
|||
|
||||
;; team is not deleted because it does not meet all
|
||||
;; conditions to be deleted.
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; query the list of teams
|
||||
(let [data {::th/type :teams
|
||||
|
@ -132,8 +132,8 @@
|
|||
(t/is (= (:default-team-id profile1) (get-in result [0 :id])))))
|
||||
|
||||
;; run permanent deletion (should be noop)
|
||||
(let [result (task {:max-age (dt/duration {:minutes 1})})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration {:minutes 1})})]
|
||||
(t/is (= 0 (:processed result))))
|
||||
|
||||
;; query the list of projects after hard deletion
|
||||
(let [data {::th/type :projects
|
||||
|
@ -147,8 +147,8 @@
|
|||
(t/is (= (:type error-data) :not-found))))
|
||||
|
||||
;; run permanent deletion
|
||||
(let [result (task {:max-age (dt/duration 0)})]
|
||||
(t/is (nil? result)))
|
||||
(let [result (task {:min-age (dt/duration 0)})]
|
||||
(t/is (= 1 (:processed result))))
|
||||
|
||||
;; query the list of projects of a after hard deletion
|
||||
(let [data {::th/type :projects
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
:profile-id (:id prof)
|
||||
:file-id (:id file)
|
||||
:pages #{(get-in file [:data :pages 0])}
|
||||
:flags #{}}
|
||||
:who-comment "team"
|
||||
:who-inspect "all"}
|
||||
out (th/mutation! data)]
|
||||
|
||||
;; (th/print-result! out)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[app.storage :as sto]
|
||||
[app.test-helpers :as th]
|
||||
[app.util.time :as dt]
|
||||
[app.util.bytes :as bs]
|
||||
[clojure.java.io :as io]
|
||||
[clojure.test :as t]
|
||||
[cuerdas.core :as str]
|
||||
|
@ -27,11 +28,11 @@
|
|||
"Given storage map, returns a storage configured with the appropriate
|
||||
backend for assets."
|
||||
([storage]
|
||||
(assoc storage :backend :tmp))
|
||||
(assoc storage :backend :assets-fs))
|
||||
([storage conn]
|
||||
(-> storage
|
||||
(assoc :conn conn)
|
||||
(assoc :backend :tmp))))
|
||||
(assoc :backend :assets-fs))))
|
||||
|
||||
(t/deftest put-and-retrieve-object
|
||||
(let [storage (-> (:app.storage/storage th/*system*)
|
||||
|
@ -43,7 +44,7 @@
|
|||
(t/is (sto/storage-object? object))
|
||||
(t/is (fs/path? @(sto/get-object-path storage object)))
|
||||
(t/is (nil? (:expired-at object)))
|
||||
(t/is (= :tmp (:backend object)))
|
||||
(t/is (= :assets-fs (:backend object)))
|
||||
(t/is (= "data" (:other (meta object))))
|
||||
(t/is (= "text/plain" (:content-type (meta object))))
|
||||
(t/is (= "content" (slurp @(sto/get-object-data storage object))))
|
||||
|
@ -197,7 +198,8 @@
|
|||
:is-shared false})
|
||||
|
||||
ttfdata (-> (io/resource "app/test_files/font-1.ttf")
|
||||
(fs/slurp-bytes))
|
||||
io/input-stream
|
||||
bs/read-as-bytes)
|
||||
|
||||
mfile {:filename "sample.jpg"
|
||||
:path (th/tempfile "app/test_files/sample.jpg")
|
||||
|
|
BIN
backend/test/app/test_files/template.penpot
Normal file
BIN
backend/test/app/test_files/template.penpot
Normal file
Binary file not shown.
|
@ -9,14 +9,15 @@
|
|||
[app.common.data :as d]
|
||||
[app.common.flags :as flags]
|
||||
[app.common.pages :as cp]
|
||||
[app.common.pprint :as pp]
|
||||
[app.common.spec :as us]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.common.pprint :as pp]
|
||||
[app.config :as cf]
|
||||
[app.db :as db]
|
||||
[app.main :as main]
|
||||
[app.media]
|
||||
[app.migrations]
|
||||
[app.rpc.commands.auth :as cmd.auth]
|
||||
[app.rpc.mutations.files :as files]
|
||||
[app.rpc.mutations.profile :as profile]
|
||||
[app.rpc.mutations.projects :as projects]
|
||||
|
@ -31,8 +32,8 @@
|
|||
[expound.alpha :as expound]
|
||||
[integrant.core :as ig]
|
||||
[mockery.core :as mk]
|
||||
[yetti.request :as yrq]
|
||||
[promesa.core :as p])
|
||||
[promesa.core :as p]
|
||||
[yetti.request :as yrq])
|
||||
(:import org.postgresql.ds.PGSimpleDataSource))
|
||||
|
||||
(def ^:dynamic *system* nil)
|
||||
|
@ -50,6 +51,7 @@
|
|||
(defn state-init
|
||||
[next]
|
||||
(let [config (-> main/system-config
|
||||
(merge main/worker-config)
|
||||
(assoc-in [:app.msgbus/msgbus :redis-uri] (:redis-uri config))
|
||||
(assoc-in [:app.db/pool :uri] (:database-uri config))
|
||||
(assoc-in [:app.db/pool :username] (:database-username config))
|
||||
|
@ -59,10 +61,12 @@
|
|||
:app.http/router
|
||||
:app.http.awsns/handler
|
||||
:app.http.session/updater
|
||||
:app.http.oauth/google
|
||||
:app.http.oauth/gitlab
|
||||
:app.http.oauth/github
|
||||
:app.http.oauth/all
|
||||
:app.auth.oidc/google-provider
|
||||
:app.auth.oidc/gitlab-provider
|
||||
:app.auth.oidc/github-provider
|
||||
:app.auth.oidc/generic-provider
|
||||
:app.auth.oidc/routes
|
||||
;; :app.auth.ldap/provider
|
||||
:app.worker/executors-monitor
|
||||
:app.http.oauth/handler
|
||||
:app.notifications/handler
|
||||
|
@ -72,18 +76,16 @@
|
|||
:app.loggers.database/reporter
|
||||
:app.loggers.zmq/receiver
|
||||
:app.worker/cron
|
||||
:app.worker/worker)
|
||||
(d/deep-merge
|
||||
{:app.tasks.file-gc/handler {:max-age (dt/duration 300)}}))
|
||||
:app.worker/worker))
|
||||
_ (ig/load-namespaces config)
|
||||
system (-> (ig/prep config)
|
||||
(ig/init))]
|
||||
(try
|
||||
(binding [*system* system
|
||||
*pool* (:app.db/pool system)]
|
||||
(mk/with-mocks [mock1 {:target 'app.rpc.mutations.profile/derive-password
|
||||
(mk/with-mocks [mock1 {:target 'app.rpc.commands.auth/derive-password
|
||||
:return identity}
|
||||
mock2 {:target 'app.rpc.mutations.profile/verify-password
|
||||
mock2 {:target 'app.rpc.commands.auth/verify-password
|
||||
:return (fn [a b] {:valid (= a b)})}]
|
||||
(next)))
|
||||
(finally
|
||||
|
@ -140,8 +142,8 @@
|
|||
:is-demo false}
|
||||
params)]
|
||||
(->> params
|
||||
(#'profile/create-profile conn)
|
||||
(#'profile/create-profile-relations conn)))))
|
||||
(cmd.auth/create-profile conn)
|
||||
(cmd.auth/create-profile-relations conn)))))
|
||||
|
||||
(defn create-project*
|
||||
([i params] (create-project* *pool* i params))
|
||||
|
@ -267,17 +269,21 @@
|
|||
{:error (handle-error e#)
|
||||
:result nil})))
|
||||
|
||||
(defn command!
|
||||
[{:keys [::type] :as data}]
|
||||
(let [method-fn (get-in *system* [:app.rpc/methods :commands type])]
|
||||
;; (app.common.pprint/pprint (:app.rpc/methods *system*))
|
||||
(try-on! (method-fn (dissoc data ::type)))))
|
||||
|
||||
(defn mutation!
|
||||
[{:keys [::type] :as data}]
|
||||
(let [method-fn (get-in *system* [:app.rpc/rpc :methods :mutation type])]
|
||||
(try-on!
|
||||
(method-fn (dissoc data ::type)))))
|
||||
(let [method-fn (get-in *system* [:app.rpc/methods :mutations type])]
|
||||
(try-on! (method-fn (dissoc data ::type)))))
|
||||
|
||||
(defn query!
|
||||
[{:keys [::type] :as data}]
|
||||
(let [method-fn (get-in *system* [:app.rpc/rpc :methods :query type])]
|
||||
(try-on!
|
||||
(method-fn (dissoc data ::type)))))
|
||||
(let [method-fn (get-in *system* [:app.rpc/methods :queries type])]
|
||||
(try-on! (method-fn (dissoc data ::type)))))
|
||||
|
||||
;; --- UTILS
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue