From bd8bb3c926999ad1cb722e32d5ae128a882713f9 Mon Sep 17 00:00:00 2001 From: Rebecca Law Date: Tue, 15 Dec 2015 15:35:30 +0000 Subject: [PATCH] 109898688: Implementation of text-not-received and email-not-received --- app/main/dao/users_dao.py | 14 +++ app/main/dao/verify_codes_dao.py | 4 +- app/main/forms.py | 15 +++ app/main/views/__init__.py | 2 +- app/main/views/code_not_received.py | 30 ++++- app/templates/views/email-not-received.html | 10 +- app/templates/views/text-not-received.html | 16 +-- tests/app/main/dao/test_users_dao.py | 17 +++ .../app/main/views/test_code_not_received.py | 117 +++++++++++++++--- 9 files changed, 192 insertions(+), 33 deletions(-) diff --git a/app/main/dao/users_dao.py b/app/main/dao/users_dao.py index 83521985e..326bafdc7 100644 --- a/app/main/dao/users_dao.py +++ b/app/main/dao/users_dao.py @@ -37,3 +37,17 @@ def activate_user(id): user.state = 'active' db.session.add(user) db.session.commit() + + +def update_email_address(id, email_address): + user = get_user_by_id(id) + user.email_address = email_address + db.session.add(user) + db.session.commit() + + +def update_mobile_number(id, mobile_number): + user = get_user_by_id(id) + user.mobile_number = mobile_number + db.session.add(user) + db.session.commit() diff --git a/app/main/dao/verify_codes_dao.py b/app/main/dao/verify_codes_dao.py index 049432982..9c48acaec 100644 --- a/app/main/dao/verify_codes_dao.py +++ b/app/main/dao/verify_codes_dao.py @@ -20,8 +20,8 @@ def get_code(user_id, code_type): return verify_code -def get_code_by_code(user_id, code_type): - return VerifyCodes.query.filter_by(user_id=user_id, code_type=code_type).first() +def get_code_by_code(user_id, code, code_type): + return VerifyCodes.query.filter_by(user_id=user_id, code=code, code_type=code_type).first() def use_code(id): diff --git a/app/main/forms.py b/app/main/forms.py index 300b2600f..e9433e176 100644 --- a/app/main/forms.py +++ b/app/main/forms.py @@ -84,6 +84,21 @@ def validate_code(field, code): return False +class EmailNotReceivedForm(Form): + email_address = StringField('Email address', validators=[ + Length(min=5, max=255), + DataRequired(message='Email cannot be empty'), + Email(message='Please enter a valid email address'), + Regexp(regex=gov_uk_email, message='Please enter a gov.uk email address') + ]) + + +class TextNotReceivedForm(Form): + mobile_number = StringField('Mobile phone number', + validators=[DataRequired(message='Please enter your mobile number'), + Regexp(regex=mobile_number, message='Please enter a +44 mobile number')]) + + class AddServiceForm(Form): service_name = StringField(validators=[DataRequired(message='Please enter your service name')]) diff --git a/app/main/views/__init__.py b/app/main/views/__init__.py index e7db79518..e092ba59c 100644 --- a/app/main/views/__init__.py +++ b/app/main/views/__init__.py @@ -12,7 +12,7 @@ def send_sms_code(user_id, mobile_number): sms_code = create_verify_code() try: verify_codes_dao.add_code(user_id=user_id, code=sms_code, code_type='sms') - admin_api_client.send_sms(mobile_number, message=sms_code, token=admin_api_client.auth_token) + admin_api_client.send_sms(mobile_number=mobile_number, message=sms_code, token=admin_api_client.auth_token) except: raise AdminApiClientException('Exception when sending sms.') return sms_code diff --git a/app/main/views/code_not_received.py b/app/main/views/code_not_received.py index c07544bc7..b5ce3bd16 100644 --- a/app/main/views/code_not_received.py +++ b/app/main/views/code_not_received.py @@ -1,23 +1,43 @@ -from flask import render_template +from flask import render_template, redirect, jsonify, session from app.main import main +from app.main.dao import users_dao, verify_codes_dao +from app.main.forms import EmailNotReceivedForm, TextNotReceivedForm +from app.main.views import send_sms_code, send_email_code @main.route("/email-not-received", methods=['GET']) def email_not_received(): - return render_template('views/email-not-received.html') + user = users_dao.get_user_by_id(session['user_id']) + return render_template('views/email-not-received.html', + form=EmailNotReceivedForm(email_address=user.email_address)) @main.route('/email-not-received', methods=['POST']) def check_and_resend_email_code(): - return None + form = EmailNotReceivedForm() + if form.validate_on_submit(): + user = users_dao.get_user_by_id(session['user_id']) + users_dao.update_email_address(id=user.id, email_address=form.email_address.data) + verify_codes_dao.use_code_for_user_and_type(user_id=user.id, code_type='email') + send_email_code(user_id=user.id, email=user.email_address) + return redirect('/verify') + return jsonify(form.errors), 400 @main.route("/text-not-received", methods=['GET']) def text_not_received(): - return render_template('views/text-not-received.html') + user = users_dao.get_user_by_id(session['user_id']) + return render_template('views/text-not-received.html', form=TextNotReceivedForm(mobile_number=user.mobile_number)) @main.route('/text-not-received', methods=['POST']) def check_and_resend_text_code(): - return None + form = TextNotReceivedForm() + if form.validate_on_submit(): + user = users_dao.get_user_by_id(session['user_id']) + users_dao.update_mobile_number(id=user.id, mobile_number=form.mobile_number.data) + verify_codes_dao.use_code_for_user_and_type(user_id=user.id, code_type='sms') + send_sms_code(user_id=user.id, mobile_number=user.mobile_number) + return redirect('/verify') + return jsonify(form.errors), 400 diff --git a/app/templates/views/email-not-received.html b/app/templates/views/email-not-received.html index 758589199..7383f26c3 100644 --- a/app/templates/views/email-not-received.html +++ b/app/templates/views/email-not-received.html @@ -13,9 +13,13 @@ GOV.UK Notify

Check your email address is correct and then resend the confirmation code.

- -
- Your email address must end in .gov.uk +

+ {{ form.hidden_tag() }} + + + {{ form.email_address(class="form-control-2-3", autocomplete="off") }}
+ Your email address must end in .gov.uk +

diff --git a/app/templates/views/text-not-received.html b/app/templates/views/text-not-received.html index 4b332c894..078b5ab53 100644 --- a/app/templates/views/text-not-received.html +++ b/app/templates/views/text-not-received.html @@ -12,15 +12,15 @@ GOV.UK Notify

Check your mobile phone number is correct and then resend the confirmation code.

+

- - -

- - -

- Resend confirmation code -

+ + {{ form.mobile_number(class="form-control-1-4", autocomplete="off") }}
+

+

+ +

+
diff --git a/tests/app/main/dao/test_users_dao.py b/tests/app/main/dao/test_users_dao.py index 10b01052f..f169a7fd9 100644 --- a/tests/app/main/dao/test_users_dao.py +++ b/tests/app/main/dao/test_users_dao.py @@ -144,3 +144,20 @@ def test_should_throws_error_when_id_does_not_exist(notifications_admin, notific with pytest.raises(AttributeError) as error: users_dao.activate_user(123) assert '''object has no attribute 'state''''' in str(error.value) + + +def test_should_update_email_address(notifications_admin, notifications_admin_db, notify_db_session): + user = User(name='Update Email', + password='somepassword', + email_address='test@it.gov.uk', + mobile_number='+441234123412', + created_at=datetime.now(), + role_id=1, + state='inactive') + users_dao.insert_user(user) + + saved = users_dao.get_user_by_id(user.id) + assert saved.email_address == 'test@it.gov.uk' + users_dao.update_email_address(user.id, 'new_email@testit.gov.uk') + updated = users_dao.get_user_by_id(user.id) + assert updated.email_address == 'new_email@testit.gov.uk' diff --git a/tests/app/main/views/test_code_not_received.py b/tests/app/main/views/test_code_not_received.py index bab907fdd..50d2d8806 100644 --- a/tests/app/main/views/test_code_not_received.py +++ b/tests/app/main/views/test_code_not_received.py @@ -1,18 +1,107 @@ -def test_should_render_email_code_not_received_template(notifications_admin): - response = notifications_admin.test_client().get('/email-not-received') - assert response.status_code == 200 - assert 'Check your email address is correct and then resend the confirmation code' \ - in response.get_data(as_text=True) +from app import admin_api_client +from app.main.dao import verify_codes_dao, users_dao +from tests.app.main import create_test_user -# def test_should_check_and_resend_email_code(notifications_admin, notifications_admin_db, notify_db_session): -# response = notifications_admin.test_client().post('/email-not-received', -# data={'email_adddress': 'test@user.gov.uk'}) -# assert response is None +def test_should_render_email_code_not_received_template_and_populate_email_address(notifications_admin, + notifications_admin_db, + notify_db_session): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + user = create_test_user() + session['user_id'] = user.id + response = client.get('/email-not-received') + assert response.status_code == 200 + assert 'Check your email address is correct and then resend the confirmation code' \ + in response.get_data(as_text=True) + assert 'value="test@user.gov.uk"' in response.get_data(as_text=True) -def test_should_render_text_code_not_received_template(notifications_admin): - response = notifications_admin.test_client().get('/text-not-received') - assert response.status_code == 200 - assert 'Check your mobile phone number is correct and then resend the confirmation code.' \ - in response.get_data(as_text=True) +def test_should_check_and_resend_email_code_redirect_to_verify(notifications_admin, + notifications_admin_db, + notify_db_session, + mocker): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + _set_up_mocker(mocker) + user = create_test_user() + session['user_id'] = user.id + verify_codes_dao.add_code(user.id, code='12345', code_type='email') + response = client.post('/email-not-received', + data={'email_address': 'test@user.gov.uk'}) + assert response.status_code == 302 + assert response.location == 'http://localhost/verify' + + +def test_should_render_text_code_not_received_template(notifications_admin, + notifications_admin_db, + notify_db_session, + mocker): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + _set_up_mocker(mocker) + user = create_test_user() + session['user_id'] = user.id + verify_codes_dao.add_code(user.id, code='12345', code_type='email') + response = client.get('/text-not-received') + assert response.status_code == 200 + assert 'Check your mobile phone number is correct and then resend the confirmation code.' \ + in response.get_data(as_text=True) + assert 'value="+441234123412"' + + +def test_should_check_and_redirect_to_verify(notifications_admin, + notifications_admin_db, + notify_db_session, + mocker): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + _set_up_mocker(mocker) + user = create_test_user() + session['user_id'] = user.id + verify_codes_dao.add_code(user.id, code='12345', code_type='sms') + response = client.post('/text-not-received', + data={'mobile_number': '+441234123412'}) + assert response.status_code == 302 + assert response.location == 'http://localhost/verify' + + +def test_should_update_email_address_resend_code(notifications_admin, + notifications_admin_db, + notify_db_session, + mocker): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + _set_up_mocker(mocker) + user = create_test_user() + session['user_id'] = user.id + verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='email') + response = client.post('/email-not-received', + data={'email_address': 'new@address.gov.uk'}) + assert response.status_code == 302 + assert response.location == 'http://localhost/verify' + updated_user = users_dao.get_user_by_id(user.id) + assert updated_user.email_address == 'new@address.gov.uk' + + +def test_should_update_mobile_number_resend_code(notifications_admin, + notifications_admin_db, + notify_db_session, + mocker): + with notifications_admin.test_client() as client: + with client.session_transaction() as session: + _set_up_mocker(mocker) + user = create_test_user() + session['user_id'] = user.id + verify_codes_dao.add_code(user_id=user.id, code='12345', code_type='sms') + response = client.post('/text-not-received', + data={'mobile_number': '+443456789012'}) + assert response.status_code == 302 + assert response.location == 'http://localhost/verify' + updated_user = users_dao.get_user_by_id(user.id) + assert updated_user.mobile_number == '+443456789012' + + +def _set_up_mocker(mocker): + mocker.patch("app.admin_api_client.send_sms") + mocker.patch("app.admin_api_client.send_email")