mirror of
https://github.com/GSA/notifications-api.git
synced 2026-07-12 17:34:48 -04:00
Fixed unit tests
This commit is contained in:
@@ -814,28 +814,31 @@ def get_specific_days_stats(
|
||||
elif days is not None:
|
||||
date_range = list(generate_date_range(start_date, days=days))
|
||||
elif end_date is not None:
|
||||
date_range = list(generate_date_range(start_date, end_date))
|
||||
date_range = list(generate_date_range(start_date, end_date=end_date))
|
||||
else:
|
||||
raise ValueError("Either 'days' or 'end_date' must be set.")
|
||||
|
||||
# Group data by local date
|
||||
grouped_data = {date: [] for date in date_range}
|
||||
# Ensure date_range is in correct format
|
||||
grouped_data = {day.strftime("%Y-%m-%d"): [] for day in date_range}
|
||||
|
||||
for item in data:
|
||||
if not isinstance(item.timestamp, datetime):
|
||||
continue
|
||||
local_datetime = item.timestamp.replace(tzinfo=pytz.utc).astimezone(user_timezone)
|
||||
local_date = local_datetime.date()
|
||||
if local_date in grouped_data:
|
||||
grouped_data[local_date].append(item)
|
||||
|
||||
local_datetime = item.timestamp.astimezone(user_timezone)
|
||||
local_date_str = local_datetime.strftime("%Y-%m-%d")
|
||||
|
||||
if local_date_str in grouped_data:
|
||||
grouped_data[local_date_str].append(item)
|
||||
|
||||
# Build final stats, optionally including total_notifications
|
||||
stats = {}
|
||||
for day in date_range:
|
||||
formatted_day = day.strftime("%Y-%m-%d")
|
||||
day_data = grouped_data[day]
|
||||
day_data = grouped_data.get(formatted_day, []) # Avoid KeyError
|
||||
total_for_day = None
|
||||
if total_notifications and day in total_notifications:
|
||||
total_for_day = total_notifications[day]
|
||||
if total_notifications and formatted_day in total_notifications:
|
||||
total_for_day = total_notifications[formatted_day]
|
||||
|
||||
stats[formatted_day] = statistics.format_statistics(
|
||||
day_data,
|
||||
|
||||
@@ -17,192 +17,144 @@ def generate_expected_output(requested_days, requested_sms_days):
|
||||
StatisticsType.REQUESTED: 1 if day in requested_sms_days else 0,
|
||||
StatisticsType.DELIVERED: 0,
|
||||
StatisticsType.FAILURE: 0,
|
||||
StatisticsType.PENDING: 0,
|
||||
},
|
||||
TemplateType.EMAIL: {
|
||||
StatisticsType.REQUESTED: 0,
|
||||
StatisticsType.DELIVERED: 0,
|
||||
StatisticsType.FAILURE: 0,
|
||||
StatisticsType.PENDING: 0,
|
||||
},
|
||||
}
|
||||
return output
|
||||
|
||||
|
||||
def create_mock_notification(notification_type, status, timestamp, count=1):
|
||||
return Mock(
|
||||
notification_type=notification_type,
|
||||
status=status,
|
||||
timestamp=timestamp,
|
||||
count=count,
|
||||
count=count
|
||||
)
|
||||
|
||||
|
||||
test_cases = [
|
||||
# Case with normal dates that don't carry over
|
||||
# Case with normal dates that don't carry over to next day when converted to UTC
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 29, 1, 20, 18, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 29, 1, 20, 18, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 28, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/New_York",
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"]),
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"])
|
||||
),
|
||||
|
||||
# Case where EST is saved as next day in UTC
|
||||
# Case where EST is saved as next day in UTC, it needs to be converted back to EST after retrieval
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 30, 4, 30, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 30, 4, 30, 0, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 29, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/New_York",
|
||||
generate_expected_output(["2025-01-29", "2025-01-30"], ["2025-01-29"]),
|
||||
generate_expected_output(["2025-01-29", "2025-01-30"], ["2025-01-29"])
|
||||
),
|
||||
|
||||
# UTC query
|
||||
# Case where UTC is queryed
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 29, 10, 15, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 29, 10, 15, 0, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 28, tzinfo=pytz.utc),
|
||||
2,
|
||||
"UTC",
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-29"]),
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-29"])
|
||||
),
|
||||
|
||||
# Central time test
|
||||
# Central time test
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 29, 3, 0, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 29, 3, 0, 0, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 28, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/Chicago",
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"]),
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"])
|
||||
),
|
||||
|
||||
# Mountain time test
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 29, 5, 0, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 29, 5, 0, 0, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 28, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/Denver",
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"]),
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"])
|
||||
),
|
||||
|
||||
# Pacific time test
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 29, 7, 30, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 29, 7, 30, 0, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 28, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/Los_Angeles",
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"]),
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-28"])
|
||||
),
|
||||
|
||||
# No timezone provided => defaults to UTC
|
||||
# Case where no timezone is provided, ensuring it defaults to UTC
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 29, 10, 15, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
[create_mock_notification(TemplateType.SMS, StatisticsType.REQUESTED, datetime(2025, 1, 29, 10, 15, 0, tzinfo=pytz.utc))],
|
||||
datetime(2025, 1, 28, tzinfo=pytz.utc),
|
||||
2,
|
||||
None,
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-29"]),
|
||||
generate_expected_output(["2025-01-28", "2025-01-29"], ["2025-01-29"])
|
||||
),
|
||||
|
||||
# DST Spring Forward
|
||||
# Daylights savings time Spring Forward: March 10, 2024 at 2 AM EST => jumps to 3 AM EST
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2024, 3, 10, 6, 30, 0, tzinfo=pytz.utc),
|
||||
datetime(2024, 3, 10, 6, 30, 0, tzinfo=pytz.utc) # UTC 6:30 AM => 1:30 AM EST (before DST kicks in)
|
||||
)],
|
||||
datetime(2024, 3, 9, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/New_York",
|
||||
generate_expected_output(["2024-03-09", "2024-03-10"], ["2024-03-10"]),
|
||||
generate_expected_output(["2024-03-09", "2024-03-10"], ["2024-03-10"]) # Should map to March 10 EST
|
||||
),
|
||||
|
||||
# DST Fall Back
|
||||
# Fall Back: November 3, 2024 at 2 AM EDT => goes back to 1 AM EST
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2024, 11, 3, 5, 30, 0, tzinfo=pytz.utc),
|
||||
datetime(2024, 11, 3, 5, 30, 0, tzinfo=pytz.utc) # UTC 5:30 AM => 1:30 AM EST after DST ends
|
||||
)],
|
||||
datetime(2024, 11, 2, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/New_York",
|
||||
generate_expected_output(["2024-11-02", "2024-11-03"], ["2024-11-03"]),
|
||||
generate_expected_output(["2024-11-02", "2024-11-03"], ["2024-11-03"])
|
||||
),
|
||||
|
||||
# No notifications
|
||||
# There are no notifications
|
||||
(
|
||||
[],
|
||||
datetime(2025, 1, 29, tzinfo=pytz.utc),
|
||||
2,
|
||||
"UTC",
|
||||
generate_expected_output(["2025-01-29", "2025-01-30"], []),
|
||||
generate_expected_output(["2025-01-29", "2025-01-30"], [])
|
||||
),
|
||||
|
||||
# Midnight edge case => 12:00 AM UTC => 7:00 PM previous day EST
|
||||
# Midnight edge case
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 10, 0, 0, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
datetime(2025, 1, 9, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/New_York",
|
||||
generate_expected_output(["2025-01-09", "2025-01-10"], ["2025-01-09"]),
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 10, 0, 0, 0, tzinfo=pytz.utc) # 12:00 AM UTC => 7:00 PM Jan 9 EST
|
||||
)],
|
||||
datetime(2025, 1, 9, tzinfo=pytz.utc),
|
||||
2,
|
||||
"America/New_York",
|
||||
generate_expected_output(["2025-01-09", "2025-01-10"], ["2025-01-09"]) # Goes back to Jan 9 EST
|
||||
),
|
||||
|
||||
# Large query (30 days)
|
||||
# Large query testing large amounts of data
|
||||
(
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 15, 12, 0, 0, tzinfo=pytz.utc),
|
||||
)],
|
||||
datetime(2025, 1, 1, tzinfo=pytz.utc),
|
||||
30,
|
||||
"America/New_York",
|
||||
generate_expected_output(
|
||||
[f"2025-01-{str(day).zfill(2)}" for day in range(1, 31)],
|
||||
["2025-01-15"],
|
||||
),
|
||||
),
|
||||
[create_mock_notification(
|
||||
TemplateType.SMS,
|
||||
StatisticsType.REQUESTED,
|
||||
datetime(2025, 1, 15, 12, 0, 0, tzinfo=pytz.utc)
|
||||
)],
|
||||
datetime(2025, 1, 1, tzinfo=pytz.utc),
|
||||
30,
|
||||
"America/New_York",
|
||||
generate_expected_output(
|
||||
[f"2025-01-{str(day).zfill(2)}" for day in range(1, 31)],
|
||||
["2025-01-15"]
|
||||
)
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"mocked_notifications, start_date, days, timezone, expected_output",
|
||||
test_cases,
|
||||
)
|
||||
@pytest.mark.parametrize("mocked_notifications, start_date, days, timezone, expected_output", test_cases)
|
||||
def test_get_specific_days(mocked_notifications, start_date, days, timezone, expected_output):
|
||||
results = get_specific_days_stats(
|
||||
mocked_notifications,
|
||||
start_date,
|
||||
days,
|
||||
timezone=timezone,
|
||||
)
|
||||
results = get_specific_days_stats(mocked_notifications, start_date, days, timezone=timezone)
|
||||
assert results == expected_output
|
||||
|
||||
Reference in New Issue
Block a user