diff --git a/.travis.yml b/.travis.yml index 681c35b5c..8d2a4b2c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,16 @@ sudo: false language: python -cache: pip +cache: + pip: true + directories: + - ~/.pip-accel python: - '3.4' addons: postgresql: '9.3' install: -- pip install -r requirements_for_test.txt +- pip install pip-accel +- pip-accel install -r requirements_for_test.txt before_script: - psql -c 'create database test_notification_api;' -U postgres script: diff --git a/app/celery/provider_tasks.py b/app/celery/provider_tasks.py index 8e6e4cb85..6e8654c5b 100644 --- a/app/celery/provider_tasks.py +++ b/app/celery/provider_tasks.py @@ -20,9 +20,8 @@ from notifications_utils.recipients import ( ) from app.dao.templates_dao import dao_get_template_by_id -from notifications_utils.template import ( - Template -) +from notifications_utils.template import Template +from notifications_utils.renderers import HTMLEmail, PlainTextEmail, SMSMessage from app.models import SMS_TYPE, EMAIL_TYPE, KEY_TYPE_TEST @@ -62,7 +61,7 @@ def send_sms_to_provider(self, service_id, notification_id): template = Template( template_model.__dict__, values={} if not notification.personalisation else notification.personalisation, - prefix=service.name + renderer=SMSMessage(prefix=service.name) ) try: if service.research_mode or notification.key_type == KEY_TYPE_TEST: @@ -129,9 +128,18 @@ def send_email_to_provider(self, service_id, notification_id): notification = get_notification_by_id(notification_id) if notification.status == 'created': try: - template = Template( - dao_get_template_by_id(notification.template_id, notification.template_version).__dict__, - values=notification.personalisation + template_dict = dao_get_template_by_id(notification.template_id, notification.template_version).__dict__ + + html_email = Template( + template_dict, + values=notification.personalisation, + renderer=HTMLEmail() + ) + + plain_text_email = Template( + template_dict, + values=notification.personalisation, + renderer=PlainTextEmail() ) if service.research_mode or notification.key_type == KEY_TYPE_TEST: @@ -145,9 +153,9 @@ def send_email_to_provider(self, service_id, notification_id): reference = provider.send_email( from_address, notification.to, - template.replaced_subject, - body=template.replaced_govuk_escaped, - html_body=template.as_HTML_email, + plain_text_email.replaced_subject, + body=plain_text_email.replaced, + html_body=html_email.replaced, reply_to_address=service.reply_to_email_address, ) diff --git a/app/notifications/rest.py b/app/notifications/rest.py index 5e549eb57..6ee2dab89 100644 --- a/app/notifications/rest.py +++ b/app/notifications/rest.py @@ -9,6 +9,7 @@ from flask import ( ) from notifications_utils.recipients import allowed_to_send_to, first_column_heading from notifications_utils.template import Template +from notifications_utils.renderers import PassThrough from app.clients.email.aws_ses import get_aws_responses from app import api_user, encryption, create_uuid, DATETIME_FORMAT, DATE_FORMAT, statsd_client from app.models import KEY_TYPE_TEAM @@ -240,7 +241,11 @@ def send_notification(notification_type): if errors: raise InvalidRequest(errors, status_code=400) - template_object = Template(template.__dict__, notification.get('personalisation', {})) + template_object = Template( + template.__dict__, + notification.get('personalisation', {}), + renderer=PassThrough() + ) if template_object.missing_data: message = 'Missing personalisation: {}'.format(", ".join(template_object.missing_data)) errors = {'template': [message]} diff --git a/app/schemas.py b/app/schemas.py index eacf41333..b4ac775d9 100644 --- a/app/schemas.py +++ b/app/schemas.py @@ -24,6 +24,8 @@ from notifications_utils.recipients import ( validate_and_format_phone_number ) +from notifications_utils.renderers import PassThrough + from app import ma from app import models from app.dao.permissions_dao import permission_dao @@ -272,7 +274,11 @@ class NotificationStatusSchema(BaseSchema): @post_dump def handle_template_merge(self, in_data): from notifications_utils.template import Template - template = Template(in_data['template'], in_data['personalisation']) + template = Template( + in_data['template'], + in_data['personalisation'], + renderer=PassThrough() + ) in_data['body'] = template.replaced if in_data['template']['template_type'] == 'email': in_data['subject'] = template.replaced_subject diff --git a/requirements.txt b/requirements.txt index 13d504b91..015df2abb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,4 +23,4 @@ statsd==3.2.1 git+https://github.com/alphagov/notifications-python-client.git@1.0.0#egg=notifications-python-client==1.0.0 -git+https://github.com/alphagov/notifications-utils.git@6.3.2#egg=notifications-utils==6.3.2 +git+https://github.com/alphagov/notifications-utils.git@8.2.0#egg=notifications-utils==8.2.0 diff --git a/tests/app/celery/test_provider_tasks.py b/tests/app/celery/test_provider_tasks.py index 1651000aa..2bf0a1902 100644 --- a/tests/app/celery/test_provider_tasks.py +++ b/tests/app/celery/test_provider_tasks.py @@ -80,10 +80,11 @@ def test_should_return_highest_priority_active_provider(notify_db, notify_db_ses def test_should_send_personalised_template_to_correct_sms_provider_and_persist( - notify_db, - notify_db_session, - sample_template_with_placeholders, - mocker): + notify_db, + notify_db_session, + sample_template_with_placeholders, + mocker +): db_notification = sample_notification(notify_db, notify_db_session, template=sample_template_with_placeholders, to_field="+447234123123", personalisation={"name": "Jo"}, status='created') @@ -101,7 +102,7 @@ def test_should_send_personalised_template_to_correct_sms_provider_and_persist( mmg_client.send_sms.assert_called_once_with( to=format_phone_number(validate_phone_number("+447234123123")), - content="Sample service: Hello Jo", + content="Sample service: Hello Jo\nYour thing is due soon", reference=str(db_notification.id), sender=None ) @@ -110,7 +111,49 @@ def test_should_send_personalised_template_to_correct_sms_provider_and_persist( assert notification.status == 'sending' assert notification.sent_at <= datetime.utcnow() assert notification.sent_by == 'mmg' - assert notification.content_char_count == 24 + assert notification.content_char_count == len("Sample service: Hello Jo\nYour thing is due soon") + assert notification.personalisation == {"name": "Jo"} + + +def test_should_send_personalised_template_to_correct_email_provider_and_persist( + notify_db, + notify_db_session, + sample_email_template_with_placeholders, + mocker +): + db_notification = sample_notification( + notify_db=notify_db, notify_db_session=notify_db_session, + template=sample_email_template_with_placeholders, + to_field="jo.smith@example.com", + personalisation={'name': 'Jo'} + ) + + mocker.patch('app.aws_ses_client.send_email', return_value='reference') + mocker.patch('app.aws_ses_client.get_name', return_value="ses") + mocker.patch('app.statsd_client.incr') + mocker.patch('app.statsd_client.timing_with_dates') + mocker.patch('app.statsd_client.timing') + + send_email_to_provider( + db_notification.service_id, + db_notification.id + ) + + app.aws_ses_client.send_email.assert_called_once_with( + '"Sample service" ', + 'jo.smith@example.com', + 'Jo', + body='Hello Jo\nThis is an email from GOV.\u200bUK', + html_body=ANY, + reply_to_address=None + ) + assert '