2016-10-31 12:22:26 +00:00
|
|
|
|
import uuid
|
2020-03-25 07:59:05 +00:00
|
|
|
|
from unittest import mock
|
2020-02-12 16:07:07 +00:00
|
|
|
|
from unittest.mock import call
|
2017-05-23 10:35:13 +01:00
|
|
|
|
|
2021-10-29 10:51:22 +01:00
|
|
|
|
import botocore
|
2016-11-14 13:56:09 +00:00
|
|
|
|
import pytest
|
2021-03-10 13:55:06 +00:00
|
|
|
|
from flask import current_app, json
|
2017-05-16 09:57:58 +01:00
|
|
|
|
|
2020-06-22 09:39:46 +01:00
|
|
|
|
from app.dao import templates_dao
|
2017-11-23 14:55:49 +00:00
|
|
|
|
from app.dao.service_sms_sender_dao import dao_update_service_sms_sender
|
2024-02-20 17:00:54 -05:00
|
|
|
|
from app.enums import (
|
|
|
|
|
|
KeyType,
|
|
|
|
|
|
NotificationStatus,
|
|
|
|
|
|
NotificationType,
|
|
|
|
|
|
ServicePermissionType,
|
2024-02-21 14:50:36 -05:00
|
|
|
|
TemplateProcessType,
|
2024-02-20 17:00:54 -05:00
|
|
|
|
TemplateType,
|
2017-11-07 14:26:18 +00:00
|
|
|
|
)
|
2024-01-16 15:52:44 -05:00
|
|
|
|
from app.models import Notification
|
2017-09-11 11:10:45 +01:00
|
|
|
|
from app.schema_validation import validate
|
2017-04-24 14:15:08 +01:00
|
|
|
|
from app.v2.errors import RateLimitError
|
2021-03-10 13:55:06 +00:00
|
|
|
|
from app.v2.notifications.notification_schemas import (
|
|
|
|
|
|
post_email_response,
|
|
|
|
|
|
post_sms_response,
|
|
|
|
|
|
)
|
2021-08-04 15:12:09 +01:00
|
|
|
|
from tests import create_service_authorization_header
|
2017-10-24 13:37:17 +01:00
|
|
|
|
from tests.app.db import (
|
2021-03-10 13:55:06 +00:00
|
|
|
|
create_api_key,
|
2017-10-30 13:36:49 +00:00
|
|
|
|
create_reply_to_email,
|
2021-03-10 13:55:06 +00:00
|
|
|
|
create_service,
|
2017-11-29 16:47:23 +00:00
|
|
|
|
create_service_sms_sender,
|
2019-06-11 16:45:35 +01:00
|
|
|
|
create_service_with_inbound_number,
|
2021-03-10 13:55:06 +00:00
|
|
|
|
create_template,
|
2017-11-07 14:26:18 +00:00
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
from tests.conftest import set_config_values
|
2016-10-27 11:46:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-06-17 13:48:48 +01:00
|
|
|
|
@pytest.mark.parametrize("reference", [None, "reference_from_client"])
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_sms_notification_returns_201(
|
|
|
|
|
|
client, sample_template_with_placeholders, mocker, reference
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-05-25 11:41:07 +01:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(sample_template_with_placeholders.id),
|
|
|
|
|
|
"personalisation": {" Name": "Jo"},
|
2017-05-25 11:41:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
if reference:
|
|
|
|
|
|
data.update({"reference": reference})
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template_with_placeholders.service_id
|
|
|
|
|
|
)
|
2020-06-17 12:13:49 +01:00
|
|
|
|
|
2017-05-25 11:41:07 +01:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-05-25 11:41:07 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2020-06-17 12:13:49 +01:00
|
|
|
|
|
2017-05-25 11:41:07 +01:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2017-09-11 11:10:45 +01:00
|
|
|
|
assert validate(resp_json, post_sms_response) == resp_json
|
2017-05-25 11:41:07 +01:00
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
2024-01-16 15:52:44 -05:00
|
|
|
|
assert notifications[0].status == NotificationStatus.CREATED
|
2017-05-25 11:41:07 +01:00
|
|
|
|
notification_id = notifications[0].id
|
2020-02-12 16:07:07 +00:00
|
|
|
|
assert notifications[0].document_download_count is None
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["id"] == str(notification_id)
|
|
|
|
|
|
assert resp_json["reference"] == reference
|
|
|
|
|
|
assert resp_json["content"][
|
|
|
|
|
|
"body"
|
|
|
|
|
|
] == sample_template_with_placeholders.content.replace("(( Name))", "Jo")
|
|
|
|
|
|
assert resp_json["content"]["from_number"] == current_app.config["FROM_NUMBER"]
|
2024-02-20 17:00:54 -05:00
|
|
|
|
assert f"v2/notifications/{notification_id}" in resp_json["uri"]
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["template"]["id"] == str(sample_template_with_placeholders.id)
|
|
|
|
|
|
assert resp_json["template"]["version"] == sample_template_with_placeholders.version
|
|
|
|
|
|
assert (
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"services/{sample_template_with_placeholders.service_id}/templates/"
|
2024-02-22 09:33:36 -05:00
|
|
|
|
f"{sample_template_with_placeholders.id}"
|
2024-02-20 17:00:54 -05:00
|
|
|
|
) in resp_json["template"]["uri"]
|
2017-05-25 11:41:07 +01:00
|
|
|
|
assert not resp_json["scheduled_for"]
|
|
|
|
|
|
assert mocked.called
|
2016-10-27 11:46:37 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_sms_notification_uses_inbound_number_as_sender(
|
|
|
|
|
|
client, notify_db_session, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
service = create_service_with_inbound_number(inbound_number="1")
|
2017-11-07 14:26:18 +00:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
template = create_template(
|
|
|
|
|
|
service=service, content="Hello (( Name))\nYour thing is due soon"
|
|
|
|
|
|
)
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-08-14 19:47:09 +01:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(template.id),
|
|
|
|
|
|
"personalisation": {" Name": "Jo"},
|
2017-08-14 19:47:09 +01:00
|
|
|
|
}
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=service.id)
|
2017-08-14 19:47:09 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-08-14 19:47:09 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-08-14 19:47:09 +01:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2017-09-11 11:10:45 +01:00
|
|
|
|
assert validate(resp_json, post_sms_response) == resp_json
|
2017-08-14 19:47:09 +01:00
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
|
|
|
|
|
notification_id = notifications[0].id
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["id"] == str(notification_id)
|
|
|
|
|
|
assert resp_json["content"]["from_number"] == "1"
|
|
|
|
|
|
assert notifications[0].reply_to_text == "1"
|
|
|
|
|
|
mocked.assert_called_once_with([str(notification_id)], queue="send-sms-tasks")
|
2017-08-14 19:47:09 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_sms_notification_uses_inbound_number_reply_to_as_sender(
|
|
|
|
|
|
client, notify_db_session, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
service = create_service_with_inbound_number(inbound_number="2028675309")
|
2017-12-18 16:17:20 +00:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
template = create_template(
|
|
|
|
|
|
service=service, content="Hello (( Name))\nYour thing is due soon"
|
|
|
|
|
|
)
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-12-18 16:17:20 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(template.id),
|
|
|
|
|
|
"personalisation": {" Name": "Jo"},
|
2017-12-18 16:17:20 +00:00
|
|
|
|
}
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=service.id)
|
2017-12-18 16:17:20 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-12-18 16:17:20 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-12-18 16:17:20 +00:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
assert validate(resp_json, post_sms_response) == resp_json
|
|
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
|
|
|
|
|
notification_id = notifications[0].id
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["id"] == str(notification_id)
|
|
|
|
|
|
assert resp_json["content"]["from_number"] == "+12028675309"
|
|
|
|
|
|
assert notifications[0].reply_to_text == "+12028675309"
|
|
|
|
|
|
mocked.assert_called_once_with([str(notification_id)], queue="send-sms-tasks")
|
2017-12-18 16:17:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-30 13:36:49 +00:00
|
|
|
|
def test_post_sms_notification_returns_201_with_sms_sender_id(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, sample_template_with_placeholders, mocker
|
2017-10-30 13:36:49 +00:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sms_sender = create_service_sms_sender(
|
|
|
|
|
|
service=sample_template_with_placeholders.service, sms_sender="123456"
|
|
|
|
|
|
)
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-10-30 13:36:49 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(sample_template_with_placeholders.id),
|
|
|
|
|
|
"personalisation": {" Name": "Jo"},
|
|
|
|
|
|
"sms_sender_id": str(sms_sender.id),
|
2017-10-30 13:36:49 +00:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template_with_placeholders.service_id
|
|
|
|
|
|
)
|
2017-10-30 13:36:49 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-10-30 13:36:49 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-10-30 13:36:49 +00:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
assert validate(resp_json, post_sms_response) == resp_json
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["content"]["from_number"] == sms_sender.sms_sender
|
2017-11-23 14:55:49 +00:00
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
|
|
|
|
|
assert notifications[0].reply_to_text == sms_sender.sms_sender
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocked.assert_called_once_with([resp_json["id"]], queue="send-sms-tasks")
|
2017-12-18 16:17:20 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_post_sms_notification_uses_sms_sender_id_reply_to(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, sample_template_with_placeholders, mocker
|
2017-12-18 16:17:20 +00:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sms_sender = create_service_sms_sender(
|
|
|
|
|
|
service=sample_template_with_placeholders.service, sms_sender="2028675309"
|
|
|
|
|
|
)
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-12-18 16:17:20 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(sample_template_with_placeholders.id),
|
|
|
|
|
|
"personalisation": {" Name": "Jo"},
|
|
|
|
|
|
"sms_sender_id": str(sms_sender.id),
|
2017-12-18 16:17:20 +00:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template_with_placeholders.service_id
|
|
|
|
|
|
)
|
2017-12-18 16:17:20 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-12-18 16:17:20 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-12-18 16:17:20 +00:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
assert validate(resp_json, post_sms_response) == resp_json
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["content"]["from_number"] == "+12028675309"
|
2017-12-18 16:17:20 +00:00
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert notifications[0].reply_to_text == "+12028675309"
|
|
|
|
|
|
mocked.assert_called_once_with([resp_json["id"]], queue="send-sms-tasks")
|
2017-10-30 13:36:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-11-23 14:55:49 +00:00
|
|
|
|
def test_notification_reply_to_text_is_original_value_if_sender_is_changed_after_post_notification(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, sample_template, mocker
|
2017-11-23 14:55:49 +00:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sms_sender = create_service_sms_sender(
|
|
|
|
|
|
service=sample_template.service, sms_sender="123456", is_default=False
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-11-23 14:55:49 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+12028675309",
|
|
|
|
|
|
"template_id": str(sample_template.id),
|
|
|
|
|
|
"sms_sender_id": str(sms_sender.id),
|
2017-11-23 14:55:49 +00:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template.service_id
|
|
|
|
|
|
)
|
2017-11-23 14:55:49 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-11-23 14:55:49 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-11-23 14:55:49 +00:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
dao_update_service_sms_sender(
|
|
|
|
|
|
service_id=sample_template.service_id,
|
|
|
|
|
|
service_sms_sender_id=sms_sender.id,
|
|
|
|
|
|
is_default=sms_sender.is_default,
|
|
|
|
|
|
sms_sender="updated",
|
|
|
|
|
|
)
|
2017-11-23 14:55:49 +00:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert notifications[0].reply_to_text == "123456"
|
2017-11-23 14:55:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
2020-06-22 09:39:46 +01:00
|
|
|
|
def test_should_cache_template_lookups_in_memory(mocker, client, sample_template):
|
|
|
|
|
|
mock_get_template = mocker.patch(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"app.dao.templates_dao.dao_get_template_by_id_and_service_id",
|
2020-06-22 09:39:46 +01:00
|
|
|
|
wraps=templates_dao.dao_get_template_by_id_and_service_id,
|
|
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2020-06-22 09:39:46 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "2028675309",
|
|
|
|
|
|
"template_id": str(sample_template.id),
|
2020-06-22 09:39:46 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-22 15:46:31 +00:00
|
|
|
|
for _ in range(5):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template.service_id
|
|
|
|
|
|
)
|
2020-06-22 09:39:46 +01:00
|
|
|
|
client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2020-06-22 09:39:46 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
2020-06-22 09:39:46 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2020-06-23 13:48:55 +01:00
|
|
|
|
assert mock_get_template.call_count == 1
|
2020-06-22 09:39:46 +01:00
|
|
|
|
assert mock_get_template.call_args_list == [
|
2023-08-29 14:54:30 -07:00
|
|
|
|
call(
|
|
|
|
|
|
service_id=str(sample_template.service_id),
|
|
|
|
|
|
template_id=str(sample_template.id),
|
|
|
|
|
|
version=None,
|
|
|
|
|
|
)
|
2020-06-22 09:39:46 +01:00
|
|
|
|
]
|
|
|
|
|
|
assert Notification.query.count() == 5
|
|
|
|
|
|
|
2022-10-14 14:45:27 +00:00
|
|
|
|
|
2020-06-26 14:10:12 +01:00
|
|
|
|
def test_should_cache_template_and_service_in_redis(mocker, client, sample_template):
|
|
|
|
|
|
from app.schemas import service_schema, template_schema
|
2020-06-22 09:39:47 +01:00
|
|
|
|
|
|
|
|
|
|
mock_redis_get = mocker.patch(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"app.redis_store.get",
|
2020-06-22 09:39:47 +01:00
|
|
|
|
return_value=None,
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_redis_set = mocker.patch(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"app.redis_store.set",
|
2020-06-22 09:39:47 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2020-06-22 09:39:47 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(sample_template.id),
|
2020-06-22 09:39:47 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template.service_id
|
|
|
|
|
|
)
|
2020-06-22 09:39:47 +01:00
|
|
|
|
client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2020-06-22 09:39:47 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
2020-06-22 09:39:47 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
expected_service_key = f"service-{sample_template.service_id}"
|
|
|
|
|
|
expected_templates_key = f"service-{sample_template.service_id}-template-{sample_template.id}-version-None"
|
2020-06-22 09:39:47 +01:00
|
|
|
|
|
2020-06-26 14:10:12 +01:00
|
|
|
|
assert mock_redis_get.call_args_list == [
|
|
|
|
|
|
call(expected_service_key),
|
|
|
|
|
|
call(expected_templates_key),
|
|
|
|
|
|
]
|
2020-06-22 09:39:47 +01:00
|
|
|
|
|
2022-05-06 15:52:44 +01:00
|
|
|
|
service_dict = service_schema.dump(sample_template.service)
|
|
|
|
|
|
template_dict = template_schema.dump(sample_template)
|
2020-06-22 09:39:47 +01:00
|
|
|
|
|
2020-06-26 14:10:12 +01:00
|
|
|
|
assert len(mock_redis_set.call_args_list) == 2
|
|
|
|
|
|
|
|
|
|
|
|
service_call, templates_call = mock_redis_set.call_args_list
|
|
|
|
|
|
|
|
|
|
|
|
assert service_call[0][0] == expected_service_key
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert json.loads(service_call[0][1]) == {"data": service_dict}
|
|
|
|
|
|
assert service_call[1]["ex"] == 604_800
|
2020-06-26 14:10:12 +01:00
|
|
|
|
|
|
|
|
|
|
assert templates_call[0][0] == expected_templates_key
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert json.loads(templates_call[0][1]) == {"data": template_dict}
|
|
|
|
|
|
assert templates_call[1]["ex"] == 604_800
|
2020-06-22 09:39:47 +01:00
|
|
|
|
|
2022-10-14 14:45:27 +00:00
|
|
|
|
|
2020-06-23 14:00:07 +01:00
|
|
|
|
def test_should_return_template_if_found_in_redis(mocker, client, sample_template):
|
2020-06-26 14:10:12 +01:00
|
|
|
|
from app.schemas import service_schema, template_schema
|
2023-08-29 14:54:30 -07:00
|
|
|
|
|
2022-05-06 15:52:44 +01:00
|
|
|
|
service_dict = service_schema.dump(sample_template.service)
|
|
|
|
|
|
template_dict = template_schema.dump(sample_template)
|
2020-06-23 14:00:07 +01:00
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"app.redis_store.get",
|
2020-06-26 14:10:12 +01:00
|
|
|
|
side_effect=[
|
2023-08-29 14:54:30 -07:00
|
|
|
|
json.dumps({"data": service_dict}).encode("utf-8"),
|
|
|
|
|
|
json.dumps({"data": template_dict}).encode("utf-8"),
|
2020-06-26 14:10:12 +01:00
|
|
|
|
],
|
2020-06-23 14:00:07 +01:00
|
|
|
|
)
|
|
|
|
|
|
mock_get_template = mocker.patch(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"app.dao.templates_dao.dao_get_template_by_id_and_service_id"
|
2020-06-26 14:10:12 +01:00
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mock_get_service = mocker.patch("app.dao.services_dao.dao_fetch_service_by_id")
|
2020-06-23 14:00:07 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2020-06-23 14:00:07 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+16615555555",
|
|
|
|
|
|
"template_id": str(sample_template.id),
|
2020-06-23 14:00:07 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template.service_id
|
|
|
|
|
|
)
|
2020-06-23 14:00:07 +01:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2020-06-23 14:00:07 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
2020-06-23 14:00:07 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
assert mock_get_template.called is False
|
2020-06-26 14:10:12 +01:00
|
|
|
|
assert mock_get_service.called is False
|
2020-06-23 14:00:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type, key_send_to, send_to",
|
|
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(NotificationType.SMS, "phone_number", "+447700900855"),
|
|
|
|
|
|
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_post_notification_returns_400_and_missing_template(
|
|
|
|
|
|
client, sample_service, notification_type, key_send_to, send_to
|
|
|
|
|
|
):
|
|
|
|
|
|
data = {key_send_to: send_to, "template_id": str(uuid.uuid4())}
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
2016-10-27 11:46:37 +01:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-01-17 13:16:26 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2016-10-27 11:46:37 +01:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
assert response.status_code == 400
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert response.headers["Content-type"] == "application/json"
|
2016-10-31 12:22:26 +00:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
error_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_json["status_code"] == 400
|
|
|
|
|
|
assert error_json["errors"] == [
|
|
|
|
|
|
{"error": "BadRequestError", "message": "Template not found"}
|
|
|
|
|
|
]
|
2016-10-31 12:22:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type, key_send_to, send_to",
|
|
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(NotificationType.SMS, "phone_number", "+447700900855"),
|
|
|
|
|
|
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_post_notification_returns_401_and_well_formed_auth_error(
|
|
|
|
|
|
client, sample_template, notification_type, key_send_to, send_to
|
|
|
|
|
|
):
|
|
|
|
|
|
data = {key_send_to: send_to, "template_id": str(sample_template.id)}
|
2016-10-31 12:22:26 +00:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-01-17 13:16:26 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json")],
|
|
|
|
|
|
)
|
2016-10-31 12:22:26 +00:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
assert response.status_code == 401
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert response.headers["Content-type"] == "application/json"
|
2017-01-17 13:16:26 +00:00
|
|
|
|
error_resp = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_resp["status_code"] == 401
|
|
|
|
|
|
assert error_resp["errors"] == [
|
|
|
|
|
|
{
|
|
|
|
|
|
"error": "AuthError",
|
|
|
|
|
|
"message": "Unauthorized: authentication token must be provided",
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2016-10-31 15:43:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type, key_send_to, send_to",
|
|
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(NotificationType.SMS, "phone_number", "+447700900855"),
|
|
|
|
|
|
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_notification_returns_400_and_for_schema_problems(
|
|
|
|
|
|
client, sample_template, notification_type, key_send_to, send_to
|
|
|
|
|
|
):
|
|
|
|
|
|
data = {key_send_to: send_to, "template": str(sample_template.id)}
|
|
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template.service_id
|
|
|
|
|
|
)
|
2016-10-31 15:43:11 +00:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-01-17 13:16:26 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2016-10-31 15:43:11 +00:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
assert response.status_code == 400
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert response.headers["Content-type"] == "application/json"
|
2017-01-17 13:16:26 +00:00
|
|
|
|
error_resp = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_resp["status_code"] == 400
|
|
|
|
|
|
assert {
|
|
|
|
|
|
"error": "ValidationError",
|
|
|
|
|
|
"message": "template_id is a required property",
|
|
|
|
|
|
} in error_resp["errors"]
|
|
|
|
|
|
assert {
|
|
|
|
|
|
"error": "ValidationError",
|
|
|
|
|
|
"message": "Additional properties are not allowed (template was unexpected)",
|
|
|
|
|
|
} in error_resp["errors"]
|
2016-11-14 13:56:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-11-21 17:32:36 +00:00
|
|
|
|
@pytest.mark.parametrize("reference", [None, "reference_from_client"])
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_email_notification_returns_201(
|
|
|
|
|
|
client, sample_email_template_with_placeholders, mocker, reference
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2016-11-14 13:56:09 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_address": sample_email_template_with_placeholders.service.users[
|
|
|
|
|
|
0
|
|
|
|
|
|
].email_address,
|
2016-11-28 15:49:29 +00:00
|
|
|
|
"template_id": sample_email_template_with_placeholders.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"personalisation": {"name": "Bob"},
|
2016-11-14 13:56:09 +00:00
|
|
|
|
}
|
2016-11-21 17:32:36 +00:00
|
|
|
|
if reference:
|
|
|
|
|
|
data.update({"reference": reference})
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_email_template_with_placeholders.service_id
|
|
|
|
|
|
)
|
2016-11-14 13:56:09 +00:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2016-11-14 13:56:09 +00:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2017-09-11 11:10:45 +01:00
|
|
|
|
assert validate(resp_json, post_email_response) == resp_json
|
2017-10-16 15:33:21 +01:00
|
|
|
|
notification = Notification.query.one()
|
2024-01-16 15:52:44 -05:00
|
|
|
|
assert notification.status == NotificationStatus.CREATED
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["id"] == str(notification.id)
|
|
|
|
|
|
assert resp_json["reference"] == reference
|
2017-03-30 10:46:23 +01:00
|
|
|
|
assert notification.reference is None
|
2017-11-23 14:55:49 +00:00
|
|
|
|
assert notification.reply_to_text is None
|
2020-02-12 16:07:07 +00:00
|
|
|
|
assert notification.document_download_count is None
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["content"][
|
|
|
|
|
|
"body"
|
|
|
|
|
|
] == sample_email_template_with_placeholders.content.replace("((name))", "Bob")
|
|
|
|
|
|
assert resp_json["content"][
|
|
|
|
|
|
"subject"
|
|
|
|
|
|
] == sample_email_template_with_placeholders.subject.replace("((name))", "Bob")
|
2024-02-20 17:00:54 -05:00
|
|
|
|
assert resp_json["content"]["from_email"] == (
|
|
|
|
|
|
f"{sample_email_template_with_placeholders.service.email_from}@"
|
|
|
|
|
|
f"{current_app.config['NOTIFY_EMAIL_DOMAIN']}"
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
2024-02-20 17:00:54 -05:00
|
|
|
|
assert f"v2/notifications/{notification.id}" in resp_json["uri"]
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["template"]["id"] == str(
|
|
|
|
|
|
sample_email_template_with_placeholders.id
|
|
|
|
|
|
)
|
|
|
|
|
|
assert (
|
|
|
|
|
|
resp_json["template"]["version"]
|
|
|
|
|
|
== sample_email_template_with_placeholders.version
|
|
|
|
|
|
)
|
|
|
|
|
|
assert (
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"services/{sample_email_template_with_placeholders.service_id}/templates/"
|
|
|
|
|
|
f"{sample_email_template_with_placeholders.id}"
|
|
|
|
|
|
) in resp_json["template"]["uri"]
|
2017-05-15 17:27:38 +01:00
|
|
|
|
assert not resp_json["scheduled_for"]
|
2016-11-14 13:56:09 +00:00
|
|
|
|
assert mocked.called
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"recipient, notification_type",
|
|
|
|
|
|
[
|
2024-01-18 10:26:40 -05:00
|
|
|
|
("simulate-delivered@notifications.service.gov.uk", NotificationType.EMAIL),
|
|
|
|
|
|
("simulate-delivered-2@notifications.service.gov.uk", NotificationType.EMAIL),
|
|
|
|
|
|
("simulate-delivered-3@notifications.service.gov.uk", NotificationType.EMAIL),
|
2024-02-20 17:00:54 -05:00
|
|
|
|
("+14254147167", NotificationType.SMS),
|
|
|
|
|
|
("+14254147755", NotificationType.SMS),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-01-18 09:56:26 +00:00
|
|
|
|
def test_should_not_persist_or_send_notification_if_simulated_recipient(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, recipient, notification_type, sample_email_template, sample_template, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
apply_async = mocker.patch(
|
2024-02-21 11:27:38 -05:00
|
|
|
|
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
|
|
|
|
|
|
2024-02-20 17:00:54 -05:00
|
|
|
|
if notification_type == NotificationType.SMS:
|
2023-08-29 14:54:30 -07:00
|
|
|
|
data = {"phone_number": recipient, "template_id": str(sample_template.id)}
|
2017-01-17 12:08:24 +00:00
|
|
|
|
else:
|
|
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_address": recipient,
|
|
|
|
|
|
"template_id": str(sample_email_template.id),
|
2017-01-17 12:08:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_email_template.service_id
|
|
|
|
|
|
)
|
2017-01-17 12:08:24 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-01-17 12:08:24 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-01-17 12:08:24 +00:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
apply_async.assert_not_called()
|
2017-07-20 17:56:51 +01:00
|
|
|
|
assert json.loads(response.get_data(as_text=True))["id"]
|
2017-01-17 12:08:24 +00:00
|
|
|
|
assert Notification.query.count() == 0
|
2017-01-17 13:16:26 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type, key_send_to, send_to",
|
|
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(NotificationType.SMS, "phone_number", "2028675309"),
|
|
|
|
|
|
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
2019-06-11 16:45:35 +01:00
|
|
|
|
def test_send_notification_uses_priority_queue_when_template_is_marked_as_priority(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
client,
|
|
|
|
|
|
sample_service,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
notification_type,
|
|
|
|
|
|
key_send_to,
|
|
|
|
|
|
send_to,
|
2019-06-11 16:45:35 +01:00
|
|
|
|
):
|
2024-02-20 17:00:54 -05:00
|
|
|
|
mocker.patch(f"app.celery.provider_tasks.deliver_{notification_type}.apply_async")
|
2017-04-27 12:47:08 +01:00
|
|
|
|
|
2019-06-11 16:45:35 +01:00
|
|
|
|
sample = create_template(
|
2024-02-21 14:50:36 -05:00
|
|
|
|
service=sample_service,
|
|
|
|
|
|
template_type=notification_type,
|
|
|
|
|
|
process_type=TemplateProcessType.PRIORITY,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
|
|
|
|
|
mocked = mocker.patch(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
2017-01-17 13:16:26 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
data = {key_send_to: send_to, "template_id": str(sample.id)}
|
2017-01-17 13:16:26 +00:00
|
|
|
|
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample.service_id)
|
2017-01-17 13:16:26 +00:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-01-17 13:16:26 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-01-17 13:16:26 +00:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notification_id = json.loads(response.data)["id"]
|
2017-03-30 10:46:23 +01:00
|
|
|
|
|
2017-01-17 13:16:26 +00:00
|
|
|
|
assert response.status_code == 201
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocked.assert_called_once_with([notification_id], queue="priority-tasks")
|
2017-04-24 14:15:08 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type, key_send_to, send_to",
|
2023-08-29 14:54:30 -07:00
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(NotificationType.SMS, "phone_number", "2028675309"),
|
|
|
|
|
|
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
2017-04-24 14:15:08 +01:00
|
|
|
|
)
|
|
|
|
|
|
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, key_send_to, send_to
|
2017-04-24 14:15:08 +01:00
|
|
|
|
):
|
2019-06-11 16:45:35 +01:00
|
|
|
|
sample = create_template(service=sample_service, template_type=notification_type)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
persist_mock = mocker.patch(
|
|
|
|
|
|
"app.v2.notifications.post_notifications.persist_notification"
|
|
|
|
|
|
)
|
|
|
|
|
|
deliver_mock = mocker.patch(
|
|
|
|
|
|
"app.v2.notifications.post_notifications.send_notification_to_queue_detached"
|
|
|
|
|
|
)
|
2017-04-24 14:15:08 +01:00
|
|
|
|
mocker.patch(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"app.v2.notifications.post_notifications.check_rate_limiting",
|
|
|
|
|
|
side_effect=RateLimitError("LIMIT", "INTERVAL", "TYPE"),
|
|
|
|
|
|
)
|
2017-04-24 14:15:08 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
data = {key_send_to: send_to, "template_id": str(sample.id)}
|
2017-04-24 14:15:08 +01:00
|
|
|
|
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample.service_id)
|
2017-04-24 14:15:08 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-04-24 14:15:08 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-04-24 14:15:08 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
error = json.loads(response.data)["errors"][0]["error"]
|
|
|
|
|
|
message = json.loads(response.data)["errors"][0]["message"]
|
|
|
|
|
|
status_code = json.loads(response.data)["status_code"]
|
2017-04-24 14:15:08 +01:00
|
|
|
|
assert response.status_code == 429
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error == "RateLimitError"
|
|
|
|
|
|
assert (
|
|
|
|
|
|
message
|
|
|
|
|
|
== "Exceeded rate limit for key type TYPE of LIMIT requests per INTERVAL seconds"
|
|
|
|
|
|
)
|
2017-04-24 14:15:08 +01:00
|
|
|
|
assert status_code == 429
|
|
|
|
|
|
|
|
|
|
|
|
assert not persist_mock.called
|
|
|
|
|
|
assert not deliver_mock.called
|
2017-05-02 10:56:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-10-19 11:06:28 +01:00
|
|
|
|
def test_post_sms_notification_returns_400_if_not_allowed_to_send_int_sms(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client,
|
|
|
|
|
|
notify_db_session,
|
2017-10-19 11:06:28 +01:00
|
|
|
|
):
|
2024-01-18 10:26:40 -05:00
|
|
|
|
service = create_service(service_permissions=[ServicePermissionType.SMS])
|
2019-06-11 16:45:35 +01:00
|
|
|
|
template = create_template(service=service)
|
2017-10-19 11:06:28 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
data = {"phone_number": "+20-12-1234-1234", "template_id": template.id}
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=service.id)
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-04-26 15:56:45 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
2017-10-19 11:06:28 +01:00
|
|
|
|
)
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 400
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert response.headers["Content-type"] == "application/json"
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
|
|
|
|
|
error_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_json["status_code"] == 400
|
|
|
|
|
|
assert error_json["errors"] == [
|
|
|
|
|
|
{
|
|
|
|
|
|
"error": "BadRequestError",
|
|
|
|
|
|
"message": "Cannot send to international mobile numbers",
|
|
|
|
|
|
}
|
2017-04-26 15:56:45 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_sms_notification_with_archived_reply_to_id_returns_400(
|
|
|
|
|
|
client, sample_template, mocker
|
|
|
|
|
|
):
|
2018-04-25 14:23:00 +01:00
|
|
|
|
archived_sender = create_service_sms_sender(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sample_template.service, "12345", is_default=False, archived=True
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2018-04-25 14:23:00 +01:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
2018-04-25 14:23:00 +01:00
|
|
|
|
"template_id": sample_template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"sms_sender_id": archived_sender.id,
|
2018-04-25 14:23:00 +01:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template.service_id
|
|
|
|
|
|
)
|
2018-04-25 14:23:00 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/sms",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2018-04-25 14:23:00 +01:00
|
|
|
|
assert response.status_code == 400
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert (
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"sms_sender_id {archived_sender.id} does not exist in database for "
|
|
|
|
|
|
f"service id {sample_template.service_id}"
|
|
|
|
|
|
) in resp_json["errors"][0]["message"]
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert "BadRequestError" in resp_json["errors"][0]["error"]
|
2018-04-25 14:23:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"recipient,label,permission_type, notification_type,expected_error",
|
|
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(
|
|
|
|
|
|
"2028675309",
|
|
|
|
|
|
"phone_number",
|
|
|
|
|
|
ServicePermissionType.EMAIL,
|
|
|
|
|
|
NotificationType.SMS,
|
|
|
|
|
|
"text messages",
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"someone@test.com",
|
|
|
|
|
|
"email_address",
|
|
|
|
|
|
ServicePermissionType.SMS,
|
|
|
|
|
|
NotificationType.EMAIL,
|
|
|
|
|
|
"emails",
|
|
|
|
|
|
),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-06-29 11:13:32 +01:00
|
|
|
|
def test_post_sms_notification_returns_400_if_not_allowed_to_send_notification(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_db_session,
|
|
|
|
|
|
client,
|
|
|
|
|
|
recipient,
|
|
|
|
|
|
label,
|
|
|
|
|
|
permission_type,
|
|
|
|
|
|
notification_type,
|
|
|
|
|
|
expected_error,
|
2019-06-11 16:45:35 +01:00
|
|
|
|
):
|
|
|
|
|
|
service = create_service(service_permissions=[permission_type])
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sample_template_without_permission = create_template(
|
|
|
|
|
|
service=service, template_type=notification_type
|
|
|
|
|
|
)
|
|
|
|
|
|
data = {label: recipient, "template_id": sample_template_without_permission.id}
|
|
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template_without_permission.service.id
|
|
|
|
|
|
)
|
2017-06-29 11:13:32 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{sample_template_without_permission.template_type}",
|
2017-06-29 11:13:32 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-06-29 11:13:32 +01:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 400
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert response.headers["Content-type"] == "application/json"
|
2017-06-29 11:13:32 +01:00
|
|
|
|
|
|
|
|
|
|
error_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_json["status_code"] == 400
|
|
|
|
|
|
assert error_json["errors"] == [
|
|
|
|
|
|
{
|
|
|
|
|
|
"error": "BadRequestError",
|
2024-02-20 17:00:54 -05:00
|
|
|
|
"message": f"Service is not allowed to send {expected_error}",
|
2023-08-29 14:54:30 -07:00
|
|
|
|
}
|
2017-06-29 11:13:32 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize("restricted", [True, False])
|
2020-07-28 11:22:19 +01:00
|
|
|
|
def test_post_sms_notification_returns_400_if_number_not_in_guest_list(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
notify_db_session, client, restricted
|
2019-06-11 16:45:35 +01:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service = create_service(
|
2024-01-18 10:27:31 -05:00
|
|
|
|
restricted=restricted,
|
|
|
|
|
|
service_permissions=[
|
|
|
|
|
|
ServicePermissionType.SMS,
|
|
|
|
|
|
ServicePermissionType.INTERNATIONAL_SMS,
|
|
|
|
|
|
],
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
2019-06-11 16:45:35 +01:00
|
|
|
|
template = create_template(service=service)
|
2024-02-20 17:00:54 -05:00
|
|
|
|
create_api_key(service=service, key_type=KeyType.TEAM)
|
2019-06-11 16:45:35 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+327700900855",
|
2019-06-11 16:45:35 +01:00
|
|
|
|
"template_id": template.id,
|
|
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
service_id=service.id,
|
|
|
|
|
|
key_type=KeyType.TEAM,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
2019-06-11 16:45:35 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2019-06-11 16:45:35 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2019-06-11 16:45:35 +01:00
|
|
|
|
|
|
|
|
|
|
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["status_code"] == 400
|
|
|
|
|
|
assert error_json["errors"] == [
|
|
|
|
|
|
{
|
|
|
|
|
|
"error": "BadRequestError",
|
|
|
|
|
|
"message": "Can’t send to this recipient using a team-only API key",
|
|
|
|
|
|
}
|
2019-06-11 16:45:35 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-10-19 11:06:28 +01:00
|
|
|
|
def test_post_sms_notification_returns_201_if_allowed_to_send_int_sms(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
sample_service,
|
|
|
|
|
|
sample_template,
|
|
|
|
|
|
client,
|
|
|
|
|
|
mocker,
|
2017-10-19 11:06:28 +01:00
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-04-27 12:47:08 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
data = {"phone_number": "+20-12-1234-1234", "template_id": sample_template.id}
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-04-26 15:56:45 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert response.headers["Content-type"] == "application/json"
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_sms_should_persist_supplied_sms_number(
|
|
|
|
|
|
client, sample_template_with_placeholders, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_sms.apply_async")
|
2017-05-15 17:27:38 +01:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+(44) 77009-00855",
|
|
|
|
|
|
"template_id": str(sample_template_with_placeholders.id),
|
|
|
|
|
|
"personalisation": {" Name": "Jo"},
|
2017-05-15 17:27:38 +01:00
|
|
|
|
}
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_template_with_placeholders.service_id
|
|
|
|
|
|
)
|
2017-04-26 15:56:45 +01:00
|
|
|
|
|
2017-05-15 17:27:38 +01:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path="/v2/notifications/sms",
|
2017-05-15 17:27:38 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-05-15 17:27:38 +01:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
notifications = Notification.query.all()
|
|
|
|
|
|
assert len(notifications) == 1
|
|
|
|
|
|
notification_id = notifications[0].id
|
2024-01-16 11:21:24 -08:00
|
|
|
|
assert "1" == notifications[0].to
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert resp_json["id"] == str(notification_id)
|
2017-05-15 17:27:38 +01:00
|
|
|
|
assert mocked.called
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_notification_raises_bad_request_if_not_valid_notification_type(
|
|
|
|
|
|
client, sample_service
|
|
|
|
|
|
):
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
2017-07-07 17:10:25 +01:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"/v2/notifications/foo",
|
|
|
|
|
|
data="{}",
|
|
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
2017-07-07 17:10:25 +01:00
|
|
|
|
)
|
2017-07-20 15:23:46 +01:00
|
|
|
|
assert response.status_code == 404
|
2017-07-07 17:10:25 +01:00
|
|
|
|
error_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert "The requested URL was not found on the server." in error_json["message"]
|
2017-10-04 14:34:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2024-02-20 17:00:54 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type", [NotificationType.SMS, NotificationType.EMAIL]
|
|
|
|
|
|
)
|
2017-10-30 13:36:49 +00:00
|
|
|
|
def test_post_notification_with_wrong_type_of_sender(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, sample_template, sample_email_template, notification_type, fake_uuid
|
|
|
|
|
|
):
|
2024-01-18 10:26:40 -05:00
|
|
|
|
if notification_type == NotificationType.EMAIL:
|
2017-10-30 13:36:49 +00:00
|
|
|
|
template = sample_email_template
|
2023-08-29 14:54:30 -07:00
|
|
|
|
form_label = "sms_sender_id"
|
2017-10-30 13:36:49 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_address": "test@test.com",
|
|
|
|
|
|
"template_id": str(sample_email_template.id),
|
|
|
|
|
|
form_label: fake_uuid,
|
2017-10-30 13:36:49 +00:00
|
|
|
|
}
|
2024-01-18 10:26:40 -05:00
|
|
|
|
elif notification_type == ServicePermissionType.SMS:
|
2017-10-30 13:36:49 +00:00
|
|
|
|
template = sample_template
|
2023-08-29 14:54:30 -07:00
|
|
|
|
form_label = "email_reply_to_id"
|
2017-10-30 13:36:49 +00:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"phone_number": "+447700900855",
|
|
|
|
|
|
"template_id": str(template.id),
|
|
|
|
|
|
form_label: fake_uuid,
|
2017-10-30 13:36:49 +00:00
|
|
|
|
}
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=template.service_id)
|
2017-10-04 14:34:45 +01:00
|
|
|
|
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2017-10-04 14:34:45 +01:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-10-04 14:34:45 +01:00
|
|
|
|
assert response.status_code == 400
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert (
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"Additional properties are not allowed ({form_label} was unexpected)"
|
2023-08-29 14:54:30 -07:00
|
|
|
|
in resp_json["errors"][0]["message"]
|
|
|
|
|
|
)
|
|
|
|
|
|
assert "ValidationError" in resp_json["errors"][0]["error"]
|
2017-10-04 14:34:45 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_email_notification_with_valid_reply_to_id_returns_201(
|
|
|
|
|
|
client, sample_email_template, mocker
|
|
|
|
|
|
):
|
|
|
|
|
|
reply_to_email = create_reply_to_email(
|
|
|
|
|
|
sample_email_template.service, "test@test.com"
|
|
|
|
|
|
)
|
|
|
|
|
|
mocked = mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2017-10-04 14:34:45 +01:00
|
|
|
|
data = {
|
|
|
|
|
|
"email_address": sample_email_template.service.users[0].email_address,
|
|
|
|
|
|
"template_id": sample_email_template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_reply_to_id": reply_to_email.id,
|
2017-10-04 14:34:45 +01:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_email_template.service_id
|
|
|
|
|
|
)
|
2017-10-04 14:34:45 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-10-04 14:34:45 +01:00
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
assert validate(resp_json, post_email_response) == resp_json
|
|
|
|
|
|
notification = Notification.query.first()
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert notification.reply_to_text == "test@test.com"
|
|
|
|
|
|
assert resp_json["id"] == str(notification.id)
|
2017-10-04 14:34:45 +01:00
|
|
|
|
assert mocked.called
|
2017-10-05 11:33:20 +01:00
|
|
|
|
|
2017-11-27 15:36:57 +00:00
|
|
|
|
assert notification.reply_to_text == reply_to_email.email_address
|
|
|
|
|
|
|
2017-10-05 11:33:20 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_email_notification_with_invalid_reply_to_id_returns_400(
|
|
|
|
|
|
client, sample_email_template, mocker, fake_uuid
|
|
|
|
|
|
):
|
|
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2017-10-05 11:33:20 +01:00
|
|
|
|
data = {
|
|
|
|
|
|
"email_address": sample_email_template.service.users[0].email_address,
|
|
|
|
|
|
"template_id": sample_email_template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_reply_to_id": fake_uuid,
|
2017-10-05 11:33:20 +01:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_email_template.service_id
|
|
|
|
|
|
)
|
2017-10-05 11:33:20 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2017-10-05 11:33:20 +01:00
|
|
|
|
assert response.status_code == 400
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert (
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"email_reply_to_id {fake_uuid} does not exist in database for service id "
|
|
|
|
|
|
f"{sample_email_template.service_id}"
|
|
|
|
|
|
) in resp_json["errors"][0]["message"]
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert "BadRequestError" in resp_json["errors"][0]["error"]
|
2018-04-25 12:19:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_email_notification_with_archived_reply_to_id_returns_400(
|
|
|
|
|
|
client, sample_email_template, mocker
|
|
|
|
|
|
):
|
2018-04-25 12:19:12 +01:00
|
|
|
|
archived_reply_to = create_reply_to_email(
|
|
|
|
|
|
sample_email_template.service,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"reply_to@test.com",
|
2018-04-25 12:19:12 +01:00
|
|
|
|
is_default=False,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
archived=True,
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
2018-04-25 12:19:12 +01:00
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_address": "test@test.com",
|
2018-04-25 12:19:12 +01:00
|
|
|
|
"template_id": sample_email_template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_reply_to_id": archived_reply_to.id,
|
2018-04-25 12:19:12 +01:00
|
|
|
|
}
|
2023-08-29 14:54:30 -07:00
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_email_template.service_id
|
|
|
|
|
|
)
|
2018-04-25 12:19:12 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2018-04-25 12:19:12 +01:00
|
|
|
|
assert response.status_code == 400
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert (
|
2024-02-20 17:00:54 -05:00
|
|
|
|
f"email_reply_to_id {archived_reply_to.id} does not exist in database for "
|
|
|
|
|
|
f"service id {sample_email_template.service_id}"
|
|
|
|
|
|
) in resp_json["errors"][0]["message"]
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert "BadRequestError" in resp_json["errors"][0]["error"]
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
2024-01-19 08:58:24 -08:00
|
|
|
|
@pytest.mark.skip(
|
|
|
|
|
|
reason="We've removed personalization from db, needs refactor if we want to support this"
|
|
|
|
|
|
)
|
2020-05-06 12:21:16 +01:00
|
|
|
|
@pytest.mark.parametrize(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"csv_param",
|
2020-05-06 12:21:16 +01:00
|
|
|
|
(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
{"is_csv": None},
|
|
|
|
|
|
{"is_csv": False},
|
|
|
|
|
|
{"is_csv": True},
|
2020-05-06 12:21:16 +01:00
|
|
|
|
{},
|
2023-08-29 14:54:30 -07:00
|
|
|
|
),
|
2020-05-06 12:21:16 +01:00
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_notification_with_document_upload(
|
|
|
|
|
|
client, notify_db_session, mocker, csv_param
|
|
|
|
|
|
):
|
2024-01-18 10:26:40 -05:00
|
|
|
|
service = create_service(service_permissions=[ServicePermissionType.EMAIL])
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service.contact_link = "contact.me@gov.uk"
|
2019-06-11 16:45:35 +01:00
|
|
|
|
template = create_template(
|
|
|
|
|
|
service=service,
|
2024-02-20 17:00:54 -05:00
|
|
|
|
template_type=TemplateType.EMAIL,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
content="Document 1: ((first_link)). Document 2: ((second_link))",
|
2018-04-04 17:34:14 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
document_download_mock = mocker.patch(
|
|
|
|
|
|
"app.v2.notifications.post_notifications.document_download_client"
|
|
|
|
|
|
)
|
|
|
|
|
|
document_download_mock.upload_document.side_effect = (
|
|
|
|
|
|
lambda service_id, content, is_csv: f"{content}-link"
|
|
|
|
|
|
)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
|
|
|
|
|
"email_address": service.users[0].email_address,
|
|
|
|
|
|
"template_id": template.id,
|
2020-02-12 16:07:07 +00:00
|
|
|
|
"personalisation": {
|
2020-05-06 12:21:16 +01:00
|
|
|
|
"first_link": {"file": "abababab", **csv_param},
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"second_link": {"file": "cdcdcdcd", **csv_param},
|
|
|
|
|
|
},
|
2018-04-04 17:34:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=service.id)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201, response.get_data(as_text=True)
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
assert validate(resp_json, post_email_response) == resp_json
|
|
|
|
|
|
|
2020-02-12 16:07:07 +00:00
|
|
|
|
assert document_download_mock.upload_document.call_args_list == [
|
2023-08-29 14:54:30 -07:00
|
|
|
|
call(str(service.id), "abababab", csv_param.get("is_csv")),
|
|
|
|
|
|
call(str(service.id), "cdcdcdcd", csv_param.get("is_csv")),
|
2020-02-12 16:07:07 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
2018-04-04 17:34:14 +01:00
|
|
|
|
notification = Notification.query.one()
|
2024-01-18 10:03:35 -08:00
|
|
|
|
|
2024-01-16 15:52:44 -05:00
|
|
|
|
assert notification.status == NotificationStatus.CREATED
|
2020-02-12 16:07:07 +00:00
|
|
|
|
assert notification.personalisation == {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"first_link": "abababab-link",
|
|
|
|
|
|
"second_link": "cdcdcdcd-link",
|
2020-02-12 16:07:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
assert notification.document_download_count == 2
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
resp_json["content"]["body"]
|
|
|
|
|
|
== "Document 1: abababab-link. Document 2: cdcdcdcd-link"
|
|
|
|
|
|
)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_notification_with_document_upload_simulated(
|
|
|
|
|
|
client, notify_db_session, mocker
|
|
|
|
|
|
):
|
2024-01-18 10:26:40 -05:00
|
|
|
|
service = create_service(service_permissions=[ServicePermissionType.EMAIL])
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service.contact_link = "contact.me@gov.uk"
|
2019-06-11 16:45:35 +01:00
|
|
|
|
template = create_template(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
service=service,
|
|
|
|
|
|
template_type=TemplateType.EMAIL,
|
|
|
|
|
|
content="Document: ((document))",
|
2018-04-04 17:34:14 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
document_download_mock = mocker.patch(
|
|
|
|
|
|
"app.v2.notifications.post_notifications.document_download_client"
|
|
|
|
|
|
)
|
|
|
|
|
|
document_download_mock.get_upload_url.return_value = "https://document-url"
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"email_address": "simulate-delivered@notifications.service.gov.uk",
|
2018-04-04 17:34:14 +01:00
|
|
|
|
"template_id": template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"personalisation": {"document": {"file": "abababab"}},
|
2018-04-04 17:34:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=service.id)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201, response.get_data(as_text=True)
|
|
|
|
|
|
resp_json = json.loads(response.get_data(as_text=True))
|
|
|
|
|
|
assert validate(resp_json, post_email_response) == resp_json
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
resp_json["content"]["body"] == "Document: https://document-url/test-document"
|
|
|
|
|
|
)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_notification_without_document_upload_permission(
|
|
|
|
|
|
client, notify_db_session, mocker
|
|
|
|
|
|
):
|
2024-01-18 10:26:40 -05:00
|
|
|
|
service = create_service(service_permissions=[ServicePermissionType.EMAIL])
|
2019-06-11 16:45:35 +01:00
|
|
|
|
template = create_template(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
service=service,
|
|
|
|
|
|
template_type=TemplateType.EMAIL,
|
|
|
|
|
|
content="Document: ((document))",
|
2018-04-04 17:34:14 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
|
|
|
|
|
document_download_mock = mocker.patch(
|
|
|
|
|
|
"app.v2.notifications.post_notifications.document_download_client"
|
|
|
|
|
|
)
|
|
|
|
|
|
document_download_mock.upload_document.return_value = "https://document-url/"
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
data = {
|
|
|
|
|
|
"email_address": service.users[0].email_address,
|
|
|
|
|
|
"template_id": template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"personalisation": {"document": {"file": "abababab"}},
|
2018-04-04 17:34:14 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=service.id)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2018-04-04 17:34:14 +01:00
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 400, response.get_data(as_text=True)
|
2018-06-25 16:58:35 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_notification_returns_400_when_get_json_throws_exception(
|
|
|
|
|
|
client, sample_email_template
|
|
|
|
|
|
):
|
|
|
|
|
|
auth_header = create_service_authorization_header(
|
|
|
|
|
|
service_id=sample_email_template.service_id
|
|
|
|
|
|
)
|
2018-06-25 16:58:35 +01:00
|
|
|
|
response = client.post(
|
|
|
|
|
|
path="v2/notifications/email",
|
|
|
|
|
|
data="[",
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
|
|
|
|
|
)
|
2018-06-25 16:58:35 +01:00
|
|
|
|
assert response.status_code == 400
|
2019-11-19 10:55:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type, content_type",
|
|
|
|
|
|
[
|
2024-02-20 17:00:54 -05:00
|
|
|
|
(NotificationType.EMAIL, "application/json"),
|
|
|
|
|
|
(NotificationType.EMAIL, "application/text"),
|
|
|
|
|
|
(NotificationType.SMS, "application/json"),
|
|
|
|
|
|
(NotificationType.SMS, "application/text"),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
2019-11-19 10:55:07 +00:00
|
|
|
|
def test_post_notification_when_payload_is_invalid_json_returns_400(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
client,
|
|
|
|
|
|
sample_service,
|
|
|
|
|
|
notification_type,
|
|
|
|
|
|
content_type,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
):
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
2019-11-19 10:55:07 +00:00
|
|
|
|
payload_not_json = {
|
|
|
|
|
|
"template_id": "dont-convert-to-json",
|
|
|
|
|
|
}
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2019-11-19 10:55:07 +00:00
|
|
|
|
data=payload_not_json,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", content_type), auth_header],
|
2019-11-19 10:55:07 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 400
|
|
|
|
|
|
error_msg = json.loads(response.get_data(as_text=True))["errors"][0]["message"]
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_msg == "Invalid JSON supplied in POST data"
|
2019-11-19 10:55:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
2024-02-20 17:00:54 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type",
|
|
|
|
|
|
[
|
|
|
|
|
|
NotificationType.EMAIL,
|
|
|
|
|
|
NotificationType.SMS,
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2019-11-19 10:55:07 +00:00
|
|
|
|
def test_post_notification_returns_201_when_content_type_is_missing_but_payload_is_valid_json(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, sample_service, notification_type, mocker
|
|
|
|
|
|
):
|
2019-11-19 10:55:07 +00:00
|
|
|
|
template = create_template(service=sample_service, template_type=notification_type)
|
2024-02-20 17:00:54 -05:00
|
|
|
|
mocker.patch(f"app.celery.provider_tasks.deliver_{notification_type}.apply_async")
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
2019-11-19 10:55:07 +00:00
|
|
|
|
|
|
|
|
|
|
valid_json = {
|
|
|
|
|
|
"template_id": str(template.id),
|
|
|
|
|
|
}
|
2024-02-21 11:27:38 -05:00
|
|
|
|
if notification_type == NotificationType.EMAIL:
|
2019-11-19 10:55:07 +00:00
|
|
|
|
valid_json.update({"email_address": sample_service.users[0].email_address})
|
|
|
|
|
|
else:
|
|
|
|
|
|
valid_json.update({"phone_number": "+447700900855"})
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2019-11-19 10:55:07 +00:00
|
|
|
|
data=json.dumps(valid_json),
|
|
|
|
|
|
headers=[auth_header],
|
|
|
|
|
|
)
|
|
|
|
|
|
assert response.status_code == 201
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-02-20 17:00:54 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type",
|
|
|
|
|
|
[
|
|
|
|
|
|
NotificationType.EMAIL,
|
|
|
|
|
|
NotificationType.SMS,
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_email_notification_when_data_is_empty_returns_400(
|
|
|
|
|
|
client, sample_service, notification_type
|
|
|
|
|
|
):
|
2021-08-04 15:12:09 +01:00
|
|
|
|
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
2019-11-19 10:55:07 +00:00
|
|
|
|
data = None
|
|
|
|
|
|
response = client.post(
|
2024-02-20 17:00:54 -05:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2019-11-19 10:55:07 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[("Content-Type", "application/json"), auth_header],
|
2019-11-19 10:55:07 +00:00
|
|
|
|
)
|
|
|
|
|
|
error_msg = json.loads(response.get_data(as_text=True))["errors"][0]["message"]
|
|
|
|
|
|
assert response.status_code == 400
|
2024-02-20 17:00:54 -05:00
|
|
|
|
if notification_type == NotificationType.SMS:
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_msg == "phone_number is a required property"
|
2019-11-21 15:21:18 +00:00
|
|
|
|
else:
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert error_msg == "email_address is a required property"
|
2020-03-25 07:59:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
2024-02-20 17:00:54 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type",
|
|
|
|
|
|
(
|
|
|
|
|
|
NotificationType.EMAIL,
|
|
|
|
|
|
NotificationType.SMS,
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
def test_post_notifications_saves_email_or_sms_to_queue(
|
|
|
|
|
|
client, notify_db_session, mocker, notification_type
|
|
|
|
|
|
):
|
|
|
|
|
|
save_task = mocker.patch(
|
|
|
|
|
|
f"app.celery.tasks.save_api_{notification_type}.apply_async"
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_send_task = mocker.patch(
|
|
|
|
|
|
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
|
|
|
|
|
)
|
2020-03-25 07:59:05 +00:00
|
|
|
|
|
2020-06-26 14:10:12 +01:00
|
|
|
|
service = create_service(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service_name="high volume service",
|
2020-06-26 14:10:12 +01:00
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
with set_config_values(
|
|
|
|
|
|
current_app,
|
|
|
|
|
|
{
|
|
|
|
|
|
"HIGH_VOLUME_SERVICE": [str(service.id)],
|
|
|
|
|
|
},
|
|
|
|
|
|
):
|
|
|
|
|
|
template = create_template(
|
|
|
|
|
|
service=service, content="((message))", template_type=notification_type
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"template_id": template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"personalisation": {"message": "Dear citizen, have a nice day"},
|
2020-10-29 11:12:46 +00:00
|
|
|
|
}
|
2024-04-01 15:12:33 -07:00
|
|
|
|
(
|
|
|
|
|
|
data.update({"email_address": "joe.citizen@example.com"})
|
|
|
|
|
|
if notification_type == NotificationType.EMAIL
|
|
|
|
|
|
else data.update({"phone_number": "+447700900855"})
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
2020-03-25 07:59:05 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2020-10-29 11:12:46 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[
|
|
|
|
|
|
("Content-Type", "application/json"),
|
|
|
|
|
|
create_service_authorization_header(service_id=service.id),
|
|
|
|
|
|
],
|
2020-10-29 11:12:46 +00:00
|
|
|
|
)
|
2020-10-27 11:10:35 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
json_resp = response.get_json()
|
|
|
|
|
|
|
|
|
|
|
|
assert response.status_code == 201
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert json_resp["id"]
|
|
|
|
|
|
assert json_resp["content"]["body"] == "Dear citizen, have a nice day"
|
|
|
|
|
|
assert json_resp["template"]["id"] == str(template.id)
|
|
|
|
|
|
save_task.assert_called_once_with(
|
|
|
|
|
|
[mock.ANY], queue=f"save-api-{notification_type}-tasks"
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
assert not mock_send_task.called
|
|
|
|
|
|
assert len(Notification.query.all()) == 0
|
2020-03-25 12:39:15 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-29 14:54:30 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"exception",
|
|
|
|
|
|
[
|
|
|
|
|
|
botocore.exceptions.ClientError({"some": "json"}, "some opname"),
|
|
|
|
|
|
botocore.parsers.ResponseParserError("exceeded max HTTP body length"),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2024-02-20 17:00:54 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type",
|
|
|
|
|
|
(
|
|
|
|
|
|
NotificationType.EMAIL,
|
|
|
|
|
|
NotificationType.SMS,
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
def test_post_notifications_saves_email_or_sms_normally_if_saving_to_queue_fails(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
client, notify_db_session, mocker, notification_type, exception
|
2020-10-29 11:12:46 +00:00
|
|
|
|
):
|
|
|
|
|
|
save_task = mocker.patch(
|
|
|
|
|
|
f"app.celery.tasks.save_api_{notification_type}.apply_async",
|
2021-11-08 10:38:53 +00:00
|
|
|
|
side_effect=exception,
|
2020-10-27 11:10:35 +00:00
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
mock_send_task = mocker.patch(
|
|
|
|
|
|
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
|
|
|
|
|
)
|
2020-03-28 09:39:12 +00:00
|
|
|
|
|
2020-06-26 14:10:12 +01:00
|
|
|
|
service = create_service(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service_name="high volume service",
|
2020-06-26 14:10:12 +01:00
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
with set_config_values(
|
|
|
|
|
|
current_app,
|
|
|
|
|
|
{
|
|
|
|
|
|
"HIGH_VOLUME_SERVICE": [str(service.id)],
|
|
|
|
|
|
},
|
|
|
|
|
|
):
|
|
|
|
|
|
template = create_template(
|
|
|
|
|
|
service=service, content="((message))", template_type=notification_type
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"template_id": template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"personalisation": {"message": "Dear citizen, have a nice day"},
|
2020-10-29 11:12:46 +00:00
|
|
|
|
}
|
2024-04-01 15:12:33 -07:00
|
|
|
|
(
|
|
|
|
|
|
data.update({"email_address": "joe.citizen@example.com"})
|
|
|
|
|
|
if notification_type == NotificationType.EMAIL
|
|
|
|
|
|
else data.update({"phone_number": "+447700900855"})
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
2020-03-28 09:39:12 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2020-10-29 11:12:46 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[
|
|
|
|
|
|
("Content-Type", "application/json"),
|
|
|
|
|
|
create_service_authorization_header(service_id=service.id),
|
|
|
|
|
|
],
|
2020-10-29 11:12:46 +00:00
|
|
|
|
)
|
2020-03-28 09:39:12 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
json_resp = response.get_json()
|
2020-10-27 11:10:35 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
assert response.status_code == 201
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert json_resp["id"]
|
|
|
|
|
|
assert json_resp["content"]["body"] == "Dear citizen, have a nice day"
|
|
|
|
|
|
assert json_resp["template"]["id"] == str(template.id)
|
|
|
|
|
|
save_task.assert_called_once_with(
|
|
|
|
|
|
[mock.ANY], queue=f"save-api-{notification_type}-tasks"
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_send_task.assert_called_once_with(
|
|
|
|
|
|
[json_resp["id"]], queue=f"send-{notification_type}-tasks"
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
assert Notification.query.count() == 1
|
2020-03-28 09:39:12 +00:00
|
|
|
|
|
2020-03-25 12:39:15 +00:00
|
|
|
|
|
2024-02-20 17:00:54 -05:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"notification_type",
|
|
|
|
|
|
(
|
|
|
|
|
|
NotificationType.EMAIL,
|
|
|
|
|
|
NotificationType.SMS,
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
def test_post_notifications_doesnt_use_save_queue_for_test_notifications(
|
|
|
|
|
|
client, notify_db_session, mocker, notification_type
|
|
|
|
|
|
):
|
2023-08-29 14:54:30 -07:00
|
|
|
|
save_task = mocker.patch(
|
|
|
|
|
|
f"app.celery.tasks.save_api_{notification_type}.apply_async"
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_send_task = mocker.patch(
|
|
|
|
|
|
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
|
|
|
|
|
)
|
2020-06-26 14:10:12 +01:00
|
|
|
|
service = create_service(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
service_name="high volume service",
|
2020-06-26 14:10:12 +01:00
|
|
|
|
)
|
2023-08-29 14:54:30 -07:00
|
|
|
|
with set_config_values(
|
|
|
|
|
|
current_app,
|
|
|
|
|
|
{
|
|
|
|
|
|
"HIGH_VOLUME_SERVICE": [str(service.id)],
|
|
|
|
|
|
},
|
|
|
|
|
|
):
|
|
|
|
|
|
template = create_template(
|
|
|
|
|
|
service=service, content="((message))", template_type=notification_type
|
|
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
data = {
|
|
|
|
|
|
"template_id": template.id,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
"personalisation": {"message": "Dear citizen, have a nice day"},
|
2020-10-29 11:12:46 +00:00
|
|
|
|
}
|
2024-04-01 15:12:33 -07:00
|
|
|
|
(
|
|
|
|
|
|
data.update({"email_address": "joe.citizen@example.com"})
|
|
|
|
|
|
if notification_type == NotificationType.EMAIL
|
|
|
|
|
|
else data.update({"phone_number": "+447700900855"})
|
2023-08-29 14:54:30 -07:00
|
|
|
|
)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
response = client.post(
|
2023-08-29 14:54:30 -07:00
|
|
|
|
path=f"/v2/notifications/{notification_type}",
|
2020-10-29 11:12:46 +00:00
|
|
|
|
data=json.dumps(data),
|
2023-08-29 14:54:30 -07:00
|
|
|
|
headers=[
|
|
|
|
|
|
("Content-Type", "application/json"),
|
|
|
|
|
|
create_service_authorization_header(
|
2024-02-21 14:14:45 -05:00
|
|
|
|
service_id=service.id,
|
|
|
|
|
|
key_type=KeyType.TEST,
|
2023-08-29 14:54:30 -07:00
|
|
|
|
),
|
|
|
|
|
|
],
|
2020-10-29 11:12:46 +00:00
|
|
|
|
)
|
2020-03-25 12:39:15 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
json_resp = response.get_json()
|
2020-03-25 12:39:15 +00:00
|
|
|
|
|
2020-10-29 11:12:46 +00:00
|
|
|
|
assert response.status_code == 201
|
2023-08-29 14:54:30 -07:00
|
|
|
|
assert json_resp["id"]
|
|
|
|
|
|
assert json_resp["content"]["body"] == "Dear citizen, have a nice day"
|
|
|
|
|
|
assert json_resp["template"]["id"] == str(template.id)
|
2020-10-29 11:12:46 +00:00
|
|
|
|
assert mock_send_task.called
|
|
|
|
|
|
assert not save_task.called
|
|
|
|
|
|
assert len(Notification.query.all()) == 1
|