mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-23 15:56:45 -04:00
merge from main
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from flask import json, url_for
|
||||
|
||||
from app.enums import NotificationStatus, NotificationType, TemplateType
|
||||
from app.utils import DATETIME_FORMAT
|
||||
from tests import create_service_authorization_header
|
||||
from tests.app.db import create_notification, create_template
|
||||
@@ -257,7 +258,7 @@ def test_get_notification_by_id_invalid_id(client, sample_notification, id):
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("template_type", ["sms", "email"])
|
||||
@pytest.mark.parametrize("template_type", [TemplateType.SMS, TemplateType.EMAIL])
|
||||
def test_get_notification_doesnt_have_delivery_estimate_for_non_letters(
|
||||
client, sample_service, template_type, mocker
|
||||
):
|
||||
@@ -306,14 +307,14 @@ def test_get_all_notifications_except_job_notifications_returns_200(
|
||||
assert len(json_response["notifications"]) == 2
|
||||
|
||||
assert json_response["notifications"][0]["id"] == str(notification.id)
|
||||
assert json_response["notifications"][0]["status"] == "created"
|
||||
assert json_response["notifications"][0]["status"] == NotificationStatus.CREATED
|
||||
assert json_response["notifications"][0]["template"] == {
|
||||
"id": str(notification.template.id),
|
||||
"uri": notification.template.get_link(),
|
||||
"version": 1,
|
||||
}
|
||||
assert json_response["notifications"][0]["phone_number"] == "1"
|
||||
assert json_response["notifications"][0]["type"] == "sms"
|
||||
assert json_response["notifications"][0]["type"] == NotificationType.SMS
|
||||
assert not json_response["notifications"][0]["scheduled_for"]
|
||||
|
||||
|
||||
@@ -376,8 +377,12 @@ def test_get_all_notifications_no_notifications_if_no_notifications(
|
||||
|
||||
|
||||
def test_get_all_notifications_filter_by_template_type(client, sample_service):
|
||||
email_template = create_template(service=sample_service, template_type="email")
|
||||
sms_template = create_template(service=sample_service, template_type="sms")
|
||||
email_template = create_template(
|
||||
service=sample_service, template_type=TemplateType.EMAIL
|
||||
)
|
||||
sms_template = create_template(
|
||||
service=sample_service, template_type=TemplateType.SMS
|
||||
)
|
||||
|
||||
notification = create_notification(
|
||||
template=email_template, to_field="don.draper@scdp.biz"
|
||||
@@ -403,14 +408,14 @@ def test_get_all_notifications_filter_by_template_type(client, sample_service):
|
||||
assert len(json_response["notifications"]) == 1
|
||||
|
||||
assert json_response["notifications"][0]["id"] == str(notification.id)
|
||||
assert json_response["notifications"][0]["status"] == "created"
|
||||
assert json_response["notifications"][0]["status"] == NotificationStatus.CREATED
|
||||
assert json_response["notifications"][0]["template"] == {
|
||||
"id": str(email_template.id),
|
||||
"uri": notification.template.get_link(),
|
||||
"version": 1,
|
||||
}
|
||||
assert json_response["notifications"][0]["email_address"] == "1"
|
||||
assert json_response["notifications"][0]["type"] == "email"
|
||||
assert json_response["notifications"][0]["type"] == NotificationType.EMAIL
|
||||
|
||||
|
||||
def test_get_all_notifications_filter_by_template_type_invalid_template_type(
|
||||
@@ -431,14 +436,20 @@ def test_get_all_notifications_filter_by_template_type_invalid_template_type(
|
||||
|
||||
assert json_response["status_code"] == 400
|
||||
assert len(json_response["errors"]) == 1
|
||||
type_str = ", ".join(
|
||||
[f"<{type(e).__name__}.{e.name}: {e.value}>" for e in TemplateType]
|
||||
)
|
||||
assert (
|
||||
json_response["errors"][0]["message"]
|
||||
== "template_type orange is not one of [sms, email]"
|
||||
== f"template_type orange is not one of [{type_str}]"
|
||||
)
|
||||
|
||||
|
||||
def test_get_all_notifications_filter_by_single_status(client, sample_template):
|
||||
notification = create_notification(template=sample_template, status="pending")
|
||||
notification = create_notification(
|
||||
template=sample_template,
|
||||
status=NotificationStatus.PENDING,
|
||||
)
|
||||
create_notification(template=sample_template)
|
||||
|
||||
auth_header = create_service_authorization_header(
|
||||
@@ -460,7 +471,7 @@ def test_get_all_notifications_filter_by_single_status(client, sample_template):
|
||||
assert len(json_response["notifications"]) == 1
|
||||
|
||||
assert json_response["notifications"][0]["id"] == str(notification.id)
|
||||
assert json_response["notifications"][0]["status"] == "pending"
|
||||
assert json_response["notifications"][0]["status"] == NotificationStatus.PENDING
|
||||
|
||||
|
||||
def test_get_all_notifications_filter_by_status_invalid_status(
|
||||
@@ -481,21 +492,27 @@ def test_get_all_notifications_filter_by_status_invalid_status(
|
||||
|
||||
assert json_response["status_code"] == 400
|
||||
assert len(json_response["errors"]) == 1
|
||||
type_str = ", ".join(
|
||||
[f"<{type(e).__name__}.{e.name}: {e.value}>" for e in NotificationStatus]
|
||||
)
|
||||
assert (
|
||||
json_response["errors"][0]["message"]
|
||||
== "status elephant is not one of [cancelled, created, sending, "
|
||||
"sent, delivered, pending, failed, technical-failure, temporary-failure, permanent-failure, "
|
||||
"pending-virus-check, validation-failed, virus-scan-failed]"
|
||||
== f"status elephant is not one of [{type_str}]"
|
||||
)
|
||||
|
||||
|
||||
def test_get_all_notifications_filter_by_multiple_statuses(client, sample_template):
|
||||
notifications = [
|
||||
create_notification(template=sample_template, status=_status)
|
||||
for _status in ["created", "pending", "sending"]
|
||||
for _status in [
|
||||
NotificationStatus.CREATED,
|
||||
NotificationStatus.PENDING,
|
||||
NotificationStatus.SENDING,
|
||||
]
|
||||
]
|
||||
failed_notification = create_notification(
|
||||
template=sample_template, status="permanent-failure"
|
||||
template=sample_template,
|
||||
status=NotificationStatus.PERMANENT_FAILURE,
|
||||
)
|
||||
|
||||
auth_header = create_service_authorization_header(
|
||||
@@ -525,10 +542,11 @@ def test_get_all_notifications_filter_by_multiple_statuses(client, sample_templa
|
||||
|
||||
def test_get_all_notifications_filter_by_failed_status(client, sample_template):
|
||||
created_notification = create_notification(
|
||||
template=sample_template, status="created"
|
||||
template=sample_template,
|
||||
status=NotificationStatus.CREATED,
|
||||
)
|
||||
failed_notifications = [
|
||||
create_notification(template=sample_template, status="failed")
|
||||
create_notification(template=sample_template, status=NotificationStatus.FAILED)
|
||||
]
|
||||
auth_header = create_service_authorization_header(
|
||||
service_id=created_notification.service_id
|
||||
@@ -648,20 +666,26 @@ def test_get_all_notifications_filter_multiple_query_parameters(
|
||||
# TODO had to change pending to sending. Is that correct?
|
||||
# this is the notification we are looking for
|
||||
older_notification = create_notification(
|
||||
template=sample_email_template, status="sending"
|
||||
template=sample_email_template,
|
||||
status=NotificationStatus.SENDING,
|
||||
)
|
||||
|
||||
# wrong status
|
||||
create_notification(template=sample_email_template)
|
||||
wrong_template = create_template(sample_email_template.service, template_type="sms")
|
||||
wrong_template = create_template(
|
||||
sample_email_template.service, template_type=TemplateType.SMS
|
||||
)
|
||||
# wrong template
|
||||
create_notification(template=wrong_template, status="sending")
|
||||
create_notification(template=wrong_template, status=NotificationStatus.SENDING)
|
||||
|
||||
# we only want notifications created before this one
|
||||
newer_notification = create_notification(template=sample_email_template)
|
||||
|
||||
# this notification was created too recently
|
||||
create_notification(template=sample_email_template, status="sending")
|
||||
create_notification(
|
||||
template=sample_email_template,
|
||||
status=NotificationStatus.SENDING,
|
||||
)
|
||||
|
||||
auth_header = create_service_authorization_header(
|
||||
service_id=newer_notification.service_id
|
||||
@@ -709,7 +733,10 @@ def test_get_all_notifications_renames_letter_statuses(
|
||||
assert response.status_code == 200
|
||||
|
||||
for noti in json_response["notifications"]:
|
||||
if noti["type"] == "sms" or noti["type"] == "email":
|
||||
assert noti["status"] == "created"
|
||||
if (
|
||||
noti["type"] == NotificationType.SMS
|
||||
or noti["type"] == NotificationType.EMAIL
|
||||
):
|
||||
assert noti["status"] == NotificationStatus.CREATED
|
||||
else:
|
||||
pytest.fail()
|
||||
|
||||
@@ -5,7 +5,7 @@ from flask import json
|
||||
from freezegun import freeze_time
|
||||
from jsonschema import ValidationError
|
||||
|
||||
from app.models import EMAIL_TYPE, NOTIFICATION_CREATED
|
||||
from app.enums import NotificationStatus, TemplateType
|
||||
from app.schema_validation import validate
|
||||
from app.v2.notifications.notification_schemas import get_notifications_request
|
||||
from app.v2.notifications.notification_schemas import (
|
||||
@@ -19,8 +19,8 @@ valid_get_json = {}
|
||||
|
||||
valid_get_with_optionals_json = {
|
||||
"reference": "test reference",
|
||||
"status": [NOTIFICATION_CREATED],
|
||||
"template_type": [EMAIL_TYPE],
|
||||
"status": [NotificationStatus.CREATED],
|
||||
"template_type": [TemplateType.EMAIL],
|
||||
"include_jobs": "true",
|
||||
"older_than": "a5149c32-f03b-4711-af49-ad6993797d45",
|
||||
}
|
||||
@@ -39,16 +39,14 @@ def test_get_notifications_valid_json(input):
|
||||
# multiple invalid statuses
|
||||
(["elephant", "giraffe", "cheetah"], []),
|
||||
# one bad status and one good status
|
||||
(["elephant"], ["created"]),
|
||||
(["elephant"], [NotificationStatus.CREATED]),
|
||||
],
|
||||
)
|
||||
def test_get_notifications_request_invalid_statuses(invalid_statuses, valid_statuses):
|
||||
partial_error_status = (
|
||||
"is not one of "
|
||||
"[cancelled, created, sending, sent, delivered, pending, failed, "
|
||||
"technical-failure, temporary-failure, permanent-failure, pending-virus-check, "
|
||||
"validation-failed, virus-scan-failed]"
|
||||
type_str = ", ".join(
|
||||
[f"<{type(e).__name__}.{e.name}: {e.value}>" for e in NotificationStatus]
|
||||
)
|
||||
partial_error_status = f"is not one of [{type_str}]"
|
||||
|
||||
with pytest.raises(ValidationError) as e:
|
||||
validate(
|
||||
@@ -58,9 +56,7 @@ def test_get_notifications_request_invalid_statuses(invalid_statuses, valid_stat
|
||||
errors = json.loads(str(e.value)).get("errors")
|
||||
assert len(errors) == len(invalid_statuses)
|
||||
for index, value in enumerate(invalid_statuses):
|
||||
assert errors[index]["message"] == "status {} {}".format(
|
||||
value, partial_error_status
|
||||
)
|
||||
assert errors[index]["message"] == f"status {value} {partial_error_status}"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
@@ -71,13 +67,16 @@ def test_get_notifications_request_invalid_statuses(invalid_statuses, valid_stat
|
||||
# multiple invalid template_types
|
||||
(["orange", "avocado", "banana"], []),
|
||||
# one bad template_type and one good template_type
|
||||
(["orange"], ["sms"]),
|
||||
(["orange"], [TemplateType.SMS]),
|
||||
],
|
||||
)
|
||||
def test_get_notifications_request_invalid_template_types(
|
||||
invalid_template_types, valid_template_types
|
||||
):
|
||||
partial_error_template_type = "is not one of [sms, email]"
|
||||
type_str = ", ".join(
|
||||
[f"<{type(e).__name__}.{e.name}: {e.value}>" for e in TemplateType]
|
||||
)
|
||||
partial_error_template_type = f"is not one of [{type_str}]"
|
||||
|
||||
with pytest.raises(ValidationError) as e:
|
||||
validate(
|
||||
@@ -88,8 +87,8 @@ def test_get_notifications_request_invalid_template_types(
|
||||
errors = json.loads(str(e.value)).get("errors")
|
||||
assert len(errors) == len(invalid_template_types)
|
||||
for index, value in enumerate(invalid_template_types):
|
||||
assert errors[index]["message"] == "template_type {} {}".format(
|
||||
value, partial_error_template_type
|
||||
assert errors[index]["message"] == (
|
||||
f"template_type {value} {partial_error_template_type}"
|
||||
)
|
||||
|
||||
|
||||
@@ -97,8 +96,8 @@ def test_get_notifications_request_invalid_statuses_and_template_types():
|
||||
with pytest.raises(ValidationError) as e:
|
||||
validate(
|
||||
{
|
||||
"status": ["created", "elephant", "giraffe"],
|
||||
"template_type": ["sms", "orange", "avocado"],
|
||||
"status": [NotificationStatus.CREATED, "elephant", "giraffe"],
|
||||
"template_type": [TemplateType.SMS, "orange", "avocado"],
|
||||
},
|
||||
get_notifications_request,
|
||||
)
|
||||
@@ -108,19 +107,18 @@ def test_get_notifications_request_invalid_statuses_and_template_types():
|
||||
assert len(errors) == 4
|
||||
|
||||
error_messages = [error["message"] for error in errors]
|
||||
type_str = ", ".join(
|
||||
[f"<{type(e).__name__}.{e.name}: {e.value}>" for e in NotificationStatus]
|
||||
)
|
||||
for invalid_status in ["elephant", "giraffe"]:
|
||||
assert (
|
||||
"status {} is not one of [cancelled, created, sending, sent, delivered, "
|
||||
"pending, failed, technical-failure, temporary-failure, permanent-failure, "
|
||||
"pending-virus-check, validation-failed, virus-scan-failed]".format(
|
||||
invalid_status
|
||||
)
|
||||
in error_messages
|
||||
)
|
||||
assert f"status {invalid_status} is not one of [{type_str}]" in error_messages
|
||||
|
||||
type_str = ", ".join(
|
||||
[f"<{type(e).__name__}.{e.name}: {e.value}>" for e in TemplateType]
|
||||
)
|
||||
for invalid_template_type in ["orange", "avocado"]:
|
||||
assert (
|
||||
"template_type {} is not one of [sms, email]".format(invalid_template_type)
|
||||
f"template_type {invalid_template_type} is not one of [{type_str}]"
|
||||
in error_messages
|
||||
)
|
||||
|
||||
|
||||
@@ -8,13 +8,15 @@ from flask import current_app, json
|
||||
|
||||
from app.dao import templates_dao
|
||||
from app.dao.service_sms_sender_dao import dao_update_service_sms_sender
|
||||
from app.models import (
|
||||
EMAIL_TYPE,
|
||||
INTERNATIONAL_SMS_TYPE,
|
||||
NOTIFICATION_CREATED,
|
||||
SMS_TYPE,
|
||||
Notification,
|
||||
from app.enums import (
|
||||
KeyType,
|
||||
NotificationStatus,
|
||||
NotificationType,
|
||||
ServicePermissionType,
|
||||
TemplateProcessType,
|
||||
TemplateType,
|
||||
)
|
||||
from app.models import Notification
|
||||
from app.schema_validation import validate
|
||||
from app.v2.errors import RateLimitError
|
||||
from app.v2.notifications.notification_schemas import (
|
||||
@@ -60,7 +62,7 @@ def test_post_sms_notification_returns_201(
|
||||
assert validate(resp_json, post_sms_response) == resp_json
|
||||
notifications = Notification.query.all()
|
||||
assert len(notifications) == 1
|
||||
assert notifications[0].status == NOTIFICATION_CREATED
|
||||
assert notifications[0].status == NotificationStatus.CREATED
|
||||
notification_id = notifications[0].id
|
||||
assert notifications[0].document_download_count is None
|
||||
assert resp_json["id"] == str(notification_id)
|
||||
@@ -69,16 +71,13 @@ def test_post_sms_notification_returns_201(
|
||||
"body"
|
||||
] == sample_template_with_placeholders.content.replace("(( Name))", "Jo")
|
||||
assert resp_json["content"]["from_number"] == current_app.config["FROM_NUMBER"]
|
||||
assert "v2/notifications/{}".format(notification_id) in resp_json["uri"]
|
||||
assert f"v2/notifications/{notification_id}" in resp_json["uri"]
|
||||
assert resp_json["template"]["id"] == str(sample_template_with_placeholders.id)
|
||||
assert resp_json["template"]["version"] == sample_template_with_placeholders.version
|
||||
assert (
|
||||
"services/{}/templates/{}".format(
|
||||
sample_template_with_placeholders.service_id,
|
||||
sample_template_with_placeholders.id,
|
||||
)
|
||||
in resp_json["template"]["uri"]
|
||||
)
|
||||
f"services/{sample_template_with_placeholders.service_id}/templates/"
|
||||
f"{sample_template_with_placeholders.id}"
|
||||
) in resp_json["template"]["uri"]
|
||||
assert not resp_json["scheduled_for"]
|
||||
assert mocked.called
|
||||
|
||||
@@ -374,8 +373,8 @@ def test_should_return_template_if_found_in_redis(mocker, client, sample_templat
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type, key_send_to, send_to",
|
||||
[
|
||||
("sms", "phone_number", "+447700900855"),
|
||||
("email", "email_address", "sample@email.com"),
|
||||
(NotificationType.SMS, "phone_number", "+447700900855"),
|
||||
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
||||
],
|
||||
)
|
||||
def test_post_notification_returns_400_and_missing_template(
|
||||
@@ -385,7 +384,7 @@ def test_post_notification_returns_400_and_missing_template(
|
||||
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
@@ -403,8 +402,8 @@ def test_post_notification_returns_400_and_missing_template(
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type, key_send_to, send_to",
|
||||
[
|
||||
("sms", "phone_number", "+447700900855"),
|
||||
("email", "email_address", "sample@email.com"),
|
||||
(NotificationType.SMS, "phone_number", "+447700900855"),
|
||||
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
||||
],
|
||||
)
|
||||
def test_post_notification_returns_401_and_well_formed_auth_error(
|
||||
@@ -413,7 +412,7 @@ def test_post_notification_returns_401_and_well_formed_auth_error(
|
||||
data = {key_send_to: send_to, "template_id": str(sample_template.id)}
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json")],
|
||||
)
|
||||
@@ -433,8 +432,8 @@ def test_post_notification_returns_401_and_well_formed_auth_error(
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type, key_send_to, send_to",
|
||||
[
|
||||
("sms", "phone_number", "+447700900855"),
|
||||
("email", "email_address", "sample@email.com"),
|
||||
(NotificationType.SMS, "phone_number", "+447700900855"),
|
||||
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
||||
],
|
||||
)
|
||||
def test_notification_returns_400_and_for_schema_problems(
|
||||
@@ -446,7 +445,7 @@ def test_notification_returns_400_and_for_schema_problems(
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
@@ -491,7 +490,7 @@ def test_post_email_notification_returns_201(
|
||||
resp_json = json.loads(response.get_data(as_text=True))
|
||||
assert validate(resp_json, post_email_response) == resp_json
|
||||
notification = Notification.query.one()
|
||||
assert notification.status == NOTIFICATION_CREATED
|
||||
assert notification.status == NotificationStatus.CREATED
|
||||
assert resp_json["id"] == str(notification.id)
|
||||
assert resp_json["reference"] == reference
|
||||
assert notification.reference is None
|
||||
@@ -503,11 +502,11 @@ def test_post_email_notification_returns_201(
|
||||
assert resp_json["content"][
|
||||
"subject"
|
||||
] == sample_email_template_with_placeholders.subject.replace("((name))", "Bob")
|
||||
assert resp_json["content"]["from_email"] == "{}@{}".format(
|
||||
sample_email_template_with_placeholders.service.email_from,
|
||||
current_app.config["NOTIFY_EMAIL_DOMAIN"],
|
||||
assert resp_json["content"]["from_email"] == (
|
||||
f"{sample_email_template_with_placeholders.service.email_from}@"
|
||||
f"{current_app.config['NOTIFY_EMAIL_DOMAIN']}"
|
||||
)
|
||||
assert "v2/notifications/{}".format(notification.id) in resp_json["uri"]
|
||||
assert f"v2/notifications/{notification.id}" in resp_json["uri"]
|
||||
assert resp_json["template"]["id"] == str(
|
||||
sample_email_template_with_placeholders.id
|
||||
)
|
||||
@@ -516,12 +515,9 @@ def test_post_email_notification_returns_201(
|
||||
== sample_email_template_with_placeholders.version
|
||||
)
|
||||
assert (
|
||||
"services/{}/templates/{}".format(
|
||||
str(sample_email_template_with_placeholders.service_id),
|
||||
str(sample_email_template_with_placeholders.id),
|
||||
)
|
||||
in resp_json["template"]["uri"]
|
||||
)
|
||||
f"services/{sample_email_template_with_placeholders.service_id}/templates/"
|
||||
f"{sample_email_template_with_placeholders.id}"
|
||||
) in resp_json["template"]["uri"]
|
||||
assert not resp_json["scheduled_for"]
|
||||
assert mocked.called
|
||||
|
||||
@@ -529,21 +525,21 @@ def test_post_email_notification_returns_201(
|
||||
@pytest.mark.parametrize(
|
||||
"recipient, notification_type",
|
||||
[
|
||||
("simulate-delivered@notifications.service.gov.uk", EMAIL_TYPE),
|
||||
("simulate-delivered-2@notifications.service.gov.uk", EMAIL_TYPE),
|
||||
("simulate-delivered-3@notifications.service.gov.uk", EMAIL_TYPE),
|
||||
("+14254147167", "sms"),
|
||||
("+14254147755", "sms"),
|
||||
("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),
|
||||
("+14254147167", NotificationType.SMS),
|
||||
("+14254147755", NotificationType.SMS),
|
||||
],
|
||||
)
|
||||
def test_should_not_persist_or_send_notification_if_simulated_recipient(
|
||||
client, recipient, notification_type, sample_email_template, sample_template, mocker
|
||||
):
|
||||
apply_async = mocker.patch(
|
||||
"app.celery.provider_tasks.deliver_{}.apply_async".format(notification_type)
|
||||
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
||||
)
|
||||
|
||||
if notification_type == "sms":
|
||||
if notification_type == NotificationType.SMS:
|
||||
data = {"phone_number": recipient, "template_id": str(sample_template.id)}
|
||||
else:
|
||||
data = {
|
||||
@@ -556,7 +552,7 @@ def test_should_not_persist_or_send_notification_if_simulated_recipient(
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
@@ -570,22 +566,27 @@ def test_should_not_persist_or_send_notification_if_simulated_recipient(
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type, key_send_to, send_to",
|
||||
[
|
||||
("sms", "phone_number", "2028675309"),
|
||||
("email", "email_address", "sample@email.com"),
|
||||
(NotificationType.SMS, "phone_number", "2028675309"),
|
||||
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
||||
],
|
||||
)
|
||||
def test_send_notification_uses_priority_queue_when_template_is_marked_as_priority(
|
||||
client, sample_service, mocker, notification_type, key_send_to, send_to
|
||||
client,
|
||||
sample_service,
|
||||
mocker,
|
||||
notification_type,
|
||||
key_send_to,
|
||||
send_to,
|
||||
):
|
||||
mocker.patch(
|
||||
"app.celery.provider_tasks.deliver_{}.apply_async".format(notification_type)
|
||||
)
|
||||
mocker.patch(f"app.celery.provider_tasks.deliver_{notification_type}.apply_async")
|
||||
|
||||
sample = create_template(
|
||||
service=sample_service, template_type=notification_type, process_type="priority"
|
||||
service=sample_service,
|
||||
template_type=notification_type,
|
||||
process_type=TemplateProcessType.PRIORITY,
|
||||
)
|
||||
mocked = mocker.patch(
|
||||
"app.celery.provider_tasks.deliver_{}.apply_async".format(notification_type)
|
||||
f"app.celery.provider_tasks.deliver_{notification_type}.apply_async"
|
||||
)
|
||||
|
||||
data = {key_send_to: send_to, "template_id": str(sample.id)}
|
||||
@@ -593,7 +594,7 @@ def test_send_notification_uses_priority_queue_when_template_is_marked_as_priori
|
||||
auth_header = create_service_authorization_header(service_id=sample.service_id)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
@@ -607,8 +608,8 @@ def test_send_notification_uses_priority_queue_when_template_is_marked_as_priori
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type, key_send_to, send_to",
|
||||
[
|
||||
("sms", "phone_number", "2028675309"),
|
||||
("email", "email_address", "sample@email.com"),
|
||||
(NotificationType.SMS, "phone_number", "2028675309"),
|
||||
(NotificationType.EMAIL, "email_address", "sample@email.com"),
|
||||
],
|
||||
)
|
||||
def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded(
|
||||
@@ -631,7 +632,7 @@ def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded(
|
||||
auth_header = create_service_authorization_header(service_id=sample.service_id)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
@@ -655,7 +656,7 @@ def test_post_sms_notification_returns_400_if_not_allowed_to_send_int_sms(
|
||||
client,
|
||||
notify_db_session,
|
||||
):
|
||||
service = create_service(service_permissions=[SMS_TYPE])
|
||||
service = create_service(service_permissions=[ServicePermissionType.SMS])
|
||||
template = create_template(service=service)
|
||||
|
||||
data = {"phone_number": "+20-12-1234-1234", "template_id": template.id}
|
||||
@@ -703,19 +704,29 @@ def test_post_sms_notification_with_archived_reply_to_id_returns_400(
|
||||
assert response.status_code == 400
|
||||
resp_json = json.loads(response.get_data(as_text=True))
|
||||
assert (
|
||||
"sms_sender_id {} does not exist in database for service id {}".format(
|
||||
archived_sender.id, sample_template.service_id
|
||||
)
|
||||
in resp_json["errors"][0]["message"]
|
||||
)
|
||||
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"]
|
||||
assert "BadRequestError" in resp_json["errors"][0]["error"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"recipient,label,permission_type, notification_type,expected_error",
|
||||
[
|
||||
("2028675309", "phone_number", "email", "sms", "text messages"),
|
||||
("someone@test.com", "email_address", "sms", "email", "emails"),
|
||||
(
|
||||
"2028675309",
|
||||
"phone_number",
|
||||
ServicePermissionType.EMAIL,
|
||||
NotificationType.SMS,
|
||||
"text messages",
|
||||
),
|
||||
(
|
||||
"someone@test.com",
|
||||
"email_address",
|
||||
ServicePermissionType.SMS,
|
||||
NotificationType.EMAIL,
|
||||
"emails",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_post_sms_notification_returns_400_if_not_allowed_to_send_notification(
|
||||
@@ -737,9 +748,7 @@ def test_post_sms_notification_returns_400_if_not_allowed_to_send_notification(
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(
|
||||
sample_template_without_permission.template_type
|
||||
),
|
||||
path=f"/v2/notifications/{sample_template_without_permission.template_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
@@ -752,7 +761,7 @@ def test_post_sms_notification_returns_400_if_not_allowed_to_send_notification(
|
||||
assert error_json["errors"] == [
|
||||
{
|
||||
"error": "BadRequestError",
|
||||
"message": "Service is not allowed to send {}".format(expected_error),
|
||||
"message": f"Service is not allowed to send {expected_error}",
|
||||
}
|
||||
]
|
||||
|
||||
@@ -762,17 +771,22 @@ def test_post_sms_notification_returns_400_if_number_not_in_guest_list(
|
||||
notify_db_session, client, restricted
|
||||
):
|
||||
service = create_service(
|
||||
restricted=restricted, service_permissions=[SMS_TYPE, INTERNATIONAL_SMS_TYPE]
|
||||
restricted=restricted,
|
||||
service_permissions=[
|
||||
ServicePermissionType.SMS,
|
||||
ServicePermissionType.INTERNATIONAL_SMS,
|
||||
],
|
||||
)
|
||||
template = create_template(service=service)
|
||||
create_api_key(service=service, key_type="team")
|
||||
create_api_key(service=service, key_type=KeyType.TEAM)
|
||||
|
||||
data = {
|
||||
"phone_number": "+327700900855",
|
||||
"template_id": template.id,
|
||||
}
|
||||
auth_header = create_service_authorization_header(
|
||||
service_id=service.id, key_type="team"
|
||||
service_id=service.id,
|
||||
key_type=KeyType.TEAM,
|
||||
)
|
||||
|
||||
response = client.post(
|
||||
@@ -856,11 +870,13 @@ def test_post_notification_raises_bad_request_if_not_valid_notification_type(
|
||||
assert "The requested URL was not found on the server." in error_json["message"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize("notification_type", ["sms", "email"])
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type", [NotificationType.SMS, NotificationType.EMAIL]
|
||||
)
|
||||
def test_post_notification_with_wrong_type_of_sender(
|
||||
client, sample_template, sample_email_template, notification_type, fake_uuid
|
||||
):
|
||||
if notification_type == EMAIL_TYPE:
|
||||
if notification_type == NotificationType.EMAIL:
|
||||
template = sample_email_template
|
||||
form_label = "sms_sender_id"
|
||||
data = {
|
||||
@@ -868,7 +884,7 @@ def test_post_notification_with_wrong_type_of_sender(
|
||||
"template_id": str(sample_email_template.id),
|
||||
form_label: fake_uuid,
|
||||
}
|
||||
elif notification_type == SMS_TYPE:
|
||||
elif notification_type == ServicePermissionType.SMS:
|
||||
template = sample_template
|
||||
form_label = "email_reply_to_id"
|
||||
data = {
|
||||
@@ -879,14 +895,14 @@ def test_post_notification_with_wrong_type_of_sender(
|
||||
auth_header = create_service_authorization_header(service_id=template.service_id)
|
||||
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 400
|
||||
resp_json = json.loads(response.get_data(as_text=True))
|
||||
assert (
|
||||
"Additional properties are not allowed ({} was unexpected)".format(form_label)
|
||||
f"Additional properties are not allowed ({form_label} was unexpected)"
|
||||
in resp_json["errors"][0]["message"]
|
||||
)
|
||||
assert "ValidationError" in resp_json["errors"][0]["error"]
|
||||
@@ -943,11 +959,9 @@ def test_post_email_notification_with_invalid_reply_to_id_returns_400(
|
||||
assert response.status_code == 400
|
||||
resp_json = json.loads(response.get_data(as_text=True))
|
||||
assert (
|
||||
"email_reply_to_id {} does not exist in database for service id {}".format(
|
||||
fake_uuid, sample_email_template.service_id
|
||||
)
|
||||
in resp_json["errors"][0]["message"]
|
||||
)
|
||||
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"]
|
||||
assert "BadRequestError" in resp_json["errors"][0]["error"]
|
||||
|
||||
|
||||
@@ -977,11 +991,9 @@ def test_post_email_notification_with_archived_reply_to_id_returns_400(
|
||||
assert response.status_code == 400
|
||||
resp_json = json.loads(response.get_data(as_text=True))
|
||||
assert (
|
||||
"email_reply_to_id {} does not exist in database for service id {}".format(
|
||||
archived_reply_to.id, sample_email_template.service_id
|
||||
)
|
||||
in resp_json["errors"][0]["message"]
|
||||
)
|
||||
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"]
|
||||
assert "BadRequestError" in resp_json["errors"][0]["error"]
|
||||
|
||||
|
||||
@@ -1000,11 +1012,11 @@ def test_post_email_notification_with_archived_reply_to_id_returns_400(
|
||||
def test_post_notification_with_document_upload(
|
||||
client, notify_db_session, mocker, csv_param
|
||||
):
|
||||
service = create_service(service_permissions=[EMAIL_TYPE])
|
||||
service = create_service(service_permissions=[ServicePermissionType.EMAIL])
|
||||
service.contact_link = "contact.me@gov.uk"
|
||||
template = create_template(
|
||||
service=service,
|
||||
template_type="email",
|
||||
template_type=TemplateType.EMAIL,
|
||||
content="Document 1: ((first_link)). Document 2: ((second_link))",
|
||||
)
|
||||
|
||||
@@ -1042,8 +1054,8 @@ def test_post_notification_with_document_upload(
|
||||
]
|
||||
|
||||
notification = Notification.query.one()
|
||||
assert notification.status == NOTIFICATION_CREATED
|
||||
|
||||
assert notification.status == NotificationStatus.CREATED
|
||||
assert notification.personalisation == {
|
||||
"first_link": "abababab-link",
|
||||
"second_link": "cdcdcdcd-link",
|
||||
@@ -1059,10 +1071,12 @@ def test_post_notification_with_document_upload(
|
||||
def test_post_notification_with_document_upload_simulated(
|
||||
client, notify_db_session, mocker
|
||||
):
|
||||
service = create_service(service_permissions=[EMAIL_TYPE])
|
||||
service = create_service(service_permissions=[ServicePermissionType.EMAIL])
|
||||
service.contact_link = "contact.me@gov.uk"
|
||||
template = create_template(
|
||||
service=service, template_type="email", content="Document: ((document))"
|
||||
service=service,
|
||||
template_type=TemplateType.EMAIL,
|
||||
content="Document: ((document))",
|
||||
)
|
||||
|
||||
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
||||
@@ -1096,9 +1110,11 @@ def test_post_notification_with_document_upload_simulated(
|
||||
def test_post_notification_without_document_upload_permission(
|
||||
client, notify_db_session, mocker
|
||||
):
|
||||
service = create_service(service_permissions=[EMAIL_TYPE])
|
||||
service = create_service(service_permissions=[ServicePermissionType.EMAIL])
|
||||
template = create_template(
|
||||
service=service, template_type="email", content="Document: ((document))"
|
||||
service=service,
|
||||
template_type=TemplateType.EMAIL,
|
||||
content="Document: ((document))",
|
||||
)
|
||||
|
||||
mocker.patch("app.celery.provider_tasks.deliver_email.apply_async")
|
||||
@@ -1140,21 +1156,24 @@ def test_post_notification_returns_400_when_get_json_throws_exception(
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type, content_type",
|
||||
[
|
||||
("email", "application/json"),
|
||||
("email", "application/text"),
|
||||
("sms", "application/json"),
|
||||
("sms", "application/text"),
|
||||
(NotificationType.EMAIL, "application/json"),
|
||||
(NotificationType.EMAIL, "application/text"),
|
||||
(NotificationType.SMS, "application/json"),
|
||||
(NotificationType.SMS, "application/text"),
|
||||
],
|
||||
)
|
||||
def test_post_notification_when_payload_is_invalid_json_returns_400(
|
||||
client, sample_service, notification_type, content_type
|
||||
client,
|
||||
sample_service,
|
||||
notification_type,
|
||||
content_type,
|
||||
):
|
||||
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
||||
payload_not_json = {
|
||||
"template_id": "dont-convert-to-json",
|
||||
}
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=payload_not_json,
|
||||
headers=[("Content-Type", content_type), auth_header],
|
||||
)
|
||||
@@ -1165,51 +1184,67 @@ def test_post_notification_when_payload_is_invalid_json_returns_400(
|
||||
assert error_msg == "Invalid JSON supplied in POST data"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("notification_type", ["email", "sms"])
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type",
|
||||
[
|
||||
NotificationType.EMAIL,
|
||||
NotificationType.SMS,
|
||||
],
|
||||
)
|
||||
def test_post_notification_returns_201_when_content_type_is_missing_but_payload_is_valid_json(
|
||||
client, sample_service, notification_type, mocker
|
||||
):
|
||||
template = create_template(service=sample_service, template_type=notification_type)
|
||||
mocker.patch(
|
||||
"app.celery.provider_tasks.deliver_{}.apply_async".format(notification_type)
|
||||
)
|
||||
mocker.patch(f"app.celery.provider_tasks.deliver_{notification_type}.apply_async")
|
||||
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
||||
|
||||
valid_json = {
|
||||
"template_id": str(template.id),
|
||||
}
|
||||
if notification_type == "email":
|
||||
if notification_type == NotificationType.EMAIL:
|
||||
valid_json.update({"email_address": sample_service.users[0].email_address})
|
||||
else:
|
||||
valid_json.update({"phone_number": "+447700900855"})
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(valid_json),
|
||||
headers=[auth_header],
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
@pytest.mark.parametrize("notification_type", ["email", "sms"])
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type",
|
||||
[
|
||||
NotificationType.EMAIL,
|
||||
NotificationType.SMS,
|
||||
],
|
||||
)
|
||||
def test_post_email_notification_when_data_is_empty_returns_400(
|
||||
client, sample_service, notification_type
|
||||
):
|
||||
auth_header = create_service_authorization_header(service_id=sample_service.id)
|
||||
data = None
|
||||
response = client.post(
|
||||
path="/v2/notifications/{}".format(notification_type),
|
||||
path=f"/v2/notifications/{notification_type}",
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
error_msg = json.loads(response.get_data(as_text=True))["errors"][0]["message"]
|
||||
assert response.status_code == 400
|
||||
if notification_type == "sms":
|
||||
if notification_type == NotificationType.SMS:
|
||||
assert error_msg == "phone_number is a required property"
|
||||
else:
|
||||
assert error_msg == "email_address is a required property"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("notification_type", ("email", "sms"))
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type",
|
||||
(
|
||||
NotificationType.EMAIL,
|
||||
NotificationType.SMS,
|
||||
),
|
||||
)
|
||||
def test_post_notifications_saves_email_or_sms_to_queue(
|
||||
client, notify_db_session, mocker, notification_type
|
||||
):
|
||||
@@ -1238,7 +1273,7 @@ def test_post_notifications_saves_email_or_sms_to_queue(
|
||||
}
|
||||
data.update(
|
||||
{"email_address": "joe.citizen@example.com"}
|
||||
) if notification_type == EMAIL_TYPE else data.update(
|
||||
) if notification_type == NotificationType.EMAIL else data.update(
|
||||
{"phone_number": "+447700900855"}
|
||||
)
|
||||
|
||||
@@ -1271,7 +1306,13 @@ def test_post_notifications_saves_email_or_sms_to_queue(
|
||||
botocore.parsers.ResponseParserError("exceeded max HTTP body length"),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("notification_type", ("email", "sms"))
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type",
|
||||
(
|
||||
NotificationType.EMAIL,
|
||||
NotificationType.SMS,
|
||||
),
|
||||
)
|
||||
def test_post_notifications_saves_email_or_sms_normally_if_saving_to_queue_fails(
|
||||
client, notify_db_session, mocker, notification_type, exception
|
||||
):
|
||||
@@ -1301,7 +1342,7 @@ def test_post_notifications_saves_email_or_sms_normally_if_saving_to_queue_fails
|
||||
}
|
||||
data.update(
|
||||
{"email_address": "joe.citizen@example.com"}
|
||||
) if notification_type == EMAIL_TYPE else data.update(
|
||||
) if notification_type == NotificationType.EMAIL else data.update(
|
||||
{"phone_number": "+447700900855"}
|
||||
)
|
||||
|
||||
@@ -1329,7 +1370,13 @@ def test_post_notifications_saves_email_or_sms_normally_if_saving_to_queue_fails
|
||||
assert Notification.query.count() == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize("notification_type", ("email", "sms"))
|
||||
@pytest.mark.parametrize(
|
||||
"notification_type",
|
||||
(
|
||||
NotificationType.EMAIL,
|
||||
NotificationType.SMS,
|
||||
),
|
||||
)
|
||||
def test_post_notifications_doesnt_use_save_queue_for_test_notifications(
|
||||
client, notify_db_session, mocker, notification_type
|
||||
):
|
||||
@@ -1357,7 +1404,7 @@ def test_post_notifications_doesnt_use_save_queue_for_test_notifications(
|
||||
}
|
||||
data.update(
|
||||
{"email_address": "joe.citizen@example.com"}
|
||||
) if notification_type == EMAIL_TYPE else data.update(
|
||||
) if notification_type == NotificationType.EMAIL else data.update(
|
||||
{"phone_number": "+447700900855"}
|
||||
)
|
||||
response = client.post(
|
||||
@@ -1366,7 +1413,8 @@ def test_post_notifications_doesnt_use_save_queue_for_test_notifications(
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_service_authorization_header(
|
||||
service_id=service.id, key_type="test"
|
||||
service_id=service.id,
|
||||
key_type=KeyType.TEST,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user