From 646075f61f83856efd3110dcc34b3d19156d1b61 Mon Sep 17 00:00:00 2001 From: Chris Hill-Scott Date: Thu, 11 Mar 2021 12:34:22 +0000 Subject: [PATCH] Put some stuff on the page This basically copies the same sections from the existing performance platform page, with the frontend cobbled together from our existing patterns. --- app/main/views/performance.py | 20 +++ app/templates/views/performance.html | 133 ++++++++++++++++++++ tests/app/main/views/test_performance.py | 150 +++++++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 app/templates/views/performance.html create mode 100644 tests/app/main/views/test_performance.py diff --git a/app/main/views/performance.py b/app/main/views/performance.py index 74e3f4835..14e8e3d65 100644 --- a/app/main/views/performance.py +++ b/app/main/views/performance.py @@ -1,4 +1,7 @@ from datetime import datetime, timedelta +from itertools import groupby +from operator import itemgetter +from statistics import mean from flask import render_template @@ -12,6 +15,23 @@ def performance(): start_date=(datetime.utcnow() - timedelta(days=90)).date(), end_date=datetime.utcnow().date(), ) + stats['organisations_using_notify'] = sorted( + [ + { + 'organisation_name': organisation_name, + 'count_of_live_services': len(list(group)), + } + for organisation_name, group in groupby( + stats['services_using_notify'], + itemgetter('organisation_name'), + ) + ], + key=itemgetter('organisation_name'), + ) + stats['average_percentage_under_10_seconds'] = mean([ + row['percentage_under_10_seconds'] + for row in stats['processing_time'] + ] or [0]) return render_template( 'views/performance.html', **stats diff --git a/app/templates/views/performance.html b/app/templates/views/performance.html new file mode 100644 index 000000000..20e70551b --- /dev/null +++ b/app/templates/views/performance.html @@ -0,0 +1,133 @@ +{% extends "withoutnav_template.html" %} +{% from "components/big-number.html" import big_number %} +{% from "components/page-header.html" import page_header %} +{% from "components/table.html" import field, list_table %} + +{% block per_page_title %} + Performance data +{% endblock %} + +{% block maincolumn_content %} + +
+
+ {{ page_header('Performance data') }} +
+
+ +

+ Messages sent since May 2016 +

+ +
+
+

Total messages

+
{{ total_notifications }}
+ total +
+
+
+
+ {{ big_number( + email_notifications, + label=email_notifications|message_count_noun('email'), + smallest=True, + ) }} +
+
+ {{ big_number( + sms_notifications, + label=sms_notifications|message_count_noun('sms'), + smallest=True, + ) }} +
+
+ {{ big_number( + letter_notifications, + label=letter_notifications|message_count_noun('letter'), + smallest=True, + ) }} +
+
+
+
+ +
+ {% call(item, row_number) list_table( + notifications_by_type, + caption_visible=False, + field_headings=[ + 'Date', + 99|message_count_noun('email')|capitalize, + 99|message_count_noun('sms')|capitalize, + 99|message_count_noun('letter')|capitalize, + ], + empty_message='No data to show' + ) %} + {% call field() %} + {{ item.date | format_date_normal }} + {% endcall %} + {% call field() %} + {{ item.emails|format_thousands }} + {% endcall %} + {% call field() %} + {{ item.sms|format_thousands }} + {% endcall %} + {% call field() %} + {{ item.letters|format_thousands }} + {% endcall %} + {% endcall %} +
+ +

+ Messages sent within 10 seconds +

+
+
+

Average

+ {{ big_number( + '{:.1f}%'.format(average_percentage_under_10_seconds), + label='on average', + ) }} +
+
+
+ {% call(item, row_number) list_table( + processing_time | reverse, + caption_visible=False, + field_headings=[ + 'Date', 'Percentage' + ], + empty_message='No data to show' + ) %} + {% call field() %} + {{ item.date | format_date_normal }} + {% endcall %} + {% call field() %} + {{ item.percentage_under_10_seconds }}% + {% endcall %} + {% endcall %} +
+ +

+ Organisations using Notify +

+
+ {% call(item, row_number) list_table( + organisations_using_notify, + caption_visible=False, + field_headings=[ + 'Organisation', 'Number of live services' + ], + empty_message='No data to show' + ) %} + {% call field() %} + {{ item.organisation_name }} + {% endcall %} + {% call field() %} + {{ item.count_of_live_services }} + {% endcall %} + {% endcall %} +
+ +{% endblock %} diff --git a/tests/app/main/views/test_performance.py b/tests/app/main/views/test_performance.py new file mode 100644 index 000000000..c6dc25074 --- /dev/null +++ b/tests/app/main/views/test_performance.py @@ -0,0 +1,150 @@ +import random +import uuid +from datetime import date + +from freezegun import freeze_time + +from tests.conftest import normalize_spaces + + +def _get_example_performance_data(): + return { + "total_notifications": 1_789_000_000, + "email_notifications": 1_123_000_000, + "sms_notifications": 987_654_321, + "letter_notifications": 1_234_567, + "live_service_count": random.randrange(1, 1000), + "notifications_by_type": [ + { + "date": "2021-02-21", + "emails": 1_234_567, "sms": 123_456, "letters": 123, + }, + { + "date": "2021-02-22", + "emails": 1, "sms": 2, "letters": 3, + }, + { + "date": "2021-02-23", + "emails": 1, "sms": 2, "letters": 3, + }, + { + "date": "2021-02-24", + "emails": 1, "sms": 2, "letters": 3, + }, + { + "date": "2021-02-25", + "emails": 1, "sms": 2, "letters": 3, + }, + { + "date": "2021-02-26", + "emails": 1, "sms": 2, "letters": 3, + }, + { + "date": "2021-02-27", + "emails": 1, "sms": 2, "letters": 3, + }, + ], + "processing_time": [ + { + "date": "2021-02-21", + "percentage_under_10_seconds": 99.2 + }, + { + "date": "2021-02-22", + "percentage_under_10_seconds": 95.3 + }, + { + "date": "2021-02-23", + "percentage_under_10_seconds": 95.6 + }, + { + "date": "2021-02-24", + "percentage_under_10_seconds": 96.7 + }, + { + "date": "2021-02-25", + "percentage_under_10_seconds": 95.7 + }, + { + "date": "2021-02-26", + "percentage_under_10_seconds": 96.5 + }, + { + "date": "2021-02-27", + "percentage_under_10_seconds": 98.6 + }, + ], + "services_using_notify": [ + { + "organisation_id": uuid.uuid4(), + "organisation_name": "Department of Examples and Patterns", + "service_id": uuid.uuid4(), + "service_name": "Example service" + }, + { + "organisation_id": uuid.uuid4(), + "organisation_name": "Department of Examples and Patterns", + "service_id": uuid.uuid4(), + "service_name": "Example service 2" + }, + { + "organisation_id": uuid.uuid4(), + "organisation_name": "Department of One Service", + "service_id": uuid.uuid4(), + "service_name": "Example service 3" + }, + ], + } + + +@freeze_time('2021-01-01') +def test_should_render_performance_page( + mocker, + client_request, + mock_get_service_and_organisation_counts, +): + mock_get_performance_data = mocker.patch( + 'app.performance_dashboard_api_client.get_performance_dashboard_stats', + return_value=_get_example_performance_data(), + ) + page = client_request.get('main.performance') + mock_get_performance_data.assert_called_once_with( + start_date=date(2020, 10, 3), + end_date=date(2021, 1, 1), + ) + assert normalize_spaces(page.select_one('main').text) == ( + 'Performance data ' + '' + 'Messages sent since May 2016 ' + 'Total messages ' + '1789000000 total ' + '1,123,000,000 emails ' + '987,654,321 text messages ' + '1,234,567 letters ' + '' + 'Date Emails Text messages Letters ' + '21 February 2021 1,234,567 123,456 123 ' + '22 February 2021 1 2 3 ' + '23 February 2021 1 2 3 ' + '24 February 2021 1 2 3 ' + '25 February 2021 1 2 3 ' + '26 February 2021 1 2 3 ' + '27 February 2021 1 2 3 ' + '' + 'Messages sent within 10 seconds ' + 'Average ' + '96.8% on average ' + 'Date Percentage ' + '27 February 2021 98.6% ' + '26 February 2021 96.5% ' + '25 February 2021 95.7% ' + '24 February 2021 96.7% ' + '23 February 2021 95.6% ' + '22 February 2021 95.3% ' + '21 February 2021 99.2% ' + '' + 'Organisations using Notify ' + 'Organisation Number of live services ' + 'Department of Examples and Patterns 2 ' + 'Department of One Service 1' + )