diff --git a/app/models/service.py b/app/models/service.py index dea52c3dc..14219b709 100644 --- a/app/models/service.py +++ b/app/models/service.py @@ -112,8 +112,12 @@ class Service(JSONModel): @cached_property def has_team_members(self): - return user_api_client.get_count_of_users_with_permission( - self.id, 'manage_service' + return ( + user_api_client.get_count_of_users_with_permission( + self.id, 'manage_service' + ) + invite_api_client.get_count_of_invites_with_permission( + self.id, 'manage_service' + ) ) > 1 def cancel_invite(self, invited_user_id): diff --git a/app/notify_client/invite_api_client.py b/app/notify_client/invite_api_client.py index 5cb856713..e07291e24 100644 --- a/app/notify_client/invite_api_client.py +++ b/app/notify_client/invite_api_client.py @@ -1,5 +1,6 @@ from app.models.user import ( InvitedUser, + roles, translate_permissions_from_admin_roles_to_db, ) from app.notify_client import NotifyAdminAPIClient, _attach_current_user, cache @@ -44,6 +45,14 @@ class InviteApiClient(NotifyAdminAPIClient): '/service/{}/invite'.format(service_id) )['data'] + def get_count_of_invites_with_permission(self, service_id, permission): + if permission not in roles.keys(): + raise TypeError('{} is not a valid permission'.format(permission)) + return len([ + invited_user for invited_user in self.get_invites_for_service(service_id) + if invited_user.has_permission_for_service(service_id, permission) + ]) + def check_token(self, token): resp = self.get(url='/invite/service/{}'.format(token)) return InvitedUser(**resp['data']) diff --git a/tests/app/main/views/test_service_settings.py b/tests/app/main/views/test_service_settings.py index 78d25e59c..9f2fbdfc3 100644 --- a/tests/app/main/views/test_service_settings.py +++ b/tests/app/main/views/test_service_settings.py @@ -617,6 +617,7 @@ def test_should_check_if_estimated_volumes_provided( mock_get_service_templates, mock_get_users_by_service, mock_get_service_organisation, + mock_get_invites_for_service, volumes, consent_to_research, expected_estimated_volumes_item, @@ -649,9 +650,14 @@ def test_should_check_if_estimated_volumes_provided( ) -@pytest.mark.parametrize('count_of_users_with_manage_service, expected_user_checklist_item', [ - (1, 'Add a team member who can manage settings, team and usage Not completed'), - (2, 'Add a team member who can manage settings, team and usage Completed'), +@pytest.mark.parametrize(( + 'count_of_users_with_manage_service,' + 'count_of_invites_with_manage_service,' + 'expected_user_checklist_item' +), [ + (1, 0, 'Add a team member who can manage settings, team and usage Not completed'), + (2, 0, 'Add a team member who can manage settings, team and usage Completed'), + (1, 1, 'Add a team member who can manage settings, team and usage Completed'), ]) @pytest.mark.parametrize('count_of_templates, expected_templates_checklist_item', [ (0, 'Add templates with examples of the content you plan to send Not completed'), @@ -679,6 +685,7 @@ def test_should_check_for_sending_things_right( mock_get_service_organisation, single_sms_sender, count_of_users_with_manage_service, + count_of_invites_with_manage_service, expected_user_checklist_item, count_of_templates, expected_templates_checklist_item, @@ -694,9 +701,13 @@ def test_should_check_for_sending_things_right( }.get(template_type) mock_count_users = mocker.patch( - 'app.main.views.service_settings.user_api_client.get_count_of_users_with_permission', + 'app.models.service.user_api_client.get_count_of_users_with_permission', return_value=count_of_users_with_manage_service ) + mock_count_invites = mocker.patch( + 'app.models.service.invite_api_client.get_count_of_invites_with_permission', + return_value=count_of_invites_with_manage_service + ) mock_templates = mocker.patch( 'app.models.service.Service.all_templates', @@ -734,6 +745,7 @@ def test_should_check_for_sending_things_right( assert normalize_spaces(checklist_items[3].text) == expected_reply_to_checklist_item mock_count_users.assert_called_once_with(SERVICE_ONE_ID, 'manage_service') + mock_count_invites.assert_called_once_with(SERVICE_ONE_ID, 'manage_service') assert mock_templates.called is True if count_of_email_templates: @@ -753,6 +765,7 @@ def test_should_not_show_go_live_button_if_checklist_not_complete( mock_get_service_templates, mock_get_users_by_service, mock_get_service_organisation, + mock_get_invites_for_service, single_sms_sender, checklist_completed, agreement_signed, @@ -893,6 +906,7 @@ def test_should_check_for_sms_sender_on_go_live( service_one, mocker, mock_get_service_organisation, + mock_get_invites_for_service, organisation_type, count_of_sms_templates, sms_senders, @@ -971,6 +985,7 @@ def test_should_check_for_mou_on_request_to_go_live( service_one, mocker, agreement_signed, + mock_get_invites_for_service, expected_item, ): mocker.patch( @@ -1015,6 +1030,7 @@ def test_should_check_for_mou_on_request_to_go_live( def test_non_gov_user_is_told_they_cant_go_live( client_request, api_nongov_user_active, + mock_get_invites_for_service, mocker, mock_get_service_organisation, ): @@ -1292,6 +1308,7 @@ def test_should_redirect_after_request_to_go_live( mock_get_service_settings_page_common, mock_get_service_templates, mock_get_users_by_service, + mock_get_invites_without_manage_permission, volumes, displayed_volumes, formatted_displayed_volumes, @@ -1577,6 +1594,7 @@ def test_route_permissions( single_reply_to_email_address, single_letter_contact_block, mock_get_service_organisation, + mock_get_invites_for_service, single_sms_sender, route, mock_get_service_settings_page_common, @@ -1610,6 +1628,7 @@ def test_route_invalid_permissions( service_one, route, mock_get_service_templates, + mock_get_invites_for_service, ): validate_route_permission( mocker, @@ -1642,6 +1661,7 @@ def test_route_for_platform_admin( route, mock_get_service_settings_page_common, mock_get_service_templates, + mock_get_invites_for_service, ): validate_route_permission(mocker, app_, diff --git a/tests/conftest.py b/tests/conftest.py index 6fa21eae0..ca6f95287 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2258,6 +2258,25 @@ def mock_get_invites_for_service(mocker, service_one, sample_invite): return mocker.patch('app.invite_api_client._get_invites_for_service', side_effect=_get_invites) +@pytest.fixture(scope='function') +def mock_get_invites_without_manage_permission(mocker, service_one, sample_invite): + + def _get_invites(service_id): + return [invite_json( + id_=str(sample_uuid()), + from_user=service_one['users'][0], + email_address='invited_user@test.gov.uk', + service_id=service_one['id'], + permissions='view_activity,send_messages,manage_api_keys', + created_at=str(datetime.utcnow()), + auth_type='sms_auth', + folder_permissions=[], + status='pending', + )] + + return mocker.patch('app.invite_api_client._get_invites_for_service', side_effect=_get_invites) + + @pytest.fixture(scope='function') def mock_check_invite_token(mocker, sample_invite): def _check_token(token):