mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-24 16:23:44 -04:00
reformat
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -32,42 +32,41 @@ from tests.app.db import (
|
||||
@pytest.fixture
|
||||
def persist_mock(mocker):
|
||||
noti = Mock(id=uuid.uuid4())
|
||||
return mocker.patch('app.service.send_notification.persist_notification', return_value=noti)
|
||||
return mocker.patch(
|
||||
"app.service.send_notification.persist_notification", return_value=noti
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def celery_mock(mocker):
|
||||
return mocker.patch('app.service.send_notification.send_notification_to_queue')
|
||||
return mocker.patch("app.service.send_notification.send_notification_to_queue")
|
||||
|
||||
|
||||
def test_send_one_off_notification_calls_celery_correctly(persist_mock, celery_mock, notify_db_session):
|
||||
def test_send_one_off_notification_calls_celery_correctly(
|
||||
persist_mock, celery_mock, notify_db_session
|
||||
):
|
||||
service = create_service()
|
||||
template = create_template(service=service)
|
||||
|
||||
service = template.service
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': '202-867-5309',
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "202-867-5309",
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
resp = send_one_off_notification(service.id, post_data)
|
||||
|
||||
assert resp == {
|
||||
'id': str(persist_mock.return_value.id)
|
||||
}
|
||||
assert resp == {"id": str(persist_mock.return_value.id)}
|
||||
|
||||
celery_mock.assert_called_once_with(
|
||||
notification=persist_mock.return_value,
|
||||
queue=None
|
||||
notification=persist_mock.return_value, queue=None
|
||||
)
|
||||
|
||||
|
||||
def test_send_one_off_notification_calls_persist_correctly_for_sms(
|
||||
persist_mock,
|
||||
celery_mock,
|
||||
notify_db_session
|
||||
persist_mock, celery_mock, notify_db_session
|
||||
):
|
||||
service = create_service()
|
||||
template = create_template(
|
||||
@@ -77,10 +76,10 @@ def test_send_one_off_notification_calls_persist_correctly_for_sms(
|
||||
)
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': '202-867-5309',
|
||||
'personalisation': {'name': 'foo'},
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "202-867-5309",
|
||||
"personalisation": {"name": "foo"},
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
send_one_off_notification(service.id, post_data)
|
||||
@@ -88,46 +87,42 @@ def test_send_one_off_notification_calls_persist_correctly_for_sms(
|
||||
persist_mock.assert_called_once_with(
|
||||
template_id=template.id,
|
||||
template_version=template.version,
|
||||
recipient=post_data['to'],
|
||||
recipient=post_data["to"],
|
||||
service=template.service,
|
||||
personalisation={'name': 'foo'},
|
||||
personalisation={"name": "foo"},
|
||||
notification_type=SMS_TYPE,
|
||||
api_key_id=None,
|
||||
key_type=KEY_TYPE_NORMAL,
|
||||
created_by_id=str(service.created_by_id),
|
||||
reply_to_text='testing',
|
||||
reply_to_text="testing",
|
||||
reference=None,
|
||||
client_reference=None
|
||||
client_reference=None,
|
||||
)
|
||||
|
||||
|
||||
def test_send_one_off_notification_calls_persist_correctly_for_international_sms(
|
||||
persist_mock,
|
||||
celery_mock,
|
||||
notify_db_session
|
||||
persist_mock, celery_mock, notify_db_session
|
||||
):
|
||||
service = create_service(service_permissions=['sms', 'international_sms'])
|
||||
service = create_service(service_permissions=["sms", "international_sms"])
|
||||
template = create_template(
|
||||
service=service,
|
||||
template_type=SMS_TYPE,
|
||||
)
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': '+(44) 7700-900 855',
|
||||
'personalisation': {'name': 'foo'},
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "+(44) 7700-900 855",
|
||||
"personalisation": {"name": "foo"},
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
send_one_off_notification(service.id, post_data)
|
||||
|
||||
assert persist_mock.call_args[1]['recipient'] == '+(44) 7700-900 855'
|
||||
assert persist_mock.call_args[1]["recipient"] == "+(44) 7700-900 855"
|
||||
|
||||
|
||||
def test_send_one_off_notification_calls_persist_correctly_for_email(
|
||||
persist_mock,
|
||||
celery_mock,
|
||||
notify_db_session
|
||||
persist_mock, celery_mock, notify_db_session
|
||||
):
|
||||
service = create_service()
|
||||
template = create_template(
|
||||
@@ -138,10 +133,10 @@ def test_send_one_off_notification_calls_persist_correctly_for_email(
|
||||
)
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': 'test@example.com',
|
||||
'personalisation': {'name': 'foo'},
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "test@example.com",
|
||||
"personalisation": {"name": "foo"},
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
send_one_off_notification(service.id, post_data)
|
||||
@@ -149,33 +144,35 @@ def test_send_one_off_notification_calls_persist_correctly_for_email(
|
||||
persist_mock.assert_called_once_with(
|
||||
template_id=template.id,
|
||||
template_version=template.version,
|
||||
recipient=post_data['to'],
|
||||
recipient=post_data["to"],
|
||||
service=template.service,
|
||||
personalisation={'name': 'foo'},
|
||||
personalisation={"name": "foo"},
|
||||
notification_type=EMAIL_TYPE,
|
||||
api_key_id=None,
|
||||
key_type=KEY_TYPE_NORMAL,
|
||||
created_by_id=str(service.created_by_id),
|
||||
reply_to_text=None,
|
||||
reference=None,
|
||||
client_reference=None
|
||||
client_reference=None,
|
||||
)
|
||||
|
||||
|
||||
def test_send_one_off_notification_honors_priority(notify_db_session, persist_mock, celery_mock):
|
||||
def test_send_one_off_notification_honors_priority(
|
||||
notify_db_session, persist_mock, celery_mock
|
||||
):
|
||||
service = create_service()
|
||||
template = create_template(service=service)
|
||||
template.process_type = PRIORITY
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': '202-867-5309',
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "202-867-5309",
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
send_one_off_notification(service.id, post_data)
|
||||
|
||||
assert celery_mock.call_args[1]['queue'] == QueueNames.PRIORITY
|
||||
assert celery_mock.call_args[1]["queue"] == QueueNames.PRIORITY
|
||||
|
||||
|
||||
def test_send_one_off_notification_raises_if_invalid_recipient(notify_db_session):
|
||||
@@ -183,169 +180,186 @@ def test_send_one_off_notification_raises_if_invalid_recipient(notify_db_session
|
||||
template = create_template(service=service)
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': 'not a phone number',
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "not a phone number",
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
with pytest.raises(InvalidPhoneError):
|
||||
send_one_off_notification(service.id, post_data)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('recipient', [
|
||||
'2028675300', # not in team or guest_list
|
||||
'2028765309', # in guest_list
|
||||
'+1-202-876-5309', # in guest_list in different format
|
||||
])
|
||||
@pytest.mark.parametrize(
|
||||
"recipient",
|
||||
[
|
||||
"2028675300", # not in team or guest_list
|
||||
"2028765309", # in guest_list
|
||||
"+1-202-876-5309", # in guest_list in different format
|
||||
],
|
||||
)
|
||||
def test_send_one_off_notification_raises_if_cant_send_to_recipient(
|
||||
notify_db_session,
|
||||
recipient,
|
||||
):
|
||||
service = create_service(restricted=True)
|
||||
template = create_template(service=service)
|
||||
dao_add_and_commit_guest_list_contacts([
|
||||
ServiceGuestList.from_string(service.id, MOBILE_TYPE, '2028765309'),
|
||||
])
|
||||
dao_add_and_commit_guest_list_contacts(
|
||||
[
|
||||
ServiceGuestList.from_string(service.id, MOBILE_TYPE, "2028765309"),
|
||||
]
|
||||
)
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': recipient,
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": recipient,
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
with pytest.raises(BadRequestError) as e:
|
||||
send_one_off_notification(service.id, post_data)
|
||||
|
||||
assert 'service is in trial mode' in e.value.message
|
||||
assert "service is in trial mode" in e.value.message
|
||||
|
||||
|
||||
def test_send_one_off_notification_raises_if_message_too_long(persist_mock, notify_db_session):
|
||||
def test_send_one_off_notification_raises_if_message_too_long(
|
||||
persist_mock, notify_db_session
|
||||
):
|
||||
service = create_service()
|
||||
template = create_template(service=service, content="Hello (( Name))\nYour thing is due soon")
|
||||
template = create_template(
|
||||
service=service, content="Hello (( Name))\nYour thing is due soon"
|
||||
)
|
||||
|
||||
post_data = {
|
||||
'template_id': str(template.id),
|
||||
'to': '07700 900 001',
|
||||
'personalisation': {'name': '🚫' * 1000},
|
||||
'created_by': str(service.created_by_id)
|
||||
"template_id": str(template.id),
|
||||
"to": "07700 900 001",
|
||||
"personalisation": {"name": "🚫" * 1000},
|
||||
"created_by": str(service.created_by_id),
|
||||
}
|
||||
|
||||
with pytest.raises(BadRequestError) as e:
|
||||
send_one_off_notification(service.id, post_data)
|
||||
|
||||
assert e.value.message == f'Your message is too long. ' \
|
||||
f'Text messages cannot be longer than {SMS_CHAR_COUNT_LIMIT} characters. ' \
|
||||
f'Your message is {1029} characters long.'
|
||||
assert (
|
||||
e.value.message == f"Your message is too long. "
|
||||
f"Text messages cannot be longer than {SMS_CHAR_COUNT_LIMIT} characters. "
|
||||
f"Your message is {1029} characters long."
|
||||
)
|
||||
|
||||
|
||||
def test_send_one_off_notification_fails_if_created_by_other_service(sample_template):
|
||||
user_not_in_service = create_user(email='some-other-user@gov.uk')
|
||||
user_not_in_service = create_user(email="some-other-user@gov.uk")
|
||||
|
||||
post_data = {
|
||||
'template_id': str(sample_template.id),
|
||||
'to': '202-867-5309',
|
||||
'created_by': str(user_not_in_service.id)
|
||||
"template_id": str(sample_template.id),
|
||||
"to": "202-867-5309",
|
||||
"created_by": str(user_not_in_service.id),
|
||||
}
|
||||
|
||||
with pytest.raises(BadRequestError) as e:
|
||||
send_one_off_notification(sample_template.service_id, post_data)
|
||||
|
||||
assert e.value.message == 'Can’t create notification - Test User is not part of the "Sample service" service'
|
||||
assert (
|
||||
e.value.message
|
||||
== 'Can’t create notification - Test User is not part of the "Sample service" service'
|
||||
)
|
||||
|
||||
|
||||
def test_send_one_off_notification_should_add_email_reply_to_text_for_notification(sample_email_template, celery_mock):
|
||||
reply_to_email = create_reply_to_email(sample_email_template.service, 'test@test.com')
|
||||
def test_send_one_off_notification_should_add_email_reply_to_text_for_notification(
|
||||
sample_email_template, celery_mock
|
||||
):
|
||||
reply_to_email = create_reply_to_email(
|
||||
sample_email_template.service, "test@test.com"
|
||||
)
|
||||
data = {
|
||||
'to': 'ok@ok.com',
|
||||
'template_id': str(sample_email_template.id),
|
||||
'sender_id': reply_to_email.id,
|
||||
'created_by': str(sample_email_template.service.created_by_id)
|
||||
"to": "ok@ok.com",
|
||||
"template_id": str(sample_email_template.id),
|
||||
"sender_id": reply_to_email.id,
|
||||
"created_by": str(sample_email_template.service.created_by_id),
|
||||
}
|
||||
|
||||
notification_id = send_one_off_notification(service_id=sample_email_template.service.id, post_data=data)
|
||||
notification = Notification.query.get(notification_id['id'])
|
||||
celery_mock.assert_called_once_with(
|
||||
notification=notification,
|
||||
queue=None
|
||||
notification_id = send_one_off_notification(
|
||||
service_id=sample_email_template.service.id, post_data=data
|
||||
)
|
||||
notification = Notification.query.get(notification_id["id"])
|
||||
celery_mock.assert_called_once_with(notification=notification, queue=None)
|
||||
assert notification.reply_to_text == reply_to_email.email_address
|
||||
|
||||
|
||||
def test_send_one_off_sms_notification_should_use_sms_sender_reply_to_text(sample_service, celery_mock):
|
||||
def test_send_one_off_sms_notification_should_use_sms_sender_reply_to_text(
|
||||
sample_service, celery_mock
|
||||
):
|
||||
template = create_template(service=sample_service, template_type=SMS_TYPE)
|
||||
sms_sender = create_service_sms_sender(
|
||||
service=sample_service,
|
||||
sms_sender='2028675309',
|
||||
is_default=False
|
||||
service=sample_service, sms_sender="2028675309", is_default=False
|
||||
)
|
||||
|
||||
data = {
|
||||
'to': '2028675000',
|
||||
'template_id': str(template.id),
|
||||
'created_by': str(sample_service.created_by_id),
|
||||
'sender_id': str(sms_sender.id),
|
||||
"to": "2028675000",
|
||||
"template_id": str(template.id),
|
||||
"created_by": str(sample_service.created_by_id),
|
||||
"sender_id": str(sms_sender.id),
|
||||
}
|
||||
|
||||
notification_id = send_one_off_notification(service_id=sample_service.id, post_data=data)
|
||||
notification = Notification.query.get(notification_id['id'])
|
||||
celery_mock.assert_called_once_with(
|
||||
notification=notification,
|
||||
queue=None
|
||||
notification_id = send_one_off_notification(
|
||||
service_id=sample_service.id, post_data=data
|
||||
)
|
||||
notification = Notification.query.get(notification_id["id"])
|
||||
celery_mock.assert_called_once_with(notification=notification, queue=None)
|
||||
|
||||
assert notification.reply_to_text == "+12028675309"
|
||||
|
||||
|
||||
def test_send_one_off_sms_notification_should_use_default_service_reply_to_text(sample_service, celery_mock):
|
||||
def test_send_one_off_sms_notification_should_use_default_service_reply_to_text(
|
||||
sample_service, celery_mock
|
||||
):
|
||||
template = create_template(service=sample_service, template_type=SMS_TYPE)
|
||||
sample_service.service_sms_senders[0].is_default = False
|
||||
create_service_sms_sender(
|
||||
service=sample_service,
|
||||
sms_sender='2028675309',
|
||||
is_default=True
|
||||
service=sample_service, sms_sender="2028675309", is_default=True
|
||||
)
|
||||
|
||||
data = {
|
||||
'to': '2028675000',
|
||||
'template_id': str(template.id),
|
||||
'created_by': str(sample_service.created_by_id),
|
||||
"to": "2028675000",
|
||||
"template_id": str(template.id),
|
||||
"created_by": str(sample_service.created_by_id),
|
||||
}
|
||||
|
||||
notification_id = send_one_off_notification(service_id=sample_service.id, post_data=data)
|
||||
notification = Notification.query.get(notification_id['id'])
|
||||
celery_mock.assert_called_once_with(
|
||||
notification=notification,
|
||||
queue=None
|
||||
notification_id = send_one_off_notification(
|
||||
service_id=sample_service.id, post_data=data
|
||||
)
|
||||
notification = Notification.query.get(notification_id["id"])
|
||||
celery_mock.assert_called_once_with(notification=notification, queue=None)
|
||||
|
||||
assert notification.reply_to_text == "+12028675309"
|
||||
|
||||
|
||||
def test_send_one_off_notification_should_throw_exception_if_reply_to_id_doesnot_exist(
|
||||
sample_email_template
|
||||
sample_email_template,
|
||||
):
|
||||
data = {
|
||||
'to': 'ok@ok.com',
|
||||
'template_id': str(sample_email_template.id),
|
||||
'sender_id': str(uuid.uuid4()),
|
||||
'created_by': str(sample_email_template.service.created_by_id)
|
||||
"to": "ok@ok.com",
|
||||
"template_id": str(sample_email_template.id),
|
||||
"sender_id": str(uuid.uuid4()),
|
||||
"created_by": str(sample_email_template.service.created_by_id),
|
||||
}
|
||||
|
||||
with pytest.raises(expected_exception=BadRequestError) as e:
|
||||
send_one_off_notification(service_id=sample_email_template.service.id, post_data=data)
|
||||
assert e.value.message == 'Reply to email address not found'
|
||||
send_one_off_notification(
|
||||
service_id=sample_email_template.service.id, post_data=data
|
||||
)
|
||||
assert e.value.message == "Reply to email address not found"
|
||||
|
||||
|
||||
def test_send_one_off_notification_should_throw_exception_if_sms_sender_id_doesnot_exist(
|
||||
sample_template
|
||||
sample_template,
|
||||
):
|
||||
data = {
|
||||
'to': '2028675000',
|
||||
'template_id': str(sample_template.id),
|
||||
'sender_id': str(uuid.uuid4()),
|
||||
'created_by': str(sample_template.service.created_by_id)
|
||||
"to": "2028675000",
|
||||
"template_id": str(sample_template.id),
|
||||
"sender_id": str(uuid.uuid4()),
|
||||
"created_by": str(sample_template.service.created_by_id),
|
||||
}
|
||||
|
||||
with pytest.raises(expected_exception=BadRequestError) as e:
|
||||
send_one_off_notification(service_id=sample_template.service.id, post_data=data)
|
||||
assert e.value.message == 'SMS sender not found'
|
||||
assert e.value.message == "SMS sender not found"
|
||||
|
||||
@@ -12,45 +12,51 @@ def test_api_key_should_create_new_api_key_for_service(notify_api, sample_servic
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
data = {
|
||||
'name': 'some secret name',
|
||||
'created_by': str(sample_service.created_by.id),
|
||||
'key_type': KEY_TYPE_NORMAL
|
||||
"name": "some secret name",
|
||||
"created_by": str(sample_service.created_by.id),
|
||||
"key_type": KEY_TYPE_NORMAL,
|
||||
}
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post(url_for('service.create_api_key', service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response = client.post(
|
||||
url_for("service.create_api_key", service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 201
|
||||
assert 'data' in json.loads(response.get_data(as_text=True))
|
||||
assert "data" in json.loads(response.get_data(as_text=True))
|
||||
saved_api_key = ApiKey.query.filter_by(service_id=sample_service.id).first()
|
||||
assert saved_api_key.service_id == sample_service.id
|
||||
assert saved_api_key.name == 'some secret name'
|
||||
assert saved_api_key.name == "some secret name"
|
||||
|
||||
|
||||
def test_api_key_should_return_error_when_service_does_not_exist(notify_api, sample_service):
|
||||
def test_api_key_should_return_error_when_service_does_not_exist(
|
||||
notify_api, sample_service
|
||||
):
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
import uuid
|
||||
|
||||
missing_service_id = uuid.uuid4()
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post(url_for('service.create_api_key', service_id=missing_service_id),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response = client.post(
|
||||
url_for("service.create_api_key", service_id=missing_service_id),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_create_api_key_without_key_type_rejects(client, sample_service):
|
||||
data = {
|
||||
'name': 'some secret name',
|
||||
'created_by': str(sample_service.created_by.id)
|
||||
}
|
||||
data = {"name": "some secret name", "created_by": str(sample_service.created_by.id)}
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post(url_for('service.create_api_key', service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response = client.post(
|
||||
url_for("service.create_api_key", service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 400
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert json_resp['result'] == 'error'
|
||||
assert json_resp['message'] == {'key_type': ['Missing data for required field.']}
|
||||
assert json_resp["result"] == "error"
|
||||
assert json_resp["message"] == {"key_type": ["Missing data for required field."]}
|
||||
|
||||
|
||||
def test_revoke_should_expire_api_key_for_service(notify_api, sample_api_key):
|
||||
@@ -58,74 +64,95 @@ def test_revoke_should_expire_api_key_for_service(notify_api, sample_api_key):
|
||||
with notify_api.test_client() as client:
|
||||
assert ApiKey.query.count() == 1
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post(url_for('service.revoke_api_key',
|
||||
service_id=sample_api_key.service_id,
|
||||
api_key_id=sample_api_key.id),
|
||||
headers=[auth_header])
|
||||
response = client.post(
|
||||
url_for(
|
||||
"service.revoke_api_key",
|
||||
service_id=sample_api_key.service_id,
|
||||
api_key_id=sample_api_key.id,
|
||||
),
|
||||
headers=[auth_header],
|
||||
)
|
||||
assert response.status_code == 202
|
||||
api_keys_for_service = ApiKey.query.get(sample_api_key.id)
|
||||
assert api_keys_for_service.expiry_date is not None
|
||||
|
||||
|
||||
def test_api_key_should_create_multiple_new_api_key_for_service(notify_api, sample_service):
|
||||
def test_api_key_should_create_multiple_new_api_key_for_service(
|
||||
notify_api, sample_service
|
||||
):
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
assert ApiKey.query.count() == 0
|
||||
data = {
|
||||
'name': 'some secret name',
|
||||
'created_by': str(sample_service.created_by.id),
|
||||
'key_type': KEY_TYPE_NORMAL
|
||||
"name": "some secret name",
|
||||
"created_by": str(sample_service.created_by.id),
|
||||
"key_type": KEY_TYPE_NORMAL,
|
||||
}
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post(url_for('service.create_api_key', service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response = client.post(
|
||||
url_for("service.create_api_key", service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 201
|
||||
assert ApiKey.query.count() == 1
|
||||
|
||||
data['name'] = 'another secret name'
|
||||
data["name"] = "another secret name"
|
||||
auth_header = create_admin_authorization_header()
|
||||
response2 = client.post(url_for('service.create_api_key', service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response2 = client.post(
|
||||
url_for("service.create_api_key", service_id=sample_service.id),
|
||||
data=json.dumps(data),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response2.status_code == 201
|
||||
assert json.loads(response.get_data(as_text=True)) != json.loads(response2.get_data(as_text=True))
|
||||
assert json.loads(response.get_data(as_text=True)) != json.loads(
|
||||
response2.get_data(as_text=True)
|
||||
)
|
||||
assert ApiKey.query.count() == 2
|
||||
|
||||
|
||||
def test_get_api_keys_should_return_all_keys_for_service(notify_api, sample_api_key):
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
another_user = create_user(email='another@it.gov.uk')
|
||||
another_user = create_user(email="another@it.gov.uk")
|
||||
|
||||
another_service = create_service(user=another_user, service_name='Another service')
|
||||
another_service = create_service(
|
||||
user=another_user, service_name="Another service"
|
||||
)
|
||||
# key for another service
|
||||
create_api_key(another_service)
|
||||
|
||||
# this service already has one key, add two more, one expired
|
||||
create_api_key(sample_api_key.service)
|
||||
one_to_expire = create_api_key(sample_api_key.service)
|
||||
expire_api_key(service_id=one_to_expire.service_id, api_key_id=one_to_expire.id)
|
||||
expire_api_key(
|
||||
service_id=one_to_expire.service_id, api_key_id=one_to_expire.id
|
||||
)
|
||||
|
||||
assert ApiKey.query.count() == 4
|
||||
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.get(url_for('service.get_api_keys',
|
||||
service_id=sample_api_key.service_id),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response = client.get(
|
||||
url_for("service.get_api_keys", service_id=sample_api_key.service_id),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert len(json_resp['apiKeys']) == 3
|
||||
assert len(json_resp["apiKeys"]) == 3
|
||||
|
||||
|
||||
def test_get_api_keys_should_return_one_key_for_service(notify_api, sample_api_key):
|
||||
with notify_api.test_request_context():
|
||||
with notify_api.test_client() as client:
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.get(url_for('service.get_api_keys',
|
||||
service_id=sample_api_key.service_id,
|
||||
key_id=sample_api_key.id),
|
||||
headers=[('Content-Type', 'application/json'), auth_header])
|
||||
response = client.get(
|
||||
url_for(
|
||||
"service.get_api_keys",
|
||||
service_id=sample_api_key.service_id,
|
||||
key_id=sample_api_key.id,
|
||||
),
|
||||
headers=[("Content-Type", "application/json"), auth_header],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert len(json_resp['apiKeys']) == 1
|
||||
assert len(json_resp["apiKeys"]) == 1
|
||||
|
||||
@@ -15,49 +15,57 @@ from tests.app.db import create_api_key, create_template
|
||||
|
||||
def test_archive_only_allows_post(client, notify_db_session):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.get('/service/{}/archive'.format(uuid.uuid4()), headers=[auth_header])
|
||||
response = client.get(
|
||||
"/service/{}/archive".format(uuid.uuid4()), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
def test_archive_service_errors_with_bad_service_id(client, notify_db_session):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post('/service/{}/archive'.format(uuid.uuid4()), headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/archive".format(uuid.uuid4()), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_deactivating_inactive_service_does_nothing(client, sample_service):
|
||||
auth_header = create_admin_authorization_header()
|
||||
sample_service.active = False
|
||||
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/archive".format(sample_service.id), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 204
|
||||
assert sample_service.name == 'Sample service'
|
||||
assert sample_service.name == "Sample service"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def archived_service(client, notify_db_session, sample_service):
|
||||
create_template(sample_service, template_name='a')
|
||||
create_template(sample_service, template_name='b')
|
||||
create_template(sample_service, template_name="a")
|
||||
create_template(sample_service, template_name="b")
|
||||
create_api_key(sample_service)
|
||||
create_api_key(sample_service)
|
||||
|
||||
notify_db_session.commit()
|
||||
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/archive".format(sample_service.id), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 204
|
||||
assert response.data == b''
|
||||
assert response.data == b""
|
||||
return sample_service
|
||||
|
||||
|
||||
@freeze_time('2018-07-07 12:00:00')
|
||||
@freeze_time("2018-07-07 12:00:00")
|
||||
def test_deactivating_service_changes_name_and_email(client, sample_service):
|
||||
auth_header = create_admin_authorization_header()
|
||||
client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
|
||||
client.post("/service/{}/archive".format(sample_service.id), headers=[auth_header])
|
||||
|
||||
archived_service = dao_fetch_service_by_id(sample_service.id)
|
||||
|
||||
assert archived_service.name == '_archived_2018-07-07_Sample service'
|
||||
assert archived_service.email_from == '_archived_2018-07-07_sample.service'
|
||||
assert archived_service.name == "_archived_2018-07-07_Sample service"
|
||||
assert archived_service.email_from == "_archived_2018-07-07_sample.service"
|
||||
|
||||
|
||||
def test_deactivating_service_revokes_api_keys(archived_service):
|
||||
@@ -76,11 +84,11 @@ def test_deactivating_service_archives_templates(archived_service):
|
||||
|
||||
def test_deactivating_service_creates_history(archived_service):
|
||||
ServiceHistory = Service.get_history_model()
|
||||
history = ServiceHistory.query.filter_by(
|
||||
id=archived_service.id
|
||||
).order_by(
|
||||
ServiceHistory.version.desc()
|
||||
).first()
|
||||
history = (
|
||||
ServiceHistory.query.filter_by(id=archived_service.id)
|
||||
.order_by(ServiceHistory.version.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
assert history.version == 2
|
||||
assert history.active is False
|
||||
@@ -88,8 +96,8 @@ def test_deactivating_service_creates_history(archived_service):
|
||||
|
||||
@pytest.fixture
|
||||
def archived_service_with_deleted_stuff(client, sample_service):
|
||||
with freeze_time('2001-01-01'):
|
||||
template = create_template(sample_service, template_name='a')
|
||||
with freeze_time("2001-01-01"):
|
||||
template = create_template(sample_service, template_name="a")
|
||||
api_key = create_api_key(sample_service)
|
||||
|
||||
expire_api_key(sample_service.id, api_key.id)
|
||||
@@ -97,27 +105,39 @@ def archived_service_with_deleted_stuff(client, sample_service):
|
||||
template.archived = True
|
||||
dao_update_template(template)
|
||||
|
||||
with freeze_time('2002-02-02'):
|
||||
with freeze_time("2002-02-02"):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post('/service/{}/archive'.format(sample_service.id), headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/archive".format(sample_service.id), headers=[auth_header]
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
assert response.data == b''
|
||||
assert response.data == b""
|
||||
return sample_service
|
||||
|
||||
|
||||
def test_deactivating_service_doesnt_affect_existing_archived_templates(archived_service_with_deleted_stuff):
|
||||
def test_deactivating_service_doesnt_affect_existing_archived_templates(
|
||||
archived_service_with_deleted_stuff,
|
||||
):
|
||||
assert archived_service_with_deleted_stuff.templates[0].archived is True
|
||||
assert archived_service_with_deleted_stuff.templates[0].updated_at == datetime(2001, 1, 1, 0, 0, 0)
|
||||
assert archived_service_with_deleted_stuff.templates[0].updated_at == datetime(
|
||||
2001, 1, 1, 0, 0, 0
|
||||
)
|
||||
assert archived_service_with_deleted_stuff.templates[0].version == 2
|
||||
|
||||
|
||||
def test_deactivating_service_doesnt_affect_existing_revoked_api_keys(archived_service_with_deleted_stuff):
|
||||
assert archived_service_with_deleted_stuff.api_keys[0].expiry_date == datetime(2001, 1, 1, 0, 0, 0)
|
||||
def test_deactivating_service_doesnt_affect_existing_revoked_api_keys(
|
||||
archived_service_with_deleted_stuff,
|
||||
):
|
||||
assert archived_service_with_deleted_stuff.api_keys[0].expiry_date == datetime(
|
||||
2001, 1, 1, 0, 0, 0
|
||||
)
|
||||
assert archived_service_with_deleted_stuff.api_keys[0].version == 2
|
||||
|
||||
|
||||
def test_deactivating_service_rolls_back_everything_on_error(sample_service, sample_api_key, sample_template):
|
||||
def test_deactivating_service_rolls_back_everything_on_error(
|
||||
sample_service, sample_api_key, sample_template
|
||||
):
|
||||
unwrapped_deactive_service = unwrap_function(dao_archive_service)
|
||||
|
||||
unwrapped_deactive_service(sample_service.id)
|
||||
|
||||
@@ -8,13 +8,13 @@ def test_create_service_inbound_api(admin_request, sample_service):
|
||||
data = {
|
||||
"url": "https://some_service/inbound-sms",
|
||||
"bearer_token": "some-unique-string",
|
||||
"updated_by_id": str(sample_service.users[0].id)
|
||||
"updated_by_id": str(sample_service.users[0].id),
|
||||
}
|
||||
resp_json = admin_request.post(
|
||||
'service_callback.create_service_inbound_api',
|
||||
"service_callback.create_service_inbound_api",
|
||||
service_id=sample_service.id,
|
||||
_data=data,
|
||||
_expected_status=201
|
||||
_expected_status=201,
|
||||
)
|
||||
|
||||
resp_json = resp_json["data"]
|
||||
@@ -30,31 +30,32 @@ def test_set_service_inbound_api_raises_404_when_service_does_not_exist(admin_re
|
||||
data = {
|
||||
"url": "https://some_service/inbound-sms",
|
||||
"bearer_token": "some-unique-string",
|
||||
"updated_by_id": str(uuid.uuid4())
|
||||
"updated_by_id": str(uuid.uuid4()),
|
||||
}
|
||||
response = admin_request.post(
|
||||
'service_callback.create_service_inbound_api',
|
||||
"service_callback.create_service_inbound_api",
|
||||
service_id=uuid.uuid4(),
|
||||
_data=data,
|
||||
_expected_status=404
|
||||
_expected_status=404,
|
||||
)
|
||||
assert response['message'] == 'No result found'
|
||||
assert response["message"] == "No result found"
|
||||
|
||||
|
||||
def test_update_service_inbound_api_updates_url(admin_request, sample_service):
|
||||
service_inbound_api = create_service_inbound_api(service=sample_service,
|
||||
url="https://original_url.com")
|
||||
service_inbound_api = create_service_inbound_api(
|
||||
service=sample_service, url="https://original_url.com"
|
||||
)
|
||||
|
||||
data = {
|
||||
"url": "https://another_url.com",
|
||||
"updated_by_id": str(sample_service.users[0].id)
|
||||
"updated_by_id": str(sample_service.users[0].id),
|
||||
}
|
||||
|
||||
response = admin_request.post(
|
||||
'service_callback.update_service_inbound_api',
|
||||
"service_callback.update_service_inbound_api",
|
||||
service_id=sample_service.id,
|
||||
inbound_api_id=service_inbound_api.id,
|
||||
_data=data
|
||||
_data=data,
|
||||
)
|
||||
|
||||
assert response["data"]["url"] == "https://another_url.com"
|
||||
@@ -62,18 +63,19 @@ def test_update_service_inbound_api_updates_url(admin_request, sample_service):
|
||||
|
||||
|
||||
def test_update_service_inbound_api_updates_bearer_token(admin_request, sample_service):
|
||||
service_inbound_api = create_service_inbound_api(service=sample_service,
|
||||
bearer_token="some_super_secret")
|
||||
service_inbound_api = create_service_inbound_api(
|
||||
service=sample_service, bearer_token="some_super_secret"
|
||||
)
|
||||
data = {
|
||||
"bearer_token": "different_token",
|
||||
"updated_by_id": str(sample_service.users[0].id)
|
||||
"updated_by_id": str(sample_service.users[0].id),
|
||||
}
|
||||
|
||||
admin_request.post(
|
||||
'service_callback.update_service_inbound_api',
|
||||
"service_callback.update_service_inbound_api",
|
||||
service_id=sample_service.id,
|
||||
inbound_api_id=service_inbound_api.id,
|
||||
_data=data
|
||||
_data=data,
|
||||
)
|
||||
assert service_inbound_api.bearer_token == "different_token"
|
||||
|
||||
@@ -82,7 +84,7 @@ def test_fetch_service_inbound_api(admin_request, sample_service):
|
||||
service_inbound_api = create_service_inbound_api(service=sample_service)
|
||||
|
||||
response = admin_request.get(
|
||||
'service_callback.fetch_service_inbound_api',
|
||||
"service_callback.fetch_service_inbound_api",
|
||||
service_id=sample_service.id,
|
||||
inbound_api_id=service_inbound_api.id,
|
||||
)
|
||||
@@ -93,7 +95,7 @@ def test_delete_service_inbound_api(admin_request, sample_service):
|
||||
service_inbound_api = create_service_inbound_api(sample_service)
|
||||
|
||||
response = admin_request.delete(
|
||||
'service_callback.remove_service_inbound_api',
|
||||
"service_callback.remove_service_inbound_api",
|
||||
service_id=sample_service.id,
|
||||
inbound_api_id=service_inbound_api.id,
|
||||
)
|
||||
@@ -106,14 +108,14 @@ def test_create_service_callback_api(admin_request, sample_service):
|
||||
data = {
|
||||
"url": "https://some_service/delivery-receipt-endpoint",
|
||||
"bearer_token": "some-unique-string",
|
||||
"updated_by_id": str(sample_service.users[0].id)
|
||||
"updated_by_id": str(sample_service.users[0].id),
|
||||
}
|
||||
|
||||
resp_json = admin_request.post(
|
||||
'service_callback.create_service_callback_api',
|
||||
"service_callback.create_service_callback_api",
|
||||
service_id=sample_service.id,
|
||||
_data=data,
|
||||
_expected_status=201
|
||||
_expected_status=201,
|
||||
)
|
||||
|
||||
resp_json = resp_json["data"]
|
||||
@@ -125,54 +127,60 @@ def test_create_service_callback_api(admin_request, sample_service):
|
||||
assert not resp_json["updated_at"]
|
||||
|
||||
|
||||
def test_set_service_callback_api_raises_404_when_service_does_not_exist(admin_request, notify_db_session):
|
||||
def test_set_service_callback_api_raises_404_when_service_does_not_exist(
|
||||
admin_request, notify_db_session
|
||||
):
|
||||
data = {
|
||||
"url": "https://some_service/delivery-receipt-endpoint",
|
||||
"bearer_token": "some-unique-string",
|
||||
"updated_by_id": str(uuid.uuid4())
|
||||
"updated_by_id": str(uuid.uuid4()),
|
||||
}
|
||||
|
||||
resp_json = admin_request.post(
|
||||
'service_callback.create_service_callback_api',
|
||||
"service_callback.create_service_callback_api",
|
||||
service_id=uuid.uuid4(),
|
||||
_data=data,
|
||||
_expected_status=404
|
||||
_expected_status=404,
|
||||
)
|
||||
assert resp_json['message'] == 'No result found'
|
||||
assert resp_json["message"] == "No result found"
|
||||
|
||||
|
||||
def test_update_service_callback_api_updates_url(admin_request, sample_service):
|
||||
service_callback_api = create_service_callback_api(service=sample_service,
|
||||
url="https://original_url.com")
|
||||
service_callback_api = create_service_callback_api(
|
||||
service=sample_service, url="https://original_url.com"
|
||||
)
|
||||
|
||||
data = {
|
||||
"url": "https://another_url.com",
|
||||
"updated_by_id": str(sample_service.users[0].id)
|
||||
"updated_by_id": str(sample_service.users[0].id),
|
||||
}
|
||||
|
||||
resp_json = admin_request.post(
|
||||
'service_callback.update_service_callback_api',
|
||||
"service_callback.update_service_callback_api",
|
||||
service_id=sample_service.id,
|
||||
callback_api_id=service_callback_api.id,
|
||||
_data=data
|
||||
_data=data,
|
||||
)
|
||||
assert resp_json["data"]["url"] == "https://another_url.com"
|
||||
assert service_callback_api.url == "https://another_url.com"
|
||||
|
||||
|
||||
def test_update_service_callback_api_updates_bearer_token(admin_request, sample_service):
|
||||
service_callback_api = create_service_callback_api(service=sample_service,
|
||||
bearer_token="some_super_secret")
|
||||
def test_update_service_callback_api_updates_bearer_token(
|
||||
admin_request, sample_service
|
||||
):
|
||||
service_callback_api = create_service_callback_api(
|
||||
service=sample_service, bearer_token="some_super_secret"
|
||||
)
|
||||
data = {
|
||||
"bearer_token": "different_token",
|
||||
"updated_by_id": str(sample_service.users[0].id)
|
||||
"updated_by_id": str(sample_service.users[0].id),
|
||||
}
|
||||
|
||||
admin_request.post(
|
||||
'service_callback.update_service_callback_api',
|
||||
"service_callback.update_service_callback_api",
|
||||
service_id=sample_service.id,
|
||||
callback_api_id=service_callback_api.id,
|
||||
_data=data
|
||||
_data=data,
|
||||
)
|
||||
assert service_callback_api.bearer_token == "different_token"
|
||||
|
||||
@@ -181,7 +189,7 @@ def test_fetch_service_callback_api(admin_request, sample_service):
|
||||
service_callback_api = create_service_callback_api(service=sample_service)
|
||||
|
||||
response = admin_request.get(
|
||||
'service_callback.fetch_service_callback_api',
|
||||
"service_callback.fetch_service_callback_api",
|
||||
service_id=sample_service.id,
|
||||
callback_api_id=service_callback_api.id,
|
||||
)
|
||||
@@ -193,7 +201,7 @@ def test_delete_service_callback_api(admin_request, sample_service):
|
||||
service_callback_api = create_service_callback_api(sample_service)
|
||||
|
||||
response = admin_request.delete(
|
||||
'service_callback.remove_service_callback_api',
|
||||
"service_callback.remove_service_callback_api",
|
||||
service_id=sample_service.id,
|
||||
callback_api_id=service_callback_api.id,
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,10 +11,11 @@ from app.service.service_callback_api_schema import (
|
||||
|
||||
|
||||
def test_service_callback_api_schema_validates():
|
||||
under_test = {"url": "https://some_url.for_service",
|
||||
"bearer_token": "something_ten_chars",
|
||||
"updated_by_id": str(uuid.uuid4())
|
||||
}
|
||||
under_test = {
|
||||
"url": "https://some_url.for_service",
|
||||
"bearer_token": "something_ten_chars",
|
||||
"updated_by_id": str(uuid.uuid4()),
|
||||
}
|
||||
|
||||
validated = validate(under_test, update_service_callback_api_schema)
|
||||
assert validated == under_test
|
||||
@@ -22,26 +23,28 @@ def test_service_callback_api_schema_validates():
|
||||
|
||||
@pytest.mark.parametrize("url", ["not a url", "https not a url", "http://valid.com"])
|
||||
def test_service_callback_api_schema_errors_for_url_not_valid_url(url):
|
||||
under_test = {"url": url,
|
||||
"bearer_token": "something_ten_chars",
|
||||
"updated_by_id": str(uuid.uuid4())
|
||||
}
|
||||
under_test = {
|
||||
"url": url,
|
||||
"bearer_token": "something_ten_chars",
|
||||
"updated_by_id": str(uuid.uuid4()),
|
||||
}
|
||||
|
||||
with pytest.raises(ValidationError) as e:
|
||||
validate(under_test, update_service_callback_api_schema)
|
||||
errors = json.loads(str(e.value)).get('errors')
|
||||
errors = json.loads(str(e.value)).get("errors")
|
||||
assert len(errors) == 1
|
||||
assert errors[0]['message'] == "url is not a valid https url"
|
||||
assert errors[0]["message"] == "url is not a valid https url"
|
||||
|
||||
|
||||
def test_service_callback_api_schema_bearer_token_under_ten_char():
|
||||
under_test = {"url": "https://some_url.for_service",
|
||||
"bearer_token": "shorty",
|
||||
"updated_by_id": str(uuid.uuid4())
|
||||
}
|
||||
under_test = {
|
||||
"url": "https://some_url.for_service",
|
||||
"bearer_token": "shorty",
|
||||
"updated_by_id": str(uuid.uuid4()),
|
||||
}
|
||||
|
||||
with pytest.raises(ValidationError) as e:
|
||||
validate(under_test, update_service_callback_api_schema)
|
||||
errors = json.loads(str(e.value)).get('errors')
|
||||
errors = json.loads(str(e.value)).get("errors")
|
||||
assert len(errors) == 1
|
||||
assert errors[0]['message'] == "bearer_token shorty is too short"
|
||||
assert errors[0]["message"] == "bearer_token shorty is too short"
|
||||
|
||||
@@ -7,55 +7,52 @@ from app.service.sender import send_notification_to_service_users
|
||||
from tests.app.db import create_service, create_template, create_user
|
||||
|
||||
|
||||
@pytest.mark.parametrize('notification_type', [
|
||||
EMAIL_TYPE,
|
||||
SMS_TYPE
|
||||
])
|
||||
@pytest.mark.parametrize("notification_type", [EMAIL_TYPE, SMS_TYPE])
|
||||
def test_send_notification_to_service_users_persists_notifications_correctly(
|
||||
notify_service,
|
||||
notification_type,
|
||||
sample_service,
|
||||
mocker
|
||||
notify_service, notification_type, sample_service, mocker
|
||||
):
|
||||
mocker.patch('app.service.sender.send_notification_to_queue')
|
||||
mocker.patch("app.service.sender.send_notification_to_queue")
|
||||
|
||||
user = sample_service.users[0]
|
||||
template = create_template(sample_service, template_type=notification_type)
|
||||
send_notification_to_service_users(service_id=sample_service.id, template_id=template.id)
|
||||
send_notification_to_service_users(
|
||||
service_id=sample_service.id, template_id=template.id
|
||||
)
|
||||
to = user.email_address if notification_type == EMAIL_TYPE else user.mobile_number
|
||||
|
||||
notification = Notification.query.one()
|
||||
|
||||
assert Notification.query.count() == 1
|
||||
assert notification.to == to
|
||||
assert str(notification.service_id) == current_app.config['NOTIFY_SERVICE_ID']
|
||||
assert str(notification.service_id) == current_app.config["NOTIFY_SERVICE_ID"]
|
||||
assert notification.template.id == template.id
|
||||
assert notification.template.template_type == notification_type
|
||||
assert notification.notification_type == notification_type
|
||||
assert notification.reply_to_text == notify_service.get_default_reply_to_email_address()
|
||||
assert (
|
||||
notification.reply_to_text
|
||||
== notify_service.get_default_reply_to_email_address()
|
||||
)
|
||||
|
||||
|
||||
def test_send_notification_to_service_users_sends_to_queue(
|
||||
notify_service,
|
||||
sample_service,
|
||||
mocker
|
||||
notify_service, sample_service, mocker
|
||||
):
|
||||
send_mock = mocker.patch('app.service.sender.send_notification_to_queue')
|
||||
send_mock = mocker.patch("app.service.sender.send_notification_to_queue")
|
||||
|
||||
template = create_template(sample_service, template_type=EMAIL_TYPE)
|
||||
send_notification_to_service_users(service_id=sample_service.id, template_id=template.id)
|
||||
send_notification_to_service_users(
|
||||
service_id=sample_service.id, template_id=template.id
|
||||
)
|
||||
|
||||
assert send_mock.called
|
||||
assert send_mock.call_count == 1
|
||||
|
||||
|
||||
def test_send_notification_to_service_users_includes_user_fields_in_personalisation(
|
||||
notify_service,
|
||||
sample_service,
|
||||
mocker
|
||||
notify_service, sample_service, mocker
|
||||
):
|
||||
persist_mock = mocker.patch('app.service.sender.persist_notification')
|
||||
mocker.patch('app.service.sender.send_notification_to_queue')
|
||||
persist_mock = mocker.patch("app.service.sender.persist_notification")
|
||||
mocker.patch("app.service.sender.send_notification_to_queue")
|
||||
|
||||
user = sample_service.users[0]
|
||||
|
||||
@@ -63,28 +60,27 @@ def test_send_notification_to_service_users_includes_user_fields_in_personalisat
|
||||
send_notification_to_service_users(
|
||||
service_id=sample_service.id,
|
||||
template_id=template.id,
|
||||
include_user_fields=['name', 'email_address', 'state']
|
||||
include_user_fields=["name", "email_address", "state"],
|
||||
)
|
||||
|
||||
persist_call = persist_mock.call_args_list[0][1]
|
||||
|
||||
assert len(persist_mock.call_args_list) == 1
|
||||
assert persist_call['personalisation'] == {
|
||||
'name': user.name,
|
||||
'email_address': user.email_address,
|
||||
'state': user.state,
|
||||
assert persist_call["personalisation"] == {
|
||||
"name": user.name,
|
||||
"email_address": user.email_address,
|
||||
"state": user.state,
|
||||
}
|
||||
|
||||
|
||||
def test_send_notification_to_service_users_sends_to_active_users_only(
|
||||
notify_service,
|
||||
mocker
|
||||
notify_service, mocker
|
||||
):
|
||||
mocker.patch('app.service.sender.send_notification_to_queue')
|
||||
mocker.patch("app.service.sender.send_notification_to_queue")
|
||||
|
||||
first_active_user = create_user(email='foo@bar.com', state='active')
|
||||
second_active_user = create_user(email='foo1@bar.com', state='active')
|
||||
pending_user = create_user(email='foo2@bar.com', state='pending')
|
||||
first_active_user = create_user(email="foo@bar.com", state="active")
|
||||
second_active_user = create_user(email="foo1@bar.com", state="active")
|
||||
pending_user = create_user(email="foo2@bar.com", state="pending")
|
||||
service = create_service(user=first_active_user)
|
||||
dao_add_user_to_service(service, second_active_user)
|
||||
dao_add_user_to_service(service, pending_user)
|
||||
|
||||
@@ -8,12 +8,16 @@ from tests.app.db import create_service_data_retention
|
||||
|
||||
def test_get_service_data_retention(client, sample_service):
|
||||
sms_data_retention = create_service_data_retention(service=sample_service)
|
||||
email_data_retention = create_service_data_retention(service=sample_service, notification_type='email',
|
||||
days_of_retention=10)
|
||||
email_data_retention = create_service_data_retention(
|
||||
service=sample_service, notification_type="email", days_of_retention=10
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'/service/{}/data-retention'.format(str(sample_service.id)),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
"/service/{}/data-retention".format(str(sample_service.id)),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -25,8 +29,11 @@ def test_get_service_data_retention(client, sample_service):
|
||||
|
||||
def test_get_service_data_retention_returns_empty_list(client, sample_service):
|
||||
response = client.get(
|
||||
'/service/{}/data-retention'.format(str(sample_service.id)),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
"/service/{}/data-retention".format(str(sample_service.id)),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert len(json.loads(response.get_data(as_text=True))) == 0
|
||||
@@ -34,125 +41,156 @@ def test_get_service_data_retention_returns_empty_list(client, sample_service):
|
||||
|
||||
def test_get_data_retention_for_service_notification_type(client, sample_service):
|
||||
data_retention = create_service_data_retention(service=sample_service)
|
||||
response = client.get('/service/{}/data-retention/notification-type/{}'.format(sample_service.id, 'sms'),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
)
|
||||
response = client.get(
|
||||
"/service/{}/data-retention/notification-type/{}".format(
|
||||
sample_service.id, "sms"
|
||||
),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.get_data(as_text=True)) == data_retention.serialize()
|
||||
|
||||
|
||||
def test_get_service_data_retention_by_id(client, sample_service):
|
||||
sms_data_retention = create_service_data_retention(service=sample_service)
|
||||
create_service_data_retention(service=sample_service, notification_type='email',
|
||||
days_of_retention=10)
|
||||
create_service_data_retention(service=sample_service, notification_type='letter',
|
||||
days_of_retention=30)
|
||||
create_service_data_retention(
|
||||
service=sample_service, notification_type="email", days_of_retention=10
|
||||
)
|
||||
create_service_data_retention(
|
||||
service=sample_service, notification_type="letter", days_of_retention=30
|
||||
)
|
||||
response = client.get(
|
||||
'/service/{}/data-retention/{}'.format(str(sample_service.id), sms_data_retention.id),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
"/service/{}/data-retention/{}".format(
|
||||
str(sample_service.id), sms_data_retention.id
|
||||
),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.get_data(as_text=True)) == sms_data_retention.serialize()
|
||||
|
||||
|
||||
def test_get_service_data_retention_by_id_returns_none_when_no_data_retention_exists(client, sample_service):
|
||||
def test_get_service_data_retention_by_id_returns_none_when_no_data_retention_exists(
|
||||
client, sample_service
|
||||
):
|
||||
response = client.get(
|
||||
'/service/{}/data-retention/{}'.format(str(sample_service.id), uuid.uuid4()),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
"/service/{}/data-retention/{}".format(str(sample_service.id), uuid.uuid4()),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.get_data(as_text=True)) == {}
|
||||
|
||||
|
||||
def test_create_service_data_retention(client, sample_service):
|
||||
data = {
|
||||
"notification_type": 'sms',
|
||||
"days_of_retention": 3
|
||||
}
|
||||
data = {"notification_type": "sms", "days_of_retention": 3}
|
||||
response = client.post(
|
||||
'/service/{}/data-retention'.format(str(sample_service.id)),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
data=json.dumps(data)
|
||||
"/service/{}/data-retention".format(str(sample_service.id)),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
data=json.dumps(data),
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
json_resp = json.loads(response.get_data(as_text=True))['result']
|
||||
json_resp = json.loads(response.get_data(as_text=True))["result"]
|
||||
results = ServiceDataRetention.query.all()
|
||||
assert len(results) == 1
|
||||
data_retention = results[0]
|
||||
assert json_resp == data_retention.serialize()
|
||||
|
||||
|
||||
def test_create_service_data_retention_returns_400_when_notification_type_is_invalid(client):
|
||||
data = {
|
||||
"notification_type": 'unknown',
|
||||
"days_of_retention": 3
|
||||
}
|
||||
def test_create_service_data_retention_returns_400_when_notification_type_is_invalid(
|
||||
client,
|
||||
):
|
||||
data = {"notification_type": "unknown", "days_of_retention": 3}
|
||||
response = client.post(
|
||||
'/service/{}/data-retention'.format(str(uuid.uuid4())),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
data=json.dumps(data)
|
||||
"/service/{}/data-retention".format(str(uuid.uuid4())),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
data=json.dumps(data),
|
||||
)
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert response.status_code == 400
|
||||
assert json_resp['errors'][0]['error'] == 'ValidationError'
|
||||
assert json_resp['errors'][0]['message'] == 'notification_type unknown is not one of [sms, email]'
|
||||
assert json_resp["errors"][0]["error"] == "ValidationError"
|
||||
assert (
|
||||
json_resp["errors"][0]["message"]
|
||||
== "notification_type unknown is not one of [sms, email]"
|
||||
)
|
||||
|
||||
|
||||
def test_create_service_data_retention_returns_400_when_data_retention_for_notification_type_already_exists(
|
||||
client, sample_service
|
||||
client, sample_service
|
||||
):
|
||||
create_service_data_retention(service=sample_service)
|
||||
data = {
|
||||
"notification_type": "sms",
|
||||
"days_of_retention": 3
|
||||
}
|
||||
data = {"notification_type": "sms", "days_of_retention": 3}
|
||||
response = client.post(
|
||||
'/service/{}/data-retention'.format(str(uuid.uuid4())),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
data=json.dumps(data)
|
||||
"/service/{}/data-retention".format(str(uuid.uuid4())),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
data=json.dumps(data),
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert json_resp['result'] == 'error'
|
||||
assert json_resp['message'] == 'Service already has data retention for sms notification type'
|
||||
assert json_resp["result"] == "error"
|
||||
assert (
|
||||
json_resp["message"]
|
||||
== "Service already has data retention for sms notification type"
|
||||
)
|
||||
|
||||
|
||||
def test_modify_service_data_retention(client, sample_service):
|
||||
data_retention = create_service_data_retention(service=sample_service)
|
||||
data = {
|
||||
"days_of_retention": 3
|
||||
}
|
||||
data = {"days_of_retention": 3}
|
||||
response = client.post(
|
||||
'/service/{}/data-retention/{}'.format(sample_service.id, data_retention.id),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
data=json.dumps(data)
|
||||
"/service/{}/data-retention/{}".format(sample_service.id, data_retention.id),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
data=json.dumps(data),
|
||||
)
|
||||
assert response.status_code == 204
|
||||
assert response.get_data(as_text=True) == ''
|
||||
assert response.get_data(as_text=True) == ""
|
||||
|
||||
|
||||
def test_modify_service_data_retention_returns_400_when_data_retention_does_not_exist(client, sample_service):
|
||||
data = {
|
||||
"days_of_retention": 3
|
||||
}
|
||||
def test_modify_service_data_retention_returns_400_when_data_retention_does_not_exist(
|
||||
client, sample_service
|
||||
):
|
||||
data = {"days_of_retention": 3}
|
||||
response = client.post(
|
||||
'/service/{}/data-retention/{}'.format(sample_service.id, uuid.uuid4()),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
data=json.dumps(data)
|
||||
"/service/{}/data-retention/{}".format(sample_service.id, uuid.uuid4()),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
data=json.dumps(data),
|
||||
)
|
||||
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_modify_service_data_retention_returns_400_when_data_is_invalid(client):
|
||||
data = {
|
||||
"bad_key": 3
|
||||
}
|
||||
data = {"bad_key": 3}
|
||||
response = client.post(
|
||||
'/service/{}/data-retention/{}'.format(uuid.uuid4(), uuid.uuid4()),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()],
|
||||
data=json.dumps(data)
|
||||
"/service/{}/data-retention/{}".format(uuid.uuid4(), uuid.uuid4()),
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
data=json.dumps(data),
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
@@ -11,85 +11,101 @@ from tests import create_admin_authorization_header
|
||||
def test_get_guest_list_returns_data(client, sample_service_guest_list):
|
||||
service_id = sample_service_guest_list.service_id
|
||||
|
||||
response = client.get(f'service/{service_id}/guest-list', headers=[create_admin_authorization_header()])
|
||||
response = client.get(
|
||||
f"service/{service_id}/guest-list",
|
||||
headers=[create_admin_authorization_header()],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.get_data(as_text=True)) == {
|
||||
'email_addresses': [sample_service_guest_list.recipient],
|
||||
'phone_numbers': []
|
||||
"email_addresses": [sample_service_guest_list.recipient],
|
||||
"phone_numbers": [],
|
||||
}
|
||||
|
||||
|
||||
def test_get_guest_list_separates_emails_and_phones(client, sample_service):
|
||||
dao_add_and_commit_guest_list_contacts([
|
||||
ServiceGuestList.from_string(sample_service.id, EMAIL_TYPE, 'service@example.com'),
|
||||
ServiceGuestList.from_string(sample_service.id, MOBILE_TYPE, '2028675309'),
|
||||
ServiceGuestList.from_string(sample_service.id, MOBILE_TYPE, '+1800-555-5555'),
|
||||
])
|
||||
dao_add_and_commit_guest_list_contacts(
|
||||
[
|
||||
ServiceGuestList.from_string(
|
||||
sample_service.id, EMAIL_TYPE, "service@example.com"
|
||||
),
|
||||
ServiceGuestList.from_string(sample_service.id, MOBILE_TYPE, "2028675309"),
|
||||
ServiceGuestList.from_string(
|
||||
sample_service.id, MOBILE_TYPE, "+1800-555-5555"
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
'service/{}/guest-list'.format(sample_service.id), headers=[create_admin_authorization_header()]
|
||||
"service/{}/guest-list".format(sample_service.id),
|
||||
headers=[create_admin_authorization_header()],
|
||||
)
|
||||
assert response.status_code == 200
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert json_resp['email_addresses'] == ['service@example.com']
|
||||
assert sorted(json_resp['phone_numbers']) == sorted(['+18005555555', '+12028675309'])
|
||||
assert json_resp["email_addresses"] == ["service@example.com"]
|
||||
assert sorted(json_resp["phone_numbers"]) == sorted(
|
||||
["+18005555555", "+12028675309"]
|
||||
)
|
||||
|
||||
|
||||
def test_get_guest_list_404s_with_unknown_service_id(client):
|
||||
path = 'service/{}/guest-list'.format(uuid.uuid4())
|
||||
path = "service/{}/guest-list".format(uuid.uuid4())
|
||||
|
||||
response = client.get(path, headers=[create_admin_authorization_header()])
|
||||
assert response.status_code == 404
|
||||
json_resp = json.loads(response.get_data(as_text=True))
|
||||
assert json_resp['result'] == 'error'
|
||||
assert json_resp['message'] == 'No result found'
|
||||
assert json_resp["result"] == "error"
|
||||
assert json_resp["message"] == "No result found"
|
||||
|
||||
|
||||
def test_get_guest_list_returns_no_data(client, sample_service):
|
||||
path = 'service/{}/guest-list'.format(sample_service.id)
|
||||
path = "service/{}/guest-list".format(sample_service.id)
|
||||
|
||||
response = client.get(path, headers=[create_admin_authorization_header()])
|
||||
|
||||
assert response.status_code == 200
|
||||
assert json.loads(response.get_data(as_text=True)) == {'email_addresses': [], 'phone_numbers': []}
|
||||
assert json.loads(response.get_data(as_text=True)) == {
|
||||
"email_addresses": [],
|
||||
"phone_numbers": [],
|
||||
}
|
||||
|
||||
|
||||
def test_update_guest_list_replaces_old_guest_list(client, sample_service_guest_list):
|
||||
data = {
|
||||
'email_addresses': ['foo@bar.com'],
|
||||
'phone_numbers': ['2028765309']
|
||||
}
|
||||
data = {"email_addresses": ["foo@bar.com"], "phone_numbers": ["2028765309"]}
|
||||
|
||||
response = client.put(
|
||||
f'service/{sample_service_guest_list.service_id}/guest-list',
|
||||
f"service/{sample_service_guest_list.service_id}/guest-list",
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()]
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
guest_list = ServiceGuestList.query.order_by(ServiceGuestList.recipient).all()
|
||||
assert len(guest_list) == 2
|
||||
assert guest_list[0].recipient == '+12028765309'
|
||||
assert guest_list[1].recipient == 'foo@bar.com'
|
||||
assert guest_list[0].recipient == "+12028765309"
|
||||
assert guest_list[1].recipient == "foo@bar.com"
|
||||
|
||||
|
||||
def test_update_guest_list_doesnt_remove_old_guest_list_if_error(client, sample_service_guest_list):
|
||||
|
||||
data = {
|
||||
'email_addresses': [''],
|
||||
'phone_numbers': ['2028675309']
|
||||
}
|
||||
def test_update_guest_list_doesnt_remove_old_guest_list_if_error(
|
||||
client, sample_service_guest_list
|
||||
):
|
||||
data = {"email_addresses": [""], "phone_numbers": ["2028675309"]}
|
||||
|
||||
response = client.put(
|
||||
'service/{}/guest-list'.format(sample_service_guest_list.service_id),
|
||||
"service/{}/guest-list".format(sample_service_guest_list.service_id),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), create_admin_authorization_header()]
|
||||
headers=[
|
||||
("Content-Type", "application/json"),
|
||||
create_admin_authorization_header(),
|
||||
],
|
||||
)
|
||||
|
||||
assert response.status_code == 400
|
||||
assert json.loads(response.get_data(as_text=True)) == {
|
||||
'result': 'error',
|
||||
'message': 'Invalid guest list: "" is not a valid email address or phone number'
|
||||
"result": "error",
|
||||
"message": 'Invalid guest list: "" is not a valid email address or phone number',
|
||||
}
|
||||
guest_list = ServiceGuestList.query.one()
|
||||
assert guest_list.id == sample_service_guest_list.id
|
||||
|
||||
@@ -14,156 +14,196 @@ from app.service.statistics import (
|
||||
format_statistics,
|
||||
)
|
||||
|
||||
StatsRow = collections.namedtuple('row', ('notification_type', 'status', 'count'))
|
||||
NewStatsRow = collections.namedtuple('row', ('notification_type', 'status', 'key_type', 'count'))
|
||||
StatsRow = collections.namedtuple("row", ("notification_type", "status", "count"))
|
||||
NewStatsRow = collections.namedtuple(
|
||||
"row", ("notification_type", "status", "key_type", "count")
|
||||
)
|
||||
|
||||
|
||||
# email_counts and sms_counts are 3-tuple of requested, delivered, failed
|
||||
@pytest.mark.idparametrize('stats, email_counts, sms_counts', {
|
||||
'empty': ([], [0, 0, 0], [0, 0, 0]),
|
||||
'always_increment_requested': ([
|
||||
StatsRow('email', 'delivered', 1),
|
||||
StatsRow('email', 'failed', 1)
|
||||
], [2, 1, 1], [0, 0, 0]),
|
||||
'dont_mix_template_types': ([
|
||||
StatsRow('email', 'delivered', 1),
|
||||
StatsRow('sms', 'delivered', 1),
|
||||
], [1, 1, 0], [1, 1, 0]),
|
||||
'convert_fail_statuses_to_failed': ([
|
||||
StatsRow('email', 'failed', 1),
|
||||
StatsRow('email', 'technical-failure', 1),
|
||||
StatsRow('email', 'temporary-failure', 1),
|
||||
StatsRow('email', 'permanent-failure', 1),
|
||||
], [4, 0, 4], [0, 0, 0]),
|
||||
'convert_sent_to_delivered': ([
|
||||
StatsRow('sms', 'sending', 1),
|
||||
StatsRow('sms', 'delivered', 1),
|
||||
StatsRow('sms', 'sent', 1),
|
||||
], [0, 0, 0], [3, 2, 0]),
|
||||
'handles_none_rows': ([
|
||||
StatsRow('sms', 'sending', 1),
|
||||
StatsRow(None, None, None)
|
||||
], [0, 0, 0], [1, 0, 0])
|
||||
})
|
||||
@pytest.mark.idparametrize(
|
||||
"stats, email_counts, sms_counts",
|
||||
{
|
||||
"empty": ([], [0, 0, 0], [0, 0, 0]),
|
||||
"always_increment_requested": (
|
||||
[StatsRow("email", "delivered", 1), StatsRow("email", "failed", 1)],
|
||||
[2, 1, 1],
|
||||
[0, 0, 0],
|
||||
),
|
||||
"dont_mix_template_types": (
|
||||
[
|
||||
StatsRow("email", "delivered", 1),
|
||||
StatsRow("sms", "delivered", 1),
|
||||
],
|
||||
[1, 1, 0],
|
||||
[1, 1, 0],
|
||||
),
|
||||
"convert_fail_statuses_to_failed": (
|
||||
[
|
||||
StatsRow("email", "failed", 1),
|
||||
StatsRow("email", "technical-failure", 1),
|
||||
StatsRow("email", "temporary-failure", 1),
|
||||
StatsRow("email", "permanent-failure", 1),
|
||||
],
|
||||
[4, 0, 4],
|
||||
[0, 0, 0],
|
||||
),
|
||||
"convert_sent_to_delivered": (
|
||||
[
|
||||
StatsRow("sms", "sending", 1),
|
||||
StatsRow("sms", "delivered", 1),
|
||||
StatsRow("sms", "sent", 1),
|
||||
],
|
||||
[0, 0, 0],
|
||||
[3, 2, 0],
|
||||
),
|
||||
"handles_none_rows": (
|
||||
[StatsRow("sms", "sending", 1), StatsRow(None, None, None)],
|
||||
[0, 0, 0],
|
||||
[1, 0, 0],
|
||||
),
|
||||
},
|
||||
)
|
||||
def test_format_statistics(stats, email_counts, sms_counts):
|
||||
|
||||
ret = format_statistics(stats)
|
||||
|
||||
assert ret['email'] == {
|
||||
assert ret["email"] == {
|
||||
status: count
|
||||
for status, count
|
||||
in zip(['requested', 'delivered', 'failed'], email_counts)
|
||||
for status, count in zip(["requested", "delivered", "failed"], email_counts)
|
||||
}
|
||||
|
||||
assert ret['sms'] == {
|
||||
assert ret["sms"] == {
|
||||
status: count
|
||||
for status, count
|
||||
in zip(['requested', 'delivered', 'failed'], sms_counts)
|
||||
for status, count in zip(["requested", "delivered", "failed"], sms_counts)
|
||||
}
|
||||
|
||||
|
||||
def test_create_zeroed_stats_dicts():
|
||||
assert create_zeroed_stats_dicts() == {
|
||||
'sms': {'requested': 0, 'delivered': 0, 'failed': 0},
|
||||
'email': {'requested': 0, 'delivered': 0, 'failed': 0},
|
||||
"sms": {"requested": 0, "delivered": 0, "failed": 0},
|
||||
"email": {"requested": 0, "delivered": 0, "failed": 0},
|
||||
}
|
||||
|
||||
|
||||
def test_create_stats_dict():
|
||||
assert create_stats_dict() == {
|
||||
'sms': {'total': 0,
|
||||
'test-key': 0,
|
||||
'failures': {'technical-failure': 0,
|
||||
'permanent-failure': 0,
|
||||
'temporary-failure': 0,
|
||||
'virus-scan-failed': 0}},
|
||||
'email': {'total': 0,
|
||||
'test-key': 0,
|
||||
'failures': {'technical-failure': 0,
|
||||
'permanent-failure': 0,
|
||||
'temporary-failure': 0,
|
||||
'virus-scan-failed': 0}},
|
||||
"sms": {
|
||||
"total": 0,
|
||||
"test-key": 0,
|
||||
"failures": {
|
||||
"technical-failure": 0,
|
||||
"permanent-failure": 0,
|
||||
"temporary-failure": 0,
|
||||
"virus-scan-failed": 0,
|
||||
},
|
||||
},
|
||||
"email": {
|
||||
"total": 0,
|
||||
"test-key": 0,
|
||||
"failures": {
|
||||
"technical-failure": 0,
|
||||
"permanent-failure": 0,
|
||||
"temporary-failure": 0,
|
||||
"virus-scan-failed": 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_format_admin_stats_only_includes_test_key_notifications_in_test_key_section():
|
||||
rows = [
|
||||
NewStatsRow('email', 'technical-failure', 'test', 3),
|
||||
NewStatsRow('sms', 'permanent-failure', 'test', 4),
|
||||
NewStatsRow("email", "technical-failure", "test", 3),
|
||||
NewStatsRow("sms", "permanent-failure", "test", 4),
|
||||
]
|
||||
stats_dict = format_admin_stats(rows)
|
||||
|
||||
assert stats_dict['email']['total'] == 0
|
||||
assert stats_dict['email']['failures']['technical-failure'] == 0
|
||||
assert stats_dict['email']['test-key'] == 3
|
||||
assert stats_dict["email"]["total"] == 0
|
||||
assert stats_dict["email"]["failures"]["technical-failure"] == 0
|
||||
assert stats_dict["email"]["test-key"] == 3
|
||||
|
||||
assert stats_dict['sms']['total'] == 0
|
||||
assert stats_dict['sms']['failures']['permanent-failure'] == 0
|
||||
assert stats_dict['sms']['test-key'] == 4
|
||||
assert stats_dict["sms"]["total"] == 0
|
||||
assert stats_dict["sms"]["failures"]["permanent-failure"] == 0
|
||||
assert stats_dict["sms"]["test-key"] == 4
|
||||
|
||||
|
||||
def test_format_admin_stats_counts_non_test_key_notifications_correctly():
|
||||
rows = [
|
||||
NewStatsRow('email', 'technical-failure', 'normal', 1),
|
||||
NewStatsRow('email', 'created', 'team', 3),
|
||||
NewStatsRow('sms', 'temporary-failure', 'normal', 6),
|
||||
NewStatsRow('sms', 'sent', 'normal', 2),
|
||||
NewStatsRow("email", "technical-failure", "normal", 1),
|
||||
NewStatsRow("email", "created", "team", 3),
|
||||
NewStatsRow("sms", "temporary-failure", "normal", 6),
|
||||
NewStatsRow("sms", "sent", "normal", 2),
|
||||
]
|
||||
stats_dict = format_admin_stats(rows)
|
||||
|
||||
assert stats_dict['email']['total'] == 4
|
||||
assert stats_dict['email']['failures']['technical-failure'] == 1
|
||||
assert stats_dict["email"]["total"] == 4
|
||||
assert stats_dict["email"]["failures"]["technical-failure"] == 1
|
||||
|
||||
assert stats_dict['sms']['total'] == 8
|
||||
assert stats_dict['sms']['failures']['permanent-failure'] == 0
|
||||
assert stats_dict["sms"]["total"] == 8
|
||||
assert stats_dict["sms"]["failures"]["permanent-failure"] == 0
|
||||
|
||||
|
||||
def _stats(requested, delivered, failed):
|
||||
return {'requested': requested, 'delivered': delivered, 'failed': failed}
|
||||
return {"requested": requested, "delivered": delivered, "failed": failed}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('year, expected_years', [
|
||||
(
|
||||
2018,
|
||||
[
|
||||
'2018-04',
|
||||
'2018-05',
|
||||
'2018-06'
|
||||
]
|
||||
),
|
||||
(
|
||||
2017,
|
||||
[
|
||||
'2017-04',
|
||||
'2017-05',
|
||||
'2017-06',
|
||||
'2017-07',
|
||||
'2017-08',
|
||||
'2017-09',
|
||||
'2017-10',
|
||||
'2017-11',
|
||||
'2017-12',
|
||||
'2018-01',
|
||||
'2018-02',
|
||||
'2018-03'
|
||||
]
|
||||
)
|
||||
])
|
||||
@freeze_time('2018-06-01 04:59:59')
|
||||
@pytest.mark.parametrize(
|
||||
"year, expected_years",
|
||||
[
|
||||
(2018, ["2018-04", "2018-05", "2018-06"]),
|
||||
(
|
||||
2017,
|
||||
[
|
||||
"2017-04",
|
||||
"2017-05",
|
||||
"2017-06",
|
||||
"2017-07",
|
||||
"2017-08",
|
||||
"2017-09",
|
||||
"2017-10",
|
||||
"2017-11",
|
||||
"2017-12",
|
||||
"2018-01",
|
||||
"2018-02",
|
||||
"2018-03",
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
@freeze_time("2018-06-01 04:59:59")
|
||||
def test_create_empty_monthly_notification_status_stats_dict(year, expected_years):
|
||||
output = create_empty_monthly_notification_status_stats_dict(year)
|
||||
assert sorted(output.keys()) == expected_years
|
||||
for v in output.values():
|
||||
assert v == {'sms': {}, 'email': {}}
|
||||
assert v == {"sms": {}, "email": {}}
|
||||
|
||||
|
||||
@freeze_time('2018-06-01 04:59:59')
|
||||
@freeze_time("2018-06-01 04:59:59")
|
||||
def test_add_monthly_notification_status_stats():
|
||||
row_data = [
|
||||
{'month': datetime(2018, 4, 1), 'notification_type': 'sms', 'notification_status': 'sending', 'count': 1},
|
||||
{'month': datetime(2018, 4, 1), 'notification_type': 'sms', 'notification_status': 'delivered', 'count': 2},
|
||||
{'month': datetime(2018, 4, 1), 'notification_type': 'email', 'notification_status': 'sending', 'count': 4},
|
||||
{'month': datetime(2018, 5, 1), 'notification_type': 'sms', 'notification_status': 'sending', 'count': 8},
|
||||
{
|
||||
"month": datetime(2018, 4, 1),
|
||||
"notification_type": "sms",
|
||||
"notification_status": "sending",
|
||||
"count": 1,
|
||||
},
|
||||
{
|
||||
"month": datetime(2018, 4, 1),
|
||||
"notification_type": "sms",
|
||||
"notification_status": "delivered",
|
||||
"count": 2,
|
||||
},
|
||||
{
|
||||
"month": datetime(2018, 4, 1),
|
||||
"notification_type": "email",
|
||||
"notification_status": "sending",
|
||||
"count": 4,
|
||||
},
|
||||
{
|
||||
"month": datetime(2018, 5, 1),
|
||||
"notification_type": "sms",
|
||||
"notification_status": "sending",
|
||||
"count": 8,
|
||||
},
|
||||
]
|
||||
rows = []
|
||||
for r in row_data:
|
||||
@@ -174,15 +214,15 @@ def test_add_monthly_notification_status_stats():
|
||||
|
||||
data = create_empty_monthly_notification_status_stats_dict(2018)
|
||||
# this data won't be affected
|
||||
data['2018-05']['email']['sending'] = 32
|
||||
data["2018-05"]["email"]["sending"] = 32
|
||||
|
||||
# this data will get combined with the 8 from row_data
|
||||
data['2018-05']['sms']['sending'] = 16
|
||||
data["2018-05"]["sms"]["sending"] = 16
|
||||
|
||||
add_monthly_notification_status_stats(data, rows)
|
||||
|
||||
assert data == {
|
||||
'2018-04': {'sms': {'sending': 1, 'delivered': 2}, 'email': {'sending': 4}},
|
||||
'2018-05': {'sms': {'sending': 24}, 'email': {'sending': 32}},
|
||||
'2018-06': {'sms': {}, 'email': {}},
|
||||
"2018-04": {"sms": {"sending": 1, "delivered": 2}, "email": {"sending": 4}},
|
||||
"2018-05": {"sms": {"sending": 24}, "email": {"sending": 32}},
|
||||
"2018-06": {"sms": {}, "email": {}},
|
||||
}
|
||||
|
||||
@@ -19,20 +19,21 @@ from tests.app.db import (
|
||||
)
|
||||
|
||||
|
||||
@freeze_time('2017-11-11 06:00')
|
||||
@freeze_time("2017-11-11 06:00")
|
||||
def test_get_template_usage_by_month_returns_correct_data(
|
||||
admin_request,
|
||||
sample_template
|
||||
admin_request, sample_template
|
||||
):
|
||||
create_ft_notification_status(local_date=date(2017, 4, 2), template=sample_template, count=3)
|
||||
create_ft_notification_status(
|
||||
local_date=date(2017, 4, 2), template=sample_template, count=3
|
||||
)
|
||||
create_notification(sample_template, created_at=datetime.utcnow())
|
||||
|
||||
resp_json = admin_request.get(
|
||||
'service.get_monthly_template_usage',
|
||||
"service.get_monthly_template_usage",
|
||||
service_id=sample_template.service_id,
|
||||
year=2017
|
||||
year=2017,
|
||||
)
|
||||
resp_json = resp_json['stats']
|
||||
resp_json = resp_json["stats"]
|
||||
|
||||
assert len(resp_json) == 2
|
||||
|
||||
@@ -51,25 +52,33 @@ def test_get_template_usage_by_month_returns_correct_data(
|
||||
assert resp_json[1]["count"] == 1
|
||||
|
||||
|
||||
@freeze_time('2017-11-11 06:00')
|
||||
def test_get_template_usage_by_month_returns_two_templates(admin_request, sample_template, sample_service):
|
||||
@freeze_time("2017-11-11 06:00")
|
||||
def test_get_template_usage_by_month_returns_two_templates(
|
||||
admin_request, sample_template, sample_service
|
||||
):
|
||||
template_one = create_template(
|
||||
sample_service,
|
||||
template_type=SMS_TYPE,
|
||||
template_name="TEST TEMPLATE",
|
||||
hidden=True
|
||||
hidden=True,
|
||||
)
|
||||
create_ft_notification_status(
|
||||
local_date=datetime(2017, 4, 2), template=template_one, count=1
|
||||
)
|
||||
create_ft_notification_status(
|
||||
local_date=datetime(2017, 4, 2), template=sample_template, count=3
|
||||
)
|
||||
create_ft_notification_status(local_date=datetime(2017, 4, 2), template=template_one, count=1)
|
||||
create_ft_notification_status(local_date=datetime(2017, 4, 2), template=sample_template, count=3)
|
||||
create_notification(sample_template, created_at=datetime.utcnow())
|
||||
|
||||
resp_json = admin_request.get(
|
||||
'service.get_monthly_template_usage',
|
||||
"service.get_monthly_template_usage",
|
||||
service_id=sample_template.service_id,
|
||||
year=2017
|
||||
year=2017,
|
||||
)
|
||||
|
||||
resp_json = sorted(resp_json['stats'], key=lambda k: (k['year'], k['month'], k['count']))
|
||||
resp_json = sorted(
|
||||
resp_json["stats"], key=lambda k: (k["year"], k["month"], k["count"])
|
||||
)
|
||||
assert len(resp_json) == 3
|
||||
|
||||
assert resp_json[0]["template_id"] == str(template_one.id)
|
||||
@@ -94,43 +103,53 @@ def test_get_template_usage_by_month_returns_two_templates(admin_request, sample
|
||||
assert resp_json[2]["count"] == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize('today_only, stats', [
|
||||
(False, {'requested': 2, 'delivered': 1, 'failed': 0}),
|
||||
(True, {'requested': 1, 'delivered': 0, 'failed': 0})
|
||||
], ids=['seven_days', 'today'])
|
||||
def test_get_service_notification_statistics(admin_request, sample_service, sample_template, today_only, stats):
|
||||
create_ft_notification_status(date(2000, 1, 1), 'sms', sample_service, count=1)
|
||||
with freeze_time('2000-01-02T12:00:00'):
|
||||
create_notification(sample_template, status='created')
|
||||
@pytest.mark.parametrize(
|
||||
"today_only, stats",
|
||||
[
|
||||
(False, {"requested": 2, "delivered": 1, "failed": 0}),
|
||||
(True, {"requested": 1, "delivered": 0, "failed": 0}),
|
||||
],
|
||||
ids=["seven_days", "today"],
|
||||
)
|
||||
def test_get_service_notification_statistics(
|
||||
admin_request, sample_service, sample_template, today_only, stats
|
||||
):
|
||||
create_ft_notification_status(date(2000, 1, 1), "sms", sample_service, count=1)
|
||||
with freeze_time("2000-01-02T12:00:00"):
|
||||
create_notification(sample_template, status="created")
|
||||
resp = admin_request.get(
|
||||
'service.get_service_notification_statistics',
|
||||
"service.get_service_notification_statistics",
|
||||
service_id=sample_template.service_id,
|
||||
today_only=today_only
|
||||
today_only=today_only,
|
||||
)
|
||||
|
||||
assert set(resp['data'].keys()) == {SMS_TYPE, EMAIL_TYPE}
|
||||
assert resp['data'][SMS_TYPE] == stats
|
||||
assert set(resp["data"].keys()) == {SMS_TYPE, EMAIL_TYPE}
|
||||
assert resp["data"][SMS_TYPE] == stats
|
||||
|
||||
|
||||
def test_get_service_notification_statistics_with_unknown_service(admin_request):
|
||||
resp = admin_request.get(
|
||||
'service.get_service_notification_statistics',
|
||||
service_id=uuid.uuid4()
|
||||
"service.get_service_notification_statistics", service_id=uuid.uuid4()
|
||||
)
|
||||
|
||||
assert resp['data'] == {
|
||||
SMS_TYPE: {'requested': 0, 'delivered': 0, 'failed': 0},
|
||||
EMAIL_TYPE: {'requested': 0, 'delivered': 0, 'failed': 0},
|
||||
assert resp["data"] == {
|
||||
SMS_TYPE: {"requested": 0, "delivered": 0, "failed": 0},
|
||||
EMAIL_TYPE: {"requested": 0, "delivered": 0, "failed": 0},
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.parametrize('kwargs, expected_json', [
|
||||
({'year': 'baz'}, {'message': 'Year must be a number', 'result': 'error'}),
|
||||
({}, {'message': 'Year must be a number', 'result': 'error'}),
|
||||
])
|
||||
def test_get_monthly_notification_stats_returns_errors(admin_request, sample_service, kwargs, expected_json):
|
||||
@pytest.mark.parametrize(
|
||||
"kwargs, expected_json",
|
||||
[
|
||||
({"year": "baz"}, {"message": "Year must be a number", "result": "error"}),
|
||||
({}, {"message": "Year must be a number", "result": "error"}),
|
||||
],
|
||||
)
|
||||
def test_get_monthly_notification_stats_returns_errors(
|
||||
admin_request, sample_service, kwargs, expected_json
|
||||
):
|
||||
response = admin_request.get(
|
||||
'service.get_monthly_notification_stats',
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=sample_service.id,
|
||||
_expected_status=400,
|
||||
**kwargs
|
||||
@@ -140,28 +159,40 @@ def test_get_monthly_notification_stats_returns_errors(admin_request, sample_ser
|
||||
|
||||
def test_get_monthly_notification_stats_returns_404_if_no_service(admin_request):
|
||||
response = admin_request.get(
|
||||
'service.get_monthly_notification_stats',
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=uuid.uuid4(),
|
||||
_expected_status=404,
|
||||
)
|
||||
assert response == {'message': 'No result found', 'result': 'error'}
|
||||
assert response == {"message": "No result found", "result": "error"}
|
||||
|
||||
|
||||
def test_get_monthly_notification_stats_returns_empty_stats_with_correct_dates(admin_request, sample_service):
|
||||
def test_get_monthly_notification_stats_returns_empty_stats_with_correct_dates(
|
||||
admin_request, sample_service
|
||||
):
|
||||
response = admin_request.get(
|
||||
'service.get_monthly_notification_stats',
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=sample_service.id,
|
||||
year=2016
|
||||
year=2016,
|
||||
)
|
||||
assert len(response['data']) == 12
|
||||
assert len(response["data"]) == 12
|
||||
|
||||
keys = [
|
||||
'2016-04', '2016-05', '2016-06', '2016-07', '2016-08', '2016-09', '2016-10', '2016-11', '2016-12',
|
||||
'2017-01', '2017-02', '2017-03'
|
||||
"2016-04",
|
||||
"2016-05",
|
||||
"2016-06",
|
||||
"2016-07",
|
||||
"2016-08",
|
||||
"2016-09",
|
||||
"2016-10",
|
||||
"2016-11",
|
||||
"2016-12",
|
||||
"2017-01",
|
||||
"2017-02",
|
||||
"2017-03",
|
||||
]
|
||||
assert sorted(response['data'].keys()) == keys
|
||||
for val in response['data'].values():
|
||||
assert val == {'sms': {}, 'email': {}}
|
||||
assert sorted(response["data"].keys()) == keys
|
||||
for val in response["data"].values():
|
||||
assert val == {"sms": {}, "email": {}}
|
||||
|
||||
|
||||
def test_get_monthly_notification_stats_returns_stats(admin_request, sample_service):
|
||||
@@ -174,104 +205,141 @@ def test_get_monthly_notification_stats_returns_stats(admin_request, sample_serv
|
||||
|
||||
create_ft_notification_status(datetime(2016, 7, 1), template=sms_t1)
|
||||
create_ft_notification_status(datetime(2016, 7, 1), template=sms_t2)
|
||||
create_ft_notification_status(datetime(2016, 7, 1), template=sms_t1, notification_status='created')
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 7, 1), template=sms_t1, notification_status="created"
|
||||
)
|
||||
create_ft_notification_status(datetime(2016, 7, 1), template=email_template)
|
||||
|
||||
response = admin_request.get(
|
||||
'service.get_monthly_notification_stats',
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=sample_service.id,
|
||||
year=2016
|
||||
year=2016,
|
||||
)
|
||||
assert len(response['data']) == 12
|
||||
assert len(response["data"]) == 12
|
||||
|
||||
assert response['data']['2016-06'] == {
|
||||
'sms': {
|
||||
assert response["data"]["2016-06"] == {
|
||||
"sms": {
|
||||
# it combines the two days
|
||||
'delivered': 2
|
||||
"delivered": 2
|
||||
},
|
||||
'email': {}
|
||||
"email": {},
|
||||
}
|
||||
assert response['data']['2016-07'] == {
|
||||
assert response["data"]["2016-07"] == {
|
||||
# it combines the two template types
|
||||
'sms': {
|
||||
'created': 1,
|
||||
'delivered': 2,
|
||||
"sms": {
|
||||
"created": 1,
|
||||
"delivered": 2,
|
||||
},
|
||||
'email': {
|
||||
'delivered': 1
|
||||
}
|
||||
"email": {"delivered": 1},
|
||||
}
|
||||
|
||||
|
||||
@freeze_time('2016-06-05 12:00:00')
|
||||
def test_get_monthly_notification_stats_combines_todays_data_and_historic_stats(admin_request, sample_template):
|
||||
create_ft_notification_status(datetime(2016, 5, 1, 12), template=sample_template, count=1)
|
||||
create_ft_notification_status(datetime(2016, 6, 1, 12), template=sample_template, notification_status='created', count=2) # noqa
|
||||
@freeze_time("2016-06-05 12:00:00")
|
||||
def test_get_monthly_notification_stats_combines_todays_data_and_historic_stats(
|
||||
admin_request, sample_template
|
||||
):
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 5, 1, 12), template=sample_template, count=1
|
||||
)
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 6, 1, 12),
|
||||
template=sample_template,
|
||||
notification_status="created",
|
||||
count=2,
|
||||
) # noqa
|
||||
|
||||
create_notification(sample_template, created_at=datetime(2016, 6, 5, 12), status='created')
|
||||
create_notification(sample_template, created_at=datetime(2016, 6, 5, 12), status='delivered')
|
||||
create_notification(
|
||||
sample_template, created_at=datetime(2016, 6, 5, 12), status="created"
|
||||
)
|
||||
create_notification(
|
||||
sample_template, created_at=datetime(2016, 6, 5, 12), status="delivered"
|
||||
)
|
||||
|
||||
# this doesn't get returned in the stats because it is old - it should be in ft_notification_status by now
|
||||
create_notification(sample_template, created_at=datetime(2016, 6, 4, 12), status='sending')
|
||||
|
||||
response = admin_request.get(
|
||||
'service.get_monthly_notification_stats',
|
||||
service_id=sample_template.service_id,
|
||||
year=2016
|
||||
create_notification(
|
||||
sample_template, created_at=datetime(2016, 6, 4, 12), status="sending"
|
||||
)
|
||||
|
||||
assert len(response['data']) == 3 # apr, may, jun
|
||||
assert response['data']['2016-05'] == {
|
||||
'sms': {
|
||||
'delivered': 1
|
||||
},
|
||||
'email': {}
|
||||
}
|
||||
assert response['data']['2016-06'] == {
|
||||
'sms': {
|
||||
response = admin_request.get(
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=sample_template.service_id,
|
||||
year=2016,
|
||||
)
|
||||
|
||||
assert len(response["data"]) == 3 # apr, may, jun
|
||||
assert response["data"]["2016-05"] == {"sms": {"delivered": 1}, "email": {}}
|
||||
assert response["data"]["2016-06"] == {
|
||||
"sms": {
|
||||
# combines the stats from the historic ft_notification_status and the current notifications
|
||||
'created': 3,
|
||||
'delivered': 1,
|
||||
"created": 3,
|
||||
"delivered": 1,
|
||||
},
|
||||
'email': {}
|
||||
"email": {},
|
||||
}
|
||||
|
||||
|
||||
def test_get_monthly_notification_stats_ignores_test_keys(admin_request, sample_service):
|
||||
create_ft_notification_status(datetime(2016, 6, 1), service=sample_service, key_type=KEY_TYPE_NORMAL, count=1)
|
||||
create_ft_notification_status(datetime(2016, 6, 1), service=sample_service, key_type=KEY_TYPE_TEAM, count=2)
|
||||
create_ft_notification_status(datetime(2016, 6, 1), service=sample_service, key_type=KEY_TYPE_TEST, count=4)
|
||||
def test_get_monthly_notification_stats_ignores_test_keys(
|
||||
admin_request, sample_service
|
||||
):
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 6, 1), service=sample_service, key_type=KEY_TYPE_NORMAL, count=1
|
||||
)
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 6, 1), service=sample_service, key_type=KEY_TYPE_TEAM, count=2
|
||||
)
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 6, 1), service=sample_service, key_type=KEY_TYPE_TEST, count=4
|
||||
)
|
||||
|
||||
response = admin_request.get('service.get_monthly_notification_stats', service_id=sample_service.id, year=2016)
|
||||
response = admin_request.get(
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=sample_service.id,
|
||||
year=2016,
|
||||
)
|
||||
|
||||
assert response['data']['2016-06']['sms'] == {'delivered': 3}
|
||||
assert response["data"]["2016-06"]["sms"] == {"delivered": 3}
|
||||
|
||||
|
||||
def test_get_monthly_notification_stats_checks_dates(admin_request, sample_service):
|
||||
t = create_template(sample_service)
|
||||
# create_ft_notification_status(datetime(2016, 3, 31), template=t, notification_status='created')
|
||||
create_ft_notification_status(datetime(2016, 4, 2), template=t, notification_status='sending')
|
||||
create_ft_notification_status(datetime(2017, 3, 31), template=t, notification_status='delivered')
|
||||
create_ft_notification_status(datetime(2017, 4, 11), template=t, notification_status='permanent-failure')
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 4, 2), template=t, notification_status="sending"
|
||||
)
|
||||
create_ft_notification_status(
|
||||
datetime(2017, 3, 31), template=t, notification_status="delivered"
|
||||
)
|
||||
create_ft_notification_status(
|
||||
datetime(2017, 4, 11), template=t, notification_status="permanent-failure"
|
||||
)
|
||||
|
||||
response = admin_request.get('service.get_monthly_notification_stats', service_id=sample_service.id, year=2016)
|
||||
assert '2016-04' in response['data']
|
||||
assert '2017-04' not in response['data']
|
||||
assert response['data']['2016-04']['sms'] == {'sending': 1}
|
||||
assert response['data']['2016-04']['sms'] == {'sending': 1}
|
||||
response = admin_request.get(
|
||||
"service.get_monthly_notification_stats",
|
||||
service_id=sample_service.id,
|
||||
year=2016,
|
||||
)
|
||||
assert "2016-04" in response["data"]
|
||||
assert "2017-04" not in response["data"]
|
||||
assert response["data"]["2016-04"]["sms"] == {"sending": 1}
|
||||
assert response["data"]["2016-04"]["sms"] == {"sending": 1}
|
||||
|
||||
|
||||
def test_get_monthly_notification_stats_only_gets_for_one_service(admin_request, notify_db_session):
|
||||
def test_get_monthly_notification_stats_only_gets_for_one_service(
|
||||
admin_request, notify_db_session
|
||||
):
|
||||
services = [create_service(), create_service(service_name="2")]
|
||||
|
||||
templates = [create_template(services[0]), create_template(services[1])]
|
||||
|
||||
create_ft_notification_status(datetime(2016, 6, 1), template=templates[0], notification_status='created')
|
||||
create_ft_notification_status(datetime(2016, 6, 1), template=templates[1], notification_status='delivered')
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 6, 1), template=templates[0], notification_status="created"
|
||||
)
|
||||
create_ft_notification_status(
|
||||
datetime(2016, 6, 1), template=templates[1], notification_status="delivered"
|
||||
)
|
||||
|
||||
response = admin_request.get('service.get_monthly_notification_stats', service_id=services[0].id, year=2016)
|
||||
response = admin_request.get(
|
||||
"service.get_monthly_notification_stats", service_id=services[0].id, year=2016
|
||||
)
|
||||
|
||||
assert response['data']['2016-06'] == {
|
||||
'sms': {'created': 1},
|
||||
'email': {}
|
||||
}
|
||||
assert response["data"]["2016-06"] == {"sms": {"created": 1}, "email": {}}
|
||||
|
||||
@@ -11,65 +11,76 @@ from tests import create_admin_authorization_header
|
||||
@pytest.mark.parametrize("endpoint", ["suspend", "resume"])
|
||||
def test_only_allows_post(client, endpoint):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.get("/service/{}/{}".format(uuid.uuid4(), endpoint),
|
||||
headers=[auth_header])
|
||||
response = client.get(
|
||||
"/service/{}/{}".format(uuid.uuid4(), endpoint), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 405
|
||||
|
||||
|
||||
@pytest.mark.parametrize("endpoint", ["suspend", "resume"])
|
||||
def test_returns_404_when_service_does_not_exist(client, endpoint):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post("/service/{}/{}".format(uuid.uuid4(), endpoint),
|
||||
headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/{}".format(uuid.uuid4(), endpoint), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
@pytest.mark.parametrize("action, active", [("suspend", False), ("resume", True)])
|
||||
def test_has_not_effect_when_service_is_already_that_state(client, sample_service, action, active, mocker):
|
||||
def test_has_not_effect_when_service_is_already_that_state(
|
||||
client, sample_service, action, active, mocker
|
||||
):
|
||||
mocked = mocker.patch("app.service.rest.dao_{}_service".format(action))
|
||||
sample_service.active = active
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post("/service/{}/{}".format(sample_service.id, action),
|
||||
headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/{}".format(sample_service.id, action), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 204
|
||||
mocked.assert_not_called()
|
||||
assert sample_service.active == active
|
||||
|
||||
|
||||
@freeze_time('2001-01-01T23:59:00')
|
||||
@freeze_time("2001-01-01T23:59:00")
|
||||
def test_suspending_service_revokes_api_keys(client, sample_service, sample_api_key):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post("/service/{}/suspend".format(sample_service.id),
|
||||
headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/suspend".format(sample_service.id), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 204
|
||||
assert sample_api_key.expiry_date == datetime(2001, 1, 1, 23, 59, 00)
|
||||
|
||||
|
||||
def test_resume_service_leaves_api_keys_revokes(client, sample_service, sample_api_key):
|
||||
with freeze_time('2001-10-22T11:59:00'):
|
||||
with freeze_time("2001-10-22T11:59:00"):
|
||||
auth_header = create_admin_authorization_header()
|
||||
client.post("/service/{}/suspend".format(sample_service.id),
|
||||
headers=[auth_header])
|
||||
with freeze_time('2001-10-22T13:59:00'):
|
||||
client.post(
|
||||
"/service/{}/suspend".format(sample_service.id), headers=[auth_header]
|
||||
)
|
||||
with freeze_time("2001-10-22T13:59:00"):
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post("/service/{}/resume".format(sample_service.id),
|
||||
headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/resume".format(sample_service.id), headers=[auth_header]
|
||||
)
|
||||
assert response.status_code == 204
|
||||
assert sample_api_key.expiry_date == datetime(2001, 10, 22, 11, 59, 00)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("action, original_state", [("suspend", True), ("resume", False)])
|
||||
@pytest.mark.parametrize(
|
||||
"action, original_state", [("suspend", True), ("resume", False)]
|
||||
)
|
||||
def test_service_history_is_created(client, sample_service, action, original_state):
|
||||
sample_service.active = original_state
|
||||
auth_header = create_admin_authorization_header()
|
||||
response = client.post("/service/{}/{}".format(sample_service.id, action),
|
||||
headers=[auth_header])
|
||||
response = client.post(
|
||||
"/service/{}/{}".format(sample_service.id, action), headers=[auth_header]
|
||||
)
|
||||
ServiceHistory = Service.get_history_model()
|
||||
history = ServiceHistory.query.filter_by(
|
||||
id=sample_service.id
|
||||
).order_by(
|
||||
ServiceHistory.version.desc()
|
||||
).first()
|
||||
history = (
|
||||
ServiceHistory.query.filter_by(id=sample_service.id)
|
||||
.order_by(ServiceHistory.version.desc())
|
||||
.first()
|
||||
)
|
||||
|
||||
assert response.status_code == 204
|
||||
assert history.version == 2
|
||||
|
||||
@@ -7,34 +7,36 @@ service_id = str(uuid.uuid4())
|
||||
|
||||
def test_url_for_get_services(notify_api):
|
||||
with notify_api.test_request_context():
|
||||
url = url_for('service.get_services')
|
||||
assert str(url) == '/service'
|
||||
url_with_user_id = url_for('service.get_services', user_id=1)
|
||||
assert str(url_with_user_id) == '/service?user_id=1'
|
||||
url = url_for("service.get_services")
|
||||
assert str(url) == "/service"
|
||||
url_with_user_id = url_for("service.get_services", user_id=1)
|
||||
assert str(url_with_user_id) == "/service?user_id=1"
|
||||
|
||||
|
||||
def test_url_for_get_service_by_id(notify_api):
|
||||
with notify_api.test_request_context():
|
||||
url = url_for('service.get_service_by_id', service_id=service_id)
|
||||
assert str(url) == '/service/{}'.format(service_id)
|
||||
url = url_for("service.get_service_by_id", service_id=service_id)
|
||||
assert str(url) == "/service/{}".format(service_id)
|
||||
|
||||
url_with_user_id = url_for('service.get_service_by_id', service_id=service_id, user_id=1)
|
||||
assert str(url_with_user_id) == '/service/{0}?user_id={1}'.format(service_id, 1)
|
||||
url_with_user_id = url_for(
|
||||
"service.get_service_by_id", service_id=service_id, user_id=1
|
||||
)
|
||||
assert str(url_with_user_id) == "/service/{0}?user_id={1}".format(service_id, 1)
|
||||
|
||||
|
||||
def test_url_for_create_service(notify_api):
|
||||
with notify_api.test_request_context():
|
||||
url = url_for('service.create_service')
|
||||
assert str(url) == '/service'
|
||||
url = url_for("service.create_service")
|
||||
assert str(url) == "/service"
|
||||
|
||||
|
||||
def test_url_for_update_service(notify_api):
|
||||
with notify_api.test_request_context():
|
||||
url = url_for('service.update_service', service_id=service_id)
|
||||
assert str(url) == '/service/{}'.format(service_id)
|
||||
url = url_for("service.update_service", service_id=service_id)
|
||||
assert str(url) == "/service/{}".format(service_id)
|
||||
|
||||
|
||||
def test_url_for_create_api_key(notify_api):
|
||||
with notify_api.test_request_context():
|
||||
url = url_for('service.create_api_key', service_id=service_id)
|
||||
assert str(url) == '/service/{}/api-key'.format(service_id)
|
||||
url = url_for("service.create_api_key", service_id=service_id)
|
||||
assert str(url) == "/service/{}/api-key".format(service_id)
|
||||
|
||||
Reference in New Issue
Block a user