Merge pull request #2136 from alphagov/guess-name

Guess people’s names when they’re invited
This commit is contained in:
Chris Hill-Scott
2018-07-11 16:11:58 +01:00
committed by GitHub
6 changed files with 104 additions and 9 deletions

View File

@@ -257,3 +257,7 @@ details .arrow {
outline: 2px solid $black;
max-width: 100%;
}
.nowrap {
white-space: nowrap;
}

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

@@ -11,7 +11,10 @@ Create an account
<div class="grid-row">
<div class="column-two-thirds">
<h1 class="heading-large">Create an account</h1>
<p>Your account will be created with this email: {{invited_user.email_address}}</p>
<p>
Your account will be created with this email address:
<span class="nowrap">{{invited_user.email_address}}</span>
</p>
<form method="post" autocomplete="off">
{{ textbox(form.name, width='3-4') }}
{% if invited_user.auth_type == 'sms_auth' %}

View File

@@ -25,7 +25,9 @@ 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.take import Take
from notifications_utils.template import (
EmailPreviewTemplate,
LetterImageTemplate,
@@ -613,3 +615,43 @@ class GovernmentEmailDomain(AgreementInfo):
def unicode_truncate(s, length):
encoded = s.encode('utf-8')[:length]
return encoded.decode('utf-8', 'ignore')
def starts_with_initial(name):
return bool(re.match(r'^.\.', name))
def remove_middle_initial(name):
return re.sub(r'\s+.\s+', ' ', name)
def remove_digits(name):
return ''.join(c for c in name if not c.isdigit())
def normalize_spaces(name):
return ' '.join(name.split())
def guess_name_from_email_address(email_address):
possible_name = re.split(r'[\@\+]', email_address)[0]
if '.' not in possible_name or starts_with_initial(possible_name):
return ''
return Take(
possible_name
).then(
str.replace, '.', ' '
).then(
remove_digits
).then(
remove_middle_initial
).then(
str.title
).then(
make_quotes_smart
).then(
normalize_spaces
)

View File

@@ -264,8 +264,10 @@ def test_new_user_accept_invite_calls_api_and_views_registration_page(
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.h1.string.strip() == 'Create an account'
email_in_page = page.find('main').find('p')
assert email_in_page.text.strip() == 'Your account will be created with this email: invited_user@test.gov.uk' # noqa
assert normalize_spaces(page.select_one('main p').text) == (
'Your account will be created with this email address: '
'invited_user@test.gov.uk'
)
form = page.find('form')
name = form.find('input', id='name')

View File

@@ -170,6 +170,44 @@ 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', [
("first.last@example.com", "First Last"),
("first.middle.last@example.com", "First Middle Last"),
("first.m.last@example.com", "First 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"),
("first.last6@example.com", "First Last"),
("first.last.212@example.com", "First Last"),
("first.2.last@example.com", "First Last"),
("first.2b.last@example.com", "First Last"),
("first.1.2.3.last@example.com", "First Last"),
("first.last.1.2.3@example.com", "First Last"),
# Instances where we cant make a good-enough guess:
("example123@example.com", ""),
("f.last@example.com", ""),
("f.m.last@example.com", ""),
])
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 +237,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(