diff --git a/app/main/forms.py b/app/main/forms.py index ad9036e1c..3cbfb7390 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -104,7 +104,7 @@ class RegisterUserFromInviteForm(Form): mobile_number = mobile_number() password = password() service = HiddenField('service') - email_address = HiddenField('email_address') + email_address = email_address() class InviteUserForm(Form): diff --git a/app/main/views/manage_users.py b/app/main/views/manage_users.py index b8dbfc4c2..a1f44ad71 100644 --- a/app/main/views/manage_users.py +++ b/app/main/views/manage_users.py @@ -28,11 +28,15 @@ from app.utils import user_has_permissions def manage_users(service_id): users = user_api_client.get_users_for_service(service_id=service_id) invited_users = invite_api_client.get_invites_for_service(service_id=service_id) + filtered_invites = [] + for invite in invited_users: + if invite.status != 'accepted': + filtered_invites.append(invite) return render_template('views/manage-users.html', service_id=service_id, users=users, current_user=current_user, - invited_users=invited_users) + invited_users=filtered_invites) @main.route("/services//users/invite", methods=['GET', 'POST']) diff --git a/app/templates/components/textbox.html b/app/templates/components/textbox.html index b50fb9ee4..78241a630 100644 --- a/app/templates/components/textbox.html +++ b/app/templates/components/textbox.html @@ -6,7 +6,8 @@ help_link=None, help_link_text=None, width='2-3', - suffix=None + suffix=None, + disabled=False ) %}
- {{ field(**{ - 'class': 'form-control form-control-{} textbox-highlight-textbox'.format(width) if highlight_tags else 'form-control form-control-{} {}'.format(width, 'textbox-right-aligned' if suffix else ''), - 'data-module': 'highlight-tags' if highlight_tags else '' - }) }} + {% if disabled %} +

{{ field(**{ + 'class': 'form-control form-control-{} textbox-highlight-textbox'.format(width) if highlight_tags else 'form-control form-control-{} {}'.format(width, 'textbox-right-aligned' if suffix else ''), + 'data-module': 'highlight-tags' if highlight_tags else '', + 'disabled': 'disabled' + }) }} +

+ {% else %} + {{ field(**{ + 'class': 'form-control form-control-{} textbox-highlight-textbox'.format(width) if highlight_tags else 'form-control form-control-{} {}'.format(width, 'textbox-right-aligned' if suffix else ''), + 'data-module': 'highlight-tags' if highlight_tags else '' + }) }} + {% endif %} + + {% if suffix %} {{ suffix }} {% endif %} diff --git a/app/templates/views/register-from-invite.html b/app/templates/views/register-from-invite.html index 7e7e81aaa..b08e8d24f 100644 --- a/app/templates/views/register-from-invite.html +++ b/app/templates/views/register-from-invite.html @@ -12,12 +12,12 @@ Create an account – GOV.UK Notify

Create an account

+ {{ textbox(form.email_address, width='3-4', disabled=True ) }} {{ textbox(form.name, width='3-4') }} {{ textbox(form.mobile_number, width='3-4') }} {{ textbox(form.password, hint="Your password must have at least 10 characters", width='3-4') }} {{ page_footer("Continue") }} {{form.service}} - {{form.email_address}}
diff --git a/tests/app/main/notify_client/test_invite_client.py b/tests/app/main/notify_client/test_invite_client.py new file mode 100644 index 000000000..94e80863d --- /dev/null +++ b/tests/app/main/notify_client/test_invite_client.py @@ -0,0 +1,20 @@ +from app.notify_client.invite_api_client import InviteApiClient + + +def test_client_returns_invite(mocker, sample_invite): + + sample_invite['status'] = 'pending' + service_id = sample_invite['service'] + + expected_data = {'data': [sample_invite]} + + expected_url = '/service/{}/invite'.format(service_id) + + client = InviteApiClient() + mock_get = mocker.patch('app.notify_client.invite_api_client.InviteApiClient.get', return_value=expected_data) + + invites = client.get_invites_for_service(service_id) + + mock_get.assert_called_once_with(expected_url) + assert len(invites) == 1 + assert invites[0].status == 'pending' diff --git a/tests/app/main/views/test_accept_invite.py b/tests/app/main/views/test_accept_invite.py index 4144d4d41..cfd1abb18 100644 --- a/tests/app/main/views/test_accept_invite.py +++ b/tests/app/main/views/test_accept_invite.py @@ -81,6 +81,39 @@ def test_new_user_accept_invite_calls_api_and_redirects_to_registration(app_, assert response.location == expected_redirect_location +def test_new_user_accept_invite_calls_api_and_views_registration_page(app_, + service_one, + mock_check_invite_token, + mock_dont_get_user_by_email, + mock_add_user_to_service, + mock_accept_invite): + + with app_.test_request_context(): + with app_.test_client() as client: + + response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True) + + mock_check_invite_token.assert_called_with('thisisnotarealtoken') + mock_dont_get_user_by_email.assert_called_with('invited_user@test.gov.uk') + + assert response.status_code == 200 + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + assert page.h1.string.strip() == 'Create an account' + + form = page.find('form') + email = form.find('input', id='email_address') + name = form.find('input', id='name') + password = form.find('input', id='password') + service = form.find('input', type='hidden', id='service') + + assert email + assert email.attrs['disabled'] + assert name + assert password + assert service + assert service.attrs['value'] == service_one['id'] + + def test_cancelled_invited_user_accepts_invited_redirect_to_cancelled_invitation(app_, service_one, mocker, diff --git a/tests/app/main/views/test_manage_users.py b/tests/app/main/views/test_manage_users.py index 123a225e3..e45392a06 100644 --- a/tests/app/main/views/test_manage_users.py +++ b/tests/app/main/views/test_manage_users.py @@ -2,6 +2,8 @@ from flask import url_for from bs4 import BeautifulSoup +from app.notify_client.models import InvitedUser + def test_should_show_overview_page( app_, @@ -180,3 +182,65 @@ def test_cancel_invited_user_cancels_user_invitations(app_, assert response.status_code == 302 assert response.location == url_for('main.manage_users', service_id=service_id, _external=True) + + +def test_manage_users_shows_invited_user(app_, + mocker, + api_user_active, + mock_get_service, + mock_login, + mock_has_permissions, + mock_get_users_by_service, + sample_invite): + + import uuid + invited_user_id = uuid.uuid4() + sample_invite['id'] = invited_user_id + data = [InvitedUser(**sample_invite)] + + with app_.test_request_context(): + with app_.test_client() as client: + client.login(api_user_active) + + mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) + + response = client.get(url_for('main.manage_users', service_id=55555)) + + assert response.status_code == 200 + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + assert page.h1.string.strip() == 'Manage team' + invites_table = page.find_all('table')[1] + cols = invites_table.find_all('td') + assert cols[0].text.strip() == 'invited_user@test.gov.uk' + assert cols[4].text.strip() == 'Cancel invitation' + + +def test_manage_users_does_not_show_accepted_invite(app_, + mocker, + api_user_active, + mock_get_service, + mock_login, + mock_has_permissions, + mock_get_users_by_service, + sample_invite): + + import uuid + invited_user_id = uuid.uuid4() + sample_invite['id'] = invited_user_id + sample_invite['status'] = 'accepted' + data = [InvitedUser(**sample_invite)] + + with app_.test_request_context(): + with app_.test_client() as client: + client.login(api_user_active) + + mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data) + + response = client.get(url_for('main.manage_users', service_id=55555)) + + assert response.status_code == 200 + page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser') + assert page.h1.string.strip() == 'Manage team' + tables = page.find_all('table') + assert len(tables) == 1 + assert not page.find(text='invited_user@test.gov.uk')