Update /platform-stats to return the data from ft_notification_status, that way the request should not time out for a long date range.

Next steps is to update the query for platform admin stats for all services.
This commit is contained in:
Rebecca Law
2018-12-03 13:59:25 +00:00
parent 7ec3dbd667
commit c766febe94
4 changed files with 120 additions and 6 deletions

View File

@@ -138,3 +138,49 @@ def fetch_notification_status_for_service_for_today_and_7_previous_days(service_
all_stats_table.c.notification_type,
all_stats_table.c.status,
).all()
def fetch_notification_status_totals_for_all_services(start_date, end_date):
stats = db.session.query(
FactNotificationStatus.notification_type.label('notification_type'),
FactNotificationStatus.notification_status.label('status'),
FactNotificationStatus.key_type,
func.sum(FactNotificationStatus.notification_count).label('count')
).filter(
FactNotificationStatus.bst_date >= start_date,
FactNotificationStatus.bst_date <= end_date
).group_by(
FactNotificationStatus.notification_type,
FactNotificationStatus.notification_status,
FactNotificationStatus.key_type,
).order_by(
FactNotificationStatus.notification_type
)
today = get_london_midnight_in_utc(datetime.utcnow())
if start_date <= today.date() <= end_date:
stats_for_today = db.session.query(
Notification.notification_type.cast(db.Text).label('notification_type'),
Notification.status,
Notification.key_type,
func.count().label('count')
).filter(
Notification.created_at >= today
).group_by(
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(
all_stats_table.c.notification_type,
all_stats_table.c.status,
func.cast(func.sum(all_stats_table.c.count), Integer).label('count'),
).group_by(
all_stats_table.c.notification_type,
all_stats_table.c.status,
).order_by(
all_stats_table.c.notification_type
)
else:
query = stats
return query.all()

View File

@@ -2,7 +2,7 @@ from datetime import datetime
from flask import Blueprint, jsonify, request
from app.dao.notifications_dao import fetch_aggregate_stats_by_date_range_for_all_services
from app.dao.fact_notification_status_dao import fetch_notification_status_totals_for_all_services
from app.errors import register_errors
from app.platform_stats.platform_stats_schema import platform_stats_request
from app.service.statistics import format_admin_stats
@@ -23,7 +23,7 @@ def get_platform_stats():
start_date = datetime.strptime(request.args.get('start_date', today), '%Y-%m-%d').date()
end_date = datetime.strptime(request.args.get('end_date', today), '%Y-%m-%d').date()
data = fetch_aggregate_stats_by_date_range_for_all_services(start_date=start_date, end_date=end_date)
data = fetch_notification_status_totals_for_all_services(start_date=start_date, end_date=end_date)
stats = format_admin_stats(data)
return jsonify(stats)

View File

@@ -1,14 +1,17 @@
from datetime import timedelta, datetime, date
from uuid import UUID
import pytest
from app.dao.fact_notification_status_dao import (
update_fact_notification_status,
fetch_notification_status_for_day,
fetch_notification_status_for_service_by_month,
fetch_notification_status_for_service_for_day,
fetch_notification_status_for_service_for_today_and_7_previous_days
fetch_notification_status_for_service_for_today_and_7_previous_days,
fetch_notification_status_totals_for_all_services
)
from app.models import FactNotificationStatus, KEY_TYPE_TEST, KEY_TYPE_TEAM, EMAIL_TYPE, SMS_TYPE
from app.models import FactNotificationStatus, KEY_TYPE_TEST, KEY_TYPE_TEAM, EMAIL_TYPE, SMS_TYPE, LETTER_TYPE
from freezegun import freeze_time
from tests.app.db import create_notification, create_service, create_template, create_ft_notification_status
@@ -220,3 +223,68 @@ def test_fetch_notification_status_for_service_for_today_and_7_previous_days(not
assert results[3].notification_type == 'sms'
assert results[3].status == 'delivered'
assert results[3].count == 19
@pytest.mark.parametrize(
"start_date, end_date, expected_email, expected_letters, expected_sms, expected_created_sms",
[
(29, 30, 3, 10, 10, 1), # not including today
(29, 31, 4, 10, 11, 2), # today included
(26, 31, 4, 15, 11, 2),
]
)
@freeze_time('2018-10-31 14:00')
def test_fetch_notification_status_totals_for_all_services(
notify_db_session,
start_date,
end_date,
expected_email,
expected_letters,
expected_sms,
expected_created_sms
):
set_up_data()
results = sorted(
fetch_notification_status_totals_for_all_services(
start_date=date(2018, 10, start_date), end_date=date(2018, 10, end_date)),
key=lambda x: (x.notification_type, x.status)
)
assert len(results) == 4
assert results[0].notification_type == 'email'
assert results[0].status == 'delivered'
assert results[0].count == expected_email
assert results[1].notification_type == 'letter'
assert results[1].status == 'delivered'
assert results[1].count == expected_letters
assert results[2].notification_type == 'sms'
assert results[2].status == 'created'
assert results[2].count == expected_created_sms
assert results[3].notification_type == 'sms'
assert results[3].status == 'delivered'
assert results[3].count == expected_sms
def set_up_data():
service_2 = create_service(service_name='service_2')
create_template(service=service_2, template_type=LETTER_TYPE)
service_1 = create_service(service_name='service_1')
sms_template = create_template(service=service_1, template_type=SMS_TYPE)
email_template = create_template(service=service_1, template_type=EMAIL_TYPE)
create_ft_notification_status(date(2018, 10, 24), 'sms', service_1, count=8)
create_ft_notification_status(date(2018, 10, 26), 'letter', service_1, count=5)
create_ft_notification_status(date(2018, 10, 29), 'sms', service_1, count=10)
create_ft_notification_status(date(2018, 10, 29), 'sms', service_1, notification_status='created')
create_ft_notification_status(date(2018, 10, 29), 'email', service_1, count=3)
create_ft_notification_status(date(2018, 10, 29), 'letter', service_2, count=10)
create_notification(service_1.templates[0], created_at=datetime(2018, 10, 30, 12, 0, 0), status='delivered')
create_notification(sms_template, created_at=datetime(2018, 10, 31, 11, 0, 0))
create_notification(sms_template, created_at=datetime(2018, 10, 31, 12, 0, 0), status='delivered')
create_notification(email_template, created_at=datetime(2018, 10, 31, 13, 0, 0), status='delivered')

View File

@@ -6,7 +6,7 @@ from freezegun import freeze_time
@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_aggregate_stats_by_date_range_for_all_services')
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')
@@ -17,7 +17,7 @@ def test_get_platform_stats_uses_todays_date_if_no_start_or_end_date_is_provided
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_aggregate_stats_by_date_range_for_all_services')
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)