diff --git a/app/main/views/index.py b/app/main/views/index.py index d2b366279f..45ba938491 100644 --- a/app/main/views/index.py +++ b/app/main/views/index.py @@ -281,7 +281,7 @@ def welcome(): @main.route("/activity", endpoint="activity") def activity(): - return render_template("views/activity.html", **get_latest_stats(get_current_locale(current_app))) + return render_template("views/activity.html", **get_latest_stats(get_current_locale(current_app), filter_heartbeats=True)) @main.route("/activity/download", endpoint="activity_download") @@ -386,7 +386,7 @@ def _render_articles_page(response): nav_items=nav_items, slug=slug_en, lang_url=get_lang_url(response, bool(page_id)), - stats=get_latest_stats(get_current_locale(current_app)) if slug_en == "home" else None, + stats=get_latest_stats(get_current_locale(current_app), filter_heartbeats=True) if slug_en == "home" else None, isHome=True if slug_en == "home" else None, ) diff --git a/app/notify_client/service_api_client.py b/app/notify_client/service_api_client.py index 85ea4bb8d7..83a7ea272b 100644 --- a/app/notify_client/service_api_client.py +++ b/app/notify_client/service_api_client.py @@ -59,11 +59,11 @@ def get_services(self, params_dict=None): """ return self.get("/service", params=params_dict) - def get_stats_by_month(self): + def get_stats_by_month(self, filter_heartbeats=False): """ Retrieve notifications stats by month. """ - return self.get("/service/delivered-notifications-stats-by-month-data") + return self.get("/service/delivered-notifications-stats-by-month-data", params={"filter_heartbeats": filter_heartbeats}) def find_services_by_name(self, service_name): return self.get("/service/find-services-by-name", params={"service_name": service_name}) diff --git a/app/utils.py b/app/utils.py index 5994761a6b..4958540f8b 100644 --- a/app/utils.py +++ b/app/utils.py @@ -92,8 +92,8 @@ def from_lambda_api(line): @cache.memoize(timeout=3600) -def get_latest_stats(lang): - results = service_api_client.get_stats_by_month()["data"] +def get_latest_stats(lang, filter_heartbeats=None): + results = service_api_client.get_stats_by_month(filter_heartbeats=filter_heartbeats)["data"] monthly_stats = {} emails_total = 0 @@ -119,7 +119,7 @@ def get_latest_stats(lang): elif notification_type == "email": emails_total += count - live_services = len(service_api_client.get_live_services_data()["data"]) + live_services = len(service_api_client.get_live_services_data({"filter_heartbeats": True})["data"]) return { "monthly_stats": monthly_stats, diff --git a/tests/app/main/views/test_index.py b/tests/app/main/views/test_index.py index 2b7ae35255..62183dad21 100644 --- a/tests/app/main/views/test_index.py +++ b/tests/app/main/views/test_index.py @@ -7,7 +7,7 @@ from app.utils import documentation_url from tests.conftest import a11y_test, normalize_spaces, sample_uuid -service = [ +services = [ { "service_id": 1, "service_name": "jessie the oak tree", @@ -25,12 +25,30 @@ "email_totals": 1200, "letter_totals": 0, "free_sms_fragment_limit": 100, - } + }, + { + "service_id": 2, + "service_name": "jessie the birch tree", + "organisation_name": "Forest", + "consent_to_research": True, + "contact_name": "Forest fairy", + "organisation_type": "Ecosystem", + "contact_email": "forest.fairy@digital.cabinet-office.canada.ca", + "contact_mobile": "+16132532223", + "live_date": "Sat, 29 Mar 2014 00:00:00 GMT", + "sms_volume_intent": 100, + "email_volume_intent": 50, + "letter_volume_intent": 20, + "sms_totals": 300, + "email_totals": 1200, + "letter_totals": 0, + "free_sms_fragment_limit": 100, + }, ] def test_non_logged_in_user_can_see_homepage(mocker, client, mock_calls_out_to_GCA): - mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": service}) + mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": services[0]}) mocker.patch( "app.service_api_client.get_stats_by_month", return_value={"data": [("2020-11-01", "email", 20)]}, @@ -50,7 +68,7 @@ def test_non_logged_in_user_can_see_homepage(mocker, client, mock_calls_out_to_G @pytest.mark.skip(reason="TODO: a11y test") def test_home_page_a11y(mocker, client, mock_calls_out_to_GCA): - mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": service}) + mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": services[0]}) mocker.patch( "app.service_api_client.get_stats_by_month", return_value={"data": [("2020-11-01", "email", 20)]}, @@ -130,15 +148,72 @@ def test_static_pages( assert not page.select_one("meta[name=description]") -def test_activity_page(mocker, client): - mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": service}) +@pytest.mark.parametrize( + "stats, services", + [ + ( + [ # Heartbeat's filtered + ("2020-11-01", "email", 20), + ("2020-11-01", "sms", 20), + ], + [ + services[0], + ], + ), + ( + [ # Heartbeat's not filtered + ("2020-11-01", "email", 170), + ("2020-11-01", "sms", 150), + ], + services, + ), + ], +) +def test_activity_page(mocker, client, stats, services): + mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": services}) mocker.patch( "app.service_api_client.get_stats_by_month", - return_value={"data": [("2020-11-01", "email", 20)]}, + return_value={"data": stats}, ) - response = client.get(url_for("main.activity")) + page = BeautifulSoup(response.data.decode("utf-8"), "html.parser") + assert response.status_code == 200 + assert page.select("div[class~='lg:text-xxl']")[0].text == str(sum(x[2] for x in stats)) + assert page.select("div[class~='lg:text-xxl']")[1].text == str(len(services)) + + +@pytest.mark.parametrize( + "stats, services", + [ + ( + [ # Heartbeat's filtered + ("2020-11-01", "email", 20), + ("2020-11-01", "sms", 20), + ], + [ + services[0], + ], + ), + ( + [ # Heartbeat's not filtered + ("2020-11-01", "email", 170), + ("2020-11-01", "sms", 150), + ], + services, + ), + ], +) +def test_home_page_displays_activity(mocker, client, stats, services): + mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": services}) + mocker.patch( + "app.service_api_client.get_stats_by_month", + return_value={"data": stats}, + ) + response = client.get(url_for("main.index")) + page = BeautifulSoup(response.data.decode("utf-8"), "html.parser") assert response.status_code == 200 + assert page.select("span[class~='xs:text-lg']")[0].text == str(len(services)) + assert page.select("span[class~='xs:text-lg']")[1].text == str(sum(x[2] for x in stats)) @pytest.mark.parametrize( @@ -269,7 +344,7 @@ def test_letter_template_preview_headers( ], ) def test_query_params(client, query_key, query_value, heading, mocker, mock_calls_out_to_GCA): - mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": service}) + mocker.patch("app.service_api_client.get_live_services_data", return_value={"data": services[0]}) mocker.patch( "app.service_api_client.get_stats_by_month", return_value={"data": [("2020-11-01", "email", 20)]}, diff --git a/tests/app/notify_client/test_service_api_client.py b/tests/app/notify_client/test_service_api_client.py index 9596a4cdd8..8103a3615a 100644 --- a/tests/app/notify_client/test_service_api_client.py +++ b/tests/app/notify_client/test_service_api_client.py @@ -59,6 +59,20 @@ def test_client_gets_service_statistics(mocker, today_only, limit_days): ) +@pytest.mark.parametrize("filter_heartbeat", [True, False]) +def test_client_gets_stats_by_month(mocker, filter_heartbeat): + client = ServiceAPIClient() + mock_get = mocker.patch.object(client, "get", return_value={"data": {"a": "b"}}) + + ret = client.get_stats_by_month(filter_heartbeat) + + assert ret["data"] == {"a": "b"} + mock_get.assert_called_once_with( + "/service/delivered-notifications-stats-by-month-data", + params={"filter_heartbeats": filter_heartbeat}, + ) + + def test_client_only_updates_allowed_attributes(mocker): mocker.patch("app.notify_client.current_user", id="1") with pytest.raises(TypeError) as error: