Merge pull request #2553 from alphagov/better-live-search-team

Scope live search on team page to name and email
This commit is contained in:
Chris Hill-Scott
2018-12-05 16:46:15 +00:00
committed by GitHub
6 changed files with 34 additions and 37 deletions

View File

@@ -18,19 +18,11 @@ from app.utils import user_has_permissions
@login_required @login_required
@user_has_permissions() @user_has_permissions()
def manage_users(service_id): def manage_users(service_id):
users = sorted(
user_api_client.get_users_for_service(service_id=service_id) + [
invite for invite in invite_api_client.get_invites_for_service(service_id=service_id)
if invite.status != 'accepted'
],
key=lambda user: user.email_address,
)
return render_template( return render_template(
'views/manage-users.html', 'views/manage-users.html',
users=users, users=current_service.team_members,
current_user=current_user, current_user=current_user,
show_search_box=(len(users) > 7), show_search_box=(len(current_service.team_members) > 7),
form=SearchUsersForm(), form=SearchUsersForm(),
permissions=permissions, permissions=permissions,
) )

View File

@@ -6,6 +6,7 @@ from app.notify_client.api_key_api_client import api_key_api_client
from app.notify_client.billing_api_client import billing_api_client from app.notify_client.billing_api_client import billing_api_client
from app.notify_client.email_branding_client import email_branding_client from app.notify_client.email_branding_client import email_branding_client
from app.notify_client.inbound_number_client import inbound_number_client from app.notify_client.inbound_number_client import inbound_number_client
from app.notify_client.invite_api_client import invite_api_client
from app.notify_client.job_api_client import job_api_client from app.notify_client.job_api_client import job_api_client
from app.notify_client.organisations_api_client import organisations_client from app.notify_client.organisations_api_client import organisations_client
from app.notify_client.service_api_client import service_api_client from app.notify_client.service_api_client import service_api_client
@@ -98,6 +99,16 @@ class Service():
def has_jobs(self): def has_jobs(self):
return job_api_client.has_jobs(self.id) return job_api_client.has_jobs(self.id)
@cached_property
def team_members(self):
return sorted(
(
invite_api_client.get_invites_for_service(service_id=self.id) +
user_api_client.get_users_for_service(service_id=self.id)
),
key=lambda user: user.email_address,
)
@cached_property @cached_property
def has_team_members(self): def has_team_members(self):
return user_api_client.get_count_of_users_with_permission( return user_api_client.get_count_of_users_with_permission(

View File

@@ -28,11 +28,16 @@ class InviteApiClient(NotifyAdminAPIClient):
return InvitedUser(**resp['data']) return InvitedUser(**resp['data'])
def get_invites_for_service(self, service_id): def get_invites_for_service(self, service_id):
endpoint = '/service/{}/invite'.format(service_id) return [
resp = self.get(endpoint) InvitedUser(**invite)
invites = resp['data'] for invite in self._get_invites_for_service(service_id)
invited_users = self._get_invited_users(invites) if invite['status'] != 'accepted'
return invited_users ]
def _get_invites_for_service(self, service_id):
return self.get(
'/service/{}/invite'.format(service_id)
)['data']
def check_token(self, token): def check_token(self, token):
resp = self.get(url='/invite/service/{}'.format(token)) resp = self.get(url='/invite/service/{}'.format(token))
@@ -51,12 +56,5 @@ class InviteApiClient(NotifyAdminAPIClient):
self.post(url='/service/{0}/invite/{1}'.format(service_id, invited_user_id), self.post(url='/service/{0}/invite/{1}'.format(service_id, invited_user_id),
data=data) data=data)
def _get_invited_users(self, invites):
invited_users = []
for invite in invites:
invited_user = InvitedUser(**invite)
invited_users.append(invited_user)
return invited_users
invite_api_client = InviteApiClient() invite_api_client = InviteApiClient()

View File

@@ -35,17 +35,17 @@
<div class="user-list-item"> <div class="user-list-item">
<h3 title="{{ user.email_address }}"> <h3 title="{{ user.email_address }}">
{%- if user.name -%} {%- if user.name -%}
<span class="heading-small">{{ user.name }}</span>&ensp; <span class="heading-small live-search-relevant">{{ user.name }}</span>&ensp;
{%- endif -%} {%- endif -%}
<span class="hint"> <span class="hint">
{%- if user.status == 'pending' -%} {%- if user.status == 'pending' -%}
{{ user.email_address }} (invited) <span class="live-search-relevant">{{ user.email_address }}</span> (invited)
{%- elif user.status == 'cancelled' -%} {%- elif user.status == 'cancelled' -%}
{{ user.email_address }} (cancelled invite) <span class="live-search-relevant">{{ user.email_address }}</span> (cancelled invite)
{%- elif user.id == current_user.id -%} {%- elif user.id == current_user.id -%}
(you) <span class="live-search-relevant">(you)</span>
{% else %} {% else %}
{{ user.email_address }} <span class="live-search-relevant">{{ user.email_address }}</span>
{% endif %} {% endif %}
</span> </span>
</h3> </h3>

View File

@@ -1,4 +1,5 @@
import copy import copy
import uuid
import pytest import pytest
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
@@ -641,24 +642,19 @@ def test_manage_users_shows_invited_user(
def test_manage_users_does_not_show_accepted_invite( def test_manage_users_does_not_show_accepted_invite(
logged_in_client, client_request,
mocker, mocker,
active_user_with_permissions, active_user_with_permissions,
sample_invite, sample_invite,
): ):
import uuid
invited_user_id = uuid.uuid4() invited_user_id = uuid.uuid4()
sample_invite['id'] = invited_user_id sample_invite['id'] = invited_user_id
sample_invite['status'] = 'accepted' sample_invite['status'] = 'accepted'
data = [InvitedUser(**sample_invite)]
service = create_sample_service(active_user_with_permissions)
mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions]) mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions])
mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) mocker.patch('app.invite_api_client._get_invites_for_service', return_value=[sample_invite])
response = logged_in_client.get(url_for('main.manage_users', service_id=service['id'])) page = client_request.get('main.manage_users', service_id=SERVICE_ONE_ID)
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.h1.string.strip() == 'Team members' assert page.h1.string.strip() == 'Team members'
user_lists = page.find_all('div', {'class': 'user-list'}) user_lists = page.find_all('div', {'class': 'user-list'})
assert len(user_lists) == 1 assert len(user_lists) == 1

View File

@@ -2170,10 +2170,10 @@ def mock_get_invites_for_service(mocker, service_one, sample_invite):
for i in range(0, 5): for i in range(0, 5):
invite = copy.copy(sample_invite) invite = copy.copy(sample_invite)
invite['email_address'] = 'user_{}@testnotify.gov.uk'.format(i) invite['email_address'] = 'user_{}@testnotify.gov.uk'.format(i)
data.append(InvitedUser(**invite)) data.append(invite)
return data return data
return mocker.patch('app.invite_api_client.get_invites_for_service', side_effect=_get_invites) return mocker.patch('app.invite_api_client._get_invites_for_service', side_effect=_get_invites)
@pytest.fixture(scope='function') @pytest.fixture(scope='function')