This commit is contained in:
Kenneth Kehl
2023-06-15 09:22:44 -07:00
parent 8db16f9410
commit 95a2db6991
3 changed files with 63 additions and 75 deletions

View File

@@ -23,7 +23,6 @@ from app.models import (
NOTIFICATION_TEMPORARY_FAILURE,
FactNotificationStatus,
Notification,
NotificationAllTimeView,
Service,
Template,
)
@@ -38,6 +37,7 @@ from app.utils import (
def update_fact_notification_status(process_day, notification_type, service_id):
start_date = get_midnight_in_utc(process_day)
end_date = get_midnight_in_utc(process_day + timedelta(days=1))
print(f"fact start {start_date} and end {end_date}")
# delete any existing rows in case some no longer exist e.g. if all messages are sent
FactNotificationStatus.query.filter(
@@ -48,25 +48,25 @@ def update_fact_notification_status(process_day, notification_type, service_id):
query = db.session.query(
literal(process_day).label("process_day"),
NotificationAllTimeView.template_id,
Notification.template_id,
literal(service_id).label("service_id"),
func.coalesce(NotificationAllTimeView.job_id, '00000000-0000-0000-0000-000000000000').label('job_id'),
func.coalesce(Notification.job_id, '00000000-0000-0000-0000-000000000000').label('job_id'),
literal(notification_type).label("notification_type"),
NotificationAllTimeView.key_type,
NotificationAllTimeView.status,
Notification.key_type,
Notification.status,
func.count().label('notification_count')
).filter(
NotificationAllTimeView.created_at >= start_date,
NotificationAllTimeView.created_at < end_date,
NotificationAllTimeView.notification_type == notification_type,
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type.in_((KEY_TYPE_NORMAL, KEY_TYPE_TEAM)),
Notification.created_at >= start_date,
Notification.created_at < end_date,
Notification.notification_type == notification_type,
Notification.service_id == service_id,
Notification.key_type.in_((KEY_TYPE_NORMAL, KEY_TYPE_TEAM)),
).group_by(
NotificationAllTimeView.template_id,
NotificationAllTimeView.template_id,
Notification.template_id,
Notification.template_id,
'job_id',
NotificationAllTimeView.key_type,
NotificationAllTimeView.status
Notification.key_type,
Notification.status
)
db.session.connection().execute(
@@ -108,17 +108,17 @@ def fetch_notification_status_for_service_for_day(fetch_day, service_id):
return db.session.query(
# return current month as a datetime so the data has the same shape as the ft_notification_status query
literal(fetch_day.replace(day=1), type_=DateTime).label('month'),
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status.label('notification_status'),
Notification.notification_type,
Notification.status.label('notification_status'),
func.count().label('count')
).filter(
NotificationAllTimeView.created_at >= get_midnight_in_utc(fetch_day),
NotificationAllTimeView.created_at < get_midnight_in_utc(fetch_day + timedelta(days=1)),
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type != KEY_TYPE_TEST
Notification.created_at >= get_midnight_in_utc(fetch_day),
Notification.created_at < get_midnight_in_utc(fetch_day + timedelta(days=1)),
Notification.service_id == service_id,
Notification.key_type != KEY_TYPE_TEST
).group_by(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status
Notification.notification_type,
Notification.status
).all()
@@ -137,18 +137,18 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days(service_
)
stats_for_today = db.session.query(
NotificationAllTimeView.notification_type.cast(db.Text),
NotificationAllTimeView.status,
*([NotificationAllTimeView.template_id] if by_template else []),
Notification.notification_type.cast(db.Text),
Notification.status,
*([Notification.template_id] if by_template else []),
func.count().label('count')
).filter(
NotificationAllTimeView.created_at >= get_midnight_in_utc(now),
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type != KEY_TYPE_TEST
Notification.created_at >= get_midnight_in_utc(now),
Notification.service_id == service_id,
Notification.key_type != KEY_TYPE_TEST
).group_by(
NotificationAllTimeView.notification_type,
*([NotificationAllTimeView.template_id] if by_template else []),
NotificationAllTimeView.status
Notification.notification_type,
*([Notification.template_id] if by_template else []),
Notification.status
)
all_stats_table = stats_for_7_days.union_all(stats_for_today).subquery()
@@ -193,16 +193,16 @@ def fetch_notification_status_totals_for_all_services(start_date, end_date):
today = get_midnight_in_utc(datetime.utcnow())
if start_date <= datetime.utcnow().date() <= end_date:
stats_for_today = db.session.query(
NotificationAllTimeView.notification_type.cast(db.Text).label('notification_type'),
NotificationAllTimeView.status,
NotificationAllTimeView.key_type,
Notification.notification_type.cast(db.Text).label('notification_type'),
Notification.status,
Notification.key_type,
func.count().label('count')
).filter(
NotificationAllTimeView.created_at >= today
Notification.created_at >= today
).group_by(
NotificationAllTimeView.notification_type.cast(db.Text),
NotificationAllTimeView.status,
NotificationAllTimeView.key_type,
Notification.notification_type.cast(db.Text),
Notification.status,
Notification.key_type,
)
all_stats_table = stats.union_all(stats_for_today).subquery()
query = db.session.query(
@@ -269,19 +269,19 @@ def fetch_stats_for_all_services_by_date_range(start_date, end_date, include_fro
if start_date <= datetime.utcnow().date() <= end_date:
today = get_midnight_in_utc(datetime.utcnow())
subquery = db.session.query(
NotificationAllTimeView.notification_type.cast(db.Text).label('notification_type'),
NotificationAllTimeView.status.label('status'),
NotificationAllTimeView.service_id.label('service_id'),
Notification.notification_type.cast(db.Text).label('notification_type'),
Notification.status.label('status'),
Notification.service_id.label('service_id'),
func.count(Notification.id).label('count')
).filter(
NotificationAllTimeView.created_at >= today
Notification.created_at >= today
).group_by(
NotificationAllTimeView.notification_type,
NotificationAllTimeView.status,
NotificationAllTimeView.service_id
Notification.notification_type,
Notification.status,
Notification.service_id
)
if not include_from_test_key:
subquery = subquery.filter(NotificationAllTimeView.key_type != KEY_TYPE_TEST)
subquery = subquery.filter(Notification.key_type != KEY_TYPE_TEST)
subquery = subquery.subquery()
stats_for_today = db.session.query(
@@ -360,24 +360,24 @@ def fetch_monthly_template_usage_for_service(start_date, end_date, service_id):
if start_date <= datetime.utcnow() <= end_date:
today = get_midnight_in_utc(datetime.utcnow())
month = get_month_from_utc_column(NotificationAllTimeView.created_at)
month = get_month_from_utc_column(Notification.created_at)
stats_for_today = db.session.query(
NotificationAllTimeView.template_id.label('template_id'),
Notification.template_id.label('template_id'),
Template.name.label('name'),
Template.template_type.label('template_type'),
extract('month', month).label('month'),
extract('year', month).label('year'),
func.count().label('count')
).join(
Template, NotificationAllTimeView.template_id == Template.id,
Template, Notification.template_id == Template.id,
).filter(
NotificationAllTimeView.created_at >= today,
NotificationAllTimeView.service_id == service_id,
NotificationAllTimeView.key_type != KEY_TYPE_TEST,
NotificationAllTimeView.status != NOTIFICATION_CANCELLED
Notification.created_at >= today,
Notification.service_id == service_id,
Notification.key_type != KEY_TYPE_TEST,
Notification.status != NOTIFICATION_CANCELLED
).group_by(
NotificationAllTimeView.template_id,
Notification.template_id,
Template.hidden,
Template.name,
Template.template_type,

View File

@@ -1,6 +1,5 @@
from datetime import date, datetime, time, timedelta
from decimal import Decimal
from uuid import UUID
import pytest
from freezegun import freeze_time
@@ -429,13 +428,13 @@ def test_create_nightly_notification_status_for_service_and_day(notify_db_sessio
process_day = datetime.utcnow().date() - timedelta(days=5)
with freeze_time(datetime.combine(process_day, time.max)):
create_notification(template=first_template, status='delivered')
create_notification(template=second_template, status='temporary-failure')
create_notification(template=second_template, status='delivered')
# team API key notifications are included
create_notification(template=second_template, status='sending', key_type=KEY_TYPE_TEAM)
create_notification(template=second_template, status='pending', key_type=KEY_TYPE_TEAM)
# test notifications are ignored
create_notification(template=second_template, status='sending', key_type=KEY_TYPE_TEST)
create_notification(template=second_template, status='pending', key_type=KEY_TYPE_TEST)
# historical notifications are included
create_notification_history(template=second_template, status='delivered')
@@ -455,7 +454,7 @@ def test_create_nightly_notification_status_for_service_and_day(notify_db_sessio
FactNotificationStatus.notification_status,
).all()
assert len(new_fact_data) == 4
assert len(new_fact_data) == 3
email_delivered_row = new_fact_data[0]
assert email_delivered_row.template_id == second_template.id
@@ -469,21 +468,11 @@ def test_create_nightly_notification_status_for_service_and_day(notify_db_sessio
assert email_sending_row.template_id == second_template.id
assert email_sending_row.service_id == second_service.id
assert email_sending_row.notification_type == 'email'
assert email_sending_row.notification_status == 'sending'
assert email_sending_row.notification_status == 'pending'
assert email_sending_row.notification_count == 1
assert email_sending_row.key_type == KEY_TYPE_TEAM
email_failure_row = new_fact_data[2]
assert email_failure_row.local_date == process_day
assert email_failure_row.template_id == second_template.id
assert email_failure_row.service_id == second_service.id
assert email_failure_row.job_id == UUID('00000000-0000-0000-0000-000000000000')
assert email_failure_row.notification_type == 'email'
assert email_failure_row.notification_status == 'temporary-failure'
assert email_failure_row.notification_count == 1
assert email_failure_row.key_type == KEY_TYPE_NORMAL
sms_delivered_row = new_fact_data[3]
sms_delivered_row = new_fact_data[2]
assert sms_delivered_row.template_id == first_template.id
assert sms_delivered_row.service_id == first_service.id
assert sms_delivered_row.notification_type == 'sms'

View File

@@ -321,7 +321,6 @@ def test_fetch_notification_statuses_for_job(sample_template):
@freeze_time('2018-10-31 14:00')
def test_fetch_stats_for_all_services_by_date_range(notify_db_session):
# TODO WHY CHANGE THE NUMBERS
service_1, service_2 = set_up_data()
results = fetch_stats_for_all_services_by_date_range(start_date=date(2018, 10, 29),
end_date=date(2018, 10, 31))
@@ -330,17 +329,17 @@ def test_fetch_stats_for_all_services_by_date_range(notify_db_session):
assert results[0].service_id == service_1.id
assert results[0].notification_type == 'email'
assert results[0].status == 'delivered'
assert results[0].count == 7 # 4
assert results[0].count == 4
assert results[1].service_id == service_1.id
assert results[1].notification_type == 'sms'
assert results[1].status == 'created'
assert results[1].count == 5 # 2
assert results[1].count == 2
assert results[2].service_id == service_1.id
assert results[2].notification_type == 'sms'
assert results[2].status == 'delivered'
assert results[2].count == 14 # 11
assert results[2].count == 11
assert results[3].service_id == service_2.id
assert not results[3].notification_type