mirror of
https://github.com/penpot/penpot.git
synced 2026-04-29 21:28:20 +00:00
✨ Improve team name validation (#9176)
This commit is contained in:
parent
94827f1848
commit
d627d1cfac
@ -497,7 +497,7 @@
|
||||
|
||||
(def ^:private schema:create-team
|
||||
[:map {:title "create-team"}
|
||||
[:name [:string {:max 250}]]
|
||||
[:name types.team/schema:team-name]
|
||||
[:features {:optional true} ::cfeat/features]
|
||||
[:id {:optional true} ::sm/uuid]])
|
||||
|
||||
@ -591,7 +591,7 @@
|
||||
|
||||
(def ^:private schema:update-team
|
||||
[:map {:title "update-team"}
|
||||
[:name [:string {:max 250}]]
|
||||
[:name types.team/schema:team-name]
|
||||
[:id ::sm/uuid]])
|
||||
|
||||
(sv/defmethod ::update-team
|
||||
|
||||
@ -767,3 +767,82 @@
|
||||
(t/is (th/success? (th/command! data)))
|
||||
(t/is (= 1 (:call-count @mock))))))
|
||||
|
||||
(t/deftest create-team-with-invalid-name
|
||||
(let [profile (th/create-profile* 1 {:is-active true})]
|
||||
|
||||
;; name with a dot should fail
|
||||
(let [data {::th/type :create-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:name "foo.bar"}
|
||||
out (th/command! data)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-type? (:error out) :validation))
|
||||
(t/is (th/ex-of-code? (:error out) :params-validation)))
|
||||
|
||||
;; name with a colon should fail
|
||||
(let [data {::th/type :create-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:name "foo:bar"}
|
||||
out (th/command! data)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-type? (:error out) :validation))
|
||||
(t/is (th/ex-of-code? (:error out) :params-validation)))
|
||||
|
||||
;; name with a slash should fail
|
||||
(let [data {::th/type :create-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:name "foo/bar"}
|
||||
out (th/command! data)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-type? (:error out) :validation))
|
||||
(t/is (th/ex-of-code? (:error out) :params-validation)))
|
||||
|
||||
;; valid name should succeed
|
||||
(let [data {::th/type :create-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:name "My Valid Team"}
|
||||
out (th/command! data)]
|
||||
(t/is (th/success? out)))))
|
||||
|
||||
(t/deftest update-team-with-invalid-name
|
||||
(let [profile (th/create-profile* 1 {:is-active true})
|
||||
team (th/create-team* 1 {:profile-id (:id profile)})]
|
||||
|
||||
;; name with a dot should fail
|
||||
(let [data {::th/type :update-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:id (:id team)
|
||||
:name "foo.bar"}
|
||||
out (th/command! data)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-type? (:error out) :validation))
|
||||
(t/is (th/ex-of-code? (:error out) :params-validation)))
|
||||
|
||||
;; name with a colon should fail
|
||||
(let [data {::th/type :update-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:id (:id team)
|
||||
:name "foo:bar"}
|
||||
out (th/command! data)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-type? (:error out) :validation))
|
||||
(t/is (th/ex-of-code? (:error out) :params-validation)))
|
||||
|
||||
;; name with a slash should fail
|
||||
(let [data {::th/type :update-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:id (:id team)
|
||||
:name "foo/bar"}
|
||||
out (th/command! data)]
|
||||
(t/is (not (th/success? out)))
|
||||
(t/is (th/ex-of-type? (:error out) :validation))
|
||||
(t/is (th/ex-of-code? (:error out) :params-validation)))
|
||||
|
||||
;; valid name should succeed
|
||||
(let [data {::th/type :update-team
|
||||
::rpc/profile-id (:id profile)
|
||||
:id (:id team)
|
||||
:name "My Valid Team"}
|
||||
out (th/command! data)]
|
||||
(t/is (th/success? out)))))
|
||||
|
||||
|
||||
@ -20,6 +20,12 @@
|
||||
(def schema:role
|
||||
[::sm/one-of {:title "TeamRole"} valid-roles])
|
||||
|
||||
(def schema:team-name
|
||||
[:and
|
||||
[::sm/text {:max 250}]
|
||||
[:fn {:error/code "errors.team-name-invalid-chars"}
|
||||
(fn [s] (not (re-find #"[.:/]" s)))]])
|
||||
|
||||
;; FIXME: specify more fields
|
||||
(def schema:team
|
||||
[:map {:title "Team"}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
(ns app.main.ui.dashboard.team-form
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.team :as ctt]
|
||||
[app.main.data.common :as dcm]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
(def ^:private schema:team-form
|
||||
[:map {:title "TeamForm"}
|
||||
[:name [::sm/text {:max 250}]]])
|
||||
[:name ctt/schema:team-name]])
|
||||
|
||||
(defn- on-create-success
|
||||
[_form response]
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
(:require-macros [app.main.style :as stl])
|
||||
(:require
|
||||
[app.common.schema :as sm]
|
||||
[app.common.types.team :as ctt]
|
||||
[app.main.data.common :as dcm]
|
||||
[app.main.data.event :as ev]
|
||||
[app.main.data.profile :as du]
|
||||
@ -59,7 +60,7 @@
|
||||
|
||||
(def ^:private schema:team-form
|
||||
[:map {:title "TeamForm"}
|
||||
[:name [::sm/text {:max 250}]]
|
||||
[:name ctt/schema:team-name]
|
||||
[:role :keyword]
|
||||
[:emails {:optional true} [::sm/set ::sm/email]]])
|
||||
|
||||
|
||||
@ -1435,6 +1435,10 @@ msgstr "The recovery token is invalid."
|
||||
msgid "errors.invalid-text"
|
||||
msgstr "Invalid text"
|
||||
|
||||
#: common/src/app/common/types/team.cljc:26
|
||||
msgid "errors.team-name-invalid-chars"
|
||||
msgstr "The team name can't contain any of the following characters:'.', ':' or '/'"
|
||||
|
||||
#: src/app/main/ui/static.cljs:74
|
||||
msgid "errors.invite-invalid"
|
||||
msgstr "Invite invalid"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user