notify-api-412 use black to enforce python style standards

This commit is contained in:
Kenneth Kehl
2023-08-23 10:35:43 -07:00
parent a7898118d7
commit 026dc14021
586 changed files with 33990 additions and 23461 deletions

View File

@@ -18,51 +18,64 @@ from tests.app.db import (
)
def test_ses_callback_should_not_set_status_once_status_is_delivered(sample_email_template):
notification = create_notification(sample_email_template, status='delivered', )
def test_ses_callback_should_not_set_status_once_status_is_delivered(
sample_email_template,
):
notification = create_notification(
sample_email_template,
status="delivered",
)
assert get_notification_by_id(notification.id).status == 'delivered'
assert get_notification_by_id(notification.id).status == "delivered"
def test_process_ses_results_in_complaint(sample_email_template):
notification = create_notification(template=sample_email_template, reference='ref1')
handle_complaint(json.loads(ses_complaint_callback()['Message']))
notification = create_notification(template=sample_email_template, reference="ref1")
handle_complaint(json.loads(ses_complaint_callback()["Message"]))
complaints = Complaint.query.all()
assert len(complaints) == 1
assert complaints[0].notification_id == notification.id
def test_handle_complaint_does_not_raise_exception_if_reference_is_missing(notify_api):
response = json.loads(ses_complaint_callback_malformed_message_id()['Message'])
response = json.loads(ses_complaint_callback_malformed_message_id()["Message"])
handle_complaint(response)
assert len(Complaint.query.all()) == 0
def test_handle_complaint_does_raise_exception_if_notification_not_found(notify_api):
response = json.loads(ses_complaint_callback()['Message'])
response = json.loads(ses_complaint_callback()["Message"])
with pytest.raises(expected_exception=SQLAlchemyError):
handle_complaint(response)
def test_process_ses_results_in_complaint_if_notification_history_does_not_exist(sample_email_template):
notification = create_notification(template=sample_email_template, reference='ref1')
handle_complaint(json.loads(ses_complaint_callback()['Message']))
def test_process_ses_results_in_complaint_if_notification_history_does_not_exist(
sample_email_template,
):
notification = create_notification(template=sample_email_template, reference="ref1")
handle_complaint(json.loads(ses_complaint_callback()["Message"]))
complaints = Complaint.query.all()
assert len(complaints) == 1
assert complaints[0].notification_id == notification.id
def test_process_ses_results_in_complaint_if_notification_does_not_exist(sample_email_template):
notification = create_notification_history(template=sample_email_template, reference='ref1')
handle_complaint(json.loads(ses_complaint_callback()['Message']))
def test_process_ses_results_in_complaint_if_notification_does_not_exist(
sample_email_template,
):
notification = create_notification_history(
template=sample_email_template, reference="ref1"
)
handle_complaint(json.loads(ses_complaint_callback()["Message"]))
complaints = Complaint.query.all()
assert len(complaints) == 1
assert complaints[0].notification_id == notification.id
def test_process_ses_results_in_complaint_save_complaint_with_null_complaint_type(notify_api, sample_email_template):
notification = create_notification(template=sample_email_template, reference='ref1')
msg = json.loads(ses_complaint_callback_with_missing_complaint_type()['Message'])
def test_process_ses_results_in_complaint_save_complaint_with_null_complaint_type(
notify_api, sample_email_template
):
notification = create_notification(template=sample_email_template, reference="ref1")
msg = json.loads(ses_complaint_callback_with_missing_complaint_type()["Message"])
handle_complaint(msg)
complaints = Complaint.query.all()
assert len(complaints) == 1
@@ -72,15 +85,15 @@ def test_process_ses_results_in_complaint_save_complaint_with_null_complaint_typ
def test_check_and_queue_callback_task(mocker, sample_notification):
mock_create = mocker.patch(
'app.celery.process_ses_receipts_tasks.create_delivery_status_callback_data'
"app.celery.process_ses_receipts_tasks.create_delivery_status_callback_data"
)
mock_send = mocker.patch(
'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async'
"app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async"
)
callback_api = create_service_callback_api(service=sample_notification.service)
mock_create.return_value = 'encrypted_status_update'
mock_create.return_value = "encrypted_status_update"
check_and_queue_callback_task(sample_notification)
@@ -91,13 +104,14 @@ def test_check_and_queue_callback_task(mocker, sample_notification):
assert mock_create_args[1].id == callback_api.id
mock_send.assert_called_once_with(
[str(sample_notification.id), mock_create.return_value], queue="service-callbacks"
[str(sample_notification.id), mock_create.return_value],
queue="service-callbacks",
)
def test_check_and_queue_callback_task_no_callback_api(mocker, sample_notification):
mock_send = mocker.patch(
'app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async'
"app.celery.service_callback_tasks.send_delivery_status_to_service.apply_async"
)
check_and_queue_callback_task(sample_notification)

View File

@@ -30,51 +30,64 @@ def test_create_content_for_notification_passes(sample_email_template):
sample_email_template.id, sample_email_template.service_id
)
content = create_content_for_notification(template, None)
assert str(content) == template.content + '\n'
assert str(content) == template.content + "\n"
def test_create_content_for_notification_with_placeholders_passes(sample_template_with_placeholders):
def test_create_content_for_notification_with_placeholders_passes(
sample_template_with_placeholders,
):
template = SerialisedTemplate.from_id_and_service_id(
sample_template_with_placeholders.id, sample_template_with_placeholders.service_id
sample_template_with_placeholders.id,
sample_template_with_placeholders.service_id,
)
content = create_content_for_notification(template, {'name': 'Bobby'})
content = create_content_for_notification(template, {"name": "Bobby"})
assert content.content == template.content
assert 'Bobby' in str(content)
assert "Bobby" in str(content)
def test_create_content_for_notification_fails_with_missing_personalisation(sample_template_with_placeholders):
def test_create_content_for_notification_fails_with_missing_personalisation(
sample_template_with_placeholders,
):
template = SerialisedTemplate.from_id_and_service_id(
sample_template_with_placeholders.id, sample_template_with_placeholders.service_id
sample_template_with_placeholders.id,
sample_template_with_placeholders.service_id,
)
with pytest.raises(BadRequestError):
create_content_for_notification(template, None)
def test_create_content_for_notification_allows_additional_personalisation(sample_template_with_placeholders):
def test_create_content_for_notification_allows_additional_personalisation(
sample_template_with_placeholders,
):
template = SerialisedTemplate.from_id_and_service_id(
sample_template_with_placeholders.id, sample_template_with_placeholders.service_id
sample_template_with_placeholders.id,
sample_template_with_placeholders.service_id,
)
create_content_for_notification(
template, {"name": "Bobby", "Additional placeholder": "Data"}
)
create_content_for_notification(template, {'name': 'Bobby', 'Additional placeholder': 'Data'})
@freeze_time("2016-01-01 11:09:00.061258")
def test_persist_notification_creates_and_save_to_db(sample_template, sample_api_key, sample_job):
def test_persist_notification_creates_and_save_to_db(
sample_template, sample_api_key, sample_job
):
assert Notification.query.count() == 0
assert NotificationHistory.query.count() == 0
notification = persist_notification(
template_id=sample_template.id,
template_version=sample_template.version,
recipient='+447111111111',
recipient="+447111111111",
service=sample_template.service,
personalisation={},
notification_type='sms',
notification_type="sms",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
job_id=sample_job.id,
job_row_number=100,
reference="ref",
reply_to_text=sample_template.service.get_default_sms_sender())
reply_to_text=sample_template.service.get_default_sms_sender(),
)
assert Notification.query.get(notification.id) is not None
@@ -95,21 +108,26 @@ def test_persist_notification_creates_and_save_to_db(sample_template, sample_api
assert notification_from_db.reference == notification.reference
assert notification_from_db.client_reference == notification.client_reference
assert notification_from_db.created_by_id == notification.created_by_id
assert notification_from_db.reply_to_text == sample_template.service.get_default_sms_sender()
assert (
notification_from_db.reply_to_text
== sample_template.service.get_default_sms_sender()
)
def test_persist_notification_throws_exception_when_missing_template(sample_api_key):
assert Notification.query.count() == 0
assert NotificationHistory.query.count() == 0
with pytest.raises(SQLAlchemyError):
persist_notification(template_id=None,
template_version=None,
recipient='+447111111111',
service=sample_api_key.service,
personalisation=None,
notification_type='sms',
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type)
persist_notification(
template_id=None,
template_version=None,
recipient="+447111111111",
service=sample_api_key.service,
personalisation=None,
notification_type="sms",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
)
assert Notification.query.count() == 0
assert NotificationHistory.query.count() == 0
@@ -123,10 +141,10 @@ def test_persist_notification_with_optionals(sample_job, sample_api_key):
persist_notification(
template_id=sample_job.template.id,
template_version=sample_job.template.version,
recipient='+12028675309',
recipient="+12028675309",
service=sample_job.service,
personalisation=None,
notification_type='sms',
notification_type="sms",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
created_at=created_at,
@@ -134,7 +152,7 @@ def test_persist_notification_with_optionals(sample_job, sample_api_key):
job_row_number=10,
client_reference="ref from client",
notification_id=n_id,
created_by_id=sample_job.created_by_id
created_by_id=sample_job.created_by_id,
)
assert Notification.query.count() == 1
assert NotificationHistory.query.count() == 0
@@ -147,43 +165,47 @@ def test_persist_notification_with_optionals(sample_job, sample_api_key):
assert persisted_notification.client_reference == "ref from client"
assert persisted_notification.reference is None
assert persisted_notification.international is False
assert persisted_notification.phone_prefix == '1'
assert persisted_notification.phone_prefix == "1"
assert persisted_notification.rate_multiplier == 1
assert persisted_notification.created_by_id == sample_job.created_by_id
assert not persisted_notification.reply_to_text
def test_persist_notification_cache_is_not_incremented_on_failure_to_create_notification(
notify_api, sample_api_key, mocker
notify_api, sample_api_key, mocker
):
mocked_redis = mocker.patch('app.redis_store.incr')
mocked_redis = mocker.patch("app.redis_store.incr")
with pytest.raises(SQLAlchemyError):
persist_notification(template_id=None,
template_version=None,
recipient='+447111111111',
service=sample_api_key.service,
personalisation=None,
notification_type='sms',
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type)
persist_notification(
template_id=None,
template_version=None,
recipient="+447111111111",
service=sample_api_key.service,
personalisation=None,
notification_type="sms",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
)
mocked_redis.assert_not_called()
def test_persist_notification_does_not_increment_cache_if_test_key(
notify_api, sample_template, sample_job, mocker, sample_test_api_key
notify_api, sample_template, sample_job, mocker, sample_test_api_key
):
daily_limit_cache = mocker.patch('app.notifications.process_notifications.redis_store.incr')
daily_limit_cache = mocker.patch(
"app.notifications.process_notifications.redis_store.incr"
)
assert Notification.query.count() == 0
assert NotificationHistory.query.count() == 0
with set_config(notify_api, 'REDIS_ENABLED', True):
with set_config(notify_api, "REDIS_ENABLED", True):
persist_notification(
template_id=sample_template.id,
template_version=sample_template.version,
recipient='+447111111111',
recipient="+447111111111",
service=sample_template.service,
personalisation={},
notification_type='sms',
notification_type="sms",
api_key_id=sample_test_api_key.id,
key_type=sample_test_api_key.key_type,
job_id=sample_job.id,
@@ -196,79 +218,157 @@ def test_persist_notification_does_not_increment_cache_if_test_key(
assert not daily_limit_cache.called
@pytest.mark.parametrize('restricted_service', [True, False])
@pytest.mark.parametrize("restricted_service", [True, False])
@freeze_time("2016-01-01 11:09:00.061258")
def test_persist_notification_increments_cache_for_trial_or_live_service(
notify_api, notify_db_session, mocker, restricted_service
notify_api, notify_db_session, mocker, restricted_service
):
service = create_service(restricted=restricted_service)
template = create_template(service=service)
api_key = create_api_key(service=service)
mocker.patch('app.notifications.process_notifications.redis_store.get', return_value=1)
mock_incr = mocker.patch('app.notifications.process_notifications.redis_store.incr')
with set_config(notify_api, 'REDIS_ENABLED', True):
mocker.patch(
"app.notifications.process_notifications.redis_store.get", return_value=1
)
mock_incr = mocker.patch("app.notifications.process_notifications.redis_store.incr")
with set_config(notify_api, "REDIS_ENABLED", True):
persist_notification(
template_id=template.id,
template_version=template.version,
recipient='+447111111122',
recipient="+447111111122",
service=template.service,
personalisation={},
notification_type='sms',
notification_type="sms",
api_key_id=api_key.id,
key_type=api_key.key_type,
reference="ref2")
reference="ref2",
)
assert mock_incr.call_count == 1
mock_incr.assert_has_calls([
# call(str(service.id) + "-2016-01-01-count", ),
call("2016-01-01-total", )
])
mock_incr.assert_has_calls(
[
# call(str(service.id) + "-2016-01-01-count", ),
call(
"2016-01-01-total",
)
]
)
@pytest.mark.parametrize('restricted_service', [True, False])
@pytest.mark.parametrize("restricted_service", [True, False])
@freeze_time("2016-01-01 11:09:00.061258")
def test_persist_notification_sets_daily_limit_cache_if_one_does_not_exists(
notify_api, notify_db_session, mocker, restricted_service
notify_api, notify_db_session, mocker, restricted_service
):
service = create_service(restricted=restricted_service)
template = create_template(service=service)
api_key = create_api_key(service=service)
mocker.patch('app.notifications.process_notifications.redis_store.get', return_value=None)
mock_set = mocker.patch('app.notifications.process_notifications.redis_store.set')
with set_config(notify_api, 'REDIS_ENABLED', True):
mocker.patch(
"app.notifications.process_notifications.redis_store.get", return_value=None
)
mock_set = mocker.patch("app.notifications.process_notifications.redis_store.set")
with set_config(notify_api, "REDIS_ENABLED", True):
persist_notification(
template_id=template.id,
template_version=template.version,
recipient='+447111111122',
recipient="+447111111122",
service=template.service,
personalisation={},
notification_type='sms',
notification_type="sms",
api_key_id=api_key.id,
key_type=api_key.key_type,
reference="ref2")
reference="ref2",
)
assert mock_set.call_count == 1
mock_set.assert_has_calls([
# call(str(service.id) + "-2016-01-01-count", 1, ex=86400),
call("2016-01-01-total", 1, ex=86400)
])
mock_set.assert_has_calls(
[
# call(str(service.id) + "-2016-01-01-count", 1, ex=86400),
call("2016-01-01-total", 1, ex=86400)
]
)
@pytest.mark.parametrize((
'research_mode, requested_queue, notification_type, key_type, expected_queue, expected_task'
), [
(True, None, 'sms', 'normal', 'research-mode-tasks', 'provider_tasks.deliver_sms'),
(True, None, 'email', 'normal', 'research-mode-tasks', 'provider_tasks.deliver_email'),
(True, None, 'email', 'team', 'research-mode-tasks', 'provider_tasks.deliver_email'),
(False, None, 'sms', 'normal', 'send-sms-tasks', 'provider_tasks.deliver_sms'),
(False, None, 'email', 'normal', 'send-email-tasks', 'provider_tasks.deliver_email'),
(False, None, 'sms', 'team', 'send-sms-tasks', 'provider_tasks.deliver_sms'),
(False, None, 'sms', 'test', 'research-mode-tasks', 'provider_tasks.deliver_sms'),
(True, 'notify-internal-tasks', 'email', 'normal', 'research-mode-tasks', 'provider_tasks.deliver_email'),
(False, 'notify-internal-tasks', 'sms', 'normal', 'notify-internal-tasks', 'provider_tasks.deliver_sms'),
(False, 'notify-internal-tasks', 'email', 'normal', 'notify-internal-tasks', 'provider_tasks.deliver_email'),
(False, 'notify-internal-tasks', 'sms', 'test', 'research-mode-tasks', 'provider_tasks.deliver_sms'),
])
@pytest.mark.parametrize(
(
"research_mode, requested_queue, notification_type, key_type, expected_queue, expected_task"
),
[
(
True,
None,
"sms",
"normal",
"research-mode-tasks",
"provider_tasks.deliver_sms",
),
(
True,
None,
"email",
"normal",
"research-mode-tasks",
"provider_tasks.deliver_email",
),
(
True,
None,
"email",
"team",
"research-mode-tasks",
"provider_tasks.deliver_email",
),
(False, None, "sms", "normal", "send-sms-tasks", "provider_tasks.deliver_sms"),
(
False,
None,
"email",
"normal",
"send-email-tasks",
"provider_tasks.deliver_email",
),
(False, None, "sms", "team", "send-sms-tasks", "provider_tasks.deliver_sms"),
(
False,
None,
"sms",
"test",
"research-mode-tasks",
"provider_tasks.deliver_sms",
),
(
True,
"notify-internal-tasks",
"email",
"normal",
"research-mode-tasks",
"provider_tasks.deliver_email",
),
(
False,
"notify-internal-tasks",
"sms",
"normal",
"notify-internal-tasks",
"provider_tasks.deliver_sms",
),
(
False,
"notify-internal-tasks",
"email",
"normal",
"notify-internal-tasks",
"provider_tasks.deliver_email",
),
(
False,
"notify-internal-tasks",
"sms",
"test",
"research-mode-tasks",
"provider_tasks.deliver_sms",
),
],
)
def test_send_notification_to_queue(
notify_db_session,
research_mode,
@@ -279,8 +379,10 @@ def test_send_notification_to_queue(
expected_task,
mocker,
):
mocked = mocker.patch('app.celery.{}.apply_async'.format(expected_task))
Notification = namedtuple('Notification', ['id', 'key_type', 'notification_type', 'created_at'])
mocked = mocker.patch("app.celery.{}.apply_async".format(expected_task))
Notification = namedtuple(
"Notification", ["id", "key_type", "notification_type", "created_at"]
)
notification = Notification(
id=uuid.uuid4(),
key_type=key_type,
@@ -288,33 +390,45 @@ def test_send_notification_to_queue(
created_at=datetime.datetime(2016, 11, 11, 16, 8, 18),
)
send_notification_to_queue(notification=notification, research_mode=research_mode, queue=requested_queue)
send_notification_to_queue(
notification=notification, research_mode=research_mode, queue=requested_queue
)
mocked.assert_called_once_with([str(notification.id)], queue=expected_queue)
def test_send_notification_to_queue_throws_exception_deletes_notification(sample_notification, mocker):
mocked = mocker.patch('app.celery.provider_tasks.deliver_sms.apply_async', side_effect=Boto3Error("EXPECTED"))
def test_send_notification_to_queue_throws_exception_deletes_notification(
sample_notification, mocker
):
mocked = mocker.patch(
"app.celery.provider_tasks.deliver_sms.apply_async",
side_effect=Boto3Error("EXPECTED"),
)
with pytest.raises(Boto3Error):
send_notification_to_queue(sample_notification, False)
mocked.assert_called_once_with([(str(sample_notification.id))], queue='send-sms-tasks')
mocked.assert_called_once_with(
[(str(sample_notification.id))], queue="send-sms-tasks"
)
assert Notification.query.count() == 0
assert NotificationHistory.query.count() == 0
@pytest.mark.parametrize("to_address, notification_type, expected", [
("+12028675000", "sms", True),
("+12028675111", "sms", True),
("+12028675222", "sms", True),
("2028675000", "sms", True),
("2028675111", "sms", True),
("simulate-delivered@notifications.service.gov.uk", "email", True),
("simulate-delivered-2@notifications.service.gov.uk", "email", True),
("simulate-delivered-3@notifications.service.gov.uk", "email", True),
("2028675309", "sms", False),
("valid_email@test.com", "email", False)
])
@pytest.mark.parametrize(
"to_address, notification_type, expected",
[
("+12028675000", "sms", True),
("+12028675111", "sms", True),
("+12028675222", "sms", True),
("2028675000", "sms", True),
("2028675111", "sms", True),
("simulate-delivered@notifications.service.gov.uk", "email", True),
("simulate-delivered-2@notifications.service.gov.uk", "email", True),
("simulate-delivered-3@notifications.service.gov.uk", "email", True),
("2028675309", "sms", False),
("valid_email@test.com", "email", False),
],
)
def test_simulated_recipient(notify_api, to_address, notification_type, expected):
"""
The values where the expected = 'research-mode' are listed in the config['SIMULATED_EMAIL_ADDRESSES']
@@ -328,7 +442,7 @@ def test_simulated_recipient(notify_api, to_address, notification_type, expected
"""
formatted_address = None
if notification_type == 'email':
if notification_type == "email":
formatted_address = validate_and_format_email_address(to_address)
else:
formatted_address = validate_and_format_phone_number(to_address)
@@ -338,11 +452,14 @@ def test_simulated_recipient(notify_api, to_address, notification_type, expected
assert is_simulated_address == expected
@pytest.mark.parametrize('recipient, expected_international, expected_prefix, expected_units', [
('+447900900123', True, '44', 1), # UK
('+73122345678', True, '7', 1), # Russia
('+360623400400', True, '36', 1), # Hungary
('2028675309', False, '1', 1)] # USA
@pytest.mark.parametrize(
"recipient, expected_international, expected_prefix, expected_units",
[
("+447900900123", True, "44", 1), # UK
("+73122345678", True, "7", 1), # Russia
("+360623400400", True, "36", 1), # Hungary
("2028675309", False, "1", 1),
], # USA
)
def test_persist_notification_with_international_info_stores_correct_info(
sample_job,
@@ -351,7 +468,7 @@ def test_persist_notification_with_international_info_stores_correct_info(
recipient,
expected_international,
expected_prefix,
expected_units
expected_units,
):
persist_notification(
template_id=sample_job.template.id,
@@ -359,12 +476,12 @@ def test_persist_notification_with_international_info_stores_correct_info(
recipient=recipient,
service=sample_job.service,
personalisation=None,
notification_type='sms',
notification_type="sms",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
job_id=sample_job.id,
job_row_number=10,
client_reference="ref from client"
client_reference="ref from client",
)
persisted_notification = Notification.query.all()[0]
@@ -374,22 +491,20 @@ def test_persist_notification_with_international_info_stores_correct_info(
def test_persist_notification_with_international_info_does_not_store_for_email(
sample_job,
sample_api_key,
mocker
sample_job, sample_api_key, mocker
):
persist_notification(
template_id=sample_job.template.id,
template_version=sample_job.template.version,
recipient='foo@bar.com',
recipient="foo@bar.com",
service=sample_job.service,
personalisation=None,
notification_type='email',
notification_type="email",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
job_id=sample_job.id,
job_row_number=10,
client_reference="ref from client"
client_reference="ref from client",
)
persisted_notification = Notification.query.all()[0]
@@ -398,20 +513,19 @@ def test_persist_notification_with_international_info_does_not_store_for_email(
assert persisted_notification.rate_multiplier is None
@pytest.mark.parametrize('recipient, expected_recipient_normalised', [
('+4407900900123', '+447900900123'),
('202-867-5309', '+12028675309'),
('1 202-867-5309', '+12028675309'),
('+1 (202) 867-5309', '+12028675309'),
('(202) 867-5309', '+12028675309'),
('2028675309', '+12028675309')
])
@pytest.mark.parametrize(
"recipient, expected_recipient_normalised",
[
("+4407900900123", "+447900900123"),
("202-867-5309", "+12028675309"),
("1 202-867-5309", "+12028675309"),
("+1 (202) 867-5309", "+12028675309"),
("(202) 867-5309", "+12028675309"),
("2028675309", "+12028675309"),
],
)
def test_persist_sms_notification_stores_normalised_number(
sample_job,
sample_api_key,
mocker,
recipient,
expected_recipient_normalised
sample_job, sample_api_key, mocker, recipient, expected_recipient_normalised
):
persist_notification(
template_id=sample_job.template.id,
@@ -419,7 +533,7 @@ def test_persist_sms_notification_stores_normalised_number(
recipient=recipient,
service=sample_job.service,
personalisation=None,
notification_type='sms',
notification_type="sms",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
job_id=sample_job.id,
@@ -430,17 +544,12 @@ def test_persist_sms_notification_stores_normalised_number(
assert persisted_notification.normalised_to == expected_recipient_normalised
@pytest.mark.parametrize('recipient, expected_recipient_normalised', [
('FOO@bar.com', 'foo@bar.com'),
('BAR@foo.com', 'bar@foo.com')
])
@pytest.mark.parametrize(
"recipient, expected_recipient_normalised",
[("FOO@bar.com", "foo@bar.com"), ("BAR@foo.com", "bar@foo.com")],
)
def test_persist_email_notification_stores_normalised_email(
sample_job,
sample_api_key,
mocker,
recipient,
expected_recipient_normalised
sample_job, sample_api_key, mocker, recipient, expected_recipient_normalised
):
persist_notification(
template_id=sample_job.template.id,
@@ -448,7 +557,7 @@ def test_persist_email_notification_stores_normalised_email(
recipient=recipient,
service=sample_job.service,
personalisation=None,
notification_type='email',
notification_type="email",
api_key_id=sample_api_key.id,
key_type=sample_api_key.key_type,
job_id=sample_job.id,
@@ -459,12 +568,10 @@ def test_persist_email_notification_stores_normalised_email(
assert persisted_notification.normalised_to == expected_recipient_normalised
def test_persist_notification_with_billable_units_stores_correct_info(
mocker
):
def test_persist_notification_with_billable_units_stores_correct_info(mocker):
service = create_service(service_permissions=[SMS_TYPE])
template = create_template(service, template_type=SMS_TYPE)
mocker.patch('app.dao.templates_dao.dao_get_template_by_id', return_value=template)
mocker.patch("app.dao.templates_dao.dao_get_template_by_id", return_value=template)
persist_notification(
template_id=template.id,
template_version=template.version,

View File

@@ -20,60 +20,68 @@ from tests.app.db import (
from tests.conftest import set_config
def sns_post(client, data, auth=True, password='testkey'):
def sns_post(client, data, auth=True, password="testkey"):
headers = [
('Content-Type', 'application/json'),
("Content-Type", "application/json"),
]
if auth:
auth_value = b64encode(f"notify:{password}".encode())
headers.append(('Authorization', f"Basic {auth_value}"))
headers.append(("Authorization", f"Basic {auth_value}"))
return client.post(
path='/notifications/sms/receive/sns',
data={"Message": data},
headers=headers
path="/notifications/sms/receive/sns", data={"Message": data}, headers=headers
)
@pytest.mark.skip(reason="Need to implement SNS tests. Body here mostly from MMG")
def test_receive_notification_returns_received_to_sns(client, mocker, sample_service_full_permissions):
mocked = mocker.patch("app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async")
prom_counter_labels_mock = mocker.patch('app.notifications.receive_notifications.INBOUND_SMS_COUNTER.labels')
def test_receive_notification_returns_received_to_sns(
client, mocker, sample_service_full_permissions
):
mocked = mocker.patch(
"app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async"
)
prom_counter_labels_mock = mocker.patch(
"app.notifications.receive_notifications.INBOUND_SMS_COUNTER.labels"
)
data = {
"originationNumber": "+12028675309",
"destinationNumber": sample_service_full_permissions.get_inbound_number(),
"messageKeyword": "JOIN",
"messageBody": "EXAMPLE",
"inboundMessageId": "cae173d2-66b9-564c-8309-21f858e9fb84",
"previousPublishedMessageId": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
"previousPublishedMessageId": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
}
response = sns_post(client, data)
assert response.status_code == 200
result = json.loads(response.get_data(as_text=True))
assert result['result'] == 'success'
assert result["result"] == "success"
prom_counter_labels_mock.assert_called_once_with("sns")
prom_counter_labels_mock.return_value.inc.assert_called_once_with()
inbound_sms_id = InboundSms.query.all()[0].id
mocked.assert_called_once_with(
[str(inbound_sms_id), str(sample_service_full_permissions.id)], queue="notify-internal-tasks")
[str(inbound_sms_id), str(sample_service_full_permissions.id)],
queue="notify-internal-tasks",
)
# TODO: figure out why creating a service first causes a db error
@pytest.mark.parametrize('permissions', [
[SMS_TYPE],
[INBOUND_SMS_TYPE],
])
@pytest.mark.parametrize(
"permissions",
[
[SMS_TYPE],
[INBOUND_SMS_TYPE],
],
)
def test_receive_notification_from_sns_without_permissions_does_not_persist(
client,
mocker,
notify_db_session,
permissions
client, mocker, notify_db_session, permissions
):
mocked = mocker.patch("app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async")
mocked = mocker.patch(
"app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async"
)
# create_service_with_inbound_number(inbound_number='12025550104', service_permissions=permissions)
data = {
"ID": "1234",
@@ -82,13 +90,13 @@ def test_receive_notification_from_sns_without_permissions_does_not_persist(
"Trigger": "Trigger?",
"Number": "testing",
"Channel": "SMS",
"DateRecieved": "2012-06-27 12:33:00"
"DateRecieved": "2012-06-27 12:33:00",
}
response = sns_post(client, data)
assert response.status_code == 200
parsed_response = json.loads(response.get_data(as_text=True))
assert parsed_response['result'] == 'success'
assert parsed_response["result"] == "success"
assert InboundSms.query.count() == 0
assert mocked.called is False
@@ -96,13 +104,19 @@ def test_receive_notification_from_sns_without_permissions_does_not_persist(
@pytest.mark.skip(reason="Need to implement inbound SNS tests. Body here from MMG")
def test_receive_notification_without_permissions_does_not_create_inbound_even_with_inbound_number_set(
client, mocker, sample_service):
inbound_number = create_inbound_number('1', service_id=sample_service.id, active=True)
client, mocker, sample_service
):
inbound_number = create_inbound_number(
"1", service_id=sample_service.id, active=True
)
mocked_send_inbound_sms = mocker.patch(
"app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async")
"app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async"
)
mocked_has_permissions = mocker.patch(
"app.notifications.receive_notifications.has_inbound_sms_permissions", return_value=False)
"app.notifications.receive_notifications.has_inbound_sms_permissions",
return_value=False,
)
data = {
"ID": "1234",
@@ -111,7 +125,7 @@ def test_receive_notification_without_permissions_does_not_create_inbound_even_w
"Trigger": "Trigger?",
"Number": inbound_number.number,
"Channel": "SMS",
"DateRecieved": "2012-06-27 12:33:00"
"DateRecieved": "2012-06-27 12:33:00",
}
response = sns_post(client, data)
@@ -122,42 +136,50 @@ def test_receive_notification_without_permissions_does_not_create_inbound_even_w
mocked_send_inbound_sms.assert_not_called()
@pytest.mark.parametrize('permissions,expected_response', [
([SMS_TYPE, INBOUND_SMS_TYPE], True),
([INBOUND_SMS_TYPE], False),
([SMS_TYPE], False),
])
def test_check_permissions_for_inbound_sms(notify_db_session, permissions, expected_response):
@pytest.mark.parametrize(
"permissions,expected_response",
[
([SMS_TYPE, INBOUND_SMS_TYPE], True),
([INBOUND_SMS_TYPE], False),
([SMS_TYPE], False),
],
)
def test_check_permissions_for_inbound_sms(
notify_db_session, permissions, expected_response
):
service = create_service(service_permissions=permissions)
assert has_inbound_sms_permissions(service.permissions) is expected_response
@pytest.mark.parametrize('raw, expected', [
(
'😬',
'😬',
),
(
'1\\n2',
'1\n2',
),
(
'\\\'"\\\'',
'\'"\'',
),
(
"""
@pytest.mark.parametrize(
"raw, expected",
[
(
"😬",
"😬",
),
(
"1\\n2",
"1\n2",
),
(
"\\'\"\\'",
"'\"'",
),
(
"""
""",
"""
"""
""",
),
(
'\x79 \\x79 \\\\x79', # we should never see the middle one
'y y \\x79',
),
])
),
(
"\x79 \\x79 \\\\x79", # we should never see the middle one
"y y \\x79",
),
],
)
def test_unescape_string(raw, expected):
assert unescape_string(raw) == expected
@@ -165,37 +187,11 @@ def test_unescape_string(raw, expected):
@pytest.mark.skip(reason="Need to implement inbound SNS tests. Body here from MMG")
def test_create_inbound_sns_sms_object(sample_service_full_permissions):
data = {
'Message': 'hello+there+%F0%9F%93%A9',
'Number': sample_service_full_permissions.get_inbound_number(),
'MSISDN': '07700 900 001',
'DateRecieved': '2017-01-02+03%3A04%3A05',
'ID': 'bar',
}
inbound_sms = create_inbound_sms_object(sample_service_full_permissions, data["Message"],
data["MSISDN"], data["ID"], data["DateRecieved"], "sns")
assert inbound_sms.service_id == sample_service_full_permissions.id
assert inbound_sms.notify_number == sample_service_full_permissions.get_inbound_number()
assert inbound_sms.user_number == '447700900001'
assert inbound_sms.provider_date == datetime(2017, 1, 2, 3, 4, 5)
assert inbound_sms.provider_reference == 'bar'
assert inbound_sms._content != 'hello there 📩'
assert inbound_sms.content == 'hello there 📩'
assert inbound_sms.provider == 'sns'
@pytest.mark.skip(reason="Need to implement inbound SNS tests. Body here from MMG")
def test_create_inbound_sns_sms_object_uses_inbound_number_if_set(sample_service_full_permissions):
sample_service_full_permissions.sms_sender = 'foo'
inbound_number = sample_service_full_permissions.get_inbound_number()
data = {
'Message': 'hello+there+%F0%9F%93%A9',
'Number': sample_service_full_permissions.get_inbound_number(),
'MSISDN': '07700 900 001',
'DateRecieved': '2017-01-02+03%3A04%3A05',
'ID': 'bar',
"Message": "hello+there+%F0%9F%93%A9",
"Number": sample_service_full_permissions.get_inbound_number(),
"MSISDN": "07700 900 001",
"DateRecieved": "2017-01-02+03%3A04%3A05",
"ID": "bar",
}
inbound_sms = create_inbound_sms_object(
@@ -204,7 +200,44 @@ def test_create_inbound_sns_sms_object_uses_inbound_number_if_set(sample_service
data["MSISDN"],
data["ID"],
data["DateRecieved"],
"sns"
"sns",
)
assert inbound_sms.service_id == sample_service_full_permissions.id
assert (
inbound_sms.notify_number
== sample_service_full_permissions.get_inbound_number()
)
assert inbound_sms.user_number == "447700900001"
assert inbound_sms.provider_date == datetime(2017, 1, 2, 3, 4, 5)
assert inbound_sms.provider_reference == "bar"
assert inbound_sms._content != "hello there 📩"
assert inbound_sms.content == "hello there 📩"
assert inbound_sms.provider == "sns"
@pytest.mark.skip(reason="Need to implement inbound SNS tests. Body here from MMG")
def test_create_inbound_sns_sms_object_uses_inbound_number_if_set(
sample_service_full_permissions,
):
sample_service_full_permissions.sms_sender = "foo"
inbound_number = sample_service_full_permissions.get_inbound_number()
data = {
"Message": "hello+there+%F0%9F%93%A9",
"Number": sample_service_full_permissions.get_inbound_number(),
"MSISDN": "07700 900 001",
"DateRecieved": "2017-01-02+03%3A04%3A05",
"ID": "bar",
}
inbound_sms = create_inbound_sms_object(
sample_service_full_permissions,
data["Message"],
data["MSISDN"],
data["ID"],
data["DateRecieved"],
"sns",
)
assert inbound_sms.service_id == sample_service_full_permissions.id
@@ -212,50 +245,65 @@ def test_create_inbound_sns_sms_object_uses_inbound_number_if_set(sample_service
@pytest.mark.skip(reason="Need to implement inbound SNS tests. Body here from MMG")
@pytest.mark.parametrize('notify_number', ['foo', 'baz'], ids=['two_matching_services', 'no_matching_services'])
def test_receive_notification_error_if_not_single_matching_service(client, notify_db_session, notify_number):
@pytest.mark.parametrize(
"notify_number",
["foo", "baz"],
ids=["two_matching_services", "no_matching_services"],
)
def test_receive_notification_error_if_not_single_matching_service(
client, notify_db_session, notify_number
):
create_service_with_inbound_number(
inbound_number='dog',
service_name='a',
service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE]
inbound_number="dog",
service_name="a",
service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE],
)
create_service_with_inbound_number(
inbound_number='bar',
service_name='b',
service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE]
inbound_number="bar",
service_name="b",
service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE],
)
data = {
'Message': 'hello',
'Number': notify_number,
'MSISDN': '7700900001',
'DateRecieved': '2017-01-02 03:04:05',
'ID': 'bar',
"Message": "hello",
"Number": notify_number,
"MSISDN": "7700900001",
"DateRecieved": "2017-01-02 03:04:05",
"ID": "bar",
}
response = sns_post(client, data)
# we still return 'RECEIVED' to MMG
assert response.status_code == 200
assert response.get_data(as_text=True) == 'RECEIVED'
assert response.get_data(as_text=True) == "RECEIVED"
assert InboundSms.query.count() == 0
@pytest.mark.skip(reason="Need to implement inbound SNS tests. Body here from MMG")
@pytest.mark.parametrize("auth, keys, status_code", [
["testkey", ["testkey"], 200],
["", ["testkey"], 401],
["wrong", ["testkey"], 403],
["testkey1", ["testkey1", "testkey2"], 200],
["testkey2", ["testkey1", "testkey2"], 200],
["wrong", ["testkey1", "testkey2"], 403],
["", [], 401],
["testkey", [], 403],
])
def test_sns_inbound_sms_auth(notify_db_session, notify_api, client, mocker, auth, keys, status_code):
mocker.patch("app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async")
@pytest.mark.parametrize(
"auth, keys, status_code",
[
["testkey", ["testkey"], 200],
["", ["testkey"], 401],
["wrong", ["testkey"], 403],
["testkey1", ["testkey1", "testkey2"], 200],
["testkey2", ["testkey1", "testkey2"], 200],
["wrong", ["testkey1", "testkey2"], 403],
["", [], 401],
["testkey", [], 403],
],
)
def test_sns_inbound_sms_auth(
notify_db_session, notify_api, client, mocker, auth, keys, status_code
):
mocker.patch(
"app.notifications.receive_notifications.tasks.send_inbound_sms_to_service.apply_async"
)
create_service_with_inbound_number(
service_name='b', inbound_number='07111111111', service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE]
service_name="b",
inbound_number="07111111111",
service_permissions=[EMAIL_TYPE, SMS_TYPE, INBOUND_SMS_TYPE],
)
data = {
@@ -265,42 +313,46 @@ def test_sns_inbound_sms_auth(notify_db_session, notify_api, client, mocker, aut
"Trigger": "Trigger?",
"Number": "testing",
"Channel": "SMS",
"DateRecieved": "2012-06-27 12:33:00"
"DateRecieved": "2012-06-27 12:33:00",
}
with set_config(notify_api, 'MMG_INBOUND_SMS_AUTH', keys):
with set_config(notify_api, "MMG_INBOUND_SMS_AUTH", keys):
response = sns_post(client, data, auth=bool(auth), password=auth)
assert response.status_code == status_code
def test_create_inbound_sms_object_works_with_alphanumeric_sender(sample_service_full_permissions):
def test_create_inbound_sms_object_works_with_alphanumeric_sender(
sample_service_full_permissions,
):
data = {
'Message': 'hello',
'Number': sample_service_full_permissions.get_inbound_number(),
'MSISDN': 'ALPHANUM3R1C',
'DateRecieved': '2017-01-02+03%3A04%3A05',
'ID': 'bar',
"Message": "hello",
"Number": sample_service_full_permissions.get_inbound_number(),
"MSISDN": "ALPHANUM3R1C",
"DateRecieved": "2017-01-02+03%3A04%3A05",
"ID": "bar",
}
inbound_sms = create_inbound_sms_object(
service=sample_service_full_permissions,
content=data["Message"],
from_number='ALPHANUM3R1C',
provider_ref='foo',
from_number="ALPHANUM3R1C",
provider_ref="foo",
date_received=None,
provider_name="mmg"
provider_name="mmg",
)
assert inbound_sms.user_number == 'ALPHANUM3R1C'
assert inbound_sms.user_number == "ALPHANUM3R1C"
@mock.patch('app.notifications.receive_notifications.dao_fetch_service_by_inbound_number')
@mock.patch(
"app.notifications.receive_notifications.dao_fetch_service_by_inbound_number"
)
def test_fetch_potential_service_cant_find_it(mock_dao):
mock_dao.return_value = None
found_service = fetch_potential_service(234, 'sns')
found_service = fetch_potential_service(234, "sns")
assert found_service is False
# Permissions will not be set so it will still return false
mock_dao.return_value = create_service()
found_service = fetch_potential_service(234, 'sns')
found_service = fetch_potential_service(234, "sns")
assert found_service is False

View File

@@ -13,106 +13,118 @@ from tests import create_service_authorization_header
from tests.app.db import create_api_key, create_notification
@pytest.mark.parametrize('type', ('email', 'sms'))
@pytest.mark.parametrize("type", ("email", "sms"))
def test_get_notification_by_id(
client,
sample_notification,
sample_email_notification,
type
client, sample_notification, sample_email_notification, type
):
if type == 'email':
if type == "email":
notification_to_get = sample_email_notification
if type == 'sms':
if type == "sms":
notification_to_get = sample_notification
auth_header = create_service_authorization_header(service_id=notification_to_get.service_id)
auth_header = create_service_authorization_header(
service_id=notification_to_get.service_id
)
response = client.get(
'/notifications/{}'.format(notification_to_get.id),
headers=[auth_header])
"/notifications/{}".format(notification_to_get.id), headers=[auth_header]
)
assert response.status_code == 200
notification = json.loads(response.get_data(as_text=True))['data']['notification']
assert notification['status'] == 'created'
assert notification['template'] == {
'id': str(notification_to_get.template.id),
'name': notification_to_get.template.name,
'template_type': notification_to_get.template.template_type,
'version': 1
notification = json.loads(response.get_data(as_text=True))["data"]["notification"]
assert notification["status"] == "created"
assert notification["template"] == {
"id": str(notification_to_get.template.id),
"name": notification_to_get.template.name,
"template_type": notification_to_get.template.template_type,
"version": 1,
}
assert notification['to'] == notification_to_get.to
assert notification['service'] == str(notification_to_get.service_id)
assert notification['body'] == notification_to_get.template.content
assert notification.get('subject', None) == notification_to_get.subject
assert notification["to"] == notification_to_get.to
assert notification["service"] == str(notification_to_get.service_id)
assert notification["body"] == notification_to_get.template.content
assert notification.get("subject", None) == notification_to_get.subject
@pytest.mark.parametrize("id", ["1234-badly-formatted-id-7890", "0"])
@pytest.mark.parametrize('type', ('email', 'sms'))
def test_get_notification_by_invalid_id(client, sample_notification, sample_email_notification, id, type):
if type == 'email':
@pytest.mark.parametrize("type", ("email", "sms"))
def test_get_notification_by_invalid_id(
client, sample_notification, sample_email_notification, id, type
):
if type == "email":
notification_to_get = sample_email_notification
if type == 'sms':
if type == "sms":
notification_to_get = sample_notification
auth_header = create_service_authorization_header(service_id=notification_to_get.service_id)
auth_header = create_service_authorization_header(
service_id=notification_to_get.service_id
)
response = client.get(
'/notifications/{}'.format(id),
headers=[auth_header])
response = client.get("/notifications/{}".format(id), headers=[auth_header])
assert response.status_code == 405
def test_get_notifications_empty_result(client, sample_api_key):
auth_header = create_service_authorization_header(service_id=sample_api_key.service_id)
auth_header = create_service_authorization_header(
service_id=sample_api_key.service_id
)
response = client.get(
path='/notifications/{}'.format(uuid.uuid4()),
headers=[auth_header])
path="/notifications/{}".format(uuid.uuid4()), headers=[auth_header]
)
notification = json.loads(response.get_data(as_text=True))
assert notification['result'] == "error"
assert notification['message'] == "No result found"
assert notification["result"] == "error"
assert notification["message"] == "No result found"
assert response.status_code == 404
@pytest.mark.parametrize('api_key_type,notification_key_type', [
(KEY_TYPE_NORMAL, KEY_TYPE_TEAM),
(KEY_TYPE_NORMAL, KEY_TYPE_TEST),
(KEY_TYPE_TEST, KEY_TYPE_NORMAL),
(KEY_TYPE_TEST, KEY_TYPE_TEAM),
(KEY_TYPE_TEAM, KEY_TYPE_NORMAL),
(KEY_TYPE_TEAM, KEY_TYPE_TEST),
])
@pytest.mark.parametrize(
"api_key_type,notification_key_type",
[
(KEY_TYPE_NORMAL, KEY_TYPE_TEAM),
(KEY_TYPE_NORMAL, KEY_TYPE_TEST),
(KEY_TYPE_TEST, KEY_TYPE_NORMAL),
(KEY_TYPE_TEST, KEY_TYPE_TEAM),
(KEY_TYPE_TEAM, KEY_TYPE_NORMAL),
(KEY_TYPE_TEAM, KEY_TYPE_TEST),
],
)
def test_get_notification_from_different_api_key_works(
client,
sample_notification,
api_key_type,
notification_key_type
client, sample_notification, api_key_type, notification_key_type
):
sample_notification.key_type = notification_key_type
api_key = ApiKey(service=sample_notification.service,
name='api_key',
created_by=sample_notification.service.created_by,
key_type=api_key_type)
api_key = ApiKey(
service=sample_notification.service,
name="api_key",
created_by=sample_notification.service.created_by,
key_type=api_key_type,
)
save_model_api_key(api_key)
response = client.get(
path='/notifications/{}'.format(sample_notification.id),
headers=_create_auth_header_from_key(api_key))
path="/notifications/{}".format(sample_notification.id),
headers=_create_auth_header_from_key(api_key),
)
assert response.status_code == 200
@pytest.mark.parametrize('key_type', [KEY_TYPE_NORMAL, KEY_TYPE_TEAM, KEY_TYPE_TEST])
def test_get_notification_from_different_api_key_of_same_type_succeeds(client, sample_notification, key_type):
creation_api_key = ApiKey(service=sample_notification.service,
name='creation_api_key',
created_by=sample_notification.service.created_by,
key_type=key_type)
@pytest.mark.parametrize("key_type", [KEY_TYPE_NORMAL, KEY_TYPE_TEAM, KEY_TYPE_TEST])
def test_get_notification_from_different_api_key_of_same_type_succeeds(
client, sample_notification, key_type
):
creation_api_key = ApiKey(
service=sample_notification.service,
name="creation_api_key",
created_by=sample_notification.service.created_by,
key_type=key_type,
)
save_model_api_key(creation_api_key)
querying_api_key = ApiKey(service=sample_notification.service,
name='querying_api_key',
created_by=sample_notification.service.created_by,
key_type=key_type)
querying_api_key = ApiKey(
service=sample_notification.service,
name="querying_api_key",
created_by=sample_notification.service.created_by,
key_type=key_type,
)
save_model_api_key(querying_api_key)
sample_notification.api_key = creation_api_key
@@ -120,104 +132,104 @@ def test_get_notification_from_different_api_key_of_same_type_succeeds(client, s
dao_update_notification(sample_notification)
response = client.get(
path='/notifications/{}'.format(sample_notification.id),
headers=_create_auth_header_from_key(querying_api_key))
path="/notifications/{}".format(sample_notification.id),
headers=_create_auth_header_from_key(querying_api_key),
)
assert response.status_code == 200
notification = json.loads(response.get_data(as_text=True))['data']['notification']
notification = json.loads(response.get_data(as_text=True))["data"]["notification"]
assert sample_notification.api_key_id != querying_api_key.id
assert notification['id'] == str(sample_notification.id)
assert notification["id"] == str(sample_notification.id)
def test_get_all_notifications(client, sample_notification):
auth_header = create_service_authorization_header(service_id=sample_notification.service_id)
auth_header = create_service_authorization_header(
service_id=sample_notification.service_id
)
response = client.get(
'/notifications',
headers=[auth_header])
response = client.get("/notifications", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert response.status_code == 200
assert notifications['notifications'][0]['status'] == 'created'
assert notifications['notifications'][0]['template'] == {
'id': str(sample_notification.template.id),
'name': sample_notification.template.name,
'template_type': sample_notification.template.template_type,
'version': 1
assert notifications["notifications"][0]["status"] == "created"
assert notifications["notifications"][0]["template"] == {
"id": str(sample_notification.template.id),
"name": sample_notification.template.name,
"template_type": sample_notification.template.template_type,
"version": 1,
}
assert notifications['notifications'][0]['to'] == '+447700900855'
assert notifications['notifications'][0]['service'] == str(sample_notification.service_id)
assert notifications['notifications'][0]['body'] == 'Dear Sir/Madam, Hello. Yours Truly, The Government.'
assert notifications["notifications"][0]["to"] == "+447700900855"
assert notifications["notifications"][0]["service"] == str(
sample_notification.service_id
)
assert (
notifications["notifications"][0]["body"]
== "Dear Sir/Madam, Hello. Yours Truly, The Government."
)
def test_normal_api_key_returns_notifications_created_from_jobs_and_from_api(
client,
sample_template,
sample_api_key,
sample_notification
client, sample_template, sample_api_key, sample_notification
):
api_notification = create_notification(template=sample_template, api_key=sample_api_key)
api_notification = create_notification(
template=sample_template, api_key=sample_api_key
)
response = client.get(
path='/notifications',
headers=_create_auth_header_from_key(sample_api_key))
path="/notifications", headers=_create_auth_header_from_key(sample_api_key)
)
assert response.status_code == 200
notifications = json.loads(response.get_data(as_text=True))['notifications']
notifications = json.loads(response.get_data(as_text=True))["notifications"]
assert len(notifications) == 2
assert set(x['id'] for x in notifications) == {str(sample_notification.id), str(api_notification.id)}
assert set(x["id"] for x in notifications) == {
str(sample_notification.id),
str(api_notification.id),
}
@pytest.mark.parametrize('key_type', [KEY_TYPE_NORMAL, KEY_TYPE_TEAM, KEY_TYPE_TEST])
@pytest.mark.parametrize("key_type", [KEY_TYPE_NORMAL, KEY_TYPE_TEAM, KEY_TYPE_TEST])
def test_get_all_notifications_only_returns_notifications_of_matching_type(
client,
sample_template,
sample_api_key,
sample_test_api_key,
sample_team_api_key,
key_type
key_type,
):
normal_notification = create_notification(
sample_template,
api_key=sample_api_key,
key_type=KEY_TYPE_NORMAL
sample_template, api_key=sample_api_key, key_type=KEY_TYPE_NORMAL
)
team_notification = create_notification(
sample_template,
api_key=sample_team_api_key,
key_type=KEY_TYPE_TEAM
sample_template, api_key=sample_team_api_key, key_type=KEY_TYPE_TEAM
)
test_notification = create_notification(
sample_template,
api_key=sample_test_api_key,
key_type=KEY_TYPE_TEST
sample_template, api_key=sample_test_api_key, key_type=KEY_TYPE_TEST
)
notification_objs = {
KEY_TYPE_NORMAL: normal_notification,
KEY_TYPE_TEAM: team_notification,
KEY_TYPE_TEST: test_notification
KEY_TYPE_TEST: test_notification,
}
response = client.get(
path='/notifications',
headers=_create_auth_header_from_key(notification_objs[key_type].api_key))
path="/notifications",
headers=_create_auth_header_from_key(notification_objs[key_type].api_key),
)
assert response.status_code == 200
notifications = json.loads(response.get_data(as_text=True))['notifications']
notifications = json.loads(response.get_data(as_text=True))["notifications"]
assert len(notifications) == 1
assert notifications[0]['id'] == str(notification_objs[key_type].id)
assert notifications[0]["id"] == str(notification_objs[key_type].id)
@pytest.mark.parametrize('key_type', [KEY_TYPE_NORMAL, KEY_TYPE_TEAM, KEY_TYPE_TEST])
@pytest.mark.parametrize("key_type", [KEY_TYPE_NORMAL, KEY_TYPE_TEAM, KEY_TYPE_TEST])
def test_do_not_return_job_notifications_by_default(
client,
sample_template,
sample_job,
key_type
client, sample_template, sample_job, key_type
):
team_api_key = create_api_key(sample_template.service, KEY_TYPE_TEAM)
normal_api_key = create_api_key(sample_template.service, KEY_TYPE_NORMAL)
@@ -231,25 +243,24 @@ def test_do_not_return_job_notifications_by_default(
notification_objs = {
KEY_TYPE_NORMAL: normal_notification,
KEY_TYPE_TEAM: team_notification,
KEY_TYPE_TEST: test_notification
KEY_TYPE_TEST: test_notification,
}
response = client.get(
path='/notifications',
headers=_create_auth_header_from_key(notification_objs[key_type].api_key))
path="/notifications",
headers=_create_auth_header_from_key(notification_objs[key_type].api_key),
)
assert response.status_code == 200
notifications = json.loads(response.get_data(as_text=True))['notifications']
notifications = json.loads(response.get_data(as_text=True))["notifications"]
assert len(notifications) == 1
assert notifications[0]['id'] == str(notification_objs[key_type].id)
assert notifications[0]["id"] == str(notification_objs[key_type].id)
@pytest.mark.parametrize('key_type', [
(KEY_TYPE_NORMAL, 2),
(KEY_TYPE_TEAM, 1),
(KEY_TYPE_TEST, 1)
])
@pytest.mark.parametrize(
"key_type", [(KEY_TYPE_NORMAL, 2), (KEY_TYPE_TEAM, 1), (KEY_TYPE_TEST, 1)]
)
def test_only_normal_api_keys_can_return_job_notifications(
client,
sample_notification_with_job,
@@ -257,38 +268,33 @@ def test_only_normal_api_keys_can_return_job_notifications(
sample_api_key,
sample_team_api_key,
sample_test_api_key,
key_type
key_type,
):
normal_notification = create_notification(
template=sample_template,
api_key=sample_api_key,
key_type=KEY_TYPE_NORMAL
template=sample_template, api_key=sample_api_key, key_type=KEY_TYPE_NORMAL
)
team_notification = create_notification(
template=sample_template,
api_key=sample_team_api_key,
key_type=KEY_TYPE_TEAM
template=sample_template, api_key=sample_team_api_key, key_type=KEY_TYPE_TEAM
)
test_notification = create_notification(
template=sample_template,
api_key=sample_test_api_key,
key_type=KEY_TYPE_TEST
template=sample_template, api_key=sample_test_api_key, key_type=KEY_TYPE_TEST
)
notification_objs = {
KEY_TYPE_NORMAL: normal_notification,
KEY_TYPE_TEAM: team_notification,
KEY_TYPE_TEST: test_notification
KEY_TYPE_TEST: test_notification,
}
response = client.get(
path='/notifications?include_jobs=true',
headers=_create_auth_header_from_key(notification_objs[key_type[0]].api_key))
path="/notifications?include_jobs=true",
headers=_create_auth_header_from_key(notification_objs[key_type[0]].api_key),
)
assert response.status_code == 200
notifications = json.loads(response.get_data(as_text=True))['notifications']
notifications = json.loads(response.get_data(as_text=True))["notifications"]
assert len(notifications) == key_type[1]
assert notifications[0]['id'] == str(notification_objs[key_type[0]].id)
assert notifications[0]["id"] == str(notification_objs[key_type[0]].id)
def test_get_all_notifications_newest_first(client, sample_email_template):
@@ -296,31 +302,31 @@ def test_get_all_notifications_newest_first(client, sample_email_template):
notification_2 = create_notification(template=sample_email_template)
notification_3 = create_notification(template=sample_email_template)
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications',
headers=[auth_header])
response = client.get("/notifications", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['notifications']) == 3
assert notifications['notifications'][0]['to'] == notification_3.to
assert notifications['notifications'][1]['to'] == notification_2.to
assert notifications['notifications'][2]['to'] == notification_1.to
assert len(notifications["notifications"]) == 3
assert notifications["notifications"][0]["to"] == notification_3.to
assert notifications["notifications"][1]["to"] == notification_2.to
assert notifications["notifications"][2]["to"] == notification_1.to
assert response.status_code == 200
def test_should_reject_invalid_page_param(client, sample_email_template):
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?page=invalid',
headers=[auth_header])
response = client.get("/notifications?page=invalid", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert response.status_code == 400
assert notifications['result'] == 'error'
assert 'Not a valid integer.' in notifications['message']['page']
assert notifications["result"] == "error"
assert "Not a valid integer." in notifications["message"]["page"]
def test_valid_page_size_param(notify_api, sample_email_template):
@@ -328,247 +334,280 @@ def test_valid_page_size_param(notify_api, sample_email_template):
create_notification(sample_email_template)
create_notification(sample_email_template)
with notify_api.test_client() as client:
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?page=1&page_size=1',
headers=[auth_header])
"/notifications?page=1&page_size=1", headers=[auth_header]
)
notifications = json.loads(response.get_data(as_text=True))
assert response.status_code == 200
assert len(notifications['notifications']) == 1
assert notifications['total'] == 2
assert notifications['page_size'] == 1
assert len(notifications["notifications"]) == 1
assert notifications["total"] == 2
assert notifications["page_size"] == 1
def test_invalid_page_size_param(client, sample_email_template):
create_notification(sample_email_template)
create_notification(sample_email_template)
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?page=1&page_size=invalid',
headers=[auth_header])
"/notifications?page=1&page_size=invalid", headers=[auth_header]
)
notifications = json.loads(response.get_data(as_text=True))
assert response.status_code == 400
assert notifications['result'] == 'error'
assert 'Not a valid integer.' in notifications['message']['page_size']
assert notifications["result"] == "error"
assert "Not a valid integer." in notifications["message"]["page_size"]
def test_should_return_pagination_links(client, sample_email_template):
# Effectively mocking page size
original_page_size = current_app.config['API_PAGE_SIZE']
original_page_size = current_app.config["API_PAGE_SIZE"]
try:
current_app.config['API_PAGE_SIZE'] = 1
current_app.config["API_PAGE_SIZE"] = 1
create_notification(sample_email_template)
notification_2 = create_notification(sample_email_template)
create_notification(sample_email_template)
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?page=2',
headers=[auth_header])
response = client.get("/notifications?page=2", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['notifications']) == 1
assert notifications['links']['last'] == '/notifications?page=3'
assert notifications['links']['prev'] == '/notifications?page=1'
assert notifications['links']['next'] == '/notifications?page=3'
assert notifications['notifications'][0]['to'] == notification_2.to
assert len(notifications["notifications"]) == 1
assert notifications["links"]["last"] == "/notifications?page=3"
assert notifications["links"]["prev"] == "/notifications?page=1"
assert notifications["links"]["next"] == "/notifications?page=3"
assert notifications["notifications"][0]["to"] == notification_2.to
assert response.status_code == 200
finally:
current_app.config['API_PAGE_SIZE'] = original_page_size
current_app.config["API_PAGE_SIZE"] = original_page_size
def test_get_all_notifications_returns_empty_list(client, sample_api_key):
auth_header = create_service_authorization_header(service_id=sample_api_key.service.id)
auth_header = create_service_authorization_header(
service_id=sample_api_key.service.id
)
response = client.get(
'/notifications',
headers=[auth_header])
response = client.get("/notifications", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert response.status_code == 200
assert len(notifications['notifications']) == 0
assert len(notifications["notifications"]) == 0
def test_filter_by_template_type(client, sample_template, sample_email_template):
create_notification(sample_template)
create_notification(sample_email_template)
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?template_type=sms',
headers=[auth_header])
response = client.get("/notifications?template_type=sms", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['notifications']) == 1
assert notifications['notifications'][0]['template']['template_type'] == 'sms'
assert len(notifications["notifications"]) == 1
assert notifications["notifications"][0]["template"]["template_type"] == "sms"
assert response.status_code == 200
def test_filter_by_multiple_template_types(client,
sample_template,
sample_email_template):
def test_filter_by_multiple_template_types(
client, sample_template, sample_email_template
):
create_notification(sample_template)
create_notification(sample_email_template)
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?template_type=sms&template_type=email',
headers=[auth_header])
"/notifications?template_type=sms&template_type=email", headers=[auth_header]
)
assert response.status_code == 200
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['notifications']) == 2
assert {'sms', 'email'} == set(x['template']['template_type'] for x in notifications['notifications'])
assert len(notifications["notifications"]) == 2
assert {"sms", "email"} == set(
x["template"]["template_type"] for x in notifications["notifications"]
)
def test_filter_by_status(client, sample_email_template):
create_notification(sample_email_template, status="delivered")
create_notification(sample_email_template)
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?status=delivered',
headers=[auth_header])
response = client.get("/notifications?status=delivered", headers=[auth_header])
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['notifications']) == 1
assert notifications['notifications'][0]['status'] == 'delivered'
assert len(notifications["notifications"]) == 1
assert notifications["notifications"][0]["status"] == "delivered"
assert response.status_code == 200
def test_filter_by_multiple_statuses(client, sample_email_template):
create_notification(sample_email_template, status="delivered")
create_notification(sample_email_template, status='sending')
create_notification(sample_email_template, status="sending")
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?status=delivered&status=sending',
headers=[auth_header]
"/notifications?status=delivered&status=sending", headers=[auth_header]
)
assert response.status_code == 200
notifications = json.loads(response.get_data(as_text=True))
assert len(notifications['notifications']) == 2
assert {'delivered', 'sending'} == set(x['status'] for x in notifications['notifications'])
assert len(notifications["notifications"]) == 2
assert {"delivered", "sending"} == set(
x["status"] for x in notifications["notifications"]
)
def test_filter_by_status_and_template_type(client, sample_template, sample_email_template):
def test_filter_by_status_and_template_type(
client, sample_template, sample_email_template
):
create_notification(sample_template)
create_notification(sample_email_template)
create_notification(sample_email_template, status="delivered")
auth_header = create_service_authorization_header(service_id=sample_email_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.get(
'/notifications?template_type=email&status=delivered',
headers=[auth_header])
"/notifications?template_type=email&status=delivered", headers=[auth_header]
)
notifications = json.loads(response.get_data(as_text=True))
assert response.status_code == 200
assert len(notifications['notifications']) == 1
assert notifications['notifications'][0]['template']['template_type'] == 'email'
assert notifications['notifications'][0]['status'] == 'delivered'
assert len(notifications["notifications"]) == 1
assert notifications["notifications"][0]["template"]["template_type"] == "email"
assert notifications["notifications"][0]["status"] == "delivered"
def test_get_notification_by_id_returns_merged_template_content(client, sample_template_with_placeholders):
def test_get_notification_by_id_returns_merged_template_content(
client, sample_template_with_placeholders
):
sample_notification = create_notification(
sample_template_with_placeholders, personalisation={"name": "world"}
)
sample_notification = create_notification(sample_template_with_placeholders, personalisation={"name": "world"})
auth_header = create_service_authorization_header(service_id=sample_notification.service_id)
auth_header = create_service_authorization_header(
service_id=sample_notification.service_id
)
response = client.get(
'/notifications/{}'.format(sample_notification.id),
headers=[auth_header])
"/notifications/{}".format(sample_notification.id), headers=[auth_header]
)
notification = json.loads(response.get_data(as_text=True))['data']['notification']
notification = json.loads(response.get_data(as_text=True))["data"]["notification"]
assert response.status_code == 200
assert notification['body'] == 'Hello world\nYour thing is due soon'
assert 'subject' not in notification
assert notification['content_char_count'] == 34
assert notification["body"] == "Hello world\nYour thing is due soon"
assert "subject" not in notification
assert notification["content_char_count"] == 34
def test_get_notification_by_id_returns_merged_template_content_for_email(
client,
sample_email_template_with_placeholders
client, sample_email_template_with_placeholders
):
sample_notification = create_notification(
sample_email_template_with_placeholders,
personalisation={"name": "world"}
sample_email_template_with_placeholders, personalisation={"name": "world"}
)
auth_header = create_service_authorization_header(
service_id=sample_notification.service_id
)
auth_header = create_service_authorization_header(service_id=sample_notification.service_id)
response = client.get(
'/notifications/{}'.format(sample_notification.id),
headers=[auth_header])
"/notifications/{}".format(sample_notification.id), headers=[auth_header]
)
notification = json.loads(response.get_data(as_text=True))['data']['notification']
notification = json.loads(response.get_data(as_text=True))["data"]["notification"]
assert response.status_code == 200
assert notification['body'] == 'Hello world\nThis is an email from GOV.UK'
assert notification['subject'] == 'world'
assert notification['content_char_count'] is None
assert notification["body"] == "Hello world\nThis is an email from GOV.UK"
assert notification["subject"] == "world"
assert notification["content_char_count"] is None
def test_get_notifications_for_service_returns_merged_template_content(client, sample_template_with_placeholders):
with freeze_time('2001-01-01T12:00:00'):
create_notification(sample_template_with_placeholders, personalisation={"name": "merged with first"})
def test_get_notifications_for_service_returns_merged_template_content(
client, sample_template_with_placeholders
):
with freeze_time("2001-01-01T12:00:00"):
create_notification(
sample_template_with_placeholders,
personalisation={"name": "merged with first"},
)
with freeze_time('2001-01-01T12:00:01'):
create_notification(sample_template_with_placeholders, personalisation={"name": "merged with second"})
with freeze_time("2001-01-01T12:00:01"):
create_notification(
sample_template_with_placeholders,
personalisation={"name": "merged with second"},
)
auth_header = create_service_authorization_header(service_id=sample_template_with_placeholders.service_id)
auth_header = create_service_authorization_header(
service_id=sample_template_with_placeholders.service_id
)
response = client.get(
path='/notifications',
headers=[auth_header])
response = client.get(path="/notifications", headers=[auth_header])
assert response.status_code == 200
assert {noti['body'] for noti in json.loads(response.get_data(as_text=True))['notifications']} == {
'Hello merged with first\nYour thing is due soon',
'Hello merged with second\nYour thing is due soon'
assert {
noti["body"]
for noti in json.loads(response.get_data(as_text=True))["notifications"]
} == {
"Hello merged with first\nYour thing is due soon",
"Hello merged with second\nYour thing is due soon",
}
def test_get_notification_selects_correct_template_for_personalisation(client,
notify_db_session,
sample_template):
def test_get_notification_selects_correct_template_for_personalisation(
client, notify_db_session, sample_template
):
create_notification(sample_template)
original_content = sample_template.content
sample_template.content = '((name))'
sample_template.content = "((name))"
dao_update_template(sample_template)
notify_db_session.commit()
create_notification(sample_template, personalisation={"name": "foo"})
auth_header = create_service_authorization_header(service_id=sample_template.service_id)
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.get(path='/notifications', headers=[auth_header])
response = client.get(path="/notifications", headers=[auth_header])
assert response.status_code == 200
resp = json.loads(response.get_data(as_text=True))
notis = sorted(resp['notifications'], key=lambda x: x['template_version'])
notis = sorted(resp["notifications"], key=lambda x: x["template_version"])
assert len(notis) == 2
assert notis[0]['template_version'] == 1
assert notis[0]['body'] == original_content
assert notis[1]['template_version'] == 2
assert notis[1]['body'] == 'foo'
assert notis[0]["template_version"] == 1
assert notis[0]["body"] == original_content
assert notis[1]["template_version"] == 2
assert notis[1]["body"] == "foo"
assert notis[0]['template_version'] == notis[0]['template']['version']
assert notis[1]['template_version'] == notis[1]['template']['version']
assert notis[0]["template_version"] == notis[0]["template"]["version"]
assert notis[1]["template_version"] == notis[1]["template"]["version"]
def _create_auth_header_from_key(api_key):
token = create_jwt_token(secret=api_key.secret, client_id=str(api_key.service_id))
return [('Authorization', 'Bearer {}'.format(token))]
return [("Authorization", "Bearer {}".format(token))]

View File

@@ -49,44 +49,54 @@ from tests.conftest import set_config
# all of these tests should have redis enabled (except where we specifically disable it)
@pytest.fixture(scope='module', autouse=True)
@pytest.fixture(scope="module", autouse=True)
def enable_redis(notify_api):
with set_config(notify_api, 'REDIS_ENABLED', True):
with set_config(notify_api, "REDIS_ENABLED", True):
yield
@pytest.mark.parametrize('key_type', ['team', 'normal'])
def test_check_service_message_limit_over_total_limit_fails(key_type, mocker, notify_db_session):
@pytest.mark.parametrize("key_type", ["team", "normal"])
def test_check_service_message_limit_over_total_limit_fails(
key_type, mocker, notify_db_session
):
service = create_service()
mocker.patch('app.redis_store.get', return_value="5001")
mocker.patch("app.redis_store.get", return_value="5001")
with pytest.raises(TotalRequestsError) as e:
check_application_over_retention_limit(key_type, service)
assert e.value.status_code == 429
assert e.value.message == 'Exceeded total application limits (5000) for today'
assert e.value.message == "Exceeded total application limits (5000) for today"
assert e.value.fields == []
@pytest.mark.parametrize('template_type, notification_type',
[(EMAIL_TYPE, EMAIL_TYPE),
(SMS_TYPE, SMS_TYPE)])
@pytest.mark.parametrize(
"template_type, notification_type", [(EMAIL_TYPE, EMAIL_TYPE), (SMS_TYPE, SMS_TYPE)]
)
def test_check_template_is_for_notification_type_pass(template_type, notification_type):
assert check_template_is_for_notification_type(notification_type=notification_type,
template_type=template_type) is None
assert (
check_template_is_for_notification_type(
notification_type=notification_type, template_type=template_type
)
is None
)
@pytest.mark.parametrize('template_type, notification_type',
[(SMS_TYPE, EMAIL_TYPE),
(EMAIL_TYPE, SMS_TYPE)])
@pytest.mark.parametrize(
"template_type, notification_type", [(SMS_TYPE, EMAIL_TYPE), (EMAIL_TYPE, SMS_TYPE)]
)
def test_check_template_is_for_notification_type_fails_when_template_type_does_not_match_notification_type(
template_type, notification_type):
template_type, notification_type
):
with pytest.raises(BadRequestError) as e:
check_template_is_for_notification_type(notification_type=notification_type,
template_type=template_type)
check_template_is_for_notification_type(
notification_type=notification_type, template_type=template_type
)
assert e.value.status_code == 400
error_message = '{0} template is not suitable for {1} notification'.format(template_type, notification_type)
error_message = "{0} template is not suitable for {1} notification".format(
template_type, notification_type
)
assert e.value.message == error_message
assert e.value.fields == [{'template': error_message}]
assert e.value.fields == [{"template": error_message}]
def test_check_template_is_active_passes(sample_template):
@@ -96,77 +106,110 @@ def test_check_template_is_active_passes(sample_template):
def test_check_template_is_active_fails(sample_template):
sample_template.archived = True
from app.dao.templates_dao import dao_update_template
dao_update_template(sample_template)
with pytest.raises(BadRequestError) as e:
check_template_is_active(sample_template)
assert e.value.status_code == 400
assert e.value.message == 'Template has been deleted'
assert e.value.fields == [{'template': 'Template has been deleted'}]
assert e.value.message == "Template has been deleted"
assert e.value.fields == [{"template": "Template has been deleted"}]
@pytest.mark.parametrize('key_type',
['test', 'normal'])
@pytest.mark.parametrize("key_type", ["test", "normal"])
def test_service_can_send_to_recipient_passes(key_type, notify_db_session):
trial_mode_service = create_service(service_name='trial mode', restricted=True)
trial_mode_service = create_service(service_name="trial mode", restricted=True)
serialised_service = SerialisedService.from_id(trial_mode_service.id)
assert service_can_send_to_recipient(trial_mode_service.users[0].email_address,
key_type,
serialised_service) is None
assert service_can_send_to_recipient(trial_mode_service.users[0].mobile_number,
key_type,
serialised_service) is None
assert (
service_can_send_to_recipient(
trial_mode_service.users[0].email_address, key_type, serialised_service
)
is None
)
assert (
service_can_send_to_recipient(
trial_mode_service.users[0].mobile_number, key_type, serialised_service
)
is None
)
@pytest.mark.parametrize('user_number, recipient_number', [
['+12028675309', '202-867-5309'],
['+447513332413', '+44 (07513) 332413'],
])
def test_service_can_send_to_recipient_passes_with_non_normalized_number(sample_service, user_number, recipient_number):
@pytest.mark.parametrize(
"user_number, recipient_number",
[
["+12028675309", "202-867-5309"],
["+447513332413", "+44 (07513) 332413"],
],
)
def test_service_can_send_to_recipient_passes_with_non_normalized_number(
sample_service, user_number, recipient_number
):
sample_service.users[0].mobile_number = user_number
serialised_service = SerialisedService.from_id(sample_service.id)
assert service_can_send_to_recipient(recipient_number, 'team', serialised_service) is None
assert (
service_can_send_to_recipient(recipient_number, "team", serialised_service)
is None
)
@pytest.mark.parametrize('user_email, recipient_email', [
['test@example.com', 'TeSt@EXAMPLE.com'],
])
def test_service_can_send_to_recipient_passes_with_non_normalized_email(sample_service, user_email, recipient_email):
@pytest.mark.parametrize(
"user_email, recipient_email",
[
["test@example.com", "TeSt@EXAMPLE.com"],
],
)
def test_service_can_send_to_recipient_passes_with_non_normalized_email(
sample_service, user_email, recipient_email
):
sample_service.users[0].email_address = user_email
serialised_service = SerialisedService.from_id(sample_service.id)
assert service_can_send_to_recipient(recipient_email, 'team', serialised_service) is None
assert (
service_can_send_to_recipient(recipient_email, "team", serialised_service)
is None
)
@pytest.mark.parametrize('key_type',
['test', 'normal'])
def test_service_can_send_to_recipient_passes_for_live_service_non_team_member(key_type, sample_service):
@pytest.mark.parametrize("key_type", ["test", "normal"])
def test_service_can_send_to_recipient_passes_for_live_service_non_team_member(
key_type, sample_service
):
serialised_service = SerialisedService.from_id(sample_service.id)
assert service_can_send_to_recipient("some_other_email@test.com",
key_type,
serialised_service) is None
assert service_can_send_to_recipient('07513332413',
key_type,
serialised_service) is None
assert (
service_can_send_to_recipient(
"some_other_email@test.com", key_type, serialised_service
)
is None
)
assert (
service_can_send_to_recipient("07513332413", key_type, serialised_service)
is None
)
def test_service_can_send_to_recipient_passes_for_guest_list_recipient_passes(sample_service):
def test_service_can_send_to_recipient_passes_for_guest_list_recipient_passes(
sample_service,
):
create_service_guest_list(sample_service, email_address="some_other_email@test.com")
assert service_can_send_to_recipient("some_other_email@test.com",
'team',
sample_service) is None
create_service_guest_list(sample_service, mobile_number='2028675309')
assert service_can_send_to_recipient('2028675309',
'team',
sample_service) is None
assert (
service_can_send_to_recipient(
"some_other_email@test.com", "team", sample_service
)
is None
)
create_service_guest_list(sample_service, mobile_number="2028675309")
assert service_can_send_to_recipient("2028675309", "team", sample_service) is None
@pytest.mark.parametrize('recipient', [
{"email_address": "some_other_email@test.com"},
{"mobile_number": "2028675300"},
])
@pytest.mark.parametrize(
"recipient",
[
{"email_address": "some_other_email@test.com"},
{"mobile_number": "2028675300"},
],
)
def test_service_can_send_to_recipient_fails_when_ignoring_guest_list(
notify_db_session,
sample_service,
@@ -176,120 +219,148 @@ def test_service_can_send_to_recipient_fails_when_ignoring_guest_list(
with pytest.raises(BadRequestError) as exec_info:
service_can_send_to_recipient(
next(iter(recipient.values())),
'team',
"team",
sample_service,
allow_guest_list_recipients=False,
)
assert exec_info.value.status_code == 400
assert exec_info.value.message == 'Cant send to this recipient using a team-only API key'
assert (
exec_info.value.message
== "Cant send to this recipient using a team-only API key"
)
assert exec_info.value.fields == []
@pytest.mark.parametrize('recipient', ['2028675300', 'some_other_email@test.com'])
@pytest.mark.parametrize('key_type, error_message',
[('team', 'Cant send to this recipient using a team-only API key'),
('normal',
"Cant send to this recipient when service is in trial mode see https://www.notifications.service.gov.uk/trial-mode")]) # noqa
@pytest.mark.parametrize("recipient", ["2028675300", "some_other_email@test.com"])
@pytest.mark.parametrize(
"key_type, error_message",
[
("team", "Cant send to this recipient using a team-only API key"),
(
"normal",
"Cant send to this recipient when service is in trial mode see https://www.notifications.service.gov.uk/trial-mode", # noqa
),
],
) # noqa
def test_service_can_send_to_recipient_fails_when_recipient_is_not_on_team(
recipient,
key_type,
error_message,
notify_db_session,
):
trial_mode_service = create_service(service_name='trial mode', restricted=True)
trial_mode_service = create_service(service_name="trial mode", restricted=True)
with pytest.raises(BadRequestError) as exec_info:
service_can_send_to_recipient(recipient,
key_type,
trial_mode_service)
service_can_send_to_recipient(recipient, key_type, trial_mode_service)
assert exec_info.value.status_code == 400
assert exec_info.value.message == error_message
assert exec_info.value.fields == []
def test_service_can_send_to_recipient_fails_when_mobile_number_is_not_on_team(sample_service):
def test_service_can_send_to_recipient_fails_when_mobile_number_is_not_on_team(
sample_service,
):
with pytest.raises(BadRequestError) as e:
service_can_send_to_recipient("0758964221",
'team',
sample_service)
service_can_send_to_recipient("0758964221", "team", sample_service)
assert e.value.status_code == 400
assert e.value.message == 'Cant send to this recipient using a team-only API key'
assert e.value.message == "Cant send to this recipient using a team-only API key"
assert e.value.fields == []
@pytest.mark.parametrize('char_count', [612, 0, 494, 200, 918])
@pytest.mark.parametrize('show_prefix', [True, False])
@pytest.mark.parametrize('template_type', ['sms', 'email'])
def test_check_is_message_too_long_passes(notify_db_session, show_prefix, char_count, template_type):
@pytest.mark.parametrize("char_count", [612, 0, 494, 200, 918])
@pytest.mark.parametrize("show_prefix", [True, False])
@pytest.mark.parametrize("template_type", ["sms", "email"])
def test_check_is_message_too_long_passes(
notify_db_session, show_prefix, char_count, template_type
):
service = create_service(prefix_sms=show_prefix)
t = create_template(service=service, content='a' * char_count, template_type=template_type)
template = templates_dao.dao_get_template_by_id_and_service_id(template_id=t.id, service_id=service.id)
t = create_template(
service=service, content="a" * char_count, template_type=template_type
)
template = templates_dao.dao_get_template_by_id_and_service_id(
template_id=t.id, service_id=service.id
)
template_with_content = get_template_instance(template=template.__dict__, values={})
assert check_is_message_too_long(template_with_content) is None
@pytest.mark.parametrize('char_count', [919, 6000])
@pytest.mark.parametrize('show_prefix', [True, False])
@pytest.mark.parametrize("char_count", [919, 6000])
@pytest.mark.parametrize("show_prefix", [True, False])
def test_check_is_message_too_long_fails(notify_db_session, show_prefix, char_count):
with pytest.raises(BadRequestError) as e:
service = create_service(prefix_sms=show_prefix)
t = create_template(service=service, content='a' * char_count, template_type='sms')
template = templates_dao.dao_get_template_by_id_and_service_id(template_id=t.id, service_id=service.id)
template_with_content = get_template_instance(template=template.__dict__, values={})
t = create_template(
service=service, content="a" * char_count, template_type="sms"
)
template = templates_dao.dao_get_template_by_id_and_service_id(
template_id=t.id, service_id=service.id
)
template_with_content = get_template_instance(
template=template.__dict__, values={}
)
check_is_message_too_long(template_with_content)
assert e.value.status_code == 400
expected_message = f'Your message is too long. '\
f'Text messages cannot be longer than {SMS_CHAR_COUNT_LIMIT} characters. '\
f'Your message is {char_count} characters long.'
expected_message = (
f"Your message is too long. "
f"Text messages cannot be longer than {SMS_CHAR_COUNT_LIMIT} characters. "
f"Your message is {char_count} characters long."
)
assert e.value.message == expected_message
assert e.value.fields == []
def test_check_is_message_too_long_passes_for_long_email(sample_service):
email_character_count = 2_000_001
t = create_template(service=sample_service, content='a' * email_character_count, template_type='email')
template = templates_dao.dao_get_template_by_id_and_service_id(template_id=t.id,
service_id=t.service_id)
t = create_template(
service=sample_service,
content="a" * email_character_count,
template_type="email",
)
template = templates_dao.dao_get_template_by_id_and_service_id(
template_id=t.id, service_id=t.service_id
)
template_with_content = get_template_instance(template=template.__dict__, values={})
template_with_content.values
with pytest.raises(BadRequestError) as e:
check_is_message_too_long(template_with_content)
assert e.value.status_code == 400
expected_message = (
'Your message is too long. ' +
'Emails cannot be longer than 2000000 bytes. ' +
'Your message is 2000001 bytes.'
"Your message is too long. "
+ "Emails cannot be longer than 2000000 bytes. "
+ "Your message is 2000001 bytes."
)
assert e.value.message == expected_message
assert e.value.fields == []
def test_check_notification_content_is_not_empty_passes(notify_api, mocker, sample_service):
def test_check_notification_content_is_not_empty_passes(
notify_api, mocker, sample_service
):
template_id = create_template(sample_service, content="Content is not empty").id
template = SerialisedTemplate.from_id_and_service_id(
template_id=template_id,
service_id=sample_service.id
template_id=template_id, service_id=sample_service.id
)
template_with_content = create_content_for_notification(template, {})
assert check_notification_content_is_not_empty(template_with_content) is None
@pytest.mark.parametrize('template_content,notification_values', [
("", {}),
("((placeholder))", {"placeholder": ""})
])
@pytest.mark.parametrize(
"template_content,notification_values",
[("", {}), ("((placeholder))", {"placeholder": ""})],
)
def test_check_notification_content_is_not_empty_fails(
notify_api, mocker, sample_service, template_content, notification_values
):
template_id = create_template(sample_service, content=template_content).id
template = SerialisedTemplate.from_id_and_service_id(
template_id=template_id,
service_id=sample_service.id
template_id=template_id, service_id=sample_service.id
)
template_with_content = create_content_for_notification(
template, notification_values
)
template_with_content = create_content_for_notification(template, notification_values)
with pytest.raises(BadRequestError) as e:
check_notification_content_is_not_empty(template_with_content)
assert e.value.status_code == 400
assert e.value.message == 'Your message is empty.'
assert e.value.message == "Your message is empty."
assert e.value.fields == []
@@ -299,18 +370,29 @@ def test_validate_template(sample_service):
@pytest.mark.parametrize("check_char_count", [True, False])
def test_validate_template_calls_all_validators(mocker, fake_uuid, sample_service, check_char_count):
def test_validate_template_calls_all_validators(
mocker, fake_uuid, sample_service, check_char_count
):
template = create_template(sample_service, template_type="email")
mock_check_type = mocker.patch('app.notifications.validators.check_template_is_for_notification_type')
mock_check_if_active = mocker.patch('app.notifications.validators.check_template_is_active')
mock_create_conent = mocker.patch(
'app.notifications.validators.create_content_for_notification', return_value="content"
mock_check_type = mocker.patch(
"app.notifications.validators.check_template_is_for_notification_type"
)
mock_check_if_active = mocker.patch(
"app.notifications.validators.check_template_is_active"
)
mock_create_conent = mocker.patch(
"app.notifications.validators.create_content_for_notification",
return_value="content",
)
mock_check_not_empty = mocker.patch(
"app.notifications.validators.check_notification_content_is_not_empty"
)
mock_check_message_is_too_long = mocker.patch(
"app.notifications.validators.check_is_message_too_long"
)
template, template_with_content = validate_template(
template.id, {}, sample_service, "email", check_char_count=check_char_count
)
mock_check_not_empty = mocker.patch('app.notifications.validators.check_notification_content_is_not_empty')
mock_check_message_is_too_long = mocker.patch('app.notifications.validators.check_is_message_too_long')
template, template_with_content = validate_template(template.id, {}, sample_service, "email",
check_char_count=check_char_count
)
mock_check_type.assert_called_once_with("email", "email")
mock_check_if_active.assert_called_once_with(template)
@@ -322,17 +404,29 @@ def test_validate_template_calls_all_validators(mocker, fake_uuid, sample_servic
assert not mock_check_message_is_too_long.called
def test_validate_template_calls_all_validators_exception_message_too_long(mocker, fake_uuid, sample_service):
def test_validate_template_calls_all_validators_exception_message_too_long(
mocker, fake_uuid, sample_service
):
template = create_template(sample_service, template_type="email")
mock_check_type = mocker.patch('app.notifications.validators.check_template_is_for_notification_type')
mock_check_if_active = mocker.patch('app.notifications.validators.check_template_is_active')
mock_create_conent = mocker.patch(
'app.notifications.validators.create_content_for_notification', return_value="content"
mock_check_type = mocker.patch(
"app.notifications.validators.check_template_is_for_notification_type"
)
mock_check_if_active = mocker.patch(
"app.notifications.validators.check_template_is_active"
)
mock_create_conent = mocker.patch(
"app.notifications.validators.create_content_for_notification",
return_value="content",
)
mock_check_not_empty = mocker.patch(
"app.notifications.validators.check_notification_content_is_not_empty"
)
mock_check_message_is_too_long = mocker.patch(
"app.notifications.validators.check_is_message_too_long"
)
template, template_with_content = validate_template(
template.id, {}, sample_service, "email", check_char_count=False
)
mock_check_not_empty = mocker.patch('app.notifications.validators.check_notification_content_is_not_empty')
mock_check_message_is_too_long = mocker.patch('app.notifications.validators.check_is_message_too_long')
template, template_with_content = validate_template(template.id, {}, sample_service, "email",
check_char_count=False)
mock_check_type.assert_called_once_with("email", "email")
mock_check_if_active.assert_called_once_with(template)
@@ -341,24 +435,24 @@ def test_validate_template_calls_all_validators_exception_message_too_long(mocke
assert not mock_check_message_is_too_long.called
@pytest.mark.parametrize('key_type', ['team', 'live', 'test'])
@pytest.mark.parametrize("key_type", ["team", "live", "test"])
def test_check_service_over_api_rate_limit_when_exceed_rate_limit_request_fails_raises_error(
key_type,
sample_service,
mocker):
key_type, sample_service, mocker
):
with freeze_time("2016-01-01 12:00:00.000000"):
if key_type == 'live':
api_key_type = 'normal'
if key_type == "live":
api_key_type = "normal"
else:
api_key_type = key_type
mocker.patch('app.redis_store.exceeded_rate_limit', return_value=True)
mocker.patch("app.redis_store.exceeded_rate_limit", return_value=True)
sample_service.restricted = True
api_key = create_api_key(sample_service, key_type=api_key_type)
serialised_service = SerialisedService.from_id(sample_service.id)
serialised_api_key = SerialisedAPIKeyCollection.from_service_id(serialised_service.id)[0]
serialised_api_key = SerialisedAPIKeyCollection.from_service_id(
serialised_service.id
)[0]
with pytest.raises(RateLimitError) as e:
check_service_over_api_rate_limit(serialised_service, serialised_api_key)
@@ -366,46 +460,51 @@ def test_check_service_over_api_rate_limit_when_exceed_rate_limit_request_fails_
assert app.redis_store.exceeded_rate_limit.called_with(
"{}-{}".format(str(sample_service.id), api_key.key_type),
sample_service.rate_limit,
60
60,
)
assert e.value.status_code == 429
assert e.value.message == 'Exceeded rate limit for key type {} of {} requests per {} seconds'.format(
key_type.upper(), sample_service.rate_limit, 60
assert (
e.value.message
== "Exceeded rate limit for key type {} of {} requests per {} seconds".format(
key_type.upper(), sample_service.rate_limit, 60
)
)
assert e.value.fields == []
def test_check_service_over_api_rate_limit_when_rate_limit_has_not_exceeded_limit_succeeds(
sample_service,
mocker):
sample_service, mocker
):
with freeze_time("2016-01-01 12:00:00.000000"):
mocker.patch('app.redis_store.exceeded_rate_limit', return_value=False)
mocker.patch("app.redis_store.exceeded_rate_limit", return_value=False)
sample_service.restricted = True
api_key = create_api_key(sample_service)
serialised_service = SerialisedService.from_id(sample_service.id)
serialised_api_key = SerialisedAPIKeyCollection.from_service_id(serialised_service.id)[0]
serialised_api_key = SerialisedAPIKeyCollection.from_service_id(
serialised_service.id
)[0]
check_service_over_api_rate_limit(serialised_service, serialised_api_key)
assert app.redis_store.exceeded_rate_limit.called_with(
"{}-{}".format(str(sample_service.id), api_key.key_type),
3000,
60
"{}-{}".format(str(sample_service.id), api_key.key_type), 3000, 60
)
def test_check_service_over_api_rate_limit_should_do_nothing_if_limiting_is_disabled(
sample_service,
mocker):
sample_service, mocker
):
with freeze_time("2016-01-01 12:00:00.000000"):
current_app.config['API_RATE_LIMIT_ENABLED'] = False
current_app.config["API_RATE_LIMIT_ENABLED"] = False
mocker.patch('app.redis_store.exceeded_rate_limit', return_value=False)
mocker.patch("app.redis_store.exceeded_rate_limit", return_value=False)
sample_service.restricted = True
create_api_key(sample_service)
serialised_service = SerialisedService.from_id(sample_service.id)
serialised_api_key = SerialisedAPIKeyCollection.from_service_id(serialised_service.id)[0]
serialised_api_key = SerialisedAPIKeyCollection.from_service_id(
serialised_service.id
)[0]
check_service_over_api_rate_limit(serialised_service, serialised_api_key)
app.redis_store.exceeded_rate_limit.assert_not_called()
@@ -414,7 +513,9 @@ def test_check_service_over_api_rate_limit_should_do_nothing_if_limiting_is_disa
def test_check_rate_limiting_validates_api_rate_limit_and_daily_limit(
notify_db_session, mocker
):
mock_rate_limit = mocker.patch('app.notifications.validators.check_service_over_api_rate_limit')
mock_rate_limit = mocker.patch(
"app.notifications.validators.check_service_over_api_rate_limit"
)
service = create_service()
api_key = create_api_key(service=service)
@@ -423,122 +524,167 @@ def test_check_rate_limiting_validates_api_rate_limit_and_daily_limit(
mock_rate_limit.assert_called_once_with(service, api_key)
@pytest.mark.parametrize('key_type', ['test', 'normal'])
@pytest.mark.parametrize("key_type", ["test", "normal"])
def test_validate_and_format_recipient_fails_when_international_number_and_service_does_not_allow_int_sms(
key_type,
notify_db_session,
key_type,
notify_db_session,
):
service = create_service(service_permissions=[SMS_TYPE])
service_model = SerialisedService.from_id(service.id)
with pytest.raises(BadRequestError) as e:
validate_and_format_recipient('+20-12-1234-1234', key_type, service_model, SMS_TYPE)
validate_and_format_recipient(
"+20-12-1234-1234", key_type, service_model, SMS_TYPE
)
assert e.value.status_code == 400
assert e.value.message == 'Cannot send to international mobile numbers'
assert e.value.message == "Cannot send to international mobile numbers"
assert e.value.fields == []
@pytest.mark.parametrize('key_type', ['test', 'normal'])
@pytest.mark.parametrize("key_type", ["test", "normal"])
def test_validate_and_format_recipient_succeeds_with_international_numbers_if_service_does_allow_int_sms(
key_type, sample_service_full_permissions):
key_type, sample_service_full_permissions
):
service_model = SerialisedService.from_id(sample_service_full_permissions.id)
result = validate_and_format_recipient('+4407513332413', key_type, service_model, SMS_TYPE)
assert result == '+447513332413'
result = validate_and_format_recipient(
"+4407513332413", key_type, service_model, SMS_TYPE
)
assert result == "+447513332413"
def test_validate_and_format_recipient_fails_when_no_recipient():
with pytest.raises(BadRequestError) as e:
validate_and_format_recipient(None, 'key_type', 'service', 'SMS_TYPE')
validate_and_format_recipient(None, "key_type", "service", "SMS_TYPE")
assert e.value.status_code == 400
assert e.value.message == "Recipient can't be empty"
@pytest.mark.parametrize('notification_type', ['sms', 'email'])
@pytest.mark.parametrize("notification_type", ["sms", "email"])
def test_check_service_email_reply_to_id_where_reply_to_id_is_none(notification_type):
assert check_service_email_reply_to_id(None, None, notification_type) is None
def test_check_service_email_reply_to_where_email_reply_to_is_found(sample_service):
reply_to_address = create_reply_to_email(sample_service, "test@test.com")
assert check_service_email_reply_to_id(sample_service.id, reply_to_address.id, EMAIL_TYPE) == "test@test.com"
assert (
check_service_email_reply_to_id(
sample_service.id, reply_to_address.id, EMAIL_TYPE
)
== "test@test.com"
)
def test_check_service_email_reply_to_id_where_service_id_is_not_found(sample_service, fake_uuid):
def test_check_service_email_reply_to_id_where_service_id_is_not_found(
sample_service, fake_uuid
):
reply_to_address = create_reply_to_email(sample_service, "test@test.com")
with pytest.raises(BadRequestError) as e:
check_service_email_reply_to_id(fake_uuid, reply_to_address.id, EMAIL_TYPE)
assert e.value.status_code == 400
assert e.value.message == 'email_reply_to_id {} does not exist in database for service id {}' \
.format(reply_to_address.id, fake_uuid)
assert (
e.value.message
== "email_reply_to_id {} does not exist in database for service id {}".format(
reply_to_address.id, fake_uuid
)
)
def test_check_service_email_reply_to_id_where_reply_to_id_is_not_found(sample_service, fake_uuid):
def test_check_service_email_reply_to_id_where_reply_to_id_is_not_found(
sample_service, fake_uuid
):
with pytest.raises(BadRequestError) as e:
check_service_email_reply_to_id(sample_service.id, fake_uuid, EMAIL_TYPE)
assert e.value.status_code == 400
assert e.value.message == 'email_reply_to_id {} does not exist in database for service id {}' \
.format(fake_uuid, sample_service.id)
assert (
e.value.message
== "email_reply_to_id {} does not exist in database for service id {}".format(
fake_uuid, sample_service.id
)
)
@pytest.mark.parametrize('notification_type', ['sms', 'email'])
@pytest.mark.parametrize("notification_type", ["sms", "email"])
def test_check_service_sms_sender_id_where_sms_sender_id_is_none(notification_type):
assert check_service_sms_sender_id(None, None, notification_type) is None
def test_check_service_sms_sender_id_where_sms_sender_id_is_found(sample_service):
sms_sender = create_service_sms_sender(service=sample_service, sms_sender='123456')
assert check_service_sms_sender_id(sample_service.id, sms_sender.id, SMS_TYPE) == '123456'
sms_sender = create_service_sms_sender(service=sample_service, sms_sender="123456")
assert (
check_service_sms_sender_id(sample_service.id, sms_sender.id, SMS_TYPE)
== "123456"
)
def test_check_service_sms_sender_id_where_service_id_is_not_found(sample_service, fake_uuid):
sms_sender = create_service_sms_sender(service=sample_service, sms_sender='123456')
def test_check_service_sms_sender_id_where_service_id_is_not_found(
sample_service, fake_uuid
):
sms_sender = create_service_sms_sender(service=sample_service, sms_sender="123456")
with pytest.raises(BadRequestError) as e:
check_service_sms_sender_id(fake_uuid, sms_sender.id, SMS_TYPE)
assert e.value.status_code == 400
assert e.value.message == 'sms_sender_id {} does not exist in database for service id {}' \
.format(sms_sender.id, fake_uuid)
assert (
e.value.message
== "sms_sender_id {} does not exist in database for service id {}".format(
sms_sender.id, fake_uuid
)
)
def test_check_service_sms_sender_id_where_sms_sender_is_not_found(sample_service, fake_uuid):
def test_check_service_sms_sender_id_where_sms_sender_is_not_found(
sample_service, fake_uuid
):
with pytest.raises(BadRequestError) as e:
check_service_sms_sender_id(sample_service.id, fake_uuid, SMS_TYPE)
assert e.value.status_code == 400
assert e.value.message == 'sms_sender_id {} does not exist in database for service id {}' \
.format(fake_uuid, sample_service.id)
assert (
e.value.message
== "sms_sender_id {} does not exist in database for service id {}".format(
fake_uuid, sample_service.id
)
)
@pytest.mark.parametrize('notification_type', ['sms', 'email'])
@pytest.mark.parametrize("notification_type", ["sms", "email"])
def test_check_reply_to_with_empty_reply_to(sample_service, notification_type):
assert check_reply_to(sample_service.id, None, notification_type) is None
def test_check_reply_to_email_type(sample_service):
reply_to_address = create_reply_to_email(sample_service, "test@test.com")
assert check_reply_to(sample_service.id, reply_to_address.id, EMAIL_TYPE) == 'test@test.com'
assert (
check_reply_to(sample_service.id, reply_to_address.id, EMAIL_TYPE)
== "test@test.com"
)
def test_check_reply_to_sms_type(sample_service):
sms_sender = create_service_sms_sender(service=sample_service, sms_sender='123456')
assert check_reply_to(sample_service.id, sms_sender.id, SMS_TYPE) == '123456'
sms_sender = create_service_sms_sender(service=sample_service, sms_sender="123456")
assert check_reply_to(sample_service.id, sms_sender.id, SMS_TYPE) == "123456"
def test_check_if_service_can_send_files_by_email_raises_if_no_contact_link_set(sample_service):
def test_check_if_service_can_send_files_by_email_raises_if_no_contact_link_set(
sample_service,
):
with pytest.raises(BadRequestError) as e:
check_if_service_can_send_files_by_email(
service_contact_link=sample_service.contact_link,
service_id=sample_service.id
service_id=sample_service.id,
)
message = f"Send files by email has not been set up - add contact details for your service at " \
f"http://localhost:6012/services/{sample_service.id}/service-settings/send-files-by-email"
message = (
f"Send files by email has not been set up - add contact details for your service at "
f"http://localhost:6012/services/{sample_service.id}/service-settings/send-files-by-email"
)
assert e.value.status_code == 400
assert e.value.message == message
def test_check_if_service_can_send_files_by_email_passes_if_contact_link_set(sample_service):
sample_service.contact_link = 'contact.me@gov.uk'
def test_check_if_service_can_send_files_by_email_passes_if_contact_link_set(
sample_service,
):
sample_service.contact_link = "contact.me@gov.uk"
check_if_service_can_send_files_by_email(
service_contact_link=sample_service.contact_link,
service_id=sample_service.id
service_contact_link=sample_service.contact_link, service_id=sample_service.id
)
@@ -548,25 +694,37 @@ def test_get_string_to_sign():
"Type": "Notification",
"MessageId": "ccccccccc-cccc-cccc-cccc-ccccccccccccc",
"TopicArn": "arn:aws:sns:us-west-2:009969138378:connector-svc-test",
"Message": "{\"AbsoluteTime\":\"2021-09-08T13:28:24.656Z\",\"Content\":\"help\",\"ContentType\":\"text/plain\",\"Id\":\"333333333-be0d-4a44-889d-d2a86fc06f0c\",\"Type\":\"MESSAGE\",\"ParticipantId\":\"bbbbbbbb-c562-4d95-b76c-dcbca8b4b5f7\",\"DisplayName\":\"Jane\",\"ParticipantRole\":\"CUSTOMER\",\"InitialContactId\":\"33333333-abc5-46db-9ad5-d772559ab556\",\"ContactId\":\"33333333-abc5-46db-9ad5-d772559ab556\"}", # noqa
"Message": '{"AbsoluteTime":"2021-09-08T13:28:24.656Z","Content":"help","ContentType":"text/plain","Id":"333333333-be0d-4a44-889d-d2a86fc06f0c","Type":"MESSAGE","ParticipantId":"bbbbbbbb-c562-4d95-b76c-dcbca8b4b5f7","DisplayName":"Jane","ParticipantRole":"CUSTOMER","InitialContactId":"33333333-abc5-46db-9ad5-d772559ab556","ContactId":"33333333-abc5-46db-9ad5-d772559ab556"}', # noqa
"Timestamp": "2021-09-08T13:28:24.860Z",
"SignatureVersion": "1",
"Signature": "examplegggggg/1tEBYdiVDgJgBoJUniUFcArLFGfg5JCvpOr/v6LPCHiD7A0BWy8+ZOnGTmOjBMn80U9jSzYhKbHDbQHaNYTo9sRyQA31JtHHiIseQeMfTDpcaAXqfs8hdIXq4XZaJYqDFqosfbvh56VPh5QgmeHTltTc7eOZBUwnt/177eOTLTt2yB0ItMV3NAYuE1Tdxya1lLYZQUIMxETTVcRAZkDIu8TbRZC9a00q2RQVjXhDaU3k+tL+kk85syW/2ryjjkDYoUb+dyRGkqMy4aKA22UpfidOtdAZ/GGtXaXSKBqazZTEUuSEzt0duLtFntQiYJanU05gtDig==", # noqa
"SigningCertURL": "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-11111111111111111111111111111111.pem", # noqa
"UnsubscribeURL": "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:000000000000:connector-svc-test:22222222-aaaa-bbbb-cccc-333333333333", # noqa
"Signature": "examplegggggg/1tEBYdiVDgJgBoJUniUFcArLFGfg5JCvpOr/v6LPCHiD7A0BWy8+ZOnGTmOjBMn80U9jSzYhKbHDbQHaNYTo9sRyQA31JtHHiIseQeMfTDpcaAXqfs8hdIXq4XZaJYqDFqosfbvh56VPh5QgmeHTltTc7eOZBUwnt/177eOTLTt2yB0ItMV3NAYuE1Tdxya1lLYZQUIMxETTVcRAZkDIu8TbRZC9a00q2RQVjXhDaU3k+tL+kk85syW/2ryjjkDYoUb+dyRGkqMy4aKA22UpfidOtdAZ/GGtXaXSKBqazZTEUuSEzt0duLtFntQiYJanU05gtDig==", # noqa
"SigningCertURL": "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-11111111111111111111111111111111.pem", # noqa
"UnsubscribeURL": "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:000000000000:connector-svc-test:22222222-aaaa-bbbb-cccc-333333333333", # noqa
"MessageAttributes": {
"InitialContactId": {"Type": "String", "Value": "33333333-abc5-46db-9ad5-d772559ab556"},
"InitialContactId": {
"Type": "String",
"Value": "33333333-abc5-46db-9ad5-d772559ab556",
},
"MessageVisibility": {"Type": "String", "Value": "ALL"},
"Type": {"Type": "String", "Value": "MESSAGE"},
"AccountId": {"Type": "String", "Value": "999999999999"},
"ContentType": {"Type": "String", "Value": "text/plain"},
"InstanceId": {"Type": "String", "Value": "dddddddd-b64e-40c5-921b-109fd92499ae"},
"ContactId": {"Type": "String", "Value": "33333333-abc5-46db-9ad5-d772559ab556"},
"ParticipantRole": {"Type": "String", "Value": "CUSTOMER"}
}
"InstanceId": {
"Type": "String",
"Value": "dddddddd-b64e-40c5-921b-109fd92499ae",
},
"ContactId": {
"Type": "String",
"Value": "33333333-abc5-46db-9ad5-d772559ab556",
},
"ParticipantRole": {"Type": "String", "Value": "CUSTOMER"},
},
}
str = get_string_to_sign(sns_payload)
assert str == b'Message\n{"AbsoluteTime":"2021-09-08T13:28:24.656Z","Content":"help","ContentType":"text/plain","Id":"333333333-be0d-4a44-889d-d2a86fc06f0c","Type":"MESSAGE","ParticipantId":"bbbbbbbb-c562-4d95-b76c-dcbca8b4b5f7","DisplayName":"Jane","ParticipantRole":"CUSTOMER","InitialContactId":"33333333-abc5-46db-9ad5-d772559ab556","ContactId":"33333333-abc5-46db-9ad5-d772559ab556"}\nMessageId\nccccccccc-cccc-cccc-cccc-ccccccccccccc\nTimestamp\n2021-09-08T13:28:24.860Z\nTopicArn\narn:aws:sns:us-west-2:009969138378:connector-svc-test\nType\nNotification\n' # noqa
assert (
str
== b'Message\n{"AbsoluteTime":"2021-09-08T13:28:24.656Z","Content":"help","ContentType":"text/plain","Id":"333333333-be0d-4a44-889d-d2a86fc06f0c","Type":"MESSAGE","ParticipantId":"bbbbbbbb-c562-4d95-b76c-dcbca8b4b5f7","DisplayName":"Jane","ParticipantRole":"CUSTOMER","InitialContactId":"33333333-abc5-46db-9ad5-d772559ab556","ContactId":"33333333-abc5-46db-9ad5-d772559ab556"}\nMessageId\nccccccccc-cccc-cccc-cccc-ccccccccccccc\nTimestamp\n2021-09-08T13:28:24.860Z\nTopicArn\narn:aws:sns:us-west-2:009969138378:connector-svc-test\nType\nNotification\n' # noqa
)
# This is a test payload with no valid cert, so it should raise a ValueError
with pytest.raises(ValueError):