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.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
|
||||
[:map
|
||||
[:org-id ::sm/uuid]
|
||||
@ -100,6 +107,21 @@
|
||||
|
||||
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:
|
||||
;; - 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;
|
||||
@ -123,7 +145,8 @@
|
||||
(when (or
|
||||
(not valid-teams-to-delete?)
|
||||
(not valid-teams-to-leave?)
|
||||
(not valid-default-team-id?))
|
||||
(not valid-default-team-id?)
|
||||
(not all-teams-selected?))
|
||||
(ex/raise :type :validation
|
||||
:code :not-valid-teams))
|
||||
|
||||
@ -135,8 +158,12 @@
|
||||
(doseq [{:keys [id reassign-to]} teams-to-leave]
|
||||
(teams/leave-team cfg {:profile-id profile-id :id id :reassign-to reassign-to}))
|
||||
|
||||
;; Rename default-team-id
|
||||
(db/exec! conn [sql:prefix-team-name-and-unset-default org-prefix default-team-id])
|
||||
;; Delete default-team-id if empty; otherwise keep it and prefix the name.
|
||||
(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
|
||||
(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})
|
||||
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)
|
||||
;; 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-id org-id
|
||||
@ -78,14 +84,81 @@
|
||||
(t/is (str/starts-with? (:name team) "[Test Org] "))
|
||||
(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
|
||||
(let [profile-owner (th/create-profile* 1 {:is-active true})
|
||||
profile-user (th/create-profile* 2 {:is-active true})
|
||||
;; profile-user is the sole owner/member of team1
|
||||
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)
|
||||
your-penpot-id (:default-team-id profile-user)
|
||||
your-penpot-id (:id org-default-team)
|
||||
|
||||
org-summary (make-org-summary
|
||||
:org-id org-id
|
||||
@ -118,9 +191,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-owner)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
@ -161,9 +235,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-user)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
@ -196,8 +271,9 @@
|
||||
|
||||
(t/deftest leave-org-error-org-owner-cannot-leave
|
||||
(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)
|
||||
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
|
||||
org-summary (make-org-summary
|
||||
@ -223,8 +299,9 @@
|
||||
(t/deftest leave-org-error-invalid-default-team-id
|
||||
(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* 99 {:profile-id (:id profile-user)})
|
||||
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-id org-id
|
||||
@ -253,9 +330,10 @@
|
||||
;; profile-user is the sole owner/member of both team1 and team2
|
||||
team1 (th/create-team* 1 {: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)
|
||||
your-penpot-id (:default-team-id profile-user)
|
||||
your-penpot-id (:id org-default-team)
|
||||
|
||||
org-summary (make-org-summary
|
||||
:org-id org-id
|
||||
@ -286,9 +364,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-owner)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
@ -319,9 +398,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-owner)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
@ -351,9 +431,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-owner)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
@ -385,9 +466,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-owner)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
@ -418,9 +500,10 @@
|
||||
_ (th/create-team-role* {:team-id (:id team1)
|
||||
:profile-id (:id profile-user)
|
||||
:role :editor})
|
||||
org-default-team (th/create-team* 99 {:profile-id (:id profile-user)})
|
||||
|
||||
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-id org-id
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user