mirror of
https://github.com/penpot/penpot.git
synced 2026-04-25 11:18:36 +00:00
🐛 Fix on nitrate leave org default org team must be deleted if empty
This commit is contained in:
parent
ac472c615a
commit
65a0fcb15b
@ -40,6 +40,13 @@
|
|||||||
AND t.id = ANY(?)
|
AND t.id = ANY(?)
|
||||||
AND t.deleted_at IS NULL")
|
AND t.deleted_at IS NULL")
|
||||||
|
|
||||||
|
(def ^:private sql:get-team-files-count
|
||||||
|
"SELECT count(*) AS total
|
||||||
|
FROM file AS f
|
||||||
|
JOIN project AS p ON (p.id = f.project_id)
|
||||||
|
WHERE p.team_id = ?
|
||||||
|
AND f.deleted_at IS NULL")
|
||||||
|
|
||||||
(def ^:private schema:leave-org
|
(def ^:private schema:leave-org
|
||||||
[:map
|
[:map
|
||||||
[:org-id ::sm/uuid]
|
[:org-id ::sm/uuid]
|
||||||
@ -100,6 +107,21 @@
|
|||||||
|
|
||||||
valid-teams-to-leave-ids (into valid-teams-to-transfer-ids valid-teams-to-exit-ids)
|
valid-teams-to-leave-ids (into valid-teams-to-transfer-ids valid-teams-to-exit-ids)
|
||||||
|
|
||||||
|
;; Get all the teams ids
|
||||||
|
all-teams-ids (into #{} d/xf:map-id (:teams org-summary))
|
||||||
|
|
||||||
|
;; Get all the ids of the teams that will be processed:
|
||||||
|
;; all the ids on teams-to-leave, teams-to-delete and default-team-id
|
||||||
|
selected-team-ids (-> (into #{default-team-id} teams-to-delete)
|
||||||
|
(into d/xf:map-id teams-to-leave))
|
||||||
|
|
||||||
|
;; Check that we are processing all the teams
|
||||||
|
all-teams-selected? (= all-teams-ids selected-team-ids)
|
||||||
|
|
||||||
|
default-team-files-count (-> (db/exec-one! conn [sql:get-team-files-count default-team-id])
|
||||||
|
:total)
|
||||||
|
delete-default-team? (= default-team-files-count 0)
|
||||||
|
|
||||||
;; for every team in teams-to-leave, check that:
|
;; for every team in teams-to-leave, check that:
|
||||||
;; - if it has a reassign-to, it belongs to valid-teams-to-transfer and
|
;; - if it has a reassign-to, it belongs to valid-teams-to-transfer and
|
||||||
;; the reassign-to is a member of the team and not the current user;
|
;; the reassign-to is a member of the team and not the current user;
|
||||||
@ -123,7 +145,8 @@
|
|||||||
(when (or
|
(when (or
|
||||||
(not valid-teams-to-delete?)
|
(not valid-teams-to-delete?)
|
||||||
(not valid-teams-to-leave?)
|
(not valid-teams-to-leave?)
|
||||||
(not valid-default-team-id?))
|
(not valid-default-team-id?)
|
||||||
|
(not all-teams-selected?))
|
||||||
(ex/raise :type :validation
|
(ex/raise :type :validation
|
||||||
:code :not-valid-teams))
|
:code :not-valid-teams))
|
||||||
|
|
||||||
@ -135,8 +158,12 @@
|
|||||||
(doseq [{:keys [id reassign-to]} teams-to-leave]
|
(doseq [{:keys [id reassign-to]} teams-to-leave]
|
||||||
(teams/leave-team cfg {:profile-id profile-id :id id :reassign-to reassign-to}))
|
(teams/leave-team cfg {:profile-id profile-id :id id :reassign-to reassign-to}))
|
||||||
|
|
||||||
;; Rename default-team-id
|
;; Delete default-team-id if empty; otherwise keep it and prefix the name.
|
||||||
(db/exec! conn [sql:prefix-team-name-and-unset-default org-prefix default-team-id])
|
(if delete-default-team?
|
||||||
|
(do
|
||||||
|
(db/update! conn :team {:is-default false} {:id default-team-id})
|
||||||
|
(teams/delete-team cfg {:profile-id profile-id :team-id default-team-id}))
|
||||||
|
(db/exec! conn [sql:prefix-team-name-and-unset-default org-prefix default-team-id]))
|
||||||
|
|
||||||
;; Api call to nitrate
|
;; Api call to nitrate
|
||||||
(nitrate/call cfg :remove-profile-from-org {:profile-id profile-id :org-id org-id})
|
(nitrate/call cfg :remove-profile-from-org {:profile-id profile-id :org-id org-id})
|
||||||
|
|||||||
@ -48,9 +48,15 @@
|
|||||||
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||||
profile-user (th/create-profile* 2 {:is-active true})
|
profile-user (th/create-profile* 2 {:is-active true})
|
||||||
|
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
project (th/create-project* 99 {:profile-id (:id profile-user)
|
||||||
|
:team-id (:id org-default-team)})
|
||||||
|
_ (th/create-file* 99 {:profile-id (:id profile-user)
|
||||||
|
:project-id (:id project)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
;; The user's personal penpot team in the org context
|
;; The user's personal penpot team in the org context
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -78,14 +84,81 @@
|
|||||||
(t/is (str/starts-with? (:name team) "[Test Org] "))
|
(t/is (str/starts-with? (:name team) "[Test Org] "))
|
||||||
(t/is (false? (:is-default team))))))))
|
(t/is (false? (:is-default team))))))))
|
||||||
|
|
||||||
|
(t/deftest leave-org-deletes-org-default-team-when-empty
|
||||||
|
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||||
|
profile-user (th/create-profile* 2 {:is-active true})
|
||||||
|
org-default-team (th/create-team* 98 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
|
org-id (uuid/random)
|
||||||
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
|
org-summary (make-org-summary
|
||||||
|
:org-id org-id
|
||||||
|
:org-name "Test Org"
|
||||||
|
:owner-id (:id profile-owner)
|
||||||
|
:your-penpot-teams [your-penpot-id]
|
||||||
|
:org-teams [])]
|
||||||
|
|
||||||
|
(with-redefs [nitrate/call (nitrate-call-mock org-summary)]
|
||||||
|
(let [data {::th/type :leave-org
|
||||||
|
::rpc/profile-id (:id profile-user)
|
||||||
|
:org-id org-id
|
||||||
|
:default-team-id your-penpot-id
|
||||||
|
:teams-to-delete []
|
||||||
|
:teams-to-leave []}
|
||||||
|
out (th/command! data)]
|
||||||
|
|
||||||
|
(t/is (th/success? out))
|
||||||
|
|
||||||
|
;; Empty org default team should be soft-deleted.
|
||||||
|
(let [team (th/db-get :team {:id your-penpot-id} {::db/remove-deleted false})]
|
||||||
|
(t/is (some? (:deleted-at team))))))))
|
||||||
|
|
||||||
|
(t/deftest leave-org-keeps-and-renames-org-default-team-when-has-files
|
||||||
|
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||||
|
profile-user (th/create-profile* 2 {:is-active true})
|
||||||
|
org-default-team (th/create-team* 97 {:profile-id (:id profile-user)})
|
||||||
|
project (th/create-project* 97 {:profile-id (:id profile-user)
|
||||||
|
:team-id (:id org-default-team)})
|
||||||
|
_ (th/create-file* 97 {:profile-id (:id profile-user)
|
||||||
|
:project-id (:id project)})
|
||||||
|
|
||||||
|
org-id (uuid/random)
|
||||||
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
|
org-summary (make-org-summary
|
||||||
|
:org-id org-id
|
||||||
|
:org-name "Test Org"
|
||||||
|
:owner-id (:id profile-owner)
|
||||||
|
:your-penpot-teams [your-penpot-id]
|
||||||
|
:org-teams [])]
|
||||||
|
|
||||||
|
(with-redefs [nitrate/call (nitrate-call-mock org-summary)]
|
||||||
|
(let [data {::th/type :leave-org
|
||||||
|
::rpc/profile-id (:id profile-user)
|
||||||
|
:org-id org-id
|
||||||
|
:default-team-id your-penpot-id
|
||||||
|
:teams-to-delete []
|
||||||
|
:teams-to-leave []}
|
||||||
|
out (th/command! data)]
|
||||||
|
|
||||||
|
(t/is (th/success? out))
|
||||||
|
|
||||||
|
;; Non-empty org default team should remain and be renamed.
|
||||||
|
(let [team (th/db-get :team {:id your-penpot-id})]
|
||||||
|
(t/is (str/starts-with? (:name team) "[Test Org] "))
|
||||||
|
(t/is (false? (:is-default team)))
|
||||||
|
(t/is (nil? (:deleted-at team))))))))
|
||||||
|
|
||||||
(t/deftest leave-org-with-teams-to-delete
|
(t/deftest leave-org-with-teams-to-delete
|
||||||
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||||
profile-user (th/create-profile* 2 {:is-active true})
|
profile-user (th/create-profile* 2 {:is-active true})
|
||||||
;; profile-user is the sole owner/member of team1
|
;; profile-user is the sole owner/member of team1
|
||||||
team1 (th/create-team* 1 {:profile-id (:id profile-user)})
|
team1 (th/create-team* 1 {:profile-id (:id profile-user)})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -118,9 +191,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-owner)
|
:profile-id (:id profile-owner)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -161,9 +235,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-user)
|
:profile-id (:id profile-user)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -196,8 +271,9 @@
|
|||||||
|
|
||||||
(t/deftest leave-org-error-org-owner-cannot-leave
|
(t/deftest leave-org-error-org-owner-cannot-leave
|
||||||
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-owner)})
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-owner)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
;; profile-owner IS the org owner in the org-summary
|
;; profile-owner IS the org owner in the org-summary
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
@ -223,8 +299,9 @@
|
|||||||
(t/deftest leave-org-error-invalid-default-team-id
|
(t/deftest leave-org-error-invalid-default-team-id
|
||||||
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||||
profile-user (th/create-profile* 2 {:is-active true})
|
profile-user (th/create-profile* 2 {:is-active true})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -253,9 +330,10 @@
|
|||||||
;; profile-user is the sole owner/member of both team1 and team2
|
;; profile-user is the sole owner/member of both team1 and team2
|
||||||
team1 (th/create-team* 1 {:profile-id (:id profile-user)})
|
team1 (th/create-team* 1 {:profile-id (:id profile-user)})
|
||||||
team2 (th/create-team* 2 {:profile-id (:id profile-user)})
|
team2 (th/create-team* 2 {:profile-id (:id profile-user)})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -286,9 +364,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-owner)
|
:profile-id (:id profile-owner)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -319,9 +398,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-owner)
|
:profile-id (:id profile-owner)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -351,9 +431,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-owner)
|
:profile-id (:id profile-owner)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -385,9 +466,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-owner)
|
:profile-id (:id profile-owner)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
@ -418,9 +500,10 @@
|
|||||||
_ (th/create-team-role* {:team-id (:id team1)
|
_ (th/create-team-role* {:team-id (:id team1)
|
||||||
:profile-id (:id profile-user)
|
:profile-id (:id profile-user)
|
||||||
:role :editor})
|
:role :editor})
|
||||||
|
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||||
|
|
||||||
org-id (uuid/random)
|
org-id (uuid/random)
|
||||||
your-penpot-id (:default-team-id profile-user)
|
your-penpot-id (:id org-default-team)
|
||||||
|
|
||||||
org-summary (make-org-summary
|
org-summary (make-org-summary
|
||||||
:org-id org-id
|
:org-id org-id
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user