mirror of
https://github.com/GSA/notifications-api.git
synced 2026-08-26 09:13:40 -04:00
Merge branch 'master' of https://github.com/alphagov/notifications-api into sms_whitelist
This commit is contained in:
@@ -25,8 +25,8 @@ from app.celery.scheduled_tasks import (
|
||||
send_scheduled_notifications,
|
||||
switch_current_sms_provider_on_slow_delivery,
|
||||
timeout_job_statistics,
|
||||
timeout_notifications
|
||||
)
|
||||
timeout_notifications,
|
||||
populate_monthly_billing)
|
||||
from app.clients.performance_platform.performance_platform_client import PerformancePlatformClient
|
||||
from app.dao.jobs_dao import dao_get_job_by_id
|
||||
from app.dao.notifications_dao import dao_get_scheduled_notifications
|
||||
@@ -36,10 +36,10 @@ from app.dao.provider_details_dao import (
|
||||
)
|
||||
from app.models import (
|
||||
Service, Template,
|
||||
SMS_TYPE, LETTER_TYPE
|
||||
)
|
||||
SMS_TYPE, LETTER_TYPE,
|
||||
MonthlyBilling)
|
||||
from app.utils import get_london_midnight_in_utc
|
||||
from tests.app.db import create_notification, create_service, create_template, create_job
|
||||
from tests.app.db import create_notification, create_service, create_template, create_job, create_rate
|
||||
from tests.app.conftest import (
|
||||
sample_job as create_sample_job,
|
||||
sample_notification_history as create_notification_history,
|
||||
@@ -98,6 +98,8 @@ def test_should_have_decorated_tasks_functions():
|
||||
'remove_transformed_dvla_files'
|
||||
assert delete_dvla_response_files_older_than_seven_days.__wrapped__.__name__ == \
|
||||
'delete_dvla_response_files_older_than_seven_days'
|
||||
assert populate_monthly_billing.__wrapped__.__name__ == \
|
||||
'populate_monthly_billing'
|
||||
|
||||
|
||||
@pytest.fixture(scope='function')
|
||||
@@ -468,7 +470,7 @@ def test_should_send_all_scheduled_notifications_to_deliver_queue(sample_templat
|
||||
|
||||
send_scheduled_notifications()
|
||||
|
||||
mocked.apply_async.assert_called_once_with([str(message_to_deliver.id)], queue='send-tasks')
|
||||
mocked.apply_async.assert_called_once_with([str(message_to_deliver.id)], queue='send-sms-tasks')
|
||||
scheduled_notifications = dao_get_scheduled_notifications()
|
||||
assert not scheduled_notifications
|
||||
|
||||
@@ -607,3 +609,30 @@ def test_delete_dvla_response_files_older_than_seven_days_does_not_remove_files(
|
||||
delete_dvla_response_files_older_than_seven_days()
|
||||
|
||||
remove_s3_mock.assert_not_called()
|
||||
|
||||
|
||||
@freeze_time("2017-07-12 02:00:00")
|
||||
def test_populate_monthly_billing(sample_template):
|
||||
yesterday = datetime(2017, 7, 11, 13, 30)
|
||||
create_rate(datetime(2016, 1, 1), 0.0123, 'sms')
|
||||
create_notification(template=sample_template, status='delivered', created_at=yesterday)
|
||||
create_notification(template=sample_template, status='delivered', created_at=yesterday - timedelta(days=1))
|
||||
create_notification(template=sample_template, status='delivered', created_at=yesterday + timedelta(days=1))
|
||||
# not included in billing
|
||||
create_notification(template=sample_template, status='delivered', created_at=yesterday - timedelta(days=30))
|
||||
|
||||
assert len(MonthlyBilling.query.all()) == 0
|
||||
populate_monthly_billing()
|
||||
|
||||
monthly_billing = MonthlyBilling.query.all()
|
||||
assert len(monthly_billing) == 1
|
||||
assert monthly_billing[0].service_id == sample_template.service_id
|
||||
assert monthly_billing[0].year == 2017
|
||||
assert monthly_billing[0].month == 'July'
|
||||
assert monthly_billing[0].notification_type == 'sms'
|
||||
assert len(monthly_billing[0].monthly_totals) == 1
|
||||
assert sorted(monthly_billing[0].monthly_totals[0]) == sorted({'international': False,
|
||||
'rate_multiplier': 1,
|
||||
'billing_units': 3,
|
||||
'rate': 0.0123,
|
||||
'total_cost': 0.0369})
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
import pytest
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from app import create_uuid
|
||||
from app.celery.statistics_tasks import (
|
||||
record_initial_job_statistics,
|
||||
record_outcome_job_statistics,
|
||||
create_initial_notification_statistic_tasks,
|
||||
create_outcome_notification_statistic_tasks)
|
||||
from app.models import (
|
||||
NOTIFICATION_STATUS_TYPES_COMPLETED,
|
||||
NOTIFICATION_SENDING,
|
||||
NOTIFICATION_PENDING,
|
||||
NOTIFICATION_CREATED,
|
||||
NOTIFICATION_DELIVERED
|
||||
)
|
||||
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from app import create_uuid
|
||||
from tests.app.conftest import sample_notification
|
||||
from app.models import NOTIFICATION_STATUS_TYPES_COMPLETED, NOTIFICATION_SENT, NOTIFICATION_SENDING, \
|
||||
NOTIFICATION_PENDING, NOTIFICATION_CREATED, NOTIFICATION_DELIVERED
|
||||
|
||||
|
||||
def test_should_create_initial_job_task_if_notification_is_related_to_a_job(
|
||||
|
||||
@@ -422,7 +422,7 @@ def test_should_send_template_to_correct_sms_task_and_persist(sample_template_wi
|
||||
assert persisted_notification.notification_type == 'sms'
|
||||
mocked_deliver_sms.assert_called_once_with(
|
||||
[str(persisted_notification.id)],
|
||||
queue="send-tasks"
|
||||
queue="send-sms-tasks"
|
||||
)
|
||||
|
||||
|
||||
@@ -483,7 +483,7 @@ def test_should_send_sms_if_restricted_service_and_valid_number(notify_db, notif
|
||||
assert persisted_notification.notification_type == 'sms'
|
||||
provider_tasks.deliver_sms.apply_async.assert_called_once_with(
|
||||
[str(persisted_notification.id)],
|
||||
queue="send-tasks"
|
||||
queue="send-sms-tasks"
|
||||
)
|
||||
|
||||
|
||||
@@ -509,7 +509,7 @@ def test_should_send_sms_if_restricted_service_and_non_team_number_with_test_key
|
||||
persisted_notification = Notification.query.one()
|
||||
mocked_deliver_sms.assert_called_once_with(
|
||||
[str(persisted_notification.id)],
|
||||
queue="send-tasks"
|
||||
queue="send-sms-tasks"
|
||||
)
|
||||
|
||||
|
||||
@@ -537,7 +537,7 @@ def test_should_send_email_if_restricted_service_and_non_team_email_address_with
|
||||
persisted_notification = Notification.query.one()
|
||||
mocked_deliver_email.assert_called_once_with(
|
||||
[str(persisted_notification.id)],
|
||||
queue="send-tasks"
|
||||
queue="send-email-tasks"
|
||||
)
|
||||
|
||||
|
||||
@@ -641,7 +641,7 @@ def test_should_send_sms_template_to_and_persist_with_job_id(sample_job, sample_
|
||||
|
||||
provider_tasks.deliver_sms.apply_async.assert_called_once_with(
|
||||
[str(persisted_notification.id)],
|
||||
queue="send-tasks"
|
||||
queue="send-sms-tasks"
|
||||
)
|
||||
|
||||
|
||||
@@ -738,7 +738,7 @@ def test_should_use_email_template_and_persist(sample_email_template_with_placeh
|
||||
assert persisted_notification.notification_type == 'email'
|
||||
|
||||
provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
||||
[str(persisted_notification.id)], queue='send-tasks')
|
||||
[str(persisted_notification.id)], queue='send-email-tasks')
|
||||
|
||||
|
||||
def test_send_email_should_use_template_version_from_job_not_latest(sample_email_template, mocker):
|
||||
@@ -769,7 +769,7 @@ def test_send_email_should_use_template_version_from_job_not_latest(sample_email
|
||||
assert not persisted_notification.sent_by
|
||||
assert persisted_notification.notification_type == 'email'
|
||||
provider_tasks.deliver_email.apply_async.assert_called_once_with([str(persisted_notification.id)],
|
||||
queue='send-tasks')
|
||||
queue='send-email-tasks')
|
||||
|
||||
|
||||
def test_should_use_email_template_subject_placeholders(sample_email_template_with_placeholders, mocker):
|
||||
@@ -795,7 +795,7 @@ def test_should_use_email_template_subject_placeholders(sample_email_template_wi
|
||||
assert not persisted_notification.reference
|
||||
assert persisted_notification.notification_type == 'email'
|
||||
provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
||||
[str(persisted_notification.id)], queue='send-tasks'
|
||||
[str(persisted_notification.id)], queue='send-email-tasks'
|
||||
)
|
||||
|
||||
|
||||
@@ -823,7 +823,7 @@ def test_should_use_email_template_and_persist_without_personalisation(sample_em
|
||||
assert not persisted_notification.reference
|
||||
assert persisted_notification.notification_type == 'email'
|
||||
provider_tasks.deliver_email.apply_async.assert_called_once_with([str(persisted_notification.id)],
|
||||
queue='send-tasks')
|
||||
queue='send-email-tasks')
|
||||
|
||||
|
||||
def test_send_sms_should_go_to_retry_queue_if_database_errors(sample_template, mocker):
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
from app.dao.date_util import get_financial_year, get_april_fools
|
||||
from datetime import datetime
|
||||
|
||||
import pytest
|
||||
|
||||
from app.dao.date_util import get_financial_year, get_april_fools, get_month_start_end_date
|
||||
|
||||
|
||||
def test_get_financial_year():
|
||||
@@ -11,3 +15,16 @@ def test_get_april_fools():
|
||||
april_fools = get_april_fools(2016)
|
||||
assert str(april_fools) == '2016-03-31 23:00:00'
|
||||
assert april_fools.tzinfo is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("month, year, expected_end",
|
||||
[(7, 2017, 31),
|
||||
(2, 2016, 29),
|
||||
(2, 2017, 28),
|
||||
(9, 2018, 30),
|
||||
(12, 2019, 31)])
|
||||
def test_get_month_start_end_date(month, year, expected_end):
|
||||
month_year = datetime(year, month, 10, 13, 30, 00)
|
||||
result = get_month_start_end_date(month_year)
|
||||
assert result[0] == datetime(year, month, 1, 0, 0, 0, 0)
|
||||
assert result[1] == datetime(year, month, expected_end, 23, 59, 59, 99999)
|
||||
|
||||
127
tests/app/dao/test_monthly_billing.py
Normal file
127
tests/app/dao/test_monthly_billing.py
Normal file
@@ -0,0 +1,127 @@
|
||||
from datetime import datetime
|
||||
|
||||
from app.dao.monthly_billing_dao import (
|
||||
create_or_update_monthly_billing_sms,
|
||||
get_monthly_billing_sms,
|
||||
get_service_ids_that_need_sms_billing_populated
|
||||
)
|
||||
from app.models import MonthlyBilling
|
||||
from tests.app.db import create_notification, create_rate, create_service, create_template
|
||||
|
||||
|
||||
def test_add_monthly_billing(sample_template):
|
||||
jan = datetime(2017, 1, 1)
|
||||
feb = datetime(2017, 2, 15)
|
||||
create_rate(start_date=jan, value=0.0158, notification_type='sms')
|
||||
create_rate(start_date=datetime(2017, 3, 31, 23, 00, 00), value=0.123, notification_type='sms')
|
||||
create_notification(template=sample_template, created_at=jan, billable_units=1, status='delivered')
|
||||
create_notification(template=sample_template, created_at=feb, billable_units=2, status='delivered')
|
||||
|
||||
create_or_update_monthly_billing_sms(service_id=sample_template.service_id,
|
||||
billing_month=jan)
|
||||
create_or_update_monthly_billing_sms(service_id=sample_template.service_id,
|
||||
billing_month=feb)
|
||||
monthly_billing = MonthlyBilling.query.all()
|
||||
assert len(monthly_billing) == 2
|
||||
assert monthly_billing[0].month == 'January'
|
||||
assert monthly_billing[1].month == 'February'
|
||||
|
||||
january = get_monthly_billing_sms(service_id=sample_template.service_id, billing_month=jan)
|
||||
expected_jan = {"billing_units": 1,
|
||||
"rate_multiplier": 1,
|
||||
"international": False,
|
||||
"rate": 0.0158,
|
||||
"total_cost": 1 * 0.0158}
|
||||
assert_monthly_billing(january, 2017, "January", sample_template.service_id, 1, expected_jan)
|
||||
|
||||
february = get_monthly_billing_sms(service_id=sample_template.service_id, billing_month=feb)
|
||||
expected_feb = {"billing_units": 2,
|
||||
"rate_multiplier": 1,
|
||||
"international": False,
|
||||
"rate": 0.0158,
|
||||
"total_cost": 2 * 0.0158}
|
||||
assert_monthly_billing(february, 2017, "February", sample_template.service_id, 1, expected_feb)
|
||||
|
||||
|
||||
def test_add_monthly_billing_multiple_rates_in_a_month(sample_template):
|
||||
rate_1 = datetime(2016, 12, 1)
|
||||
rate_2 = datetime(2017, 1, 15)
|
||||
create_rate(start_date=rate_1, value=0.0158, notification_type='sms')
|
||||
create_rate(start_date=rate_2, value=0.0124, notification_type='sms')
|
||||
|
||||
create_notification(template=sample_template, created_at=datetime(2017, 1, 1), billable_units=1, status='delivered')
|
||||
create_notification(template=sample_template, created_at=datetime(2017, 1, 14, 23, 59), billable_units=1,
|
||||
status='delivered')
|
||||
|
||||
create_notification(template=sample_template, created_at=datetime(2017, 1, 15), billable_units=2,
|
||||
status='delivered')
|
||||
create_notification(template=sample_template, created_at=datetime(2017, 1, 17, 13, 30, 57), billable_units=4,
|
||||
status='delivered')
|
||||
|
||||
create_or_update_monthly_billing_sms(service_id=sample_template.service_id,
|
||||
billing_month=rate_2)
|
||||
monthly_billing = MonthlyBilling.query.all()
|
||||
assert len(monthly_billing) == 1
|
||||
assert monthly_billing[0].month == 'January'
|
||||
|
||||
january = get_monthly_billing_sms(service_id=sample_template.service_id, billing_month=rate_2)
|
||||
first_row = {"billing_units": 2,
|
||||
"rate_multiplier": 1,
|
||||
"international": False,
|
||||
"rate": 0.0158,
|
||||
"total_cost": 3 * 0.0158}
|
||||
assert_monthly_billing(january, 2017, "January", sample_template.service_id, 2, first_row)
|
||||
second_row = {"billing_units": 6,
|
||||
"rate_multiplier": 1,
|
||||
"international": False,
|
||||
"rate": 0.0124,
|
||||
"total_cost": 1 * 0.0124}
|
||||
assert sorted(january.monthly_totals[1]) == sorted(second_row)
|
||||
|
||||
|
||||
def test_update_monthly_billing_overwrites_old_totals(sample_template):
|
||||
july = datetime(2017, 7, 1)
|
||||
create_rate(july, 0.123, 'sms')
|
||||
create_notification(template=sample_template, created_at=datetime(2017, 7, 2), billable_units=1, status='delivered')
|
||||
|
||||
create_or_update_monthly_billing_sms(sample_template.service_id, july)
|
||||
first_update = get_monthly_billing_sms(sample_template.service_id, july)
|
||||
expected = {"billing_units": 1,
|
||||
"rate_multiplier": 1,
|
||||
"international": False,
|
||||
"rate": 0.123,
|
||||
"total_cost": 1 * 0.123}
|
||||
assert_monthly_billing(first_update, 2017, "July", sample_template.service_id, 1, expected)
|
||||
|
||||
create_notification(template=sample_template, created_at=datetime(2017, 7, 5), billable_units=2, status='delivered')
|
||||
create_or_update_monthly_billing_sms(sample_template.service_id, july)
|
||||
second_update = get_monthly_billing_sms(sample_template.service_id, july)
|
||||
expected_update = {"billing_units": 3,
|
||||
"rate_multiplier": 1,
|
||||
"international": False,
|
||||
"rate": 0.123,
|
||||
"total_cost": 3 * 0.123}
|
||||
assert_monthly_billing(second_update, 2017, "July", sample_template.service_id, 1, expected_update)
|
||||
|
||||
|
||||
def assert_monthly_billing(monthly_billing, year, month, service_id, expected_len, first_row):
|
||||
assert monthly_billing.year == year
|
||||
assert monthly_billing.month == month
|
||||
assert monthly_billing.service_id == service_id
|
||||
assert len(monthly_billing.monthly_totals) == expected_len
|
||||
assert sorted(monthly_billing.monthly_totals[0]) == sorted(first_row)
|
||||
|
||||
|
||||
def test_get_service_id(notify_db_session):
|
||||
service_1 = create_service(service_name="Service One")
|
||||
template_1 = create_template(service=service_1)
|
||||
service_2 = create_service(service_name="Service Two")
|
||||
template_2 = create_template(service=service_2)
|
||||
create_notification(template=template_1, created_at=datetime(2017, 6, 30, 13, 30), status='delivered')
|
||||
create_notification(template=template_1, created_at=datetime(2017, 7, 1, 14, 30), status='delivered')
|
||||
create_notification(template=template_2, created_at=datetime(2017, 7, 15, 13, 30))
|
||||
create_notification(template=template_2, created_at=datetime(2017, 7, 31, 13, 30))
|
||||
services = get_service_ids_that_need_sms_billing_populated(start_date=datetime(2017, 7, 1),
|
||||
end_date=datetime(2017, 7, 16))
|
||||
expected_services = [service_1.id, service_2.id]
|
||||
assert sorted([x.service_id for x in services]) == sorted(expected_services)
|
||||
@@ -6,7 +6,7 @@ from flask import current_app
|
||||
|
||||
from app.dao.date_util import get_financial_year
|
||||
from app.dao.notification_usage_dao import (
|
||||
get_rates_for_year,
|
||||
get_rates_for_daterange,
|
||||
get_yearly_billing_data,
|
||||
get_monthly_billing_data,
|
||||
get_total_billable_units_for_sent_sms_notifications_in_date_range,
|
||||
@@ -24,22 +24,22 @@ from freezegun import freeze_time
|
||||
from tests.conftest import set_config
|
||||
|
||||
|
||||
def test_get_rates_for_year(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2016, 5, 18), 0.016)
|
||||
set_up_rate(notify_db, datetime(2017, 3, 31, 23), 0.0158)
|
||||
start_date, end_date = get_financial_year(2017)
|
||||
rates = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert len(rates) == 1
|
||||
assert datetime.strftime(rates[0].valid_from, '%Y-%m-%d %H:%M:%S') == "2017-03-31 23:00:00"
|
||||
assert rates[0].rate == 0.0158
|
||||
|
||||
|
||||
def test_get_rates_for_year_multiple_result_per_year(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange_multiple_result_per_year(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2016, 4, 1), 0.015)
|
||||
set_up_rate(notify_db, datetime(2016, 5, 18), 0.016)
|
||||
set_up_rate(notify_db, datetime(2017, 4, 1), 0.0158)
|
||||
start_date, end_date = get_financial_year(2016)
|
||||
rates = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert len(rates) == 2
|
||||
assert datetime.strftime(rates[0].valid_from, '%Y-%m-%d %H:%M:%S') == "2016-04-01 00:00:00"
|
||||
assert rates[0].rate == 0.015
|
||||
@@ -47,12 +47,12 @@ def test_get_rates_for_year_multiple_result_per_year(notify_db, notify_db_sessio
|
||||
assert rates[1].rate == 0.016
|
||||
|
||||
|
||||
def test_get_rates_for_year_returns_correct_rates(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange_returns_correct_rates(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2016, 4, 1), 0.015)
|
||||
set_up_rate(notify_db, datetime(2016, 9, 1), 0.016)
|
||||
set_up_rate(notify_db, datetime(2017, 6, 1), 0.0175)
|
||||
start_date, end_date = get_financial_year(2017)
|
||||
rates_2017 = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates_2017 = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert len(rates_2017) == 2
|
||||
assert datetime.strftime(rates_2017[0].valid_from, '%Y-%m-%d %H:%M:%S') == "2016-09-01 00:00:00"
|
||||
assert rates_2017[0].rate == 0.016
|
||||
@@ -60,43 +60,56 @@ def test_get_rates_for_year_returns_correct_rates(notify_db, notify_db_session):
|
||||
assert rates_2017[1].rate == 0.0175
|
||||
|
||||
|
||||
def test_get_rates_for_year_in_the_future(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange_in_the_future(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2016, 4, 1), 0.015)
|
||||
set_up_rate(notify_db, datetime(2017, 6, 1), 0.0175)
|
||||
start_date, end_date = get_financial_year(2018)
|
||||
rates = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert datetime.strftime(rates[0].valid_from, '%Y-%m-%d %H:%M:%S') == "2017-06-01 00:00:00"
|
||||
assert rates[0].rate == 0.0175
|
||||
|
||||
|
||||
def test_get_rates_for_year_returns_empty_list_if_year_is_before_earliest_rate(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange_returns_empty_list_if_year_is_before_earliest_rate(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2016, 4, 1), 0.015)
|
||||
set_up_rate(notify_db, datetime(2017, 6, 1), 0.0175)
|
||||
start_date, end_date = get_financial_year(2015)
|
||||
rates = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert rates == []
|
||||
|
||||
|
||||
def test_get_rates_for_year_early_rate(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange_early_rate(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2015, 6, 1), 0.014)
|
||||
set_up_rate(notify_db, datetime(2016, 6, 1), 0.015)
|
||||
set_up_rate(notify_db, datetime(2016, 9, 1), 0.016)
|
||||
set_up_rate(notify_db, datetime(2017, 6, 1), 0.0175)
|
||||
start_date, end_date = get_financial_year(2016)
|
||||
rates = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert len(rates) == 3
|
||||
|
||||
|
||||
def test_get_rates_for_year_edge_case(notify_db, notify_db_session):
|
||||
def test_get_rates_for_daterange_edge_case(notify_db, notify_db_session):
|
||||
set_up_rate(notify_db, datetime(2016, 3, 31, 23, 00), 0.015)
|
||||
set_up_rate(notify_db, datetime(2017, 3, 31, 23, 00), 0.0175)
|
||||
start_date, end_date = get_financial_year(2016)
|
||||
rates = get_rates_for_year(start_date, end_date, 'sms')
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert len(rates) == 1
|
||||
assert datetime.strftime(rates[0].valid_from, '%Y-%m-%d %H:%M:%S') == "2016-03-31 23:00:00"
|
||||
assert rates[0].rate == 0.015
|
||||
|
||||
|
||||
def test_get_rates_for_daterange_where_daterange_is_one_month_that_falls_between_rate_valid_from(
|
||||
notify_db, notify_db_session
|
||||
):
|
||||
set_up_rate(notify_db, datetime(2017, 1, 1), 0.175)
|
||||
set_up_rate(notify_db, datetime(2017, 3, 31), 0.123)
|
||||
start_date = datetime(2017, 2, 1, 00, 00, 00)
|
||||
end_date = datetime(2017, 2, 28, 23, 59, 59, 99999)
|
||||
rates = get_rates_for_daterange(start_date, end_date, 'sms')
|
||||
assert len(rates) == 1
|
||||
assert datetime.strftime(rates[0].valid_from, '%Y-%m-%d %H:%M:%S') == "2017-01-01 00:00:00"
|
||||
assert rates[0].rate == 0.175
|
||||
|
||||
|
||||
def test_get_yearly_billing_data(notify_db, notify_db_session, sample_template, sample_email_template):
|
||||
set_up_rate(notify_db, datetime(2016, 4, 1), 0.014)
|
||||
set_up_rate(notify_db, datetime(2016, 6, 1), 0.0158)
|
||||
@@ -254,8 +267,7 @@ def test_get_monthly_billing_data_with_multiple_rates(notify_db, notify_db_sessi
|
||||
assert results[3] == ('June', 4, 1, False, 'sms', 0.0175)
|
||||
|
||||
|
||||
def test_get_monthly_billing_data_with_no_notifications_for_year(notify_db, notify_db_session, sample_template,
|
||||
sample_email_template):
|
||||
def test_get_monthly_billing_data_with_no_notifications_for_daterange(notify_db, notify_db_session, sample_template):
|
||||
set_up_rate(notify_db, datetime(2016, 4, 1), 0.014)
|
||||
results = get_monthly_billing_data(sample_template.service_id, 2016)
|
||||
assert len(results) == 0
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from app.dao.provider_rates_dao import create_provider_rates
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from datetime import datetime
|
||||
import uuid
|
||||
|
||||
|
||||
from app import db
|
||||
from app.dao.jobs_dao import dao_create_job
|
||||
from app.dao.service_inbound_api_dao import save_service_inbound_api
|
||||
from app.models import (
|
||||
@@ -11,6 +11,7 @@ from app.models import (
|
||||
Notification,
|
||||
ScheduledNotification,
|
||||
ServicePermission,
|
||||
Rate,
|
||||
Job,
|
||||
InboundSms,
|
||||
Organisation,
|
||||
@@ -239,3 +240,10 @@ def create_organisation(colour='blue', logo='test_x2.png', name='test_org_1'):
|
||||
dao_create_organisation(organisation)
|
||||
|
||||
return organisation
|
||||
|
||||
|
||||
def create_rate(start_date, value, notification_type):
|
||||
rate = Rate(id=uuid.uuid4(), valid_from=start_date, rate=value, notification_type=notification_type)
|
||||
db.session.add(rate)
|
||||
db.session.commit()
|
||||
return rate
|
||||
|
||||
@@ -78,7 +78,7 @@ def test_should_call_deliver_sms_task_if_send_sms_to_provider_fails(notify_api,
|
||||
)
|
||||
app.delivery.send_to_providers.send_sms_to_provider.assert_called_with(sample_notification)
|
||||
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_with(
|
||||
(str(sample_notification.id)), queue='send-tasks'
|
||||
(str(sample_notification.id)), queue='send-sms-tasks'
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
@@ -100,6 +100,6 @@ def test_should_call_deliver_email_task_if_send_email_to_provider_fails(
|
||||
)
|
||||
app.delivery.send_to_providers.send_email_to_provider.assert_called_with(sample_email_notification)
|
||||
app.celery.provider_tasks.deliver_email.apply_async.assert_called_with(
|
||||
(str(sample_email_notification.id)), queue='send-tasks'
|
||||
(str(sample_email_notification.id)), queue='send-email-tasks'
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
@@ -132,7 +132,7 @@ def test_send_notification_with_placeholders_replaced(notify_api, sample_email_t
|
||||
|
||||
mocked.assert_called_once_with(
|
||||
[notification_id],
|
||||
queue="send-tasks"
|
||||
queue="send-email-tasks"
|
||||
)
|
||||
assert response.status_code == 201
|
||||
assert response_data['body'] == u'Hello Jo\nThis is an email from GOV.\u200BUK'
|
||||
@@ -342,7 +342,7 @@ def test_should_allow_valid_sms_notification(notify_api, sample_template, mocker
|
||||
response_data = json.loads(response.data)['data']
|
||||
notification_id = response_data['notification']['id']
|
||||
|
||||
mocked.assert_called_once_with([notification_id], queue='send-tasks')
|
||||
mocked.assert_called_once_with([notification_id], queue='send-sms-tasks')
|
||||
assert response.status_code == 201
|
||||
assert notification_id
|
||||
assert 'subject' not in response_data
|
||||
@@ -395,7 +395,7 @@ def test_should_allow_valid_email_notification(notify_api, sample_email_template
|
||||
notification_id = response_data['notification']['id']
|
||||
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
||||
[notification_id],
|
||||
queue="send-tasks"
|
||||
queue="send-email-tasks"
|
||||
)
|
||||
|
||||
assert response.status_code == 201
|
||||
@@ -593,7 +593,10 @@ def test_should_send_email_if_team_api_key_and_a_service_user(notify_api, sample
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(auth_header))])
|
||||
|
||||
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with([fake_uuid], queue='send-tasks')
|
||||
app.celery.provider_tasks.deliver_email.apply_async.assert_called_once_with(
|
||||
[fake_uuid],
|
||||
queue='send-email-tasks'
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
@@ -689,57 +692,67 @@ def test_should_send_sms_if_team_api_key_and_a_service_user(notify_api, sample_t
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(auth_header))])
|
||||
|
||||
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with([fake_uuid], queue='send-tasks')
|
||||
app.celery.provider_tasks.deliver_sms.apply_async.assert_called_once_with([fake_uuid], queue='send-sms-tasks')
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_type',
|
||||
[SMS_TYPE, EMAIL_TYPE])
|
||||
def test_should_persist_notification(notify_api, sample_template,
|
||||
sample_email_template,
|
||||
template_type,
|
||||
fake_uuid, mocker):
|
||||
with notify_api.test_request_context(), notify_api.test_client() as client:
|
||||
mocked = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(template_type))
|
||||
mocker.patch('app.dao.notifications_dao.create_uuid', return_value=fake_uuid)
|
||||
template = sample_template if template_type == SMS_TYPE else sample_email_template
|
||||
to = sample_template.service.created_by.mobile_number if template_type == SMS_TYPE \
|
||||
else sample_email_template.service.created_by.email_address
|
||||
data = {
|
||||
'to': to,
|
||||
'template': template.id
|
||||
}
|
||||
api_key = ApiKey(
|
||||
service=template.service,
|
||||
name='team_key',
|
||||
created_by=template.created_by,
|
||||
key_type=KEY_TYPE_TEAM)
|
||||
save_model_api_key(api_key)
|
||||
auth_header = create_jwt_token(secret=api_key.secret, client_id=str(api_key.service_id))
|
||||
@pytest.mark.parametrize('template_type,queue_name', [
|
||||
(SMS_TYPE, 'send-sms-tasks'),
|
||||
(EMAIL_TYPE, 'send-email-tasks')
|
||||
])
|
||||
def test_should_persist_notification(
|
||||
client,
|
||||
sample_template,
|
||||
sample_email_template,
|
||||
fake_uuid,
|
||||
mocker,
|
||||
template_type,
|
||||
queue_name
|
||||
):
|
||||
mocked = mocker.patch('app.celery.provider_tasks.deliver_{}.apply_async'.format(template_type))
|
||||
mocker.patch('app.dao.notifications_dao.create_uuid', return_value=fake_uuid)
|
||||
template = sample_template if template_type == SMS_TYPE else sample_email_template
|
||||
to = sample_template.service.created_by.mobile_number if template_type == SMS_TYPE \
|
||||
else sample_email_template.service.created_by.email_address
|
||||
data = {
|
||||
'to': to,
|
||||
'template': template.id
|
||||
}
|
||||
api_key = ApiKey(
|
||||
service=template.service,
|
||||
name='team_key',
|
||||
created_by=template.created_by,
|
||||
key_type=KEY_TYPE_TEAM)
|
||||
save_model_api_key(api_key)
|
||||
auth_header = create_jwt_token(secret=api_key.secret, client_id=str(api_key.service_id))
|
||||
|
||||
response = client.post(
|
||||
path='/notifications/{}'.format(template_type),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(auth_header))])
|
||||
response = client.post(
|
||||
path='/notifications/{}'.format(template_type),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), ('Authorization', 'Bearer {}'.format(auth_header))])
|
||||
|
||||
mocked.assert_called_once_with([fake_uuid], queue='send-tasks')
|
||||
assert response.status_code == 201
|
||||
mocked.assert_called_once_with([fake_uuid], queue=queue_name)
|
||||
assert response.status_code == 201
|
||||
|
||||
notification = notifications_dao.get_notification_by_id(fake_uuid)
|
||||
assert notification.to == to
|
||||
assert notification.template_id == template.id
|
||||
assert notification.notification_type == template_type
|
||||
notification = notifications_dao.get_notification_by_id(fake_uuid)
|
||||
assert notification.to == to
|
||||
assert notification.template_id == template.id
|
||||
assert notification.notification_type == template_type
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_type',
|
||||
[SMS_TYPE, EMAIL_TYPE])
|
||||
@pytest.mark.parametrize('template_type,queue_name', [
|
||||
(SMS_TYPE, 'send-sms-tasks'),
|
||||
(EMAIL_TYPE, 'send-email-tasks')
|
||||
])
|
||||
def test_should_delete_notification_and_return_error_if_sqs_fails(
|
||||
client,
|
||||
sample_email_template,
|
||||
sample_template,
|
||||
fake_uuid,
|
||||
mocker,
|
||||
template_type):
|
||||
client,
|
||||
sample_email_template,
|
||||
sample_template,
|
||||
fake_uuid,
|
||||
mocker,
|
||||
template_type,
|
||||
queue_name
|
||||
):
|
||||
mocked = mocker.patch(
|
||||
'app.celery.provider_tasks.deliver_{}.apply_async'.format(template_type),
|
||||
side_effect=Exception("failed to talk to SQS")
|
||||
@@ -768,7 +781,7 @@ def test_should_delete_notification_and_return_error_if_sqs_fails(
|
||||
)
|
||||
assert str(e.value) == 'failed to talk to SQS'
|
||||
|
||||
mocked.assert_called_once_with([fake_uuid], queue='send-tasks')
|
||||
mocked.assert_called_once_with([fake_uuid], queue=queue_name)
|
||||
assert not notifications_dao.get_notification_by_id(fake_uuid)
|
||||
assert not NotificationHistory.query.get(fake_uuid)
|
||||
|
||||
@@ -1119,7 +1132,7 @@ def test_should_allow_store_original_number_on_sms_notification(client, sample_t
|
||||
response_data = json.loads(response.data)['data']
|
||||
notification_id = response_data['notification']['id']
|
||||
|
||||
mocked.assert_called_once_with([notification_id], queue='send-tasks')
|
||||
mocked.assert_called_once_with([notification_id], queue='send-sms-tasks')
|
||||
assert response.status_code == 201
|
||||
assert notification_id
|
||||
notifications = Notification.query.all()
|
||||
|
||||
@@ -51,10 +51,18 @@ def test_persist_notification_creates_and_save_to_db(sample_template, sample_api
|
||||
|
||||
assert Notification.query.count() == 0
|
||||
assert NotificationHistory.query.count() == 0
|
||||
notification = persist_notification(sample_template.id, sample_template.version, '+447111111111',
|
||||
sample_template.service, {}, 'sms', sample_api_key.id,
|
||||
sample_api_key.key_type, job_id=sample_job.id,
|
||||
job_row_number=100, reference="ref")
|
||||
notification = persist_notification(
|
||||
template_id=sample_template.id,
|
||||
template_version=sample_template.version,
|
||||
recipient='+447111111111',
|
||||
service=sample_template.service,
|
||||
personalisation={},
|
||||
notification_type='sms',
|
||||
api_key_id=sample_api_key.id,
|
||||
key_type=sample_api_key.key_type,
|
||||
job_id=sample_job.id,
|
||||
job_row_number=100,
|
||||
reference="ref")
|
||||
|
||||
assert Notification.query.get(notification.id) is not None
|
||||
assert NotificationHistory.query.get(notification.id) is not None
|
||||
@@ -127,14 +135,14 @@ def test_persist_notification_does_not_increment_cache_if_test_key(
|
||||
assert Notification.query.count() == 0
|
||||
assert NotificationHistory.query.count() == 0
|
||||
persist_notification(
|
||||
sample_template.id,
|
||||
sample_template.version,
|
||||
'+447111111111',
|
||||
sample_template.service,
|
||||
{},
|
||||
'sms',
|
||||
api_key.id,
|
||||
api_key.key_type,
|
||||
template_id=sample_template.id,
|
||||
template_version=sample_template.version,
|
||||
recipient='+447111111111',
|
||||
service=sample_template.service,
|
||||
personalisation={},
|
||||
notification_type='sms',
|
||||
api_key_id=api_key.id,
|
||||
key_type=api_key.key_type,
|
||||
job_id=sample_job.id,
|
||||
job_row_number=100,
|
||||
reference="ref",
|
||||
@@ -193,18 +201,33 @@ def test_persist_notification_increments_cache_if_key_exists(sample_template, sa
|
||||
mock_incr = mocker.patch('app.notifications.process_notifications.redis_store.incr')
|
||||
mock_incr_hash_value = mocker.patch('app.notifications.process_notifications.redis_store.increment_hash_value')
|
||||
|
||||
persist_notification(sample_template.id, sample_template.version, '+447111111111',
|
||||
sample_template.service, {}, 'sms', sample_api_key.id,
|
||||
sample_api_key.key_type, reference="ref")
|
||||
persist_notification(
|
||||
template_id=sample_template.id,
|
||||
template_version=sample_template.version,
|
||||
recipient='+447111111111',
|
||||
service=sample_template.service,
|
||||
personalisation={},
|
||||
notification_type='sms',
|
||||
api_key_id=sample_api_key.id,
|
||||
key_type=sample_api_key.key_type,
|
||||
reference="ref"
|
||||
)
|
||||
mock_incr.assert_not_called()
|
||||
mock_incr_hash_value.assert_not_called()
|
||||
|
||||
mocker.patch('app.notifications.process_notifications.redis_store.get', return_value=1)
|
||||
mocker.patch('app.notifications.process_notifications.redis_store.get_all_from_hash',
|
||||
return_value={sample_template.id, 1})
|
||||
persist_notification(sample_template.id, sample_template.version, '+447111111122',
|
||||
sample_template.service, {}, 'sms', sample_api_key.id,
|
||||
sample_api_key.key_type, reference="ref2")
|
||||
persist_notification(
|
||||
template_id=sample_template.id,
|
||||
template_version=sample_template.version,
|
||||
recipient='+447111111122',
|
||||
service=sample_template.service,
|
||||
personalisation={},
|
||||
notification_type='sms',
|
||||
api_key_id=sample_api_key.id,
|
||||
key_type=sample_api_key.key_type,
|
||||
reference="ref2")
|
||||
mock_incr.assert_called_once_with(str(sample_template.service_id) + "-2016-01-01-count", )
|
||||
mock_incr_hash_value.assert_called_once_with(cache_key_for_service_template_counter(sample_template.service_id),
|
||||
sample_template.id)
|
||||
@@ -214,9 +237,9 @@ def test_persist_notification_increments_cache_if_key_exists(sample_template, sa
|
||||
[(True, None, 'research-mode-tasks', 'sms', 'normal'),
|
||||
(True, None, 'research-mode-tasks', 'email', 'normal'),
|
||||
(True, None, 'research-mode-tasks', 'email', 'team'),
|
||||
(False, None, 'send-tasks', 'sms', 'normal'),
|
||||
(False, None, 'send-tasks', 'email', 'normal'),
|
||||
(False, None, 'send-tasks', 'sms', 'team'),
|
||||
(False, None, 'send-sms-tasks', 'sms', 'normal'),
|
||||
(False, None, 'send-email-tasks', 'email', 'normal'),
|
||||
(False, None, 'send-sms-tasks', 'sms', 'team'),
|
||||
(False, None, 'research-mode-tasks', 'sms', 'test'),
|
||||
(True, 'notify-internal-tasks', 'research-mode-tasks', 'email', 'normal'),
|
||||
(False, 'notify-internal-tasks', 'notify-internal-tasks', 'sms', 'normal'),
|
||||
|
||||
@@ -5,7 +5,7 @@ import pytest
|
||||
from notifications_utils.recipients import InvalidPhoneError
|
||||
|
||||
from app.v2.errors import BadRequestError, TooManyRequestsError
|
||||
from app.celery import QueueNames
|
||||
from app.config import QueueNames
|
||||
from app.service.send_notification import send_one_off_notification
|
||||
from app.models import KEY_TYPE_NORMAL, PRIORITY, SMS_TYPE
|
||||
|
||||
|
||||
166
tests/app/v2/notifications/test_post_letter_notifications.py
Normal file
166
tests/app/v2/notifications/test_post_letter_notifications.py
Normal file
@@ -0,0 +1,166 @@
|
||||
|
||||
import uuid
|
||||
|
||||
from flask import url_for, json
|
||||
import pytest
|
||||
|
||||
from app.models import Job, Notification, SMS_TYPE, EMAIL_TYPE, LETTER_TYPE
|
||||
from app.v2.errors import RateLimitError
|
||||
|
||||
from tests import create_authorization_header
|
||||
from tests.app.db import create_service, create_template
|
||||
|
||||
|
||||
pytestmark = pytest.mark.skip('Leters not currently implemented')
|
||||
|
||||
|
||||
def letter_request(client, data, service_id, _expected_status=201):
|
||||
resp = client.post(
|
||||
url_for('v2_notifications.post_notification', notification_type='letter'),
|
||||
data=json.dumps(data),
|
||||
headers=[('Content-Type', 'application/json'), create_authorization_header(service_id=service_id)]
|
||||
)
|
||||
json_resp = json.loads(resp.get_data(as_text=True))
|
||||
assert resp.status_code == _expected_status, json_resp
|
||||
return json_resp
|
||||
|
||||
|
||||
@pytest.mark.parametrize('reference', [None, 'reference_from_client'])
|
||||
def test_post_letter_notification_returns_201(client, sample_letter_template, mocker, reference):
|
||||
mocked = mocker.patch('app.celery.tasks.build_dvla_file.apply_async')
|
||||
data = {
|
||||
'template_id': str(sample_letter_template.id),
|
||||
'personalisation': {
|
||||
'address_line_1': 'Her Royal Highness Queen Elizabeth II',
|
||||
'address_line_2': 'Buckingham Palace',
|
||||
'address_line_3': 'London',
|
||||
'postcode': 'SW1 1AA',
|
||||
'name': 'Lizzie'
|
||||
}
|
||||
}
|
||||
|
||||
if reference:
|
||||
data.update({'reference': reference})
|
||||
|
||||
resp_json = letter_request(client, data, service_id=sample_letter_template.service_id)
|
||||
|
||||
job = Job.query.one()
|
||||
notification = Notification.query.all()
|
||||
notification_id = notification.id
|
||||
assert resp_json['id'] == str(notification_id)
|
||||
assert resp_json['reference'] == reference
|
||||
assert resp_json['content']['subject'] == sample_letter_template.subject
|
||||
assert resp_json['content']['body'] == sample_letter_template.content
|
||||
assert 'v2/notifications/{}'.format(notification_id) in resp_json['uri']
|
||||
assert resp_json['template']['id'] == str(sample_letter_template.id)
|
||||
assert resp_json['template']['version'] == sample_letter_template.version
|
||||
assert (
|
||||
'services/{}/templates/{}'.format(
|
||||
sample_letter_template.service_id,
|
||||
sample_letter_template.id
|
||||
) in resp_json['template']['uri']
|
||||
)
|
||||
assert not resp_json['scheduled_for']
|
||||
|
||||
mocked.assert_called_once_with((str(job.id), ), queue='job-tasks')
|
||||
|
||||
|
||||
def test_post_letter_notification_returns_400_and_missing_template(
|
||||
client,
|
||||
sample_service
|
||||
):
|
||||
data = {
|
||||
'template_id': str(uuid.uuid4()),
|
||||
'personalisation': {'address_line_1': '', 'postcode': ''}
|
||||
}
|
||||
|
||||
error_json = letter_request(client, data, service_id=sample_service.id, _expected_status=400)
|
||||
|
||||
assert error_json['status_code'] == 400
|
||||
assert error_json['errors'] == [{'error': 'BadRequestError', 'message': 'Template not found'}]
|
||||
|
||||
|
||||
def test_post_notification_returns_403_and_well_formed_auth_error(
|
||||
client,
|
||||
sample_letter_template
|
||||
):
|
||||
data = {
|
||||
'template_id': str(sample_letter_template.id),
|
||||
'personalisation': {'address_line_1': '', 'postcode': ''}
|
||||
}
|
||||
|
||||
error_json = letter_request(client, data, service_id=sample_letter_template.service_id, _expected_status=401)
|
||||
|
||||
assert error_json['status_code'] == 401
|
||||
assert error_json['errors'] == [{
|
||||
'error': 'AuthError',
|
||||
'message': 'Unauthorized, authentication token must be provided'
|
||||
}]
|
||||
|
||||
|
||||
def test_notification_returns_400_for_schema_problems(
|
||||
client,
|
||||
sample_service
|
||||
):
|
||||
data = {
|
||||
'personalisation': {'address_line_1': '', 'postcode': ''}
|
||||
}
|
||||
|
||||
error_json = letter_request(client, data, service_id=sample_service.id, _expected_status=400)
|
||||
|
||||
assert error_json['status_code'] == 400
|
||||
assert error_json['errors'] == [{
|
||||
'error': 'ValidationError',
|
||||
'message': 'template_id is a required property'
|
||||
}]
|
||||
|
||||
|
||||
def test_returns_a_429_limit_exceeded_if_rate_limit_exceeded(
|
||||
client,
|
||||
sample_letter_template,
|
||||
mocker
|
||||
):
|
||||
persist_mock = mocker.patch('app.v2.notifications.post_notifications.persist_notification')
|
||||
mocker.patch(
|
||||
'app.v2.notifications.post_notifications.check_rate_limiting',
|
||||
side_effect=RateLimitError('LIMIT', 'INTERVAL', 'TYPE')
|
||||
)
|
||||
|
||||
data = {
|
||||
'template_id': str(sample_letter_template.id),
|
||||
'personalisation': {'address_line_1': '', 'postcode': ''}
|
||||
}
|
||||
|
||||
error_json = letter_request(client, data, service_id=sample_letter_template.service_id, _expected_status=429)
|
||||
|
||||
assert error_json['status_code'] == 429
|
||||
assert error_json['errors'] == [{
|
||||
'error': 'RateLimitError',
|
||||
'message': 'Exceeded rate limit for key type TYPE of LIMIT requests per INTERVAL seconds'
|
||||
}]
|
||||
|
||||
assert not persist_mock.called
|
||||
|
||||
|
||||
@pytest.mark.parametrize('service_args', [
|
||||
{'service_permissions': [EMAIL_TYPE, SMS_TYPE]},
|
||||
{'restricted': True}
|
||||
])
|
||||
def test_post_letter_notification_returns_403_if_not_allowed_to_send_notification(
|
||||
client,
|
||||
notify_db_session,
|
||||
service_args
|
||||
):
|
||||
service = create_service(**service_args)
|
||||
template = create_template(service, template_type=LETTER_TYPE)
|
||||
|
||||
data = {
|
||||
'template_id': str(template.id),
|
||||
'personalisation': {'address_line_1': '', 'postcode': ''}
|
||||
}
|
||||
|
||||
error_json = letter_request(client, data, service_id=service.id, _expected_status=400)
|
||||
assert error_json['status_code'] == 403
|
||||
assert error_json['errors'] == [
|
||||
{'error': 'BadRequestError', 'message': 'Cannot send letters'}
|
||||
]
|
||||
@@ -58,8 +58,8 @@ def test_post_sms_notification_returns_201(client, sample_template_with_placehol
|
||||
@pytest.mark.parametrize("notification_type, key_send_to, send_to",
|
||||
[("sms", "phone_number", "+447700900855"),
|
||||
("email", "email_address", "sample@email.com")])
|
||||
def test_post_sms_notification_returns_400_and_missing_template(client, sample_service,
|
||||
notification_type, key_send_to, send_to):
|
||||
def test_post_notification_returns_400_and_missing_template(client, sample_service,
|
||||
notification_type, key_send_to, send_to):
|
||||
data = {
|
||||
key_send_to: send_to,
|
||||
'template_id': str(uuid.uuid4())
|
||||
@@ -201,6 +201,7 @@ def test_should_not_persist_or_send_notification_if_simulated_recipient(
|
||||
|
||||
assert response.status_code == 201
|
||||
apply_async.assert_not_called()
|
||||
assert json.loads(response.get_data(as_text=True))["id"]
|
||||
assert Notification.query.count() == 0
|
||||
|
||||
|
||||
@@ -433,3 +434,15 @@ def test_post_notification_raises_bad_request_if_service_not_invited_to_schedule
|
||||
error_json = json.loads(response.get_data(as_text=True))
|
||||
assert error_json['errors'] == [
|
||||
{"error": "BadRequestError", "message": 'Cannot schedule notifications (this feature is invite-only)'}]
|
||||
|
||||
|
||||
def test_post_notification_raises_bad_request_if_not_valid_notification_type(client, sample_service):
|
||||
auth_header = create_authorization_header(service_id=sample_service.id)
|
||||
response = client.post(
|
||||
'/v2/notifications/foo',
|
||||
data='{}',
|
||||
headers=[('Content-Type', 'application/json'), auth_header]
|
||||
)
|
||||
assert response.status_code == 404
|
||||
error_json = json.loads(response.get_data(as_text=True))
|
||||
assert 'The requested URL was not found on the server.' in error_json['message']
|
||||
|
||||
Reference in New Issue
Block a user