Files
notifications-api/tests/app/service/send_notification/test_send_notification.py

1415 lines
47 KiB
Python
Raw Normal View History

import random
import string
2021-03-10 13:55:06 +00:00
import pytest
from flask import current_app, json
from freezegun import freeze_time
from notifications_python_client.authentication import create_jwt_token
from notifications_utils import SMS_CHAR_COUNT_LIMIT
import app
from app.dao import notifications_dao
from app.dao.api_key_dao import save_model_api_key
2021-03-10 13:55:06 +00:00
from app.dao.services_dao import dao_update_service
from app.dao.templates_dao import dao_get_all_templates_for_service, dao_update_template
from app.enums import KeyType, NotificationType, TemplateType
from app.errors import InvalidRequest
from app.models import ApiKey, Notification, NotificationHistory, Template
from app.service.send_notification import send_one_off_notification
2020-03-17 15:41:30 +00:00
from app.v2.errors import RateLimitError
from tests import create_service_authorization_header
from tests.app.db import (
create_api_key,
create_notification,
2021-03-10 13:55:06 +00:00
create_reply_to_email,
create_service,
create_service_guest_list,
create_template,
)
@pytest.mark.parametrize("template_type", [TemplateType.SMS, TemplateType.EMAIL])
2023-08-29 14:54:30 -07:00
def test_create_notification_should_reject_if_missing_required_fields(
notify_api, sample_api_key, mocker, template_type
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
data = {}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_api_key.service_id
)
response = client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
mocked.assert_not_called()
2023-08-29 14:54:30 -07:00
assert json_resp["result"] == "error"
assert "Missing data for required field." in json_resp["message"]["to"][0]
assert (
"Missing data for required field."
in json_resp["message"]["template"][0]
)
assert response.status_code == 400
def test_should_reject_bad_phone_numbers(notify_api, sample_template, mocker):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": "invalid", "template": sample_template.id}
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
mocked.assert_not_called()
2023-08-29 14:54:30 -07:00
assert json_resp["result"] == "error"
assert len(json_resp["message"].keys()) == 1
assert (
"Invalid phone number: The string supplied did not seem to be a phone number."
in json_resp["message"]["to"]
)
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"template_type, to",
[
(TemplateType.SMS, "+447700900855"),
(TemplateType.EMAIL, "ok@ok.com"),
],
2023-08-29 14:54:30 -07:00
)
def test_send_notification_invalid_template_id(
notify_api, sample_template, mocker, fake_uuid, template_type, to
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
2023-08-29 14:54:30 -07:00
data = {"to": to, "template": fake_uuid}
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
mocked.assert_not_called()
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
test_string = "Template not found"
assert test_string in json_resp["message"]
@freeze_time("2016-01-01 11:09:00.061258")
2023-08-29 14:54:30 -07:00
def test_send_notification_with_placeholders_replaced(
notify_api, sample_email_template_with_placeholders, mocker
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
data = {
2023-08-29 14:54:30 -07:00
"to": "ok@ok.com",
"template": str(sample_email_template_with_placeholders.id),
"personalisation": {"name": "Jo"},
}
auth_header = create_service_authorization_header(
service_id=sample_email_template_with_placeholders.service.id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
2023-08-29 14:54:30 -07:00
response_data = json.loads(response.data)["data"]
notification_id = response_data["notification"]["id"]
data.update(
{"template_version": sample_email_template_with_placeholders.version}
)
2023-08-29 14:54:30 -07:00
mocked.assert_called_once_with([notification_id], queue="send-email-tasks")
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
assert response_data["body"] == "Hello Jo\nThis is an email from GOV.UK"
assert response_data["subject"] == "Jo"
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"personalisation, expected_body, expected_subject",
[
(
2023-08-29 14:54:30 -07:00
["Jo", "John", "Josephine"],
(
"Hello \n\n"
"* Jo\n"
"* John\n"
"* Josephine\n"
"This is an email from GOV.UK"
),
"Jo, John and Josephine",
),
(
2023-08-29 14:54:30 -07:00
6,
("Hello 6\n" "This is an email from GOV.UK"),
"6",
),
2023-08-29 14:54:30 -07:00
],
)
def test_send_notification_with_placeholders_replaced_with_unusual_types(
client,
sample_email_template_with_placeholders,
mocker,
personalisation,
expected_body,
expected_subject,
):
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(
{
2023-08-29 14:54:30 -07:00
"to": "ok@ok.com",
"template": str(sample_email_template_with_placeholders.id),
"personalisation": {"name": personalisation},
}
),
headers=[
2023-08-29 14:54:30 -07:00
("Content-Type", "application/json"),
create_service_authorization_header(
service_id=sample_email_template_with_placeholders.service.id
),
],
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
response_data = json.loads(response.data)["data"]
assert response_data["body"] == expected_body
assert response_data["subject"] == expected_subject
@pytest.mark.parametrize(
"personalisation, expected_body, expected_subject",
[
(
None,
("we consider None equivalent to missing personalisation"),
"",
),
],
)
2023-05-25 10:50:01 -07:00
def test_send_notification_with_placeholders_replaced_with_unusual_types_no_personalization(
client,
sample_email_template_with_placeholders,
mocker,
personalisation,
expected_body,
expected_subject,
):
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
2023-05-25 10:50:01 -07:00
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
2023-05-25 10:50:01 -07:00
data=json.dumps(
{
2023-08-29 14:54:30 -07:00
"to": "ok@ok.com",
"template": str(sample_email_template_with_placeholders.id),
"personalisation": {"name": personalisation},
2023-05-25 10:50:01 -07:00
}
),
headers=[
2023-08-29 14:54:30 -07:00
("Content-Type", "application/json"),
create_service_authorization_header(
service_id=sample_email_template_with_placeholders.service.id
),
],
2023-05-25 10:50:01 -07:00
)
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
def test_should_not_send_notification_for_archived_template(
notify_api, sample_template
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
sample_template.archived = True
dao_update_template(sample_template)
2023-08-29 14:54:30 -07:00
json_data = json.dumps(
{"to": "+447700900855", "template": sample_template.id}
)
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
resp = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json_data,
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert resp.status_code == 400
json_resp = json.loads(resp.get_data(as_text=True))
2023-08-29 14:54:30 -07:00
assert "Template has been deleted" in json_resp["message"]
@pytest.mark.parametrize(
"template_type, to",
[
(TemplateType.SMS, "+447700900855"),
(TemplateType.EMAIL, "not-someone-we-trust@email-address.com"),
2023-08-29 14:54:30 -07:00
],
)
def test_should_not_send_notification_if_restricted_and_not_a_service_user(
notify_api, sample_template, sample_email_template, mocker, template_type, to
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
template = (
sample_template
if template_type == TemplateType.SMS
else sample_email_template
2023-08-29 14:54:30 -07:00
)
template.service.restricted = True
dao_update_service(template.service)
2023-08-29 14:54:30 -07:00
data = {"to": to, "template": template.id}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=template.service_id
)
response = client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
mocked.assert_not_called()
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
assert [
(
"Cant send to this recipient when service is in trial mode "
" see https://www.notifications.service.gov.uk/trial-mode"
)
] == json_resp["message"]["to"]
@pytest.mark.parametrize("template_type", [TemplateType.SMS, TemplateType.EMAIL])
2023-08-29 14:54:30 -07:00
def test_should_send_notification_if_restricted_and_a_service_user(
notify_api, sample_template, sample_email_template, template_type, mocker
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
2023-08-29 14:54:30 -07:00
template = (
sample_template
if template_type == TemplateType.SMS
else sample_email_template
2023-08-29 14:54:30 -07:00
)
to = (
template.service.created_by.mobile_number
if template_type == TemplateType.SMS
else template.service.created_by.email_address
2023-08-29 14:54:30 -07:00
)
template.service.restricted = True
dao_update_service(template.service)
2023-08-29 14:54:30 -07:00
data = {"to": to, "template": template.id}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=template.service_id
)
response = client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert mocked.called == 1
assert response.status_code == 201
@pytest.mark.parametrize("template_type", [TemplateType.SMS, TemplateType.EMAIL])
2023-08-29 14:54:30 -07:00
def test_should_not_allow_template_from_another_service(
notify_api, service_factory, sample_user, mocker, template_type
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
service_1 = service_factory.get(
"service 1", user=sample_user, email_from="service.1"
)
service_2 = service_factory.get(
"service 2", user=sample_user, email_from="service.2"
)
2023-08-29 14:54:30 -07:00
service_2_templates = dao_get_all_templates_for_service(
service_id=service_2.id
)
to = (
sample_user.mobile_number
if template_type == TemplateType.SMS
2023-08-29 14:54:30 -07:00
else sample_user.email_address
)
data = {"to": to, "template": service_2_templates[0].id}
auth_header = create_service_authorization_header(service_id=service_1.id)
response = client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
mocked.assert_not_called()
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
test_string = "Template not found"
assert test_string in json_resp["message"]
@freeze_time("2016-01-01 11:09:00.061258")
def test_should_allow_valid_sms_notification(notify_api, sample_template, mocker):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": "202 867 5309", "template": str(sample_template.id)}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
2023-08-29 14:54:30 -07:00
response_data = json.loads(response.data)["data"]
notification_id = response_data["notification"]["id"]
2023-08-29 14:54:30 -07:00
mocked.assert_called_once_with([notification_id], queue="send-sms-tasks")
assert response.status_code == 201
assert notification_id
2023-08-29 14:54:30 -07:00
assert "subject" not in response_data
assert response_data["body"] == sample_template.content
assert response_data["template_version"] == sample_template.version
2023-08-29 14:54:30 -07:00
def test_should_reject_email_notification_with_bad_email(
notify_api, sample_email_template, mocker
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
to_address = "bad-email"
2023-08-29 14:54:30 -07:00
data = {"to": to_address, "template": str(sample_email_template.service_id)}
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
data = json.loads(response.get_data(as_text=True))
mocked.apply_async.assert_not_called()
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
assert data["result"] == "error"
assert data["message"]["to"][0] == "Not a valid email address"
@freeze_time("2016-01-01 11:09:00.061258")
2023-08-29 14:54:30 -07:00
def test_should_allow_valid_email_notification(
notify_api, sample_email_template, mocker
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": "ok@ok.com", "template": str(sample_email_template.id)}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
response_data = json.loads(response.get_data(as_text=True))["data"]
notification_id = response_data["notification"]["id"]
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
2023-08-29 14:54:30 -07:00
[notification_id], queue="send-email-tasks"
)
assert response.status_code == 201
assert notification_id
2023-08-29 14:54:30 -07:00
assert response_data["subject"] == "Email Subject"
assert response_data["body"] == sample_email_template.content
assert response_data["template_version"] == sample_email_template.version
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize("restricted", [True, False])
@freeze_time("2016-01-01 12:00:00.061258")
def test_should_allow_api_call_if_under_day_limit_regardless_of_type(
2023-08-29 14:54:30 -07:00
notify_api, sample_user, mocker, restricted
):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
service = create_service(restricted=restricted, message_limit=2)
email_template = create_template(service, template_type=TemplateType.EMAIL)
sms_template = create_template(service, template_type=TemplateType.SMS)
create_notification(template=email_template)
2023-08-29 14:54:30 -07:00
data = {"to": sample_user.mobile_number, "template": str(sms_template.id)}
auth_header = create_service_authorization_header(service_id=service.id)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 201
def test_should_not_return_html_in_body(notify_api, sample_service, mocker):
with notify_api.test_request_context():
with notify_api.test_client() as client:
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
email_template = create_template(
sample_service, template_type=TemplateType.EMAIL, content="hello\nthere"
2023-08-29 14:54:30 -07:00
)
2023-08-29 14:54:30 -07:00
data = {"to": "ok@ok.com", "template": str(email_template.id)}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=email_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
assert (
json.loads(response.get_data(as_text=True))["data"]["body"]
== "hello\nthere"
)
2023-08-29 14:54:30 -07:00
def test_should_not_send_email_if_team_api_key_and_not_a_service_user(
client, sample_email_template, mocker
):
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
data = {
2023-08-29 14:54:30 -07:00
"to": "not-someone-we-trust@email-address.com",
"template": str(sample_email_template.id),
}
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id, key_type=KeyType.TEAM
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
app.celery.provider_tasks.deliver_email.apply_async.assert_not_called()
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
assert ["Cant send to this recipient using a team-only API key"] == json_resp[
"message"
]["to"]
2023-08-29 14:54:30 -07:00
def test_should_not_send_sms_if_team_api_key_and_not_a_service_user(
client, sample_template, mocker
):
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
data = {
2023-08-29 14:54:30 -07:00
"to": "2028675300",
"template": str(sample_template.id),
}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template.service_id, key_type=KeyType.TEAM
2023-08-29 14:54:30 -07:00
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
json_resp = json.loads(response.get_data(as_text=True))
app.celery.provider_tasks.deliver_sms.apply_async.assert_not_called()
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
assert ["Cant send to this recipient using a team-only API key"] == json_resp[
"message"
]["to"]
2023-08-29 14:54:30 -07:00
def test_should_send_email_if_team_api_key_and_a_service_user(
client, sample_email_template, fake_uuid, mocker
):
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
mocker.patch(
"app.notifications.process_notifications.uuid.uuid4", return_value=fake_uuid
)
data = {
2023-08-29 14:54:30 -07:00
"to": sample_email_template.service.created_by.email_address,
"template": sample_email_template.id,
}
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id, key_type=KeyType.TEAM
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
2023-08-29 14:54:30 -07:00
[fake_uuid], queue="send-email-tasks"
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize("restricted", [True, False])
@pytest.mark.parametrize("limit", [0, 1])
def test_should_send_sms_to_anyone_with_test_key(
client, sample_template, mocker, restricted, limit, fake_uuid
):
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
mocker.patch(
"app.notifications.process_notifications.uuid.uuid4", return_value=fake_uuid
)
2023-08-29 14:54:30 -07:00
data = {"to": "2028675300", "template": sample_template.id}
sample_template.service.restricted = restricted
sample_template.service.message_limit = limit
api_key = ApiKey(
service=sample_template.service,
2023-08-29 14:54:30 -07:00
name="test_key",
created_by=sample_template.created_by,
key_type=KeyType.TEST,
)
save_model_api_key(api_key)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=api_key.secret, client_id=str(api_key.service_id)
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with(
2023-08-29 14:54:30 -07:00
[fake_uuid], queue="send-sms-tasks"
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize("restricted", [True, False])
@pytest.mark.parametrize("limit", [0, 1])
def test_should_send_email_to_anyone_with_test_key(
client, sample_email_template, mocker, restricted, limit, fake_uuid
):
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
mocker.patch(
"app.notifications.process_notifications.uuid.uuid4", return_value=fake_uuid
)
2023-08-29 14:54:30 -07:00
data = {"to": "anyone123@example.com", "template": sample_email_template.id}
sample_email_template.service.restricted = restricted
sample_email_template.service.message_limit = limit
api_key = ApiKey(
service=sample_email_template.service,
2023-08-29 14:54:30 -07:00
name="test_key",
created_by=sample_email_template.created_by,
key_type=KeyType.TEST,
)
save_model_api_key(api_key)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=api_key.secret, client_id=str(api_key.service_id)
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
2023-08-29 14:54:30 -07:00
[fake_uuid], queue="send-email-tasks"
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
def test_should_send_sms_if_team_api_key_and_a_service_user(
client, sample_template, fake_uuid, mocker
):
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
mocker.patch(
"app.notifications.process_notifications.uuid.uuid4", return_value=fake_uuid
)
data = {
2023-08-29 14:54:30 -07:00
"to": sample_template.service.created_by.mobile_number,
"template": sample_template.id,
}
2023-08-29 14:54:30 -07:00
api_key = ApiKey(
service=sample_template.service,
name="team_key",
created_by=sample_template.created_by,
key_type=KeyType.TEAM,
2023-08-29 14:54:30 -07:00
)
save_model_api_key(api_key)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=api_key.secret, client_id=str(api_key.service_id)
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
2023-08-29 14:54:30 -07:00
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with(
[fake_uuid], queue="send-sms-tasks"
)
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"template_type,queue_name",
[
(TemplateType.SMS, "send-sms-tasks"),
(TemplateType.EMAIL, "send-email-tasks"),
],
2023-08-29 14:54:30 -07:00
)
def test_should_persist_notification(
client,
sample_template,
sample_email_template,
fake_uuid,
mocker,
template_type,
2023-08-29 14:54:30 -07:00
queue_name,
):
2023-08-29 14:54:30 -07:00
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
mocker.patch(
"app.notifications.process_notifications.uuid.uuid4", return_value=fake_uuid
)
template = (
sample_template if template_type == TemplateType.SMS else sample_email_template
)
2023-08-29 14:54:30 -07:00
to = (
sample_template.service.created_by.mobile_number
if template_type == TemplateType.SMS
else sample_email_template.service.created_by.email_address
2023-08-29 14:54:30 -07:00
)
data = {"to": to, "template": template.id}
api_key = ApiKey(
service=template.service,
2023-08-29 14:54:30 -07:00
name="team_key",
created_by=template.created_by,
key_type=KeyType.TEAM,
2023-08-29 14:54:30 -07:00
)
save_model_api_key(api_key)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=api_key.secret, client_id=str(api_key.service_id)
)
response = client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
mocked.assert_called_once_with([fake_uuid], queue=queue_name)
assert response.status_code == 201
notification = notifications_dao.get_notification_by_id(fake_uuid)
assert notification.to == "1"
assert notification.template_id == template.id
assert notification.notification_type == template_type
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"template_type,queue_name",
[(TemplateType.SMS, "send-sms-tasks"), (TemplateType.EMAIL, "send-email-tasks")],
2023-08-29 14:54:30 -07:00
)
2022-09-28 16:27:37 -04:00
def test_should_delete_notification_and_return_error_if_redis_fails(
client,
sample_email_template,
sample_template,
fake_uuid,
mocker,
template_type,
2023-08-29 14:54:30 -07:00
queue_name,
):
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{template_type}.apply_async",
2023-08-29 14:54:30 -07:00
side_effect=Exception("failed to talk to redis"),
)
mocker.patch(
"app.notifications.process_notifications.uuid.uuid4", return_value=fake_uuid
)
template = (
sample_template if template_type == TemplateType.SMS else sample_email_template
)
2023-08-29 14:54:30 -07:00
to = (
sample_template.service.created_by.mobile_number
if template_type == TemplateType.SMS
else sample_email_template.service.created_by.email_address
2023-08-29 14:54:30 -07:00
)
data = {"to": to, "template": template.id}
api_key = ApiKey(
service=template.service,
2023-08-29 14:54:30 -07:00
name="team_key",
created_by=template.created_by,
key_type=KeyType.TEAM,
2023-08-29 14:54:30 -07:00
)
save_model_api_key(api_key)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=api_key.secret, client_id=str(api_key.service_id)
)
2023-07-21 11:24:22 -07:00
with pytest.raises(expected_exception=Exception) as e:
client.post(
path=f"/notifications/{template_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
2023-08-29 14:54:30 -07:00
assert str(e.value) == "failed to talk to redis"
mocked.assert_called_once_with([fake_uuid], queue=queue_name)
assert not notifications_dao.get_notification_by_id(fake_uuid)
assert not NotificationHistory.query.get(fake_uuid)
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"to_email",
[
"simulate-delivered@notifications.service.gov.uk",
"simulate-delivered-2@notifications.service.gov.uk",
"simulate-delivered-3@notifications.service.gov.uk",
],
)
def test_should_not_persist_notification_or_send_email_if_simulated_email(
2023-08-29 14:54:30 -07:00
client, to_email, sample_email_template, mocker
):
apply_async = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": to_email, "template": sample_email_template.id}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_email_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 201
apply_async.assert_not_called()
assert Notification.query.count() == 0
2024-02-02 09:32:24 -08:00
@pytest.mark.parametrize("to_sms", ["+14254147755", "+14254147167"])
def test_should_not_persist_notification_or_send_sms_if_simulated_number(
2023-08-29 14:54:30 -07:00
client, to_sms, sample_template, mocker
):
apply_async = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": to_sms, "template": sample_template.id}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 201
apply_async.assert_not_called()
assert Notification.query.count() == 0
@pytest.mark.parametrize("key_type", [KeyType.NORMAL, KeyType.TEAM])
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"notification_type, to",
[
(TemplateType.SMS, "2028675300"),
(TemplateType.EMAIL, "non_guest_list_recipient@mail.com"),
],
)
def test_should_not_send_notification_to_non_guest_list_recipient_in_trial_mode(
2023-08-29 14:54:30 -07:00
client, sample_service_guest_list, notification_type, to, key_type, mocker
):
service = sample_service_guest_list.service
service.restricted = True
service.message_limit = 2
2023-08-29 14:54:30 -07:00
apply_async = mocker.patch(
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
template = create_template(service, template_type=notification_type)
assert sample_service_guest_list.service_id == service.id
assert to not in [member.recipient for member in service.guest_list]
create_notification(template=template)
2023-08-29 14:54:30 -07:00
data = {"to": to, "template": str(template.id)}
api_key = create_api_key(service, key_type=key_type)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=api_key.secret, client_id=str(api_key.service_id)
)
response = client.post(
path=f"/notifications/{notification_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
expected_response_message = (
2023-08-29 14:54:30 -07:00
(
"Cant send to this recipient when service is in trial mode "
" see https://www.notifications.service.gov.uk/trial-mode"
)
if key_type == KeyType.NORMAL
2023-08-29 14:54:30 -07:00
else ("Cant send to this recipient using a team-only API key")
)
json_resp = json.loads(response.get_data(as_text=True))
assert response.status_code == 400
2023-08-29 14:54:30 -07:00
assert json_resp["result"] == "error"
assert expected_response_message in json_resp["message"]["to"]
apply_async.assert_not_called()
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize("service_restricted", [True, False])
@pytest.mark.parametrize("key_type", [KeyType.NORMAL, KeyType.TEAM])
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"notification_type, to, normalized_to",
[
(NotificationType.SMS, "2028675300", "+12028675300"),
(NotificationType.EMAIL, "guest_list_recipient@mail.com", None),
2023-08-29 14:54:30 -07:00
],
)
def test_should_send_notification_to_guest_list_recipient(
client,
sample_service,
notification_type,
to,
2023-01-06 10:02:23 -05:00
normalized_to,
key_type,
service_restricted,
2023-08-29 14:54:30 -07:00
mocker,
):
sample_service.message_limit = 2
sample_service.restricted = service_restricted
2023-08-29 14:54:30 -07:00
apply_async = mocker.patch(
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
template = create_template(sample_service, template_type=notification_type)
if notification_type == NotificationType.SMS:
service_guest_list = create_service_guest_list(sample_service, mobile_number=to)
elif notification_type == NotificationType.EMAIL:
service_guest_list = create_service_guest_list(sample_service, email_address=to)
assert service_guest_list.service_id == sample_service.id
2023-08-29 14:54:30 -07:00
assert (normalized_to or to) in [
member.recipient for member in sample_service.guest_list
]
create_notification(template=template)
2023-08-29 14:54:30 -07:00
data = {"to": to, "template": str(template.id)}
sample_key = create_api_key(sample_service, key_type=key_type)
2023-08-29 14:54:30 -07:00
auth_header = create_jwt_token(
secret=sample_key.secret, client_id=str(sample_key.service_id)
)
response = client.post(
path=f"/notifications/{notification_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[
("Content-Type", "application/json"),
("Authorization", f"Bearer {auth_header}"),
2023-08-29 14:54:30 -07:00
],
)
json_resp = json.loads(response.get_data(as_text=True))
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
assert json_resp["data"]["notification"]["id"]
assert json_resp["data"]["body"] == template.content
assert json_resp["data"]["template_version"] == template.version
assert apply_async.called
2016-09-27 16:54:00 +01:00
@pytest.mark.parametrize(
2023-08-29 14:54:30 -07:00
"notification_type, template_type, to",
[
(NotificationType.EMAIL, TemplateType.SMS, "notify@digital.fake.gov"),
(NotificationType.SMS, TemplateType.EMAIL, "+12028675309"),
2023-08-29 14:54:30 -07:00
],
)
def test_should_error_if_notification_type_does_not_match_template_type(
2023-08-29 14:54:30 -07:00
client, sample_service, template_type, notification_type, to
):
template = create_template(sample_service, template_type=template_type)
2023-08-29 14:54:30 -07:00
data = {"to": to, "template": template.id}
auth_header = create_service_authorization_header(service_id=template.service_id)
2023-08-29 14:54:30 -07:00
response = client.post(
f"/notifications/{notification_type}",
2023-08-29 14:54:30 -07:00
data=json.dumps(data),
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 400
json_resp = json.loads(response.get_data(as_text=True))
2023-08-29 14:54:30 -07:00
assert json_resp["result"] == "error"
assert (
f"{template_type} template is not suitable for {notification_type} notification"
2023-08-29 14:54:30 -07:00
in json_resp["message"]
)
def test_create_template_raises_invalid_request_exception_with_missing_personalisation(
2023-08-29 14:54:30 -07:00
sample_template_with_placeholders,
):
template = Template.query.get(sample_template_with_placeholders.id)
from app.notifications.rest import create_template_object_for_notification
2023-08-29 14:54:30 -07:00
with pytest.raises(InvalidRequest) as e:
create_template_object_for_notification(template, {})
2023-08-29 14:54:30 -07:00
assert {"template": ["Missing personalisation: Name"]} == e.value.message
def test_create_template_doesnt_raise_with_too_much_personalisation(
2023-08-29 14:54:30 -07:00
sample_template_with_placeholders,
):
from app.notifications.rest import create_template_object_for_notification
2023-08-29 14:54:30 -07:00
template = Template.query.get(sample_template_with_placeholders.id)
2023-08-29 14:54:30 -07:00
create_template_object_for_notification(template, {"name": "Jo", "extra": "stuff"})
@pytest.mark.parametrize(
"template_type, should_error",
[
(TemplateType.SMS, True),
(TemplateType.EMAIL, False),
],
)
def test_create_template_raises_invalid_request_when_content_too_large(
2023-08-29 14:54:30 -07:00
sample_service, template_type, should_error
):
2023-08-29 14:54:30 -07:00
sample = create_template(
sample_service, template_type=template_type, content="((long_text))"
)
template = Template.query.get(sample.id)
from app.notifications.rest import create_template_object_for_notification
2023-08-29 14:54:30 -07:00
try:
2023-08-29 14:54:30 -07:00
create_template_object_for_notification(
template,
{
"long_text": "".join(
random.choice(string.ascii_uppercase + string.digits)
for _ in range(SMS_CHAR_COUNT_LIMIT + 1)
)
},
)
if should_error:
pytest.fail("expected an InvalidRequest")
except InvalidRequest as e:
if not should_error:
pytest.fail("do not expect an InvalidRequest")
2023-08-29 14:54:30 -07:00
assert e.message == {
"content": [
f"Content has a character count greater than the limit of {SMS_CHAR_COUNT_LIMIT}"
2023-08-29 14:54:30 -07:00
]
}
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"notification_type,send_to",
[
(NotificationType.SMS, "2028675309"),
(
NotificationType.EMAIL,
"sample@email.com",
),
],
2023-08-29 14:54:30 -07:00
)
def test_send_notification_uses_priority_queue_when_template_is_marked_as_priority(
client,
sample_service,
mocker,
notification_type,
send_to,
):
2023-08-29 14:54:30 -07:00
sample = create_template(
sample_service, template_type=notification_type, process_type="priority"
)
mocked = mocker.patch(
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
2023-08-29 14:54:30 -07:00
)
2023-08-29 14:54:30 -07:00
data = {"to": send_to, "template": str(sample.id)}
auth_header = create_service_authorization_header(service_id=sample.service_id)
response = client.post(
path=f"/notifications/{notification_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
2023-08-29 14:54:30 -07:00
response_data = json.loads(response.data)["data"]
notification_id = response_data["notification"]["id"]
assert response.status_code == 201
2023-08-29 14:54:30 -07:00
mocked.assert_called_once_with([notification_id], queue="priority-tasks")
@pytest.mark.parametrize(
"notification_type, send_to",
[
(NotificationType.SMS, "2028675309"),
(
NotificationType.EMAIL,
"sample@email.com",
),
],
)
def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded(
2023-08-29 14:54:30 -07:00
client, sample_service, mocker, notification_type, send_to
):
sample = create_template(sample_service, template_type=notification_type)
2023-08-29 14:54:30 -07:00
persist_mock = mocker.patch("app.notifications.rest.persist_notification")
deliver_mock = mocker.patch("app.notifications.rest.send_notification_to_queue")
mocker.patch(
2023-08-29 14:54:30 -07:00
"app.notifications.rest.check_rate_limiting",
side_effect=RateLimitError("LIMIT", "INTERVAL", "TYPE"),
)
2023-08-29 14:54:30 -07:00
data = {"to": send_to, "template": str(sample.id)}
auth_header = create_service_authorization_header(service_id=sample.service_id)
response = client.post(
path=f"/notifications/{notification_type}",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
2023-08-29 14:54:30 -07:00
message = json.loads(response.data)["message"]
result = json.loads(response.data)["result"]
assert response.status_code == 429
2023-08-29 14:54:30 -07:00
assert result == "error"
assert message == (
"Exceeded rate limit for key type TYPE of LIMIT "
"requests per INTERVAL seconds"
2023-08-29 14:54:30 -07:00
)
assert not persist_mock.called
assert not deliver_mock.called
2023-08-29 14:54:30 -07:00
def test_should_allow_store_original_number_on_sms_notification(
client, sample_template, mocker
):
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": "(202) 867-5309", "template": str(sample_template.id)}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
2023-08-29 14:54:30 -07:00
response_data = json.loads(response.data)["data"]
notification_id = response_data["notification"]["id"]
2023-08-29 14:54:30 -07:00
mocked.assert_called_once_with([notification_id], queue="send-sms-tasks")
assert response.status_code == 201
assert notification_id
notifications = Notification.query.all()
assert len(notifications) == 1
assert "1" == notifications[0].to
def test_should_not_allow_sending_to_international_number_without_international_permission(
client, sample_template, mocker
):
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
2023-08-29 14:54:30 -07:00
data = {"to": "+(44) 7700-900 855", "template": str(sample_template.id)}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert not mocked.called
assert response.status_code == 400
error_json = json.loads(response.get_data(as_text=True))
2023-08-29 14:54:30 -07:00
assert error_json["result"] == "error"
assert error_json["message"] == "Cannot send to international mobile numbers"
def test_should_allow_sending_to_international_number_with_international_permission(
client, sample_service_full_permissions, mocker
):
2023-08-29 14:54:30 -07:00
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
template = create_template(sample_service_full_permissions)
2023-08-29 14:54:30 -07:00
data = {"to": "+(44) 7700-900 855", "template": str(template.id)}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_service_full_permissions.id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 201
def test_should_not_allow_sms_notifications_if_service_permission_not_set(
client,
mocker,
sample_template_without_sms_permission,
):
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
data = {
2023-08-29 14:54:30 -07:00
"to": "+12028675309",
"template": str(sample_template_without_sms_permission.id),
}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template_without_sms_permission.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/sms",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert not mocked.called
assert response.status_code == 400
error_json = json.loads(response.get_data(as_text=True))
2023-08-29 14:54:30 -07:00
assert error_json["result"] == "error"
assert error_json["message"]["service"][0] == "Cannot send text messages"
def test_should_not_allow_email_notifications_if_service_permission_not_set(
client,
mocker,
sample_template_without_email_permission,
):
2023-08-29 14:54:30 -07:00
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
data = {
2023-08-29 14:54:30 -07:00
"to": "notify@digital.fake.gov",
"template": str(sample_template_without_email_permission.id),
}
2023-08-29 14:54:30 -07:00
auth_header = create_service_authorization_header(
service_id=sample_template_without_email_permission.service_id
)
response = client.post(
2023-08-29 14:54:30 -07:00
path="/notifications/email",
data=json.dumps(data),
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert not mocked.called
assert response.status_code == 400
error_json = json.loads(response.get_data(as_text=True))
2023-08-29 14:54:30 -07:00
assert error_json["result"] == "error"
assert error_json["message"]["service"][0] == "Cannot send emails"
@pytest.mark.parametrize(
"notification_type, err_msg",
2023-08-29 14:54:30 -07:00
[("apple", "apple notification type is not supported")],
)
def test_should_throw_exception_if_notification_type_is_invalid(
client, sample_service, notification_type, err_msg
):
auth_header = create_service_authorization_header(service_id=sample_service.id)
response = client.post(
path=f"/notifications/{notification_type}",
data={},
2023-08-29 14:54:30 -07:00
headers=[("Content-Type", "application/json"), auth_header],
)
assert response.status_code == 400
assert json.loads(response.get_data(as_text=True))["message"] == err_msg
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize(
"notification_type, recipient",
[
(NotificationType.SMS, "2028675309"),
(
NotificationType.EMAIL,
"test@gov.uk",
),
],
2023-08-29 14:54:30 -07:00
)
def test_post_notification_should_set_reply_to_text(
client, sample_service, mocker, notification_type, recipient
):
mocker.patch(f"app.celery.provider_tasks.deliver_{notification_type}.apply_async")
template = create_template(sample_service, template_type=notification_type)
2023-08-29 14:54:30 -07:00
expected_reply_to = current_app.config["FROM_NUMBER"]
if notification_type == NotificationType.EMAIL:
2023-08-29 14:54:30 -07:00
expected_reply_to = "reply_to@gov.uk"
create_reply_to_email(
service=sample_service, email_address=expected_reply_to, is_default=True
)
2023-08-29 14:54:30 -07:00
data = {"to": recipient, "template": str(template.id)}
response = client.post(
f"/notifications/{notification_type}",
2023-08-29 14:54:30 -07:00
data=json.dumps(data),
headers=[
("Content-Type", "application/json"),
create_service_authorization_header(service_id=sample_service.id),
],
)
assert response.status_code == 201
notifications = Notification.query.all()
assert len(notifications) == 1
assert notifications[0].reply_to_text == expected_reply_to
@pytest.mark.skip(reason="Rewrite without letters?")
2023-08-29 14:54:30 -07:00
@pytest.mark.parametrize("reference_paceholder,", [None, "ref2"])
def test_send_notification_should_set_client_reference_from_placeholder(
sample_letter_template, mocker, reference_paceholder
):
2023-08-29 14:54:30 -07:00
deliver_mock = mocker.patch(
"app.celery.tasks.letters_pdf_tasks.get_pdf_for_templated_letter.apply_async"
)
data = {
2023-08-29 14:54:30 -07:00
"template_id": sample_letter_template.id,
"personalisation": {
"address_line_1": "Jane",
"address_line_2": "Moss Lane",
"address_line_3": "SW1A 1AA",
},
2023-08-29 14:54:30 -07:00
"to": "Jane",
"created_by": sample_letter_template.service.created_by_id,
}
if reference_paceholder:
2023-08-29 14:54:30 -07:00
data["personalisation"]["reference"] = reference_paceholder
notification_id = send_one_off_notification(sample_letter_template.service_id, data)
assert deliver_mock.called
2023-08-29 14:54:30 -07:00
notification = Notification.query.get(notification_id["id"])
assert notification.client_reference == reference_paceholder