Guess people’s names when they’re invited

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).
This commit is contained in:
Chris Hill-Scott
2018-07-02 09:08:21 +01:00
parent d08e2b7ee3
commit 3683f99c3b
3 changed files with 51 additions and 6 deletions

View File

@@ -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='Cant 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()])

View File

@@ -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())

View File

@@ -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 OLast"),
("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(