From 3683f99c3bef135a0f50ca0d12e7b176de08295e Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Mon, 2 Jul 2018 09:08:21 +0100 Subject: [PATCH] =?UTF-8?q?Guess=20people=E2=80=99s=20names=20when=20they?= =?UTF-8?q?=E2=80=99re=20invited?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Most people’s names, especially in government are in the format firstname.lastname@department.gov.uk. This means that you can pretty reliably guess that their name is ‘Firstname Lastname’. When users are invited to Notify we know their email address already. So this commit pre-populates the registration form based on this guess. This is a nice little detail, but it should also stop the browser pre-filling the name field with someone’s email address (which I think happens because the browser assumes a registration form will have an email field). --- app/main/forms.py | 11 ++++----- app/utils.py | 11 +++++++++ tests/app/main/views/test_register.py | 35 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/app/main/forms.py b/app/main/forms.py index 55faafbcc..826080376 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -41,6 +41,7 @@ from app.main.validators import ( ValidGovEmail, ) from app.notify_client.models import roles +from app.utils import guess_name_from_email_address def get_time_value_and_label(future_time): @@ -215,20 +216,18 @@ class RegisterUserForm(StripWhitespaceForm): auth_type = HiddenField('auth_type', default='sms_auth') -class RegisterUserFromInviteForm(StripWhitespaceForm): +class RegisterUserFromInviteForm(RegisterUserForm): def __init__(self, invited_user): super().__init__( service=invited_user['service'], email_address=invited_user['email_address'], auth_type=invited_user['auth_type'], + name=guess_name_from_email_address( + invited_user['email_address'] + ), ) - name = StringField( - 'Full name', - validators=[DataRequired(message='Can’t be empty')] - ) mobile_number = InternationalPhoneNumber('Mobile number', validators=[]) - password = password() service = HiddenField('service') email_address = HiddenField('email_address') auth_type = HiddenField('auth_type', validators=[DataRequired()]) diff --git a/app/utils.py b/app/utils.py index 4cb3a1d2a..b57732bd4 100644 --- a/app/utils.py +++ b/app/utils.py @@ -25,6 +25,7 @@ from flask import ( url_for, ) from flask_login import current_user +from notifications_utils.formatters import make_quotes_smart from notifications_utils.recipients import RecipientCSV from notifications_utils.template import ( EmailPreviewTemplate, @@ -613,3 +614,13 @@ class GovernmentEmailDomain(AgreementInfo): def unicode_truncate(s, length): encoded = s.encode('utf-8')[:length] return encoded.decode('utf-8', 'ignore') + + +def guess_name_from_email_address(email_address): + + possible_name = re.split(r'[\@\+]', email_address)[0] + + if '.' not in possible_name: + return '' + + return make_quotes_smart(possible_name.replace('.', ' ').title()) diff --git a/tests/app/main/views/test_register.py b/tests/app/main/views/test_register.py index 8341f23f9..45c4aa714 100644 --- a/tests/app/main/views/test_register.py +++ b/tests/app/main/views/test_register.py @@ -170,6 +170,34 @@ def test_register_with_existing_email_sends_emails( assert response.location == url_for('main.registration_continue', _external=True) +@pytest.mark.parametrize('email_address, expected_value', [ + ("example123@example.com", ""), + ("first.last@example.com", "First Last"), + ("first.middle.last@example.com", "First Middle Last"), + ("first.last-last@example.com", "First Last-Last"), + ("first.o'last@example.com", "First O’Last"), + ("first.last+testing@example.com", "First Last"), + ("first.last+testing+testing@example.com", "First Last"), +]) +def test_shows_registration_page_from_invite( + client_request, + fake_uuid, + email_address, + expected_value, +): + with client_request.session_transaction() as session: + session['invited_user'] = InvitedUser( + fake_uuid, fake_uuid, "", + email_address, + ["manage_users"], + "pending", + datetime.utcnow(), + 'sms_auth', + ).serialize() + page = client_request.get('main.register_from_invite') + assert page.select_one('input[name=name]')['value'] == expected_value + + def test_register_from_invite( client, fake_uuid, @@ -199,6 +227,13 @@ def test_register_from_invite( ) assert response.status_code == 302 assert response.location == url_for('main.verify', _external=True) + mock_register_user.assert_called_once_with( + 'Registered in another Browser', + invited_user.email_address, + '+4407700900460', + 'somreallyhardthingtoguess', + 'sms_auth', + ) def test_register_from_invite_when_user_registers_in_another_browser(