2016-02-16 17:17:02 +00:00
|
|
|
|
import uuid
|
2016-07-06 14:31:52 +01:00
|
|
|
|
from datetime import datetime
|
2017-03-30 10:38:41 +01:00
|
|
|
|
from unittest.mock import Mock
|
2017-01-17 16:51:27 +00:00
|
|
|
|
|
|
|
|
|
|
import pytest
|
2017-03-15 15:26:58 +00:00
|
|
|
|
from flask import current_app
|
2016-06-20 13:33:53 +01:00
|
|
|
|
from freezegun import freeze_time
|
|
|
|
|
|
from sqlalchemy.exc import SQLAlchemyError
|
2017-03-24 15:25:02 +00:00
|
|
|
|
from notifications_utils.template import SMSMessageTemplate, WithSubjectTemplate, LetterDVLATemplate
|
2017-01-17 16:51:27 +00:00
|
|
|
|
from celery.exceptions import Retry
|
|
|
|
|
|
|
2016-08-05 10:44:43 +01:00
|
|
|
|
from app import (encryption, DATETIME_FORMAT)
|
2016-06-07 12:53:31 +01:00
|
|
|
|
from app.celery import provider_tasks
|
2016-06-20 13:33:53 +01:00
|
|
|
|
from app.celery import tasks
|
2017-04-05 11:57:56 +01:00
|
|
|
|
from app.celery.tasks import s3, build_dvla_file, create_dvla_file_contents
|
2016-03-09 17:46:01 +00:00
|
|
|
|
from app.celery.tasks import (
|
|
|
|
|
|
process_job,
|
2017-01-17 16:51:27 +00:00
|
|
|
|
process_row,
|
|
|
|
|
|
send_sms,
|
|
|
|
|
|
send_email,
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
persist_letter,
|
2017-01-17 16:51:27 +00:00
|
|
|
|
get_template_class
|
2016-03-09 17:46:01 +00:00
|
|
|
|
)
|
2016-09-28 13:53:05 +01:00
|
|
|
|
from app.dao import jobs_dao, services_dao
|
2017-04-05 11:57:56 +01:00
|
|
|
|
from app.models import (
|
|
|
|
|
|
Notification,
|
|
|
|
|
|
KEY_TYPE_TEAM,
|
|
|
|
|
|
KEY_TYPE_TEST,
|
|
|
|
|
|
KEY_TYPE_NORMAL,
|
|
|
|
|
|
SMS_TYPE,
|
|
|
|
|
|
EMAIL_TYPE,
|
|
|
|
|
|
LETTER_TYPE,
|
|
|
|
|
|
Job)
|
2017-01-17 16:51:27 +00:00
|
|
|
|
|
2016-02-24 17:12:30 +00:00
|
|
|
|
from tests.app import load_example_csv
|
2016-03-03 12:05:18 +00:00
|
|
|
|
from tests.app.conftest import (
|
|
|
|
|
|
sample_service,
|
2016-03-09 11:28:52 +00:00
|
|
|
|
sample_template,
|
|
|
|
|
|
sample_job,
|
2016-03-09 13:57:53 +00:00
|
|
|
|
sample_email_template,
|
|
|
|
|
|
sample_notification
|
2016-03-03 12:05:18 +00:00
|
|
|
|
)
|
2017-03-15 15:26:58 +00:00
|
|
|
|
from tests.app.db import create_user, create_notification, create_job
|
2016-02-24 17:12:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-18 11:47:01 +00:00
|
|
|
|
class AnyStringWith(str):
|
|
|
|
|
|
def __eq__(self, other):
|
|
|
|
|
|
return self in other
|
|
|
|
|
|
|
2016-05-10 09:04:22 +01:00
|
|
|
|
|
2016-04-06 14:31:33 +01:00
|
|
|
|
mmg_error = {'Error': '40', 'Description': 'error'}
|
|
|
|
|
|
|
2016-03-10 15:40:41 +00:00
|
|
|
|
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
def _notification_json(template, to, personalisation=None, job_id=None, row_number=0):
|
|
|
|
|
|
return {
|
2016-06-20 16:23:56 +01:00
|
|
|
|
"template": str(template.id),
|
|
|
|
|
|
"template_version": template.version,
|
|
|
|
|
|
"to": to,
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
"notification_type": template.template_type,
|
|
|
|
|
|
"personalisation": personalisation or {},
|
|
|
|
|
|
"job": job_id and str(job_id),
|
|
|
|
|
|
"row_number": row_number
|
2016-06-20 16:23:56 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-08-05 10:44:43 +01:00
|
|
|
|
def test_should_have_decorated_tasks_functions():
|
|
|
|
|
|
assert process_job.__wrapped__.__name__ == 'process_job'
|
|
|
|
|
|
assert send_sms.__wrapped__.__name__ == 'send_sms'
|
|
|
|
|
|
assert send_email.__wrapped__.__name__ == 'send_email'
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-01-17 12:00:34 +00:00
|
|
|
|
@pytest.fixture
|
|
|
|
|
|
def email_job_with_placeholders(notify_db, notify_db_session, sample_email_template_with_placeholders):
|
|
|
|
|
|
return sample_job(notify_db, notify_db_session, template=sample_email_template_with_placeholders)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# -------------- process_job tests -------------- #
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-02-25 11:23:04 +00:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2016-09-07 15:35:12 +01:00
|
|
|
|
def test_should_process_sms_job(sample_job, mocker):
|
2016-02-24 17:12:30 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('sms'))
|
|
|
|
|
|
mocker.patch('app.celery.tasks.send_sms.apply_async')
|
|
|
|
|
|
mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-02-24 17:12:30 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-02-24 17:12:30 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(sample_job.id)
|
2016-04-07 13:44:04 +01:00
|
|
|
|
s3.get_job_from_s3.assert_called_once_with(
|
|
|
|
|
|
str(sample_job.service.id),
|
|
|
|
|
|
str(sample_job.id)
|
|
|
|
|
|
)
|
2016-03-09 07:27:26 +00:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['to'] == '+441234123123'
|
2016-05-13 16:25:05 +01:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['template'] == str(sample_job.template.id)
|
|
|
|
|
|
assert encryption.encrypt.call_args[0][0]['template_version'] == sample_job.template.version
|
2016-11-30 17:22:03 +00:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['personalisation'] == {'phonenumber': '+441234123123'}
|
2016-05-19 10:46:03 +01:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['row_number'] == 0
|
2016-02-24 17:12:30 +00:00
|
|
|
|
tasks.send_sms.apply_async.assert_called_once_with(
|
|
|
|
|
|
(str(sample_job.service_id),
|
|
|
|
|
|
"uuid",
|
2016-02-25 11:23:04 +00:00
|
|
|
|
"something_encrypted",
|
2016-11-21 15:16:21 +00:00
|
|
|
|
"2016-01-01T11:09:00.061258Z"),
|
2016-08-30 17:27:01 +01:00
|
|
|
|
queue="db-sms"
|
2016-02-24 17:12:30 +00:00
|
|
|
|
)
|
|
|
|
|
|
job = jobs_dao.dao_get_job_by_id(sample_job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'finished'
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.assert_not_called()
|
2016-02-24 17:12:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-09 11:28:52 +00:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2016-04-05 14:28:19 +01:00
|
|
|
|
def test_should_not_process_sms_job_if_would_exceed_send_limits(notify_db,
|
|
|
|
|
|
notify_db_session,
|
2016-09-07 15:35:12 +01:00
|
|
|
|
mocker):
|
2016-03-09 11:28:52 +00:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, limit=9)
|
2016-03-09 14:49:14 +00:00
|
|
|
|
job = sample_job(notify_db, notify_db_session, service=service, notification_count=10)
|
2016-03-09 11:28:52 +00:00
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('multiple_sms'))
|
2017-01-17 12:00:34 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.process_row')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-03-09 11:28:52 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(job.id)
|
|
|
|
|
|
|
|
|
|
|
|
job = jobs_dao.dao_get_job_by_id(job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'sending limits exceeded'
|
2016-10-07 12:48:58 +01:00
|
|
|
|
assert s3.get_job_from_s3.called is False
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.process_row.called is False
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.assert_not_called()
|
2016-03-09 13:57:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-04-05 14:28:19 +01:00
|
|
|
|
def test_should_not_process_sms_job_if_would_exceed_send_limits_inc_today(notify_db,
|
|
|
|
|
|
notify_db_session,
|
2016-09-07 15:35:12 +01:00
|
|
|
|
mocker):
|
2016-03-09 13:57:53 +00:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, limit=1)
|
|
|
|
|
|
job = sample_job(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
|
|
|
|
|
|
sample_notification(notify_db, notify_db_session, service=service, job=job)
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('sms'))
|
2017-01-17 12:00:34 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.process_row')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-03-09 13:57:53 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(job.id)
|
|
|
|
|
|
|
|
|
|
|
|
job = jobs_dao.dao_get_job_by_id(job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'sending limits exceeded'
|
2016-10-07 12:48:58 +01:00
|
|
|
|
assert s3.get_job_from_s3.called is False
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.process_row.called is False
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.assert_not_called()
|
2016-03-09 13:57:53 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_not_process_email_job_if_would_exceed_send_limits_inc_today(notify_db, notify_db_session, mocker):
|
|
|
|
|
|
service = sample_service(notify_db, notify_db_session, limit=1)
|
|
|
|
|
|
template = sample_email_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
job = sample_job(notify_db, notify_db_session, service=service, template=template)
|
|
|
|
|
|
|
|
|
|
|
|
sample_notification(notify_db, notify_db_session, service=service, job=job)
|
|
|
|
|
|
|
2017-01-17 12:00:34 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3')
|
|
|
|
|
|
mocker.patch('app.celery.tasks.process_row')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-03-09 13:57:53 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(job.id)
|
|
|
|
|
|
|
|
|
|
|
|
job = jobs_dao.dao_get_job_by_id(job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'sending limits exceeded'
|
2016-10-07 12:48:58 +01:00
|
|
|
|
assert s3.get_job_from_s3.called is False
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.process_row.called is False
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.assert_not_called()
|
2016-03-09 11:28:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2016-03-09 14:49:14 +00:00
|
|
|
|
def test_should_not_process_email_job_if_would_exceed_send_limits(notify_db, notify_db_session, mocker):
|
2016-03-09 13:57:53 +00:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, limit=0)
|
2016-03-09 11:28:52 +00:00
|
|
|
|
template = sample_email_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
job = sample_job(notify_db, notify_db_session, service=service, template=template)
|
|
|
|
|
|
|
2016-10-07 12:48:58 +01:00
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3')
|
2017-01-17 12:00:34 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.process_row')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-03-09 11:28:52 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(job.id)
|
|
|
|
|
|
|
|
|
|
|
|
job = jobs_dao.dao_get_job_by_id(job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'sending limits exceeded'
|
2016-10-07 12:48:58 +01:00
|
|
|
|
assert s3.get_job_from_s3.called is False
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.process_row.called is False
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.assert_not_called()
|
2016-03-09 11:28:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-10-07 12:55:48 +01:00
|
|
|
|
def test_should_not_process_job_if_already_pending(notify_db, notify_db_session, mocker):
|
|
|
|
|
|
job = sample_job(notify_db, notify_db_session, job_status='scheduled')
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3')
|
2017-01-17 12:00:34 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.process_row')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
2016-10-07 12:55:48 +01:00
|
|
|
|
|
|
|
|
|
|
process_job(job.id)
|
|
|
|
|
|
|
|
|
|
|
|
assert s3.get_job_from_s3.called is False
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.process_row.called is False
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.assert_not_called()
|
2016-10-07 12:55:48 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-09 11:35:12 +00:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2016-04-25 16:37:55 +01:00
|
|
|
|
def test_should_process_email_job_if_exactly_on_send_limits(notify_db,
|
|
|
|
|
|
notify_db_session,
|
2016-09-07 15:35:12 +01:00
|
|
|
|
mocker):
|
2016-03-09 11:35:12 +00:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, limit=10)
|
|
|
|
|
|
template = sample_email_template(notify_db, notify_db_session, service=service)
|
2016-03-09 14:49:14 +00:00
|
|
|
|
job = sample_job(notify_db, notify_db_session, service=service, template=template, notification_count=10)
|
2016-03-09 11:35:12 +00:00
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('multiple_email'))
|
|
|
|
|
|
mocker.patch('app.celery.tasks.send_email.apply_async')
|
|
|
|
|
|
mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
|
|
|
|
|
|
mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")
|
|
|
|
|
|
|
|
|
|
|
|
process_job(job.id)
|
|
|
|
|
|
|
2016-04-07 13:44:04 +01:00
|
|
|
|
s3.get_job_from_s3.assert_called_once_with(
|
|
|
|
|
|
str(job.service.id),
|
|
|
|
|
|
str(job.id)
|
|
|
|
|
|
)
|
2016-03-09 11:35:12 +00:00
|
|
|
|
job = jobs_dao.dao_get_job_by_id(job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'finished'
|
2016-03-09 11:35:12 +00:00
|
|
|
|
tasks.send_email.apply_async.assert_called_with(
|
2016-04-25 16:37:55 +01:00
|
|
|
|
(
|
|
|
|
|
|
str(job.service_id),
|
|
|
|
|
|
"uuid",
|
|
|
|
|
|
"something_encrypted",
|
2016-11-21 15:16:21 +00:00
|
|
|
|
"2016-01-01T11:09:00.061258Z"
|
2016-04-25 16:37:55 +01:00
|
|
|
|
),
|
2016-08-30 17:27:01 +01:00
|
|
|
|
queue="db-email"
|
2016-03-09 11:35:12 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-09-07 15:35:12 +01:00
|
|
|
|
def test_should_not_create_send_task_for_empty_file(sample_job, mocker):
|
2016-02-25 09:59:50 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('empty'))
|
|
|
|
|
|
mocker.patch('app.celery.tasks.send_sms.apply_async')
|
|
|
|
|
|
|
|
|
|
|
|
process_job(sample_job.id)
|
|
|
|
|
|
|
2016-04-07 13:44:04 +01:00
|
|
|
|
s3.get_job_from_s3.assert_called_once_with(
|
|
|
|
|
|
str(sample_job.service.id),
|
|
|
|
|
|
str(sample_job.id)
|
|
|
|
|
|
)
|
2016-02-25 09:59:50 +00:00
|
|
|
|
job = jobs_dao.dao_get_job_by_id(sample_job.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'finished'
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.send_sms.apply_async.called is False
|
2016-12-22 14:40:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-02-25 11:23:04 +00:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2016-12-22 14:40:33 +00:00
|
|
|
|
def test_should_process_email_job(email_job_with_placeholders, mocker):
|
|
|
|
|
|
email_csv = """email_address,name
|
|
|
|
|
|
test@test.com,foo
|
|
|
|
|
|
"""
|
|
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=email_csv)
|
2016-02-25 09:59:50 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.send_email.apply_async')
|
|
|
|
|
|
mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
|
|
|
|
|
|
mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")
|
|
|
|
|
|
|
2016-12-22 14:40:33 +00:00
|
|
|
|
process_job(email_job_with_placeholders.id)
|
2016-02-25 09:59:50 +00:00
|
|
|
|
|
2016-04-07 13:44:04 +01:00
|
|
|
|
s3.get_job_from_s3.assert_called_once_with(
|
2016-12-22 14:40:33 +00:00
|
|
|
|
str(email_job_with_placeholders.service.id),
|
|
|
|
|
|
str(email_job_with_placeholders.id)
|
2016-04-07 13:44:04 +01:00
|
|
|
|
)
|
2016-03-09 07:27:26 +00:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['to'] == 'test@test.com'
|
2016-12-22 14:40:33 +00:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['template'] == str(email_job_with_placeholders.template.id)
|
|
|
|
|
|
assert encryption.encrypt.call_args[0][0]['template_version'] == email_job_with_placeholders.template.version
|
|
|
|
|
|
assert encryption.encrypt.call_args[0][0]['personalisation'] == {'emailaddress': 'test@test.com', 'name': 'foo'}
|
2016-02-25 09:59:50 +00:00
|
|
|
|
tasks.send_email.apply_async.assert_called_once_with(
|
2016-04-25 16:37:55 +01:00
|
|
|
|
(
|
2016-12-22 14:40:33 +00:00
|
|
|
|
str(email_job_with_placeholders.service_id),
|
2016-04-25 16:37:55 +01:00
|
|
|
|
"uuid",
|
|
|
|
|
|
"something_encrypted",
|
2016-11-21 15:16:21 +00:00
|
|
|
|
"2016-01-01T11:09:00.061258Z"
|
2016-04-25 16:37:55 +01:00
|
|
|
|
),
|
2016-08-30 17:27:01 +01:00
|
|
|
|
queue="db-email"
|
2016-02-25 09:59:50 +00:00
|
|
|
|
)
|
2016-12-22 14:40:33 +00:00
|
|
|
|
job = jobs_dao.dao_get_job_by_id(email_job_with_placeholders.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'finished'
|
2016-02-25 09:59:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
|
|
|
|
|
def test_should_process_letter_job(sample_letter_job, mocker):
|
|
|
|
|
|
csv = """address_line_1,address_line_2,address_line_3,address_line_4,postcode,name
|
|
|
|
|
|
A1,A2,A3,A4,A_POST,Alice
|
|
|
|
|
|
"""
|
|
|
|
|
|
s3_mock = mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=csv)
|
|
|
|
|
|
mocker.patch('app.celery.tasks.send_email.apply_async')
|
|
|
|
|
|
process_row_mock = mocker.patch('app.celery.tasks.process_row')
|
|
|
|
|
|
mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file')
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(sample_letter_job.id)
|
|
|
|
|
|
|
|
|
|
|
|
s3_mock.assert_called_once_with(
|
|
|
|
|
|
str(sample_letter_job.service.id),
|
|
|
|
|
|
str(sample_letter_job.id)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
row_call = process_row_mock.mock_calls[0][1]
|
|
|
|
|
|
|
|
|
|
|
|
assert row_call[0] == 0
|
|
|
|
|
|
assert row_call[1] == ['A1', 'A2', 'A3', 'A4', None, None, 'A_POST']
|
|
|
|
|
|
assert dict(row_call[2]) == {
|
|
|
|
|
|
'addressline1': 'A1',
|
|
|
|
|
|
'addressline2': 'A2',
|
|
|
|
|
|
'addressline3': 'A3',
|
|
|
|
|
|
'addressline4': 'A4',
|
|
|
|
|
|
'postcode': 'A_POST'
|
|
|
|
|
|
}
|
|
|
|
|
|
assert row_call[4] == sample_letter_job
|
|
|
|
|
|
assert row_call[5] == sample_letter_job.service
|
|
|
|
|
|
|
|
|
|
|
|
assert process_row_mock.call_count == 1
|
|
|
|
|
|
|
2017-04-05 11:57:56 +01:00
|
|
|
|
assert sample_letter_job.job_status == 'in progress'
|
2017-03-15 15:26:58 +00:00
|
|
|
|
tasks.build_dvla_file.apply_async.assert_called_once_with([str(sample_letter_job.id)], queue="process-job")
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-04-05 11:57:56 +01:00
|
|
|
|
def test_should_process_all_sms_job(sample_job_with_placeholdered_template,
|
2016-09-07 15:35:12 +01:00
|
|
|
|
mocker):
|
2016-02-24 17:12:30 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3', return_value=load_example_csv('multiple_sms'))
|
|
|
|
|
|
mocker.patch('app.celery.tasks.send_sms.apply_async')
|
|
|
|
|
|
mocker.patch('app.encryption.encrypt', return_value="something_encrypted")
|
|
|
|
|
|
mocker.patch('app.celery.tasks.create_uuid', return_value="uuid")
|
|
|
|
|
|
|
2016-03-09 07:27:26 +00:00
|
|
|
|
process_job(sample_job_with_placeholdered_template.id)
|
2016-02-24 17:12:30 +00:00
|
|
|
|
|
2016-03-09 07:27:26 +00:00
|
|
|
|
s3.get_job_from_s3.assert_called_once_with(
|
2016-04-07 13:44:04 +01:00
|
|
|
|
str(sample_job_with_placeholdered_template.service.id),
|
|
|
|
|
|
str(sample_job_with_placeholdered_template.id)
|
2016-03-09 07:27:26 +00:00
|
|
|
|
)
|
|
|
|
|
|
assert encryption.encrypt.call_args[0][0]['to'] == '+441234123120'
|
2016-05-13 16:25:05 +01:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['template'] == str(sample_job_with_placeholdered_template.template.id)
|
2016-06-13 11:38:25 +01:00
|
|
|
|
assert encryption.encrypt.call_args[0][0][
|
|
|
|
|
|
'template_version'] == sample_job_with_placeholdered_template.template.version # noqa
|
2016-11-30 17:22:03 +00:00
|
|
|
|
assert encryption.encrypt.call_args[0][0]['personalisation'] == {'phonenumber': '+441234123120', 'name': 'chris'}
|
2017-01-17 12:00:34 +00:00
|
|
|
|
assert tasks.send_sms.apply_async.call_count == 10
|
2016-03-09 07:27:26 +00:00
|
|
|
|
job = jobs_dao.dao_get_job_by_id(sample_job_with_placeholdered_template.id)
|
2016-10-05 14:56:32 +01:00
|
|
|
|
assert job.job_status == 'finished'
|
2016-02-16 17:17:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-17 12:00:34 +00:00
|
|
|
|
# -------------- process_row tests -------------- #
|
|
|
|
|
|
|
2017-01-18 11:29:38 +00:00
|
|
|
|
|
|
|
|
|
|
@freeze_time('2001-01-01T12:00:00')
|
|
|
|
|
|
@pytest.mark.parametrize('template_type, research_mode, expected_function, expected_queue', [
|
|
|
|
|
|
(SMS_TYPE, False, 'send_sms', 'db-sms'),
|
|
|
|
|
|
(SMS_TYPE, True, 'send_sms', 'research-mode'),
|
|
|
|
|
|
(EMAIL_TYPE, False, 'send_email', 'db-email'),
|
|
|
|
|
|
(EMAIL_TYPE, True, 'send_email', 'research-mode'),
|
|
|
|
|
|
(LETTER_TYPE, False, 'persist_letter', 'db-letter'),
|
|
|
|
|
|
(LETTER_TYPE, True, 'persist_letter', 'research-mode'),
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_process_row_sends_letter_task(template_type, research_mode, expected_function, expected_queue, mocker):
|
|
|
|
|
|
mocker.patch('app.celery.tasks.create_uuid', return_value='noti_uuid')
|
|
|
|
|
|
task_mock = mocker.patch('app.celery.tasks.{}.apply_async'.format(expected_function))
|
|
|
|
|
|
encrypt_mock = mocker.patch('app.celery.tasks.encryption.encrypt')
|
|
|
|
|
|
template = Mock(id='template_id', template_type=template_type)
|
|
|
|
|
|
job = Mock(id='job_id', template_version='temp_vers')
|
|
|
|
|
|
service = Mock(id='service_id', research_mode=research_mode)
|
|
|
|
|
|
|
|
|
|
|
|
process_row('row_num', 'recip', {'foo': 'bar'}, template, job, service)
|
|
|
|
|
|
|
|
|
|
|
|
encrypt_mock.assert_called_once_with({
|
|
|
|
|
|
'template': 'template_id',
|
|
|
|
|
|
'template_version': 'temp_vers',
|
|
|
|
|
|
'job': 'job_id',
|
|
|
|
|
|
'to': 'recip',
|
|
|
|
|
|
'row_number': 'row_num',
|
|
|
|
|
|
'personalisation': {'foo': 'bar'}
|
|
|
|
|
|
})
|
|
|
|
|
|
task_mock.assert_called_once_with(
|
|
|
|
|
|
(
|
|
|
|
|
|
'service_id',
|
|
|
|
|
|
'noti_uuid',
|
|
|
|
|
|
# encrypted data
|
|
|
|
|
|
encrypt_mock.return_value,
|
|
|
|
|
|
'2001-01-01T12:00:00.000000Z'
|
|
|
|
|
|
),
|
|
|
|
|
|
queue=expected_queue
|
|
|
|
|
|
)
|
2017-01-17 12:00:34 +00:00
|
|
|
|
# -------- send_sms and send_email tests -------- #
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-06-13 11:38:25 +01:00
|
|
|
|
def test_should_send_template_to_correct_sms_task_and_persist(sample_template_with_placeholders, mocker):
|
2016-11-22 15:05:11 +00:00
|
|
|
|
notification = _notification_json(sample_template_with_placeholders,
|
|
|
|
|
|
to="+447234123123", personalisation={"name": "Jo"})
|
|
|
|
|
|
|
|
|
|
|
|
mocked_deliver_sms = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
|
|
|
|
|
|
|
|
|
|
|
send_sms(
|
|
|
|
|
|
sample_template_with_placeholders.service_id,
|
|
|
|
|
|
uuid.uuid4(),
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
persisted_notification = Notification.query.one()
|
|
|
|
|
|
assert persisted_notification.to == '+447234123123'
|
|
|
|
|
|
assert persisted_notification.template_id == sample_template_with_placeholders.id
|
|
|
|
|
|
assert persisted_notification.template_version == sample_template_with_placeholders.version
|
|
|
|
|
|
assert persisted_notification.status == 'created'
|
|
|
|
|
|
assert persisted_notification.created_at <= datetime.utcnow()
|
|
|
|
|
|
assert not persisted_notification.sent_at
|
|
|
|
|
|
assert not persisted_notification.sent_by
|
|
|
|
|
|
assert not persisted_notification.job_id
|
|
|
|
|
|
assert persisted_notification.personalisation == {'name': 'Jo'}
|
|
|
|
|
|
assert persisted_notification._personalisation == encryption.encrypt({"name": "Jo"})
|
|
|
|
|
|
assert persisted_notification.notification_type == 'sms'
|
|
|
|
|
|
mocked_deliver_sms.assert_called_once_with(
|
|
|
|
|
|
[str(persisted_notification.id)],
|
|
|
|
|
|
queue="send-sms"
|
|
|
|
|
|
)
|
2016-02-23 17:39:08 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-09-28 15:29:10 +01:00
|
|
|
|
def test_should_put_send_sms_task_in_research_mode_queue_if_research_mode_service(notify_db, notify_db_session, mocker):
|
|
|
|
|
|
service = sample_service(notify_db, notify_db_session)
|
|
|
|
|
|
service.research_mode = True
|
|
|
|
|
|
services_dao.dao_update_service(service)
|
|
|
|
|
|
|
|
|
|
|
|
template = sample_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
|
|
|
|
|
|
notification = _notification_json(template, to="+447234123123")
|
|
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
mocked_deliver_sms = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2016-09-28 15:29:10 +01:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
|
|
|
|
|
|
send_sms(
|
|
|
|
|
|
template.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-09-28 15:29:10 +01:00
|
|
|
|
provider_tasks.deliver_sms.apply_async.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)],
|
2016-09-28 15:29:10 +01:00
|
|
|
|
queue="research-mode"
|
|
|
|
|
|
)
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert mocked_deliver_sms.called
|
2016-09-28 15:29:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-03-03 12:05:18 +00:00
|
|
|
|
def test_should_send_sms_if_restricted_service_and_valid_number(notify_db, notify_db_session, mocker):
|
2016-12-28 12:30:26 +00:00
|
|
|
|
user = create_user(mobile_number="07700 900890")
|
2016-03-03 12:05:18 +00:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
|
|
|
|
|
template = sample_template(notify_db, notify_db_session, service=service)
|
2016-05-13 16:25:05 +01:00
|
|
|
|
notification = _notification_json(template, "+447700900890") # The user’s own number, but in a different format
|
|
|
|
|
|
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2016-03-03 12:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encrypt_notification = encryption.encrypt(notification)
|
2016-03-03 12:05:18 +00:00
|
|
|
|
send_sms(
|
|
|
|
|
|
service.id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encrypt_notification,
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
2016-03-03 12:05:18 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-06-21 14:38:17 +01:00
|
|
|
|
assert persisted_notification.to == '+447700900890'
|
|
|
|
|
|
assert persisted_notification.template_id == template.id
|
|
|
|
|
|
assert persisted_notification.template_version == template.version
|
|
|
|
|
|
assert persisted_notification.status == 'created'
|
2016-06-22 13:32:27 +01:00
|
|
|
|
assert persisted_notification.created_at <= datetime.utcnow()
|
2016-06-21 14:38:17 +01:00
|
|
|
|
assert not persisted_notification.sent_at
|
|
|
|
|
|
assert not persisted_notification.sent_by
|
|
|
|
|
|
assert not persisted_notification.job_id
|
2016-06-22 13:32:27 +01:00
|
|
|
|
assert not persisted_notification.personalisation
|
2016-07-06 14:31:52 +01:00
|
|
|
|
assert persisted_notification.notification_type == 'sms'
|
2016-11-11 16:00:31 +00:00
|
|
|
|
provider_tasks.deliver_sms.apply_async.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)],
|
2016-11-11 16:00:31 +00:00
|
|
|
|
queue="send-sms"
|
|
|
|
|
|
)
|
2016-06-21 14:38:17 +01:00
|
|
|
|
|
2016-03-03 12:05:18 +00:00
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
def test_should_send_sms_if_restricted_service_and_non_team_number_with_test_key(notify_db,
|
|
|
|
|
|
notify_db_session,
|
|
|
|
|
|
mocker):
|
2016-12-28 12:30:26 +00:00
|
|
|
|
user = create_user(mobile_number="07700 900205")
|
2016-09-07 09:57:20 +01:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
|
|
|
|
|
template = sample_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
|
|
|
|
|
|
notification = _notification_json(template, "07700 900849")
|
2016-11-11 10:41:39 +00:00
|
|
|
|
mocked_deliver_sms = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2016-09-07 09:57:20 +01:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
send_sms(
|
|
|
|
|
|
service.id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT),
|
|
|
|
|
|
key_type=KEY_TYPE_TEST
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-11-11 16:00:31 +00:00
|
|
|
|
mocked_deliver_sms.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)],
|
2016-09-07 09:57:20 +01:00
|
|
|
|
queue="send-sms"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
def test_should_send_email_if_restricted_service_and_non_team_email_address_with_test_key(notify_db,
|
|
|
|
|
|
notify_db_session,
|
|
|
|
|
|
mocker):
|
2016-12-28 12:30:26 +00:00
|
|
|
|
user = create_user()
|
2016-09-07 09:57:20 +01:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
|
|
|
|
|
template = sample_template(
|
|
|
|
|
|
notify_db, notify_db_session, service=service, template_type='email', subject_line='Hello'
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
notification = _notification_json(template, to="test@example.com")
|
2016-11-11 10:41:39 +00:00
|
|
|
|
mocked_deliver_email = mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
2016-09-07 09:57:20 +01:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
service.id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT),
|
|
|
|
|
|
key_type=KEY_TYPE_TEST
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-11-11 16:00:31 +00:00
|
|
|
|
mocked_deliver_email.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)],
|
2016-09-07 09:57:20 +01:00
|
|
|
|
queue="send-email"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-03-03 12:05:18 +00:00
|
|
|
|
def test_should_not_send_sms_if_restricted_service_and_invalid_number(notify_db, notify_db_session, mocker):
|
2016-12-28 12:30:26 +00:00
|
|
|
|
user = create_user(mobile_number="07700 900205")
|
2016-03-03 12:05:18 +00:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
|
|
|
|
|
template = sample_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
|
2016-05-13 16:25:05 +01:00
|
|
|
|
notification = _notification_json(template, "07700 900849")
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2016-03-03 12:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
send_sms(
|
|
|
|
|
|
service.id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
2016-03-03 12:05:18 +00:00
|
|
|
|
)
|
2016-10-07 12:48:58 +01:00
|
|
|
|
assert provider_tasks.deliver_sms.apply_async.called is False
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-03-03 12:05:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-04-05 15:27:16 +01:00
|
|
|
|
def test_should_not_send_email_if_restricted_service_and_invalid_email_address(notify_db, notify_db_session, mocker):
|
2016-12-28 12:30:26 +00:00
|
|
|
|
user = create_user()
|
2016-04-05 15:27:16 +01:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
|
|
|
|
|
template = sample_template(
|
|
|
|
|
|
notify_db, notify_db_session, service=service, template_type='email', subject_line='Hello'
|
|
|
|
|
|
)
|
2016-05-13 16:25:05 +01:00
|
|
|
|
notification = _notification_json(template, to="test@example.com")
|
2016-04-05 15:27:16 +01:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
2016-04-06 15:56:34 +01:00
|
|
|
|
send_email(
|
2016-04-05 15:27:16 +01:00
|
|
|
|
service.id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
2016-04-05 15:27:16 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-04-05 15:27:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
2016-09-28 15:48:12 +01:00
|
|
|
|
def test_should_put_send_email_task_in_research_mode_queue_if_research_mode_service(
|
|
|
|
|
|
notify_db, notify_db_session, mocker
|
|
|
|
|
|
):
|
2016-09-28 15:29:10 +01:00
|
|
|
|
service = sample_service(notify_db, notify_db_session)
|
|
|
|
|
|
service.research_mode = True
|
|
|
|
|
|
services_dao.dao_update_service(service)
|
|
|
|
|
|
|
|
|
|
|
|
template = sample_email_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
|
|
|
|
|
|
notification = _notification_json(template, to="test@test.com")
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
|
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
template.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-09-28 15:29:10 +01:00
|
|
|
|
provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)],
|
2016-09-28 15:29:10 +01:00
|
|
|
|
queue="research-mode"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-06-30 17:32:49 +01:00
|
|
|
|
def test_should_send_sms_template_to_and_persist_with_job_id(sample_job, sample_api_key, mocker):
|
2016-05-19 10:46:03 +01:00
|
|
|
|
notification = _notification_json(
|
|
|
|
|
|
sample_job.template,
|
|
|
|
|
|
to="+447234123123",
|
|
|
|
|
|
job_id=sample_job.id,
|
|
|
|
|
|
row_number=2)
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2016-02-23 17:39:08 +00:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
2016-11-11 14:56:33 +00:00
|
|
|
|
now = datetime.utcnow()
|
2016-02-23 17:39:08 +00:00
|
|
|
|
send_sms(
|
|
|
|
|
|
sample_job.service.id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encryption.encrypt(notification),
|
2016-11-11 14:56:33 +00:00
|
|
|
|
now.strftime(DATETIME_FORMAT),
|
2016-06-30 17:32:49 +01:00
|
|
|
|
api_key_id=str(sample_api_key.id),
|
2016-09-28 17:02:57 +01:00
|
|
|
|
key_type=KEY_TYPE_NORMAL
|
2016-03-08 17:45:37 +00:00
|
|
|
|
)
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-03-16 13:33:12 +00:00
|
|
|
|
assert persisted_notification.to == '+447234123123'
|
2016-02-23 17:39:08 +00:00
|
|
|
|
assert persisted_notification.job_id == sample_job.id
|
|
|
|
|
|
assert persisted_notification.template_id == sample_job.template.id
|
2016-06-21 14:38:17 +01:00
|
|
|
|
assert persisted_notification.status == 'created'
|
2016-06-07 12:53:31 +01:00
|
|
|
|
assert not persisted_notification.sent_at
|
2016-11-11 14:56:33 +00:00
|
|
|
|
assert persisted_notification.created_at <= now
|
2016-06-07 12:53:31 +01:00
|
|
|
|
assert not persisted_notification.sent_by
|
2016-05-19 10:46:03 +01:00
|
|
|
|
assert persisted_notification.job_row_number == 2
|
2016-06-30 17:32:49 +01:00
|
|
|
|
assert persisted_notification.api_key_id == sample_api_key.id
|
2016-09-28 17:02:57 +01:00
|
|
|
|
assert persisted_notification.key_type == KEY_TYPE_NORMAL
|
2016-07-06 14:31:52 +01:00
|
|
|
|
assert persisted_notification.notification_type == 'sms'
|
2016-02-16 17:17:02 +00:00
|
|
|
|
|
2016-11-11 16:00:31 +00:00
|
|
|
|
provider_tasks.deliver_sms.apply_async.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)],
|
2016-11-11 16:00:31 +00:00
|
|
|
|
queue="send-sms"
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-02-16 17:17:02 +00:00
|
|
|
|
|
2016-09-28 17:02:57 +01:00
|
|
|
|
def test_should_not_send_email_if_team_key_and_recipient_not_in_team(sample_email_template_with_placeholders,
|
|
|
|
|
|
sample_team_api_key,
|
|
|
|
|
|
mocker):
|
2016-05-19 10:46:03 +01:00
|
|
|
|
notification = _notification_json(
|
|
|
|
|
|
sample_email_template_with_placeholders,
|
|
|
|
|
|
"my_email@my_email.com",
|
|
|
|
|
|
{"name": "Jo"},
|
|
|
|
|
|
row_number=1)
|
2016-09-30 11:07:32 +01:00
|
|
|
|
apply_async = mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
2016-09-28 17:02:57 +01:00
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
|
|
|
|
|
|
team_members = [user.email_address for user in sample_email_template_with_placeholders.service.users]
|
|
|
|
|
|
assert "my_email@my_email.com" not in team_members
|
|
|
|
|
|
|
|
|
|
|
|
with freeze_time("2016-01-01 11:09:00.00000"):
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
sample_email_template_with_placeholders.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
now.strftime(DATETIME_FORMAT),
|
|
|
|
|
|
api_key_id=str(sample_team_api_key.id),
|
|
|
|
|
|
key_type=KEY_TYPE_TEAM
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-09-28 17:02:57 +01:00
|
|
|
|
|
|
|
|
|
|
apply_async.not_called()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_not_send_sms_if_team_key_and_recipient_not_in_team(notify_db, notify_db_session, mocker):
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-12-28 12:30:26 +00:00
|
|
|
|
user = create_user(mobile_number="07700 900205")
|
2016-09-28 17:02:57 +01:00
|
|
|
|
service = sample_service(notify_db, notify_db_session, user=user, restricted=True)
|
|
|
|
|
|
template = sample_template(notify_db, notify_db_session, service=service)
|
|
|
|
|
|
|
|
|
|
|
|
team_members = [user.mobile_number for user in service.users]
|
|
|
|
|
|
assert "07890 300000" not in team_members
|
|
|
|
|
|
|
|
|
|
|
|
notification = _notification_json(template, "07700 900849")
|
2016-10-13 15:53:01 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2016-09-28 17:02:57 +01:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
send_sms(
|
|
|
|
|
|
service.id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
datetime.utcnow().strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
2016-10-13 15:53:01 +01:00
|
|
|
|
assert provider_tasks.deliver_sms.apply_async.called is False
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-09-28 17:02:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_use_email_template_and_persist(sample_email_template_with_placeholders, sample_api_key, mocker):
|
2017-01-17 12:00:34 +00:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
|
|
|
|
|
|
|
|
|
|
|
now = datetime(2016, 1, 1, 11, 9, 0)
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
|
2016-11-11 17:36:38 +00:00
|
|
|
|
with freeze_time("2016-01-01 12:00:00.000000"):
|
|
|
|
|
|
notification = _notification_json(
|
|
|
|
|
|
sample_email_template_with_placeholders,
|
|
|
|
|
|
'my_email@my_email.com',
|
|
|
|
|
|
{"name": "Jo"},
|
|
|
|
|
|
row_number=1)
|
2017-01-17 12:00:34 +00:00
|
|
|
|
|
|
|
|
|
|
with freeze_time("2016-01-01 11:10:00.00000"):
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
sample_email_template_with_placeholders.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
now.strftime(DATETIME_FORMAT),
|
|
|
|
|
|
api_key_id=str(sample_api_key.id),
|
|
|
|
|
|
key_type=sample_api_key.key_type
|
|
|
|
|
|
)
|
2016-11-11 17:36:38 +00:00
|
|
|
|
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-04-13 15:31:08 +01:00
|
|
|
|
assert persisted_notification.to == 'my_email@my_email.com'
|
|
|
|
|
|
assert persisted_notification.template_id == sample_email_template_with_placeholders.id
|
2016-05-13 16:25:05 +01:00
|
|
|
|
assert persisted_notification.template_version == sample_email_template_with_placeholders.version
|
2016-11-11 14:56:33 +00:00
|
|
|
|
assert persisted_notification.created_at == now
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert not persisted_notification.sent_at
|
|
|
|
|
|
assert persisted_notification.status == 'created'
|
|
|
|
|
|
assert not persisted_notification.sent_by
|
2016-05-19 10:46:03 +01:00
|
|
|
|
assert persisted_notification.job_row_number == 1
|
2016-06-22 13:32:27 +01:00
|
|
|
|
assert persisted_notification.personalisation == {'name': 'Jo'}
|
|
|
|
|
|
assert persisted_notification._personalisation == encryption.encrypt({"name": "Jo"})
|
2016-06-30 17:32:49 +01:00
|
|
|
|
assert persisted_notification.api_key_id == sample_api_key.id
|
2016-09-28 17:02:57 +01:00
|
|
|
|
assert persisted_notification.key_type == KEY_TYPE_NORMAL
|
2016-07-06 14:31:52 +01:00
|
|
|
|
assert persisted_notification.notification_type == 'email'
|
2016-11-11 17:36:38 +00:00
|
|
|
|
|
2016-11-11 16:00:31 +00:00
|
|
|
|
provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)], queue='send-email')
|
2016-05-13 16:25:05 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_send_email_should_use_template_version_from_job_not_latest(sample_email_template, mocker):
|
|
|
|
|
|
notification = _notification_json(sample_email_template, 'my_email@my_email.com')
|
|
|
|
|
|
version_on_notification = sample_email_template.version
|
|
|
|
|
|
# Change the template
|
|
|
|
|
|
from app.dao.templates_dao import dao_update_template, dao_get_template_by_id
|
|
|
|
|
|
sample_email_template.content = sample_email_template.content + " another version of the template"
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
2016-05-13 16:25:05 +01:00
|
|
|
|
dao_update_template(sample_email_template)
|
|
|
|
|
|
t = dao_get_template_by_id(sample_email_template.id)
|
|
|
|
|
|
assert t.version > version_on_notification
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
sample_email_template.service_id,
|
2016-11-11 16:00:31 +00:00
|
|
|
|
uuid.uuid4(),
|
2016-07-01 14:14:28 +01:00
|
|
|
|
encryption.encrypt(notification),
|
2016-05-13 16:25:05 +01:00
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
2016-07-01 14:14:28 +01:00
|
|
|
|
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-05-13 16:25:05 +01:00
|
|
|
|
assert persisted_notification.to == 'my_email@my_email.com'
|
|
|
|
|
|
assert persisted_notification.template_id == sample_email_template.id
|
|
|
|
|
|
assert persisted_notification.template_version == version_on_notification
|
2016-04-13 15:31:08 +01:00
|
|
|
|
assert persisted_notification.created_at == now
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert not persisted_notification.sent_at
|
|
|
|
|
|
assert persisted_notification.status == 'created'
|
|
|
|
|
|
assert not persisted_notification.sent_by
|
2016-07-06 14:31:52 +01:00
|
|
|
|
assert persisted_notification.notification_type == 'email'
|
2016-11-16 16:15:30 +00:00
|
|
|
|
provider_tasks.deliver_email.apply_async.assert_called_once_with([str(persisted_notification.id)],
|
|
|
|
|
|
queue='send-email')
|
2016-04-13 15:31:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_use_email_template_subject_placeholders(sample_email_template_with_placeholders, mocker):
|
2016-05-13 16:25:05 +01:00
|
|
|
|
notification = _notification_json(sample_email_template_with_placeholders,
|
|
|
|
|
|
"my_email@my_email.com", {"name": "Jo"})
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
2016-04-13 15:31:08 +01:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
sample_email_template_with_placeholders.service_id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encryption.encrypt(notification),
|
2016-04-13 15:31:08 +01:00
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
2016-11-14 14:41:32 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-02-22 17:17:29 +00:00
|
|
|
|
assert persisted_notification.to == 'my_email@my_email.com'
|
2016-02-29 14:43:44 +00:00
|
|
|
|
assert persisted_notification.template_id == sample_email_template_with_placeholders.id
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert persisted_notification.status == 'created'
|
2016-11-11 14:56:33 +00:00
|
|
|
|
assert persisted_notification.created_at == now
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert not persisted_notification.sent_by
|
2016-06-22 13:32:27 +01:00
|
|
|
|
assert persisted_notification.personalisation == {"name": "Jo"}
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert not persisted_notification.reference
|
2016-07-06 14:31:52 +01:00
|
|
|
|
assert persisted_notification.notification_type == 'email'
|
2016-11-11 16:00:31 +00:00
|
|
|
|
provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
2016-11-16 16:15:30 +00:00
|
|
|
|
[str(persisted_notification.id)], queue='send-email'
|
2016-11-11 16:00:31 +00:00
|
|
|
|
)
|
2016-03-11 09:40:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-05-13 16:25:05 +01:00
|
|
|
|
def test_should_use_email_template_and_persist_without_personalisation(sample_email_template, mocker):
|
2016-06-22 13:32:27 +01:00
|
|
|
|
notification = _notification_json(sample_email_template, "my_email@my_email.com")
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
2016-03-02 12:27:07 +00:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
2016-06-30 17:32:49 +01:00
|
|
|
|
|
2016-03-02 12:27:07 +00:00
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
sample_email_template.service_id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encryption.encrypt(notification),
|
2016-03-08 17:45:37 +00:00
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
2016-03-02 12:27:07 +00:00
|
|
|
|
)
|
2016-11-14 15:29:23 +00:00
|
|
|
|
persisted_notification = Notification.query.one()
|
2016-06-22 13:32:27 +01:00
|
|
|
|
assert persisted_notification.to == 'my_email@my_email.com'
|
|
|
|
|
|
assert persisted_notification.template_id == sample_email_template.id
|
|
|
|
|
|
assert persisted_notification.created_at == now
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert not persisted_notification.sent_at
|
|
|
|
|
|
assert persisted_notification.status == 'created'
|
|
|
|
|
|
assert not persisted_notification.sent_by
|
2016-06-22 13:32:27 +01:00
|
|
|
|
assert not persisted_notification.personalisation
|
2016-07-01 14:14:28 +01:00
|
|
|
|
assert not persisted_notification.reference
|
|
|
|
|
|
assert persisted_notification.notification_type == 'email'
|
2016-11-16 16:15:30 +00:00
|
|
|
|
provider_tasks.deliver_email.apply_async.assert_called_once_with([str(persisted_notification.id)],
|
2016-11-11 16:00:31 +00:00
|
|
|
|
queue='send-email')
|
2016-03-02 12:27:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-07-01 14:14:28 +01:00
|
|
|
|
def test_send_sms_should_go_to_retry_queue_if_database_errors(sample_template, mocker):
|
2016-05-13 16:25:05 +01:00
|
|
|
|
notification = _notification_json(sample_template, "+447234123123")
|
2016-06-07 12:53:31 +01:00
|
|
|
|
|
|
|
|
|
|
expected_exception = SQLAlchemyError()
|
|
|
|
|
|
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
2017-01-17 16:51:27 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.send_sms.retry', side_effect=Retry)
|
2016-11-11 10:41:39 +00:00
|
|
|
|
mocker.patch('app.notifications.process_notifications.dao_create_notification', side_effect=expected_exception)
|
2016-02-25 09:59:50 +00:00
|
|
|
|
now = datetime.utcnow()
|
2016-02-16 17:17:02 +00:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
|
2017-01-17 16:51:27 +00:00
|
|
|
|
with pytest.raises(Retry):
|
2016-06-07 12:53:31 +01:00
|
|
|
|
send_sms(
|
|
|
|
|
|
sample_template.service_id,
|
|
|
|
|
|
notification_id,
|
2016-06-22 13:32:27 +01:00
|
|
|
|
encryption.encrypt(notification),
|
2016-06-07 12:53:31 +01:00
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
2016-10-07 12:48:58 +01:00
|
|
|
|
assert provider_tasks.deliver_sms.apply_async.called is False
|
2016-06-07 12:53:31 +01:00
|
|
|
|
tasks.send_sms.retry.assert_called_with(exc=expected_exception, queue='retry')
|
2016-02-16 17:17:02 +00:00
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-02-16 17:17:02 +00:00
|
|
|
|
|
2016-06-13 11:38:25 +01:00
|
|
|
|
|
2016-07-01 14:14:28 +01:00
|
|
|
|
def test_send_email_should_go_to_retry_queue_if_database_errors(sample_email_template, mocker):
|
|
|
|
|
|
notification = _notification_json(sample_email_template, "test@example.gov.uk")
|
2016-02-22 17:17:29 +00:00
|
|
|
|
|
2016-07-01 14:14:28 +01:00
|
|
|
|
expected_exception = SQLAlchemyError()
|
2016-02-22 17:17:29 +00:00
|
|
|
|
|
2016-09-28 15:05:50 +01:00
|
|
|
|
mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
2017-01-17 16:51:27 +00:00
|
|
|
|
mocker.patch('app.celery.tasks.send_email.retry', side_effect=Retry)
|
2016-11-11 10:41:39 +00:00
|
|
|
|
mocker.patch('app.notifications.process_notifications.dao_create_notification', side_effect=expected_exception)
|
2016-02-25 09:59:50 +00:00
|
|
|
|
now = datetime.utcnow()
|
2016-02-22 17:17:29 +00:00
|
|
|
|
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
|
2017-01-17 16:51:27 +00:00
|
|
|
|
with pytest.raises(Retry):
|
2016-07-01 14:14:28 +01:00
|
|
|
|
send_email(
|
|
|
|
|
|
sample_email_template.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification),
|
|
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
2016-11-11 16:00:31 +00:00
|
|
|
|
assert not provider_tasks.deliver_email.apply_async.called
|
2016-07-01 14:14:28 +01:00
|
|
|
|
tasks.send_email.retry.assert_called_with(exc=expected_exception, queue='retry')
|
|
|
|
|
|
|
2016-11-11 10:41:39 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2016-11-25 17:32:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_send_email_does_not_send_duplicate_and_does_not_put_in_retry_queue(sample_notification, mocker):
|
|
|
|
|
|
json = _notification_json(sample_notification.template, sample_notification.to, job_id=uuid.uuid4(), row_number=1)
|
|
|
|
|
|
deliver_email = mocker.patch('app.celery.provider_tasks.deliver_email.apply_async')
|
|
|
|
|
|
retry = mocker.patch('app.celery.tasks.send_email.retry', side_effect=Exception())
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
|
|
|
|
|
|
notification_id = sample_notification.id
|
|
|
|
|
|
|
|
|
|
|
|
send_email(
|
|
|
|
|
|
sample_notification.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(json),
|
|
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
|
|
|
|
|
assert Notification.query.count() == 1
|
|
|
|
|
|
assert not deliver_email.called
|
|
|
|
|
|
assert not retry.called
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_send_sms_does_not_send_duplicate_and_does_not_put_in_retry_queue(sample_notification, mocker):
|
|
|
|
|
|
json = _notification_json(sample_notification.template, sample_notification.to, job_id=uuid.uuid4(), row_number=1)
|
|
|
|
|
|
deliver_sms = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async')
|
|
|
|
|
|
retry = mocker.patch('app.celery.tasks.send_sms.retry', side_effect=Exception())
|
|
|
|
|
|
now = datetime.utcnow()
|
|
|
|
|
|
|
|
|
|
|
|
notification_id = sample_notification.id
|
|
|
|
|
|
|
|
|
|
|
|
send_sms(
|
|
|
|
|
|
sample_notification.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(json),
|
|
|
|
|
|
now.strftime(DATETIME_FORMAT)
|
|
|
|
|
|
)
|
|
|
|
|
|
assert Notification.query.count() == 1
|
|
|
|
|
|
assert not deliver_sms.called
|
|
|
|
|
|
assert not retry.called
|
2017-01-17 16:51:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
persist_letter saves address correctly to database
the `to` field stores either the phone number or the email address
of the recipient - it's a bit more complicated for letters, since
there are address lines 1 through 6, and a postcode. In utils, they're
stored alongside the personalisation, and we have to ensure that when
we persist to the database we keep as much parity with utils to make
our work easier. Aside from sending, the `to` field is also used to
show recipients on the front end report pages - we've decided that the
best thing to store here is address_line_1 - which is probably going to
be either a person's name, company name, or PO box number
Also, a lot of tests and test cleanup - I added create_template and
create_notification functions in db.py, so if you're creating new
fixtures you can use these functions, and you won't need to pass
notify_db and notify_db_session around, huzzah!
also removed create param from sample_notification since it's not used
anywhere
2017-01-19 12:10:32 +00:00
|
|
|
|
def test_persist_letter_saves_letter_to_database(sample_letter_job, mocker):
|
|
|
|
|
|
personalisation = {
|
|
|
|
|
|
'addressline1': 'Foo',
|
|
|
|
|
|
'addressline2': 'Bar',
|
|
|
|
|
|
'addressline3': 'Baz',
|
|
|
|
|
|
'addressline4': 'Wibble',
|
|
|
|
|
|
'addressline5': 'Wobble',
|
|
|
|
|
|
'addressline6': 'Wubble',
|
|
|
|
|
|
'postcode': 'Flob',
|
|
|
|
|
|
}
|
|
|
|
|
|
notification_json = _notification_json(
|
|
|
|
|
|
template=sample_letter_job.template,
|
|
|
|
|
|
to='Foo',
|
|
|
|
|
|
personalisation=personalisation,
|
|
|
|
|
|
job_id=sample_letter_job.id,
|
|
|
|
|
|
row_number=1
|
|
|
|
|
|
)
|
|
|
|
|
|
notification_id = uuid.uuid4()
|
|
|
|
|
|
created_at = datetime.utcnow()
|
|
|
|
|
|
|
|
|
|
|
|
persist_letter(
|
|
|
|
|
|
sample_letter_job.service_id,
|
|
|
|
|
|
notification_id,
|
|
|
|
|
|
encryption.encrypt(notification_json),
|
|
|
|
|
|
created_at
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
notification_db = Notification.query.one()
|
|
|
|
|
|
assert notification_db.id == notification_id
|
|
|
|
|
|
assert notification_db.to == 'Foo'
|
|
|
|
|
|
assert notification_db.job_id == sample_letter_job.id
|
|
|
|
|
|
assert notification_db.template_id == sample_letter_job.template.id
|
|
|
|
|
|
assert notification_db.template_version == sample_letter_job.template.version
|
|
|
|
|
|
assert notification_db.status == 'created'
|
|
|
|
|
|
assert notification_db.created_at == created_at
|
|
|
|
|
|
assert notification_db.notification_type == 'letter'
|
|
|
|
|
|
assert notification_db.sent_at is None
|
|
|
|
|
|
assert notification_db.sent_by is None
|
|
|
|
|
|
assert notification_db.personalisation == personalisation
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-02 11:34:00 +00:00
|
|
|
|
def test_should_cancel_job_if_service_is_inactive(sample_service,
|
|
|
|
|
|
sample_job,
|
|
|
|
|
|
mocker):
|
|
|
|
|
|
sample_service.active = False
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch('app.celery.tasks.s3.get_job_from_s3')
|
|
|
|
|
|
mocker.patch('app.celery.tasks.process_row')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mock_dvla_file_task = mocker.patch('app.celery.tasks.build_dvla_file')
|
2017-02-02 11:34:00 +00:00
|
|
|
|
|
|
|
|
|
|
process_job(sample_job.id)
|
|
|
|
|
|
|
|
|
|
|
|
job = jobs_dao.dao_get_job_by_id(sample_job.id)
|
|
|
|
|
|
assert job.job_status == 'cancelled'
|
|
|
|
|
|
s3.get_job_from_s3.assert_not_called()
|
|
|
|
|
|
tasks.process_row.assert_not_called()
|
2017-03-15 15:26:58 +00:00
|
|
|
|
mock_dvla_file_task.assert_not_called()
|
2017-02-02 11:34:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-17 16:51:27 +00:00
|
|
|
|
@pytest.mark.parametrize('template_type, expected_class', [
|
|
|
|
|
|
(SMS_TYPE, SMSMessageTemplate),
|
|
|
|
|
|
(EMAIL_TYPE, WithSubjectTemplate),
|
|
|
|
|
|
(LETTER_TYPE, WithSubjectTemplate),
|
|
|
|
|
|
])
|
|
|
|
|
|
def test_get_template_class(template_type, expected_class):
|
2017-01-24 10:53:41 +00:00
|
|
|
|
assert get_template_class(template_type) == expected_class
|
2017-03-15 15:26:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_build_dvla_file(sample_letter_template, mocker):
|
|
|
|
|
|
job = create_job(template=sample_letter_template, notification_count=2)
|
|
|
|
|
|
create_notification(template=job.template, job=job)
|
|
|
|
|
|
create_notification(template=job.template, job=job)
|
2017-04-03 12:20:49 +01:00
|
|
|
|
mocked_upload = mocker.patch("app.celery.tasks.s3upload")
|
|
|
|
|
|
mocked_letter_template = mocker.patch("app.celery.tasks.LetterDVLATemplate")
|
|
|
|
|
|
mocked_letter_template_instance = mocked_letter_template.return_value
|
|
|
|
|
|
mocked_letter_template_instance.__str__.return_value = "dvla|string"
|
2017-03-15 15:26:58 +00:00
|
|
|
|
build_dvla_file(job.id)
|
|
|
|
|
|
|
2017-04-03 12:20:49 +01:00
|
|
|
|
mocked_upload.assert_called_once_with(
|
|
|
|
|
|
filedata="dvla|string\ndvla|string\n",
|
|
|
|
|
|
region=current_app.config['AWS_REGION'],
|
|
|
|
|
|
bucket_name=current_app.config['DVLA_UPLOAD_BUCKET_NAME'],
|
|
|
|
|
|
file_location="{}-dvla-job.text".format(job.id)
|
|
|
|
|
|
)
|
2017-04-05 11:57:56 +01:00
|
|
|
|
assert Job.query.get(job.id).job_status == 'ready to send'
|
2017-03-15 15:26:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_build_dvla_file_retries_if_all_notifications_are_not_created(sample_letter_template, mocker):
|
2017-04-05 11:57:56 +01:00
|
|
|
|
job = create_job(template=sample_letter_template, notification_count=2, job_status='in progress')
|
2017-03-15 15:26:58 +00:00
|
|
|
|
create_notification(template=job.template, job=job)
|
|
|
|
|
|
|
|
|
|
|
|
mocked = mocker.patch("app.celery.tasks.s3upload")
|
|
|
|
|
|
mocker.patch('app.celery.tasks.build_dvla_file.retry', side_effect=Retry)
|
|
|
|
|
|
with pytest.raises(Retry):
|
|
|
|
|
|
build_dvla_file(job.id)
|
|
|
|
|
|
mocked.assert_not_called()
|
|
|
|
|
|
|
|
|
|
|
|
tasks.build_dvla_file.retry.assert_called_with(queue='retry',
|
|
|
|
|
|
exc="All notifications for job {} are not persisted".format(job.id))
|
2017-04-05 11:57:56 +01:00
|
|
|
|
assert Job.query.get(job.id).job_status == 'in progress'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_create_dvla_file_contents(sample_letter_template, mocker):
|
|
|
|
|
|
mocker.patch("app.celery.tasks.random.randint", return_value=999)
|
|
|
|
|
|
job = create_job(template=sample_letter_template, notification_count=2)
|
|
|
|
|
|
create_notification(template=job.template, job=job)
|
|
|
|
|
|
create_notification(template=job.template, job=job)
|
|
|
|
|
|
mocked_letter_template = mocker.patch("app.celery.tasks.LetterDVLATemplate")
|
|
|
|
|
|
mocked_letter_template_instance = mocked_letter_template.return_value
|
|
|
|
|
|
mocked_letter_template_instance.__str__.return_value = "dvla|string"
|
|
|
|
|
|
create_dvla_file_contents(job.id)
|
|
|
|
|
|
# Template
|
|
|
|
|
|
assert mocked_letter_template.call_args[0][0]['subject'] == 'Template subject'
|
|
|
|
|
|
assert mocked_letter_template.call_args[0][0]['content'] == 'Dear Sir/Madam, Hello. Yours Truly, The Government.'
|
|
|
|
|
|
|
|
|
|
|
|
# Personalisation
|
|
|
|
|
|
assert mocked_letter_template.call_args[0][1] is None
|
|
|
|
|
|
|
|
|
|
|
|
# Named arguments
|
|
|
|
|
|
assert mocked_letter_template.call_args[1]['numeric_id'] == 999
|
|
|
|
|
|
assert mocked_letter_template.call_args[1]['contact_block'] == 'London,\nSW1A 1AA'
|
2017-03-24 15:25:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time("2017-03-23 11:09:00.061258")
|
|
|
|
|
|
def test_dvla_letter_template(sample_letter_notification):
|
|
|
|
|
|
t = {"content": sample_letter_notification.template.content,
|
|
|
|
|
|
"subject": sample_letter_notification.template.subject}
|
|
|
|
|
|
letter = LetterDVLATemplate(t,
|
|
|
|
|
|
sample_letter_notification.personalisation,
|
|
|
|
|
|
12345)
|
2017-04-05 12:27:27 +01:00
|
|
|
|
assert str(letter) == "140|500|001||201703230012345|||||||||||||A1|A2|A3|A4|A5|A6||A_POST|||||||||23 March 2017<cr><cr><h1>Template subject<normal><cr><cr>Dear Sir/Madam, Hello. Yours Truly, The Government.<cr><cr>" # noqa
|