import uuid from datetime import date, datetime import pytest from freezegun import freeze_time from app.enums import ( KeyType, NotificationStatus, NotificationType, StatisticsType, TemplateType, ) from app.utils import utc_now from tests.app.db import ( create_ft_notification_status, create_notification, create_service, create_template, ) @freeze_time("2017-11-11 06:00") def test_get_template_usage_by_month_returns_correct_data( admin_request, sample_template ): create_ft_notification_status( local_date=date(2017, 4, 2), template=sample_template, count=3, ) create_notification(sample_template, created_at=utc_now()) resp_json = admin_request.get( "service.get_monthly_template_usage", service_id=sample_template.service_id, year=2017, ) resp_json = resp_json["stats"] assert len(resp_json) == 2 assert resp_json[0]["template_id"] == str(sample_template.id) assert resp_json[0]["name"] == sample_template.name assert resp_json[0]["type"] == sample_template.template_type assert resp_json[0]["month"] == 4 assert resp_json[0]["year"] == 2017 assert resp_json[0]["count"] == 3 assert resp_json[1]["template_id"] == str(sample_template.id) assert resp_json[1]["name"] == sample_template.name assert resp_json[1]["type"] == sample_template.template_type assert resp_json[1]["month"] == 11 assert resp_json[1]["year"] == 2017 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 ): template_one = create_template( sample_service, template_type=TemplateType.SMS, template_name="TEST TEMPLATE", 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_notification(sample_template, created_at=utc_now()) resp_json = admin_request.get( "service.get_monthly_template_usage", service_id=sample_template.service_id, year=2017, ) 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) assert resp_json[0]["name"] == template_one.name assert resp_json[0]["type"] == template_one.template_type assert resp_json[0]["month"] == 4 assert resp_json[0]["year"] == 2017 assert resp_json[0]["count"] == 1 assert resp_json[1]["template_id"] == str(sample_template.id) assert resp_json[1]["name"] == sample_template.name assert resp_json[1]["type"] == sample_template.template_type assert resp_json[1]["month"] == 4 assert resp_json[1]["year"] == 2017 assert resp_json[1]["count"] == 3 assert resp_json[2]["template_id"] == str(sample_template.id) assert resp_json[2]["name"] == sample_template.name assert resp_json[2]["type"] == sample_template.template_type assert resp_json[2]["month"] == 11 assert resp_json[2]["year"] == 2017 assert resp_json[2]["count"] == 1 @pytest.mark.parametrize( "today_only, stats", [ ( False, { StatisticsType.REQUESTED: 2, StatisticsType.DELIVERED: 1, StatisticsType.FAILURE: 0, }, ), ( True, { StatisticsType.REQUESTED: 1, StatisticsType.DELIVERED: 0, StatisticsType.FAILURE: 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), NotificationType.SMS, sample_service, count=1 ) with freeze_time("2000-01-02T12:00:00"): create_notification(sample_template, status=NotificationStatus.CREATED) resp = admin_request.get( "service.get_service_notification_statistics", service_id=sample_template.service_id, today_only=today_only, ) assert set(resp["data"].keys()) == { NotificationType.SMS, NotificationType.EMAIL, } assert resp["data"][NotificationType.SMS] == 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() ) assert resp["data"] == { NotificationType.SMS: { StatisticsType.REQUESTED: 0, StatisticsType.DELIVERED: 0, StatisticsType.FAILURE: 0, }, NotificationType.EMAIL: { StatisticsType.REQUESTED: 0, StatisticsType.DELIVERED: 0, StatisticsType.FAILURE: 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 ): response = admin_request.get( "service.get_monthly_notification_stats", service_id=sample_service.id, _expected_status=400, **kwargs ) assert response == expected_json def test_get_monthly_notification_stats_returns_404_if_no_service(admin_request): response = admin_request.get( "service.get_monthly_notification_stats", service_id=uuid.uuid4(), _expected_status=404, ) assert response == {"message": "No result found", "result": "error"} 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_id=sample_service.id, year=2016, ) assert len(response["data"]) == 12 keys = [ "2016-01", "2016-02", "2016-03", "2016-04", "2016-05", "2016-06", "2016-07", "2016-08", "2016-09", "2016-10", "2016-11", "2016-12", ] assert sorted(response["data"].keys()) == keys for val in response["data"].values(): assert val == {NotificationType.SMS: {}, NotificationType.EMAIL: {}} def test_get_monthly_notification_stats_returns_stats(admin_request, sample_service): sms_t1 = create_template(sample_service) sms_t2 = create_template(sample_service) email_template = create_template(sample_service, template_type=TemplateType.EMAIL) create_notification( sms_t1, created_at=datetime(2016, 6, 1, 1, 1, 0), status=NotificationStatus.DELIVERED, ) create_notification( sms_t1, created_at=datetime(2016, 6, 2, 1, 1, 0), status=NotificationStatus.DELIVERED, ) create_notification( sms_t1, created_at=datetime(2016, 7, 1, 1, 1, 0), status=NotificationStatus.DELIVERED, ) create_notification( sms_t2, created_at=datetime(2016, 7, 1, 1, 1, 0), status=NotificationStatus.DELIVERED, ) create_notification( sms_t1, created_at=datetime(2016, 7, 1, 1, 1, 0), status=NotificationStatus.CREATED, ) create_notification( email_template, created_at=datetime(2016, 7, 1, 1, 1, 0), status=NotificationStatus.DELIVERED, ) response = admin_request.get( "service.get_monthly_notification_stats", service_id=sample_service.id, year=2016, ) assert len(response["data"]) == 12 assert response["data"]["2016-06"] == { NotificationType.SMS: { # it combines the two days NotificationStatus.DELIVERED: 2, StatisticsType.REQUESTED: 2, }, NotificationType.EMAIL: {}, } assert response["data"]["2016-07"] == { # it combines the two template types NotificationType.SMS: { NotificationStatus.CREATED: 1, NotificationStatus.DELIVERED: 2, StatisticsType.REQUESTED: 3, }, NotificationType.EMAIL: { StatisticsType.DELIVERED: 1, StatisticsType.REQUESTED: 1, }, } def test_get_monthly_notification_stats_ignores_test_keys( admin_request, sample_service ): create_template(service=sample_service) create_notification( sample_service.templates[0], created_at=datetime(2016, 6, 1, 1, 1, 0), key_type=KeyType.NORMAL, status=NotificationStatus.DELIVERED, ) create_notification( sample_service.templates[0], created_at=datetime(2016, 6, 2, 1, 1, 0), key_type=KeyType.NORMAL, status=NotificationStatus.DELIVERED, ) create_notification( sample_service.templates[0], created_at=datetime(2016, 6, 1, 1, 1, 0), key_type=KeyType.TEAM, status=NotificationStatus.DELIVERED, ) create_notification( sample_service.templates[0], created_at=datetime(2016, 6, 1, 1, 1, 0), key_type=KeyType.TEST, status=NotificationStatus.DELIVERED, ) response = admin_request.get( "service.get_monthly_notification_stats", service_id=sample_service.id, year=2016, ) assert response["data"]["2016-06"][NotificationType.SMS] == { NotificationStatus.DELIVERED: 3, StatisticsType.REQUESTED: 3, } def test_get_monthly_notification_stats_checks_dates(admin_request, sample_service): t = create_template(sample_service) create_notification( t, created_at=datetime(2016, 4, 2), status=NotificationStatus.SENDING, ) create_notification( t, created_at=datetime(2017, 3, 31), status=NotificationStatus.DELIVERED, ) create_notification( t, created_at=datetime(2017, 4, 11), status=NotificationStatus.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"][NotificationType.SMS] == { NotificationStatus.SENDING: 1, StatisticsType.REQUESTED: 1, } assert response["data"]["2016-04"][NotificationType.SMS] == { NotificationStatus.SENDING: 1, StatisticsType.REQUESTED: 1, } 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_notification( templates[0], created_at=datetime(2016, 6, 1), status=NotificationStatus.CREATED, ) create_notification( templates[1], created_at=datetime(2016, 6, 1), status=NotificationStatus.DELIVERED, ) response = admin_request.get( "service.get_monthly_notification_stats", service_id=services[0].id, year=2016, ) assert response["data"]["2016-06"] == { NotificationType.SMS: { NotificationStatus.CREATED: 1, StatisticsType.REQUESTED: 1, }, NotificationType.EMAIL: {}, }