diff --git a/app/models/user.py b/app/models/user.py
index ce7e41842..9cfa07869 100644
--- a/app/models/user.py
+++ b/app/models/user.py
@@ -151,7 +151,7 @@ class User(JSONModel, UserMixin):
return session.get('current_session_id') != self.current_session_id
def activate(self):
- if self.state == 'pending':
+ if self.is_pending:
user_data = user_api_client.activate_user(self.id)
return self.__class__(user_data['data'])
else:
@@ -192,6 +192,10 @@ class User(JSONModel, UserMixin):
def is_active(self):
return self.state == 'active'
+ @property
+ def is_pending(self):
+ return self.state == 'pending'
+
@property
def is_gov_user(self):
return is_gov_user(self.email_address)
@@ -440,6 +444,13 @@ class User(JSONModel, UserMixin):
def complete_webauthn_login_attempt(self, is_successful=True):
return user_api_client.complete_webauthn_login_attempt(self.id, is_successful)
+ def is_editable_by(self, other_user):
+ if other_user == self:
+ return False
+ if self.is_active or self.is_pending:
+ return True
+ return False
+
class InvitedUser(JSONModel):
@@ -575,6 +586,9 @@ class InvitedUser(JSONModel):
# only used on the manage users page to display the count, so okay to not be fully fledged for now
return [{'id': x} for x in self.folder_permissions]
+ def is_editable_by(self, other):
+ return False
+
class InvitedOrgUser(JSONModel):
diff --git a/app/templates/views/manage-users.html b/app/templates/views/manage-users.html
index b17469d1c..a8d3daac7 100644
--- a/app/templates/views/manage-users.html
+++ b/app/templates/views/manage-users.html
@@ -73,7 +73,7 @@
{% if current_user.has_permissions('manage_service') %}
{% if user.status == 'pending' %}
Cancel invitation for {{ user.email_address }}
- {% elif user.state == 'active' and current_user.id != user.id %}
+ {% elif user.is_editable_by(current_user) %}
Change details for {{ user.name }} {{ user.email_address }}
{% endif %}
{% endif %}
diff --git a/tests/app/main/views/test_manage_users.py b/tests/app/main/views/test_manage_users.py
index 14005bc28..cf57eef0d 100644
--- a/tests/app/main/views/test_manage_users.py
+++ b/tests/app/main/views/test_manage_users.py
@@ -151,6 +151,45 @@ def test_should_show_overview_page(
mock_get_users.assert_called_once_with(SERVICE_ONE_ID)
+@pytest.mark.parametrize('state', (
+ 'active', 'pending',
+))
+def test_should_show_change_details_link(
+ client_request,
+ mocker,
+ mock_get_invites_for_service,
+ mock_get_template_folders,
+ service_one,
+ active_user_with_permissions,
+ active_caseworking_user,
+ state,
+):
+ current_user = active_user_with_permissions
+
+ other_user = active_caseworking_user
+ other_user['id'] = uuid.uuid4()
+ other_user['email_address'] = 'zzzzzzz@example.gov.uk'
+ other_user['state'] = state
+
+ mocker.patch('app.user_api_client.get_user', return_value=current_user)
+ mocker.patch('app.models.user.Users.client_method', return_value=[
+ current_user,
+ other_user,
+ ])
+
+ page = client_request.get('main.manage_users', service_id=SERVICE_ONE_ID)
+ link = page.select('.user-list-item')[-1].select_one('a')
+
+ assert normalize_spaces(link.text) == (
+ 'Change details for Test User zzzzzzz@example.gov.uk'
+ )
+ assert link['href'] == url_for(
+ '.edit_user_permissions',
+ service_id=SERVICE_ONE_ID,
+ user_id=other_user['id'],
+ )
+
+
@pytest.mark.parametrize('number_of_users', (
pytest.param(7, marks=pytest.mark.xfail),
pytest.param(8),