diff --git a/.ds.baseline b/.ds.baseline index 4fba5f2ce..ac9497189 100644 --- a/.ds.baseline +++ b/.ds.baseline @@ -92,7 +92,7 @@ }, { "path": "detect_secrets.filters.common.is_baseline_file", - "filename": ".secrets.baseline" + "filename": ".ds.baseline" }, { "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies", @@ -239,7 +239,7 @@ "filename": "tests/app/dao/test_services_dao.py", "hashed_secret": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8", "is_verified": false, - "line_number": 261, + "line_number": 265, "is_secret": false } ], @@ -384,5 +384,5 @@ } ] }, - "generated_at": "2024-05-20T15:20:28Z" + "generated_at": "2024-07-10T20:12:22Z" } diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index 550a7ab94..19755edfe 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -692,7 +692,7 @@ def fetch_notification_stats_for_service_by_month_by_user( ) -def get_specific_days_stats(results, start_date, days=None, end_date=None): +def get_specific_days_stats(data, start_date, days=None, end_date=None): if days is not None and end_date is not None: raise ValueError("Only set days OR set end_date, not both.") elif days is not None: @@ -702,14 +702,14 @@ def get_specific_days_stats(results, start_date, days=None, end_date=None): else: raise ValueError("Either days or end_date must be set.") - grouped_results = {date: [] for date in gen_range} | { - day: [row for row in results if row.day.date() == day] - for day in {item.day.date() for item in results} + grouped_data = {date: [] for date in gen_range} | { + day: [row for row in data if row.day.date() == day] + for day in {item.day.date() for item in data} } stats = { day.strftime("%Y-%m-%d"): statistics.format_statistics(rows) - for day, rows in grouped_results.items() + for day, rows in grouped_data.items() } return stats diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 6441f20e0..e590eb5b4 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -1,6 +1,7 @@ import uuid from datetime import datetime, timedelta from unittest import mock +from unittest.mock import Mock import pytest import sqlalchemy @@ -38,6 +39,7 @@ from app.dao.services_dao import ( delete_service_and_all_associated_db_objects, get_live_services_with_organization, get_services_by_partial_name, + get_specific_days_stats, ) from app.dao.users_dao import create_user_code, save_model_user from app.enums import ( @@ -48,6 +50,7 @@ from app.enums import ( OrganizationType, PermissionType, ServicePermissionType, + StatisticsType, TemplateType, ) from app.models import ( @@ -1580,3 +1583,180 @@ def test_get_live_services_with_organization(sample_organization): (live_service.name, sample_organization.name), (service_without_org.name, None), ] + + +_this_date = utc_now() - timedelta(days=4) + + +@pytest.mark.parametrize( + ["data", "start_date", "days", "end_date", "expected", "is_error"], + [ + [None, _this_date, None, None, None, True], + [None, _this_date, 4, _this_date - timedelta(4), None, True], + [ + [ + {"day": _this_date, "something": "else"}, + {"day": _this_date, "something": "new"}, + {"day": _this_date + timedelta(days=1), "something": "borrowed"}, + {"day": _this_date + timedelta(days=2), "something": "old"}, + {"day": _this_date + timedelta(days=4), "something": "blue"}, + ], + _this_date, + 4, + None, + { + _this_date.date().strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 2, + }, + }, + (_this_date.date() + timedelta(days=1)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 1, + }, + }, + (_this_date.date() + timedelta(days=2)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 1, + }, + }, + (_this_date.date() + timedelta(days=3)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + }, + (_this_date.date() + timedelta(days=4)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 1, + }, + }, + }, + False, + ], + [ + [ + {"day": _this_date, "something": "else"}, + {"day": _this_date, "something": "new"}, + {"day": _this_date + timedelta(days=1), "something": "borrowed"}, + {"day": _this_date + timedelta(days=2), "something": "old"}, + {"day": _this_date + timedelta(days=4), "something": "blue"}, + ], + _this_date, + None, + _this_date + timedelta(4), + { + _this_date.date().strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 2, + }, + }, + (_this_date.date() + timedelta(days=1)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 1, + }, + }, + (_this_date.date() + timedelta(days=2)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 1, + }, + }, + (_this_date.date() + timedelta(days=3)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + }, + (_this_date.date() + timedelta(days=4)).strftime("%Y-%m-%d"): { + TemplateType.EMAIL: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 0, + }, + TemplateType.SMS: { + StatisticsType.DELIVERED: 0, + StatisticsType.FAILURE: 0, + StatisticsType.REQUESTED: 1, + }, + }, + }, + False, + ], + ], +) +def test_get_specific_days(data, start_date, days, end_date, expected, is_error): + if is_error: + with pytest.raises(ValueError): + get_specific_days_stats(data, start_date, days, end_date) + else: + new_data = [] + for line in data: + new_line = Mock() + new_line.day = line["day"] + new_line.notification_type = NotificationType.SMS + new_line.count = 1 + new_line.something = line["something"] + new_data.append(new_line) + results = get_specific_days_stats(new_data, start_date, days, end_date) + assert results == expected