🐛 Fix incorrect handling request access with deleted profiles

* 📎 Add minor improvements to team tests

* 🐛 Fix incorrect handling request access with deleted profiles

* 🐛 Fix redirect loop on empty route

Happens when the current profile is deleted from team

* 🐛 Fix urls on request access emails

* 📎 Revert url changes on emails
This commit is contained in:
Andrey Antukh
2025-02-19 11:04:19 +01:00
committed by GitHub
parent 19bae05f41
commit 4744085426
13 changed files with 166 additions and 62 deletions

View File

@@ -37,18 +37,17 @@
:role :editor}]
;; invite external user without complaints
(let [data (assoc data :emails ["foo@bar.com"])
out (th/command! data)
(let [data (assoc data :emails ["foo@bar.com"])
out (th/command! data)
;; retrieve the value from the database and check its content
invitation (db/exec-one!
th/*pool*
["select count(*) as num from team_invitation where team_id = ? and email_to = ?"
(:team-id data) "foo@bar.com"])]
invitations (th/db-query :team-invitation
{:team-id (:team-id data)
:email-to "foo@bar.com"})]
;; (th/print-result! out)
(t/is (th/success? out))
(t/is (= 1 (:call-count (deref mock))))
(t/is (= 1 (:num invitation))))
(t/is (= 1 (count invitations))))
;; invite internal user without complaints
(th/reset-mock! mock)
@@ -102,6 +101,105 @@
(t/is (= :validation (:type edata)))
(t/is (= :member-is-muted (:code edata))))))))
(t/deftest create-team-invitations-with-request-access
(with-mocks [mock {:target 'app.email/send! :return nil}]
(let [profile1 (th/create-profile* 1 {:is-active true})
requester (th/create-profile* 2 {:is-active true :email "requester@example.com"})
team (th/create-team* 1 {:profile-id (:id profile1)})
proj (th/create-project* 1 {:profile-id (:id profile1)
:team-id (:id team)})
file (th/create-file* 1 {:profile-id (:id profile1)
:project-id (:id proj)})]
(let [data {::th/type :create-team-access-request
::rpc/profile-id (:id requester)
:file-id (:id file)}
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock))))
(th/reset-mock! mock)
(let [data {::th/type :create-team-invitations
::rpc/profile-id (:id profile1)
:team-id (:id team)
:role :editor
:emails ["requester@example.com"]}
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock)))
;; Check that request is properly removed
(let [requests (th/db-query :team-access-request
{:requester-id (:id requester)})]
(t/is (= 0 (count requests))))
(let [rows (th/db-query :team-profile-rel {:team-id (:id team)})]
(t/is (= 2 (count rows))))))))
(t/deftest create-team-invitations-with-request-access-2
(with-mocks [mock {:target 'app.email/send! :return nil}]
(let [profile1 (th/create-profile* 1 {:is-active true})
requester (th/create-profile* 2 {:is-active true
:email "requester@example.com"})
team (th/create-team* 1 {:profile-id (:id profile1)})
proj (th/create-project* 1 {:profile-id (:id profile1)
:team-id (:id team)})
file (th/create-file* 1 {:profile-id (:id profile1)
:project-id (:id proj)})]
;; Create the first access request
(let [data {::th/type :create-team-access-request
::rpc/profile-id (:id requester)
:file-id (:id file)}
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock))))
(th/reset-mock! mock)
;; Proceed to delete the requester user
(th/db-update! :profile
{:deleted-at (dt/in-past "1h")}
{:id (:id requester)})
;; Create a new profile with the same email
(let [requester' (th/create-profile* 3 {:is-active true :email "requester@example.com"})]
;; Create a request access with new requester
(let [data {::th/type :create-team-access-request
::rpc/profile-id (:id requester')
:file-id (:id file)}
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock))))
(th/reset-mock! mock)
;; Create an invitation for the requester email
(let [data {::th/type :create-team-invitations
::rpc/profile-id (:id profile1)
:team-id (:id team)
:role :editor
:emails ["requester@example.com"]}
out (th/command! data)]
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock))))
;; Check that request is properly removed
(let [requests (th/db-query :team-access-request
{:requester-id (:id requester')})]
(t/is (= 0 (count requests))))
(let [[r1 r2 :as rows] (th/db-query :team-profile-rel
{:team-id (:id team)}
{:order-by [:created-at]})]
(t/is (= 2 (count rows)))
(t/is (= (:profile-id r1) (:id profile1)))
(t/is (= (:profile-id r2) (:id requester'))))))))
(t/deftest invitation-tokens
(with-mocks [mock {:target 'app.email/send! :return nil}]
@@ -486,14 +584,12 @@
;; request success
(let [out (th/command! data)
;; retrieve the value from the database and check its content
request (db/exec-one!
th/*pool*
["select count(*) as num from team_access_request where team_id = ? and requester_id = ?"
(:id team) (:id requester)])]
requests (th/db-query :team-access-request
{:team-id (:id team)
:requester-id (:id requester)})]
(t/is (th/success? out))
(t/is (= 1 (:call-count @mock)))
(t/is (= 1 (:num request))))
(t/is (= 1 (count requests))))
;; request again fails
(th/reset-mock! mock)
@@ -509,10 +605,10 @@
;; request again when is expired success
(th/reset-mock! mock)
(db/exec-one!
th/*pool*
["update team_access_request set valid_until = ? where team_id = ? and requester_id = ?"
(dt/in-past "1h") (:id team) (:id requester)])
(th/db-update! :team-access-request
{:valid-until (dt/in-past "1h")}
{:team-id (:id team)
:requester-id (:id requester)})
(t/is (th/success? (th/command! data)))
(t/is (= 1 (:call-count @mock))))))