From e5b0d568fa1f40c792ca3bb1c26d73915d24e309 Mon Sep 17 00:00:00 2001 From: Leo Hemsted Date: Thu, 28 Jul 2016 15:24:21 +0100 Subject: [PATCH] ensure stats returned for lifespan of service even if they've never sent a notification for realsies --- app/service/rest.py | 6 ++++-- app/service/statistics.py | 6 ++++-- tests/app/service/test_rest.py | 26 ++++++++++++++++++++++++++ tests/app/service/test_statistics.py | 17 ++++++++++++----- 4 files changed, 46 insertions(+), 9 deletions(-) diff --git a/app/service/rest.py b/app/service/rest.py index 94da8b009..f77846b31 100644 --- a/app/service/rest.py +++ b/app/service/rest.py @@ -43,6 +43,7 @@ from app.errors import ( register_errors, InvalidRequest ) +from app.service import statistics service = Blueprint('service', __name__) register_errors(service) @@ -239,8 +240,9 @@ def get_all_notifications_for_service(service_id): @service.route('//notifications/weekly', methods=['GET']) def get_weekly_notification_stats(service_id): service = dao_fetch_service_by_id(service_id) - statistics = dao_fetch_weekly_historical_stats_for_service(service_id, created_at, preceeding_monday) - return jsonify(data=statistics.format_weekly_notification_stats(statistics)) + stats = dao_fetch_weekly_historical_stats_for_service(service_id) + stats = statistics.format_weekly_notification_stats(stats, service.created_at) + return jsonify(data={week.date().isoformat(): statistics for week, statistics in stats.items()}) def get_detailed_service(service_id, today_only=False): diff --git a/app/service/statistics.py b/app/service/statistics.py index 369de4d9a..abcb25740 100644 --- a/app/service/statistics.py +++ b/app/service/statistics.py @@ -16,10 +16,12 @@ def format_statistics(statistics): def format_weekly_notification_stats(statistics, service_created_at): - preceeding_monday = service_created_at - timedelta(days=service_created_at.weekday()) + preceeding_monday = (service_created_at - timedelta(days=service_created_at.weekday())) + # turn a datetime into midnight that day http://stackoverflow.com/a/1937636 + preceeding_monday_midnight = datetime.combine(preceeding_monday.date(), datetime.min.time()) week_dict = { week: _create_zeroed_stats_dicts() - for week in _weeks_for_range(preceeding_monday, datetime.utcnow()) + for week in _weeks_for_range(preceeding_monday_midnight, datetime.utcnow()) } for row in statistics: _update_statuses_from_row(week_dict[row.week_start][row.notification_type], row) diff --git a/tests/app/service/test_rest.py b/tests/app/service/test_rest.py index 9b4c334e2..7b3749cc4 100644 --- a/tests/app/service/test_rest.py +++ b/tests/app/service/test_rest.py @@ -1121,3 +1121,29 @@ def test_get_detailed_service(notify_db, notify_db_session, notify_api, sample_s assert 'statistics' in service.keys() assert set(service['statistics'].keys()) == set(['sms', 'email']) assert service['statistics']['sms'] == stats + + +@freeze_time('2016-07-28') +def test_get_weekly_notification_stats(notify_api, sample_notification): + with notify_api.test_request_context(), notify_api.test_client() as client: + resp = client.get( + '/service/{}/notifications/weekly'.format(sample_notification.service_id), + headers=[create_authorization_header()] + ) + + assert resp.status_code == 200 + data = json.loads(resp.get_data(as_text=True))['data'] + assert data == { + '2016-07-25': { + 'sms': { + 'requested': 1, + 'delivered': 0, + 'failed': 0 + }, + 'email': { + 'requested': 0, + 'delivered': 0, + 'failed': 0 + } + } + } diff --git a/tests/app/service/test_statistics.py b/tests/app/service/test_statistics.py index d2b4fd348..a4d8648e0 100644 --- a/tests/app/service/test_statistics.py +++ b/tests/app/service/test_statistics.py @@ -69,6 +69,10 @@ def test_create_zeroed_stats_dicts(): } +def _stats(requested, delivered, failed): + return {'requested': requested, 'delivered': delivered, 'failed': failed} + + @freeze_time('2016-07-28T12:00:00') @pytest.mark.parametrize('created_at, statistics, expected_results', [ # with no stats and just today, return this week's stats @@ -78,6 +82,13 @@ def test_create_zeroed_stats_dicts(): 'email': _stats(0, 0, 0) } }), + # with a random created time, still create the dict for midnight + (datetime(2016, 7, 28, 12, 13, 14), [], { + datetime(2016, 7, 25, 0, 0, 0): { + 'sms': _stats(0, 0, 0), + 'email': _stats(0, 0, 0) + } + }), # with no stats but a service (datetime(2016, 7, 14), [], { datetime(2016, 7, 11): { @@ -111,7 +122,7 @@ def test_create_zeroed_stats_dicts(): (datetime(2016, 7, 21), [ WeeklyStatsRow('sms', 'created', datetime(2016, 7, 18), 1), WeeklyStatsRow('sms', 'delivered', datetime(2016, 7, 18), 1), - WeeklyStatsRow('sms', 'created', datetime(2016, 7, 18), 1), + WeeklyStatsRow('sms', 'created', datetime(2016, 7, 25), 1), ], { datetime(2016, 7, 18): { 'sms': _stats(2, 1, 0), @@ -125,7 +136,3 @@ def test_create_zeroed_stats_dicts(): ]) def test_format_weekly_notification_stats(statistics, created_at, expected_results): assert format_weekly_notification_stats(statistics, created_at) == expected_results - - -def _stats(requested, delivered, failed): - return {'requested': requested, 'delivered': delivered, 'failed': failed}