Files
notifications-api/tests/app/platform_stats/test_rest.py
Cliff Hill 9fde1f30ea "sms" entries cleaned up.
Signed-off-by: Cliff Hill <Clifford.hill@gsa.gov>
2024-02-28 12:58:17 -05:00

304 lines
9.8 KiB
Python

from datetime import date, datetime
import pytest
from freezegun import freeze_time
from app.enums import KeyType, NotificationStatus, NotificationType, TemplateType
from app.errors import InvalidRequest
from app.platform_stats.rest import validate_date_range_is_within_a_financial_year
from tests.app.db import (
create_ft_billing,
create_ft_notification_status,
create_notification,
create_service,
create_template,
set_up_usage_data,
)
@freeze_time("2018-06-01")
def test_get_platform_stats_uses_todays_date_if_no_start_or_end_date_is_provided(
admin_request, mocker
):
today = datetime.now().date()
dao_mock = mocker.patch(
"app.platform_stats.rest.fetch_notification_status_totals_for_all_services"
)
mocker.patch("app.service.rest.statistics.format_statistics")
admin_request.get("platform_stats.get_platform_stats")
dao_mock.assert_called_once_with(start_date=today, end_date=today)
def test_get_platform_stats_can_filter_by_date(admin_request, mocker):
start_date = date(2017, 1, 1)
end_date = date(2018, 1, 1)
dao_mock = mocker.patch(
"app.platform_stats.rest.fetch_notification_status_totals_for_all_services"
)
mocker.patch("app.service.rest.statistics.format_statistics")
admin_request.get(
"platform_stats.get_platform_stats", start_date=start_date, end_date=end_date
)
dao_mock.assert_called_once_with(start_date=start_date, end_date=end_date)
def test_get_platform_stats_validates_the_date(admin_request):
start_date = "1234-56-78"
response = admin_request.get(
"platform_stats.get_platform_stats", start_date=start_date, _expected_status=400
)
assert response["errors"][0]["message"] == "start_date month must be in 1..12"
@freeze_time("2018-10-31 14:00")
def test_get_platform_stats_with_real_query(admin_request, notify_db_session):
service_1 = create_service(service_name="service_1")
sms_template = create_template(service=service_1, template_type=TemplateType.SMS)
email_template = create_template(
service=service_1,
template_type=TemplateType.EMAIL,
)
create_ft_notification_status(
date(2018, 10, 29), NotificationType.SMS, service_1, count=10
)
create_ft_notification_status(
date(2018, 10, 29), NotificationType.EMAIL, service_1, count=3
)
create_notification(
sms_template,
created_at=datetime(2018, 10, 31, 11, 0, 0),
key_type=KeyType.TEST,
)
create_notification(
sms_template,
created_at=datetime(2018, 10, 31, 12, 0, 0),
status=NotificationStatus.DELIVERED,
)
create_notification(
email_template,
created_at=datetime(2018, 10, 31, 13, 0, 0),
status=NotificationStatus.DELIVERED,
)
response = admin_request.get(
"platform_stats.get_platform_stats",
start_date=date(2018, 10, 29),
)
assert response == {
NotificationType.EMAIL: {
"failures": {
NotificationStatus.VIRUS_SCAN_FAILED: 0,
NotificationStatus.TEMPORARY_FAILURE: 0,
NotificationStatus.PERMANENT_FAILURE: 0,
NotificationStatus.TECHNICAL_FAILURE: 0,
},
"total": 4,
"test-key": 0,
},
NotificationType.SMS: {
"failures": {
NotificationStatus.VIRUS_SCAN_FAILED: 0,
NotificationStatus.TEMPORARY_FAILURE: 0,
NotificationStatus.PERMANENT_FAILURE: 0,
NotificationStatus.TECHNICAL_FAILURE: 0,
},
"total": 11,
"test-key": 1,
},
}
@pytest.mark.parametrize(
"start_date, end_date",
[
("2019-04-01", "2019-06-30"),
("2019-08-01", "2019-09-30"),
("2019-01-01", "2019-03-31"),
],
)
def test_validate_date_range_is_within_a_financial_year(start_date, end_date):
validate_date_range_is_within_a_financial_year(start_date, end_date)
@pytest.mark.parametrize(
"start_date, end_date",
[
("2019-04-01", "2020-06-30"),
("2018-01-01", "2019-04-30"),
("2019-12-01", "2020-04-30"),
],
)
def test_validate_date_range_is_within_a_financial_year_raises(start_date, end_date):
with pytest.raises(expected_exception=InvalidRequest) as e:
validate_date_range_is_within_a_financial_year(start_date, end_date)
assert e.value.message == "Date must be in a single financial year."
assert e.value.status_code == 400
def test_validate_date_is_within_a_financial_year_raises_validation_error():
start_date = "2019-08-01"
end_date = "2019-06-01"
with pytest.raises(expected_exception=InvalidRequest) as e:
validate_date_range_is_within_a_financial_year(start_date, end_date)
assert e.value.message == "Start date must be before end date"
assert e.value.status_code == 400
@pytest.mark.parametrize(
"start_date, end_date", [("22-01-2019", "2019-08-01"), ("2019-07-01", "not-date")]
)
def test_validate_date_is_within_a_financial_year_when_input_is_not_a_date(
start_date, end_date
):
with pytest.raises(expected_exception=InvalidRequest) as e:
validate_date_range_is_within_a_financial_year(start_date, end_date)
assert e.value.message == "Input must be a date in the format: YYYY-MM-DD"
assert e.value.status_code == 400
def test_get_data_for_billing_report(notify_db_session, admin_request):
fixtures = set_up_usage_data(datetime(2019, 5, 1))
response = admin_request.get(
"platform_stats.get_data_for_billing_report",
start_date="2019-05-01",
end_date="2019-06-30",
)
# we set up 4 services, but only 1 returned. service_with_emails was skipped as it had no bills to pay,
# and likewise the service with SMS within allowance was skipped. too.
assert len(response) == 1
assert response[0]["organization_id"] == ""
assert response[0]["service_id"] == str(fixtures["service_with_sms_without_org"].id)
assert response[0]["sms_cost"] == 0.33
assert response[0]["sms_chargeable_units"] == 3
assert response[0]["purchase_order_number"] == "sms purchase order number"
assert response[0]["contact_names"] == "sms billing contact names"
assert (
response[0]["contact_email_addresses"]
== "sms@billing.contact email@addresses.gov.uk"
)
assert response[0]["billing_reference"] == "sms billing reference"
def test_daily_volumes_report(
notify_db_session, sample_template, sample_email_template, admin_request
):
set_up_usage_data(datetime(2022, 3, 1))
response = admin_request.get(
"platform_stats.daily_volumes_report",
start_date="2022-03-01",
end_date="2022-03-31",
)
assert len(response) == 3
assert response[0] == {
"day": "2022-03-01",
"email_totals": 10,
"sms_chargeable_units": 2,
"sms_fragment_totals": 2,
"sms_totals": 1,
}
assert response[1] == {
"day": "2022-03-03",
"email_totals": 0,
"sms_chargeable_units": 2,
"sms_fragment_totals": 2,
"sms_totals": 2,
}
assert response[2] == {
"day": "2022-03-08",
"email_totals": 0,
"sms_chargeable_units": 4,
"sms_fragment_totals": 4,
"sms_totals": 2,
}
def test_volumes_by_service_report(
notify_db_session, sample_template, sample_email_template, admin_request
):
fixture = set_up_usage_data(datetime(2022, 3, 1))
response = admin_request.get(
"platform_stats.volumes_by_service_report",
start_date="2022-03-01",
end_date="2022-03-01",
)
assert len(response) == 5
# since we are using a pre-set up fixture, we only care about some of the results
assert response[0] == {
"email_totals": 0,
"free_allowance": 10,
"organization_id": str(fixture["org_1"].id),
"organization_name": fixture["org_1"].name,
"service_id": str(fixture["service_1_sms_and_letter"].id),
"service_name": fixture["service_1_sms_and_letter"].name,
"sms_chargeable_units": 2,
"sms_notifications": 1,
}
assert response[1] == {
"email_totals": 0,
"free_allowance": 10,
"organization_id": str(fixture["org_1"].id),
"organization_name": fixture["org_1"].name,
"service_id": str(fixture["service_with_out_ft_billing_this_year"].id),
"service_name": fixture["service_with_out_ft_billing_this_year"].name,
"sms_chargeable_units": 0,
"sms_notifications": 0,
}
assert response[3] == {
"email_totals": 0,
"free_allowance": 10,
"organization_id": "",
"organization_name": "",
"service_id": str(fixture["service_with_sms_without_org"].id),
"service_name": fixture["service_with_sms_without_org"].name,
"sms_chargeable_units": 0,
"sms_notifications": 0,
}
assert response[4] == {
"email_totals": 0,
"free_allowance": 10,
"organization_id": "",
"organization_name": "",
"service_id": str(fixture["service_with_sms_within_allowance"].id),
"service_name": fixture["service_with_sms_within_allowance"].name,
"sms_chargeable_units": 0,
"sms_notifications": 0,
}
def test_daily_sms_provider_volumes_report(admin_request, sample_template):
create_ft_billing(
"2022-03-01",
sample_template,
provider="foo",
rate=1.5,
notifications_sent=1,
billable_unit=3,
)
resp = admin_request.get(
"platform_stats.daily_sms_provider_volumes_report",
start_date="2022-03-01",
end_date="2022-03-01",
)
assert len(resp) == 1
assert resp[0] == {
"day": "2022-03-01",
"provider": "foo",
"sms_totals": 1,
"sms_fragment_totals": 3,
"sms_chargeable_units": 3,
"sms_cost": 4.5,
}