2018-02-20 11:22:17 +00:00
|
|
|
|
import copy
|
2017-07-07 15:51:59 +01:00
|
|
|
|
import json
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from datetime import datetime
|
2016-04-05 11:40:13 +01:00
|
|
|
|
|
2016-07-20 14:12:03 +01:00
|
|
|
|
import pytest
|
2024-08-09 14:29:14 -07:00
|
|
|
|
from flask import url_for
|
2016-06-19 09:04:21 +01:00
|
|
|
|
from freezegun import freeze_time
|
2018-04-25 14:12:58 +01:00
|
|
|
|
|
|
|
|
|
|
from app.main.views.dashboard import (
|
2019-01-16 10:54:52 +00:00
|
|
|
|
aggregate_notifications_stats,
|
2018-04-25 14:12:58 +01:00
|
|
|
|
aggregate_status_types,
|
2019-01-16 10:54:52 +00:00
|
|
|
|
aggregate_template_usage,
|
2018-04-25 14:12:58 +01:00
|
|
|
|
format_monthly_stats_to_list,
|
|
|
|
|
|
get_dashboard_totals,
|
|
|
|
|
|
get_tuples_of_financial_years,
|
|
|
|
|
|
)
|
2018-02-20 11:22:17 +00:00
|
|
|
|
from tests import (
|
2023-07-12 12:09:44 -04:00
|
|
|
|
organization_json,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
service_json,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
validate_route_permission,
|
|
|
|
|
|
validate_route_permission_with_client,
|
2016-09-29 18:44:10 +01:00
|
|
|
|
)
|
2017-05-22 17:02:03 +01:00
|
|
|
|
from tests.conftest import (
|
2019-06-20 09:53:21 +01:00
|
|
|
|
ORGANISATION_ID,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
SERVICE_ONE_ID,
|
2019-12-19 16:59:07 +00:00
|
|
|
|
create_active_caseworking_user,
|
|
|
|
|
|
create_active_user_view_permissions,
|
2017-07-04 13:38:08 +01:00
|
|
|
|
normalize_spaces,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
)
|
2015-12-18 10:26:56 +00:00
|
|
|
|
|
2024-01-08 14:53:34 -08:00
|
|
|
|
FAKE_ONE_OFF_NOTIFICATION = {
|
|
|
|
|
|
"links": {},
|
|
|
|
|
|
"notifications": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"api_key": None,
|
|
|
|
|
|
"billable_units": 0,
|
|
|
|
|
|
"carrier": None,
|
|
|
|
|
|
"client_reference": None,
|
|
|
|
|
|
"created_at": "2023-12-14T20:35:55+00:00",
|
|
|
|
|
|
"created_by": {
|
|
|
|
|
|
"email_address": "grsrbsrgsrf@fake.gov",
|
|
|
|
|
|
"id": "de059e0a-42e5-48bb-939e-4f76804ab739",
|
2024-02-12 15:29:26 -08:00
|
|
|
|
"name": "mocked_user",
|
2024-01-08 14:53:34 -08:00
|
|
|
|
},
|
|
|
|
|
|
"document_download_count": None,
|
|
|
|
|
|
"id": "a3442b43-0ba1-4854-9e0a-d2fba1cc9b81",
|
|
|
|
|
|
"international": False,
|
|
|
|
|
|
"job": {
|
|
|
|
|
|
"id": "55b242b5-9f62-4271-aff7-039e9c320578",
|
|
|
|
|
|
"original_file_name": "1127b78e-a4a8-4b70-8f4f-9f4fbf03ece2.csv",
|
|
|
|
|
|
},
|
|
|
|
|
|
"job_row_number": 0,
|
|
|
|
|
|
"key_name": None,
|
|
|
|
|
|
"key_type": "normal",
|
|
|
|
|
|
"normalised_to": "+16615555555",
|
|
|
|
|
|
"notification_type": "sms",
|
|
|
|
|
|
"personalisation": {
|
|
|
|
|
|
"dayofweek": "2",
|
|
|
|
|
|
"favecolor": "3",
|
|
|
|
|
|
"phonenumber": "+16615555555",
|
|
|
|
|
|
},
|
|
|
|
|
|
"phone_prefix": "1",
|
|
|
|
|
|
"provider_response": None,
|
|
|
|
|
|
"rate_multiplier": 1.0,
|
|
|
|
|
|
"reference": None,
|
|
|
|
|
|
"reply_to_text": "development",
|
|
|
|
|
|
"sent_at": None,
|
|
|
|
|
|
"sent_by": None,
|
|
|
|
|
|
"service": "f62d840f-8bcb-4b36-b959-4687e16dd1a1",
|
|
|
|
|
|
"status": "created",
|
|
|
|
|
|
"template": {
|
|
|
|
|
|
"content": "((day of week)) and ((fave color))",
|
|
|
|
|
|
"id": "bd9caa7e-00ee-4c5a-839e-10ae1a7e6f73",
|
2024-02-12 15:29:26 -08:00
|
|
|
|
"name": "Template Testing",
|
2024-01-08 14:53:34 -08:00
|
|
|
|
"redact_personalisation": False,
|
|
|
|
|
|
"subject": None,
|
|
|
|
|
|
"template_type": "sms",
|
|
|
|
|
|
"version": 1,
|
|
|
|
|
|
},
|
|
|
|
|
|
"to": "+16615555555",
|
|
|
|
|
|
"updated_at": None,
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
"page_size": 50,
|
|
|
|
|
|
"total": 1,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-01-26 09:43:41 -08:00
|
|
|
|
MOCK_JOBS = {
|
2024-01-26 11:29:03 -08:00
|
|
|
|
"data": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"archived": False,
|
|
|
|
|
|
"created_at": "2024-01-04T20:43:52+00:00",
|
|
|
|
|
|
"created_by": {
|
|
|
|
|
|
"id": "mocked_user_id",
|
|
|
|
|
|
"name": "mocked_user",
|
|
|
|
|
|
},
|
2024-02-12 15:29:26 -08:00
|
|
|
|
"id": "55b242b5-9f62-4271-aff7-039e9c320578",
|
2024-01-26 11:29:03 -08:00
|
|
|
|
"job_status": "finished",
|
|
|
|
|
|
"notification_count": 1,
|
|
|
|
|
|
"original_file_name": "mocked_file.csv",
|
|
|
|
|
|
"processing_finished": "2024-01-25T23:02:25+00:00",
|
|
|
|
|
|
"processing_started": "2024-01-25T23:02:24+00:00",
|
|
|
|
|
|
"scheduled_for": None,
|
|
|
|
|
|
"service": "21b3ee3d-1cb0-4666-bfa0-9c5ac26d3fe3",
|
|
|
|
|
|
"service_name": {"name": "Mock Texting Service"},
|
|
|
|
|
|
"statistics": [{"count": 1, "status": "sending"}],
|
|
|
|
|
|
"template": "6a456418-498c-4c86-b0cd-9403c14a216c",
|
|
|
|
|
|
"template_name": "Mock Template Name",
|
2024-01-08 14:53:34 -08:00
|
|
|
|
"template_type": "sms",
|
2024-01-26 11:29:03 -08:00
|
|
|
|
"template_version": 3,
|
|
|
|
|
|
"updated_at": "2024-01-25T23:02:25+00:00",
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
2024-01-08 14:53:34 -08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-02-12 15:29:26 -08:00
|
|
|
|
MOCK_JOBS_AND_NOTIFICATIONS = [
|
|
|
|
|
|
{
|
|
|
|
|
|
"created_at": MOCK_JOBS["data"][0]["created_at"],
|
|
|
|
|
|
"created_by": MOCK_JOBS["data"][0]["created_by"],
|
|
|
|
|
|
"download_link": "/services/21b3ee3d-1cb0-4666-bfa0-9c5ac26d3fe3/jobs/463b5ecb-4e32-43e5-aa90-0234d19fceaa.csv",
|
|
|
|
|
|
"job_id": "55b242b5-9f62-4271-aff7-039e9c320578",
|
|
|
|
|
|
"notification_count": MOCK_JOBS["data"][0]["notification_count"],
|
|
|
|
|
|
"notifications": FAKE_ONE_OFF_NOTIFICATION["notifications"],
|
|
|
|
|
|
"time_left": "Data available for 7 days",
|
2024-02-21 07:45:21 -08:00
|
|
|
|
"view_job_link": "/services/21b3ee3d-1cb0-4666-bfa0-9c5ac26d3fe3/jobs/463b5ecb-4e32-43e5-aa90-0234d19fceaa",
|
2024-02-12 15:29:26 -08:00
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
2016-04-06 15:48:04 +01:00
|
|
|
|
stub_template_stats = [
|
|
|
|
|
|
{
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"template_type": "sms",
|
|
|
|
|
|
"template_name": "one",
|
|
|
|
|
|
"template_id": "id-1",
|
|
|
|
|
|
"status": "created",
|
|
|
|
|
|
"count": 50,
|
2024-08-29 17:10:51 -07:00
|
|
|
|
"last_used": "2024-01-25T23:02:25+00:00",
|
|
|
|
|
|
"created_by": "Test user",
|
|
|
|
|
|
"created_by_id": "987654",
|
|
|
|
|
|
"template_folder": "Some_folder",
|
|
|
|
|
|
"template_folder_id": "123456",
|
2016-08-18 15:30:57 +01:00
|
|
|
|
},
|
2016-04-06 15:48:04 +01:00
|
|
|
|
{
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"template_type": "email",
|
|
|
|
|
|
"template_name": "two",
|
|
|
|
|
|
"template_id": "id-2",
|
|
|
|
|
|
"status": "created",
|
|
|
|
|
|
"count": 100,
|
2024-08-29 17:10:51 -07:00
|
|
|
|
"last_used": "2024-01-25T23:02:25+00:00",
|
|
|
|
|
|
"created_by": "Test user",
|
|
|
|
|
|
"created_by_id": "987654",
|
|
|
|
|
|
"template_folder": "Some_folder",
|
|
|
|
|
|
"template_folder_id": "123456",
|
2019-01-16 10:54:52 +00:00
|
|
|
|
},
|
|
|
|
|
|
{
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"template_type": "email",
|
|
|
|
|
|
"template_name": "two",
|
|
|
|
|
|
"template_id": "id-2",
|
|
|
|
|
|
"status": "technical-failure",
|
|
|
|
|
|
"count": 100,
|
2024-08-29 17:10:51 -07:00
|
|
|
|
"last_used": "2024-01-25T23:02:25+00:00",
|
|
|
|
|
|
"created_by": "Test user",
|
|
|
|
|
|
"created_by_id": "987654",
|
|
|
|
|
|
"template_folder": "Some_folder",
|
|
|
|
|
|
"template_folder_id": "123456",
|
2018-03-05 21:54:54 +00:00
|
|
|
|
},
|
2019-01-15 16:44:37 +00:00
|
|
|
|
{
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"template_type": "sms",
|
|
|
|
|
|
"template_name": "one",
|
|
|
|
|
|
"template_id": "id-1",
|
|
|
|
|
|
"status": "delivered",
|
|
|
|
|
|
"count": 50,
|
2024-08-29 17:10:51 -07:00
|
|
|
|
"last_used": "2024-01-25T23:02:25+00:00",
|
|
|
|
|
|
"created_by": "Test user",
|
|
|
|
|
|
"created_by_id": "987654",
|
|
|
|
|
|
"template_folder": "Some_folder",
|
|
|
|
|
|
"template_folder_id": "123456",
|
2019-01-15 16:44:37 +00:00
|
|
|
|
},
|
2016-04-06 15:48:04 +01:00
|
|
|
|
]
|
|
|
|
|
|
|
2024-08-09 14:29:14 -07:00
|
|
|
|
date_range = {"start_date": "2024-01-01", "days": 7}
|
|
|
|
|
|
|
|
|
|
|
|
mock_daily_stats = {
|
|
|
|
|
|
date_range["start_date"]: {
|
|
|
|
|
|
"email": {"delivered": 0, "failure": 0, "requested": 0},
|
|
|
|
|
|
"sms": {"delivered": 0, "failure": 1, "requested": 1},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mock_daily_stats_by_user = {
|
|
|
|
|
|
date_range["start_date"]: {
|
|
|
|
|
|
"email": {"delivered": 1, "failure": 0, "requested": 1},
|
|
|
|
|
|
"sms": {"delivered": 1, "failure": 0, "requested": 1},
|
|
|
|
|
|
},
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2016-04-06 15:48:04 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"user",
|
2023-09-15 09:48:35 -04:00
|
|
|
|
[
|
2023-08-25 09:12:23 -07:00
|
|
|
|
create_active_user_view_permissions(),
|
|
|
|
|
|
create_active_caseworking_user(),
|
2023-09-15 09:48:35 -04:00
|
|
|
|
],
|
2023-08-25 09:12:23 -07:00
|
|
|
|
)
|
2018-02-14 10:38:00 +00:00
|
|
|
|
def test_redirect_from_old_dashboard(
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request,
|
2018-06-14 11:39:06 +01:00
|
|
|
|
user,
|
|
|
|
|
|
mocker,
|
2018-02-14 10:38:00 +00:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch("app.user_api_client.get_user", return_value=user)
|
|
|
|
|
|
expected_location = "/services/{}".format(SERVICE_ONE_ID)
|
2018-02-14 10:38:00 +00:00
|
|
|
|
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request.get_url(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"/services/{}/dashboard".format(SERVICE_ONE_ID),
|
2021-12-31 12:08:14 +00:00
|
|
|
|
_expected_redirect=expected_location,
|
|
|
|
|
|
)
|
2018-02-14 10:38:00 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert expected_location == url_for(
|
|
|
|
|
|
"main.service_dashboard", service_id=SERVICE_ONE_ID
|
|
|
|
|
|
)
|
2018-02-14 10:38:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
2018-06-14 11:39:06 +01:00
|
|
|
|
def test_redirect_caseworkers_to_templates(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
active_caseworking_user,
|
|
|
|
|
|
):
|
2023-01-19 17:29:21 -05:00
|
|
|
|
client_request.login(active_caseworking_user)
|
2018-06-14 11:39:06 +01:00
|
|
|
|
client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2018-06-14 11:39:06 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
_expected_status=302,
|
|
|
|
|
|
_expected_redirect=url_for(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.choose_template",
|
2018-06-14 11:39:06 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
),
|
2018-06-14 11:39:06 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-07-04 13:04:25 +01:00
|
|
|
|
def test_get_started(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2016-07-04 13:04:25 +01:00
|
|
|
|
):
|
2017-10-18 14:51:26 +01:00
|
|
|
|
mocker.patch(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"app.template_statistics_client.get_template_statistics_for_service",
|
|
|
|
|
|
return_value=copy.deepcopy(stub_template_stats),
|
2017-10-18 14:51:26 +01:00
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2016-07-04 13:04:25 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mock_get_service_templates_when_no_templates_exist.assert_called_once_with(
|
|
|
|
|
|
SERVICE_ONE_ID
|
|
|
|
|
|
)
|
|
|
|
|
|
assert "Get started" in page.text
|
2016-07-04 13:04:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_started_is_hidden_once_templates_exist(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2016-07-04 13:04:25 +01:00
|
|
|
|
):
|
2017-10-18 14:51:26 +01:00
|
|
|
|
mocker.patch(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"app.template_statistics_client.get_template_statistics_for_service",
|
|
|
|
|
|
return_value=copy.deepcopy(stub_template_stats),
|
2017-10-18 14:51:26 +01:00
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2016-07-04 13:04:25 +01:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
mock_get_service_templates.assert_called_once_with(SERVICE_ONE_ID)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert not page.find("h2", string="Get started")
|
2016-07-04 13:04:25 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-06-05 14:48:24 +01:00
|
|
|
|
def test_inbound_messages_not_visible_to_service_without_permissions(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mocker,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
mock_get_template_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = []
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2017-06-05 14:48:24 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert not page.select(".big-number-meta-wrapper")
|
2017-06-05 14:48:24 +01:00
|
|
|
|
assert mock_get_inbound_sms_summary.called is False
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-01-06 15:29:21 +00:00
|
|
|
|
def test_inbound_messages_shows_count_of_messages_when_there_are_messages(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mocker,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
service_one,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
|
|
|
|
|
mock_get_jobs,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_scheduled_job_stats,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mock_get_template_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-01-06 15:29:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["inbound_sms"]
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2020-01-06 15:29:21 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2020-01-06 15:29:21 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2024-01-26 11:16:45 -08:00
|
|
|
|
mock_get_jobs.assert_called_with(SERVICE_ONE_ID)
|
|
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
banner = page.select("a.banner-dashboard")[1]
|
|
|
|
|
|
assert (
|
|
|
|
|
|
normalize_spaces(banner.text)
|
|
|
|
|
|
== "9,999 text messages received latest message just now"
|
2020-01-06 15:29:21 +00:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert banner["href"] == url_for("main.inbox", service_id=SERVICE_ONE_ID)
|
2020-01-06 15:29:21 +00:00
|
|
|
|
|
2017-05-22 17:02:03 +01:00
|
|
|
|
|
2020-01-06 15:29:21 +00:00
|
|
|
|
def test_inbound_messages_shows_count_of_messages_when_there_are_no_messages(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
|
|
|
|
|
mock_get_jobs,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_scheduled_job_stats,
|
2020-01-06 15:29:21 +00:00
|
|
|
|
mock_get_service_statistics,
|
|
|
|
|
|
mock_get_template_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2020-01-06 15:29:21 +00:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_inbound_sms_summary_with_no_messages,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["inbound_sms"]
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2024-01-26 11:16:45 -08:00
|
|
|
|
mock_get_jobs.assert_called_with(SERVICE_ONE_ID)
|
|
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
banner = page.select("a.banner-dashboard")[1]
|
|
|
|
|
|
assert normalize_spaces(banner.text) == "0 text messages received"
|
|
|
|
|
|
assert banner["href"] == url_for("main.inbox", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2023-09-15 09:48:35 -04:00
|
|
|
|
("index", "expected_row"),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
enumerate(
|
|
|
|
|
|
[
|
|
|
|
|
|
"(202) 867-5300 message-1 1 hour ago",
|
|
|
|
|
|
"(202) 867-5300 message-2 1 hour ago",
|
|
|
|
|
|
"(202) 867-5300 message-3 1 hour ago",
|
|
|
|
|
|
"(202) 867-5302 message-4 3 hours ago",
|
2024-04-11 15:39:50 -07:00
|
|
|
|
"+33(0)1 12345678 message-5 5 hours ago",
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"(202) 555-0104 message-6 7 hours ago",
|
|
|
|
|
|
"(202) 555-0104 message-7 9 hours ago",
|
|
|
|
|
|
]
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2017-05-22 17:02:03 +01:00
|
|
|
|
def test_inbox_showing_inbound_messages(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
service_one,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mock_get_template_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2018-04-04 15:57:31 +01:00
|
|
|
|
mock_get_most_recent_inbound_sms,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
index,
|
|
|
|
|
|
expected_row,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["inbound_sms"]
|
2017-06-05 14:48:24 +01:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.inbox",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2017-05-22 17:02:03 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
rows = page.select("tbody tr")
|
2018-04-04 15:39:50 +01:00
|
|
|
|
assert len(rows) == 8
|
2017-05-22 17:02:03 +01:00
|
|
|
|
assert normalize_spaces(rows[index].text) == expected_row
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert page.select_one("a[download]")["href"] == url_for(
|
|
|
|
|
|
"main.inbox_download",
|
2017-10-17 11:41:12 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2017-05-22 17:02:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-03-21 15:08:03 +00:00
|
|
|
|
def test_get_inbound_sms_shows_page_links(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2018-03-21 15:08:03 +00:00
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2018-03-21 15:08:03 +00:00
|
|
|
|
mock_get_template_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2018-04-04 15:57:31 +01:00
|
|
|
|
mock_get_most_recent_inbound_sms,
|
2018-03-21 15:08:03 +00:00
|
|
|
|
mock_get_inbound_number_for_service,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["inbound_sms"]
|
2018-03-21 15:08:03 +00:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.inbox",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
page=2,
|
|
|
|
|
|
)
|
2018-03-21 15:08:03 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "Next page" in page.find("li", {"class": "next-page"}).text
|
|
|
|
|
|
assert "Previous page" in page.find("li", {"class": "previous-page"}).text
|
2018-03-21 15:08:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-05-22 17:02:03 +01:00
|
|
|
|
def test_empty_inbox(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
service_one,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
mock_get_template_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2018-04-04 15:57:31 +01:00
|
|
|
|
mock_get_most_recent_inbound_sms_with_no_messages,
|
2017-08-24 13:57:12 +01:00
|
|
|
|
mock_get_inbound_number_for_service,
|
2017-05-22 17:02:03 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["inbound_sms"]
|
2017-06-05 14:48:24 +01:00
|
|
|
|
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.inbox",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2017-05-22 17:02:03 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert normalize_spaces(page.select("tbody tr")) == (
|
|
|
|
|
|
"When users text your service’s phone number (2028675301) you’ll see the messages here"
|
2017-05-22 17:02:03 +01:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert not page.select("a[download]")
|
|
|
|
|
|
assert not page.select("li.next-page")
|
|
|
|
|
|
assert not page.select("li.previous-page")
|
2017-05-22 17:02:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"endpoint",
|
|
|
|
|
|
[
|
|
|
|
|
|
"main.inbox",
|
|
|
|
|
|
"main.inbox_updates",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-06-05 14:48:24 +01:00
|
|
|
|
def test_inbox_not_accessible_to_service_without_permissions(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
service_one,
|
2017-07-12 14:39:50 +01:00
|
|
|
|
endpoint,
|
2017-06-05 14:48:24 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = []
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.get(
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
_expected_status=403,
|
|
|
|
|
|
)
|
2017-06-05 14:48:24 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-07-07 15:58:40 +01:00
|
|
|
|
def test_anyone_can_see_inbox(
|
2022-01-04 18:33:23 +00:00
|
|
|
|
client_request,
|
2017-07-07 15:58:40 +01:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mocker,
|
2018-04-04 15:57:31 +01:00
|
|
|
|
mock_get_most_recent_inbound_sms_with_no_messages,
|
2017-08-24 13:57:12 +01:00
|
|
|
|
mock_get_inbound_number_for_service,
|
2017-07-07 15:58:40 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["inbound_sms"]
|
2017-07-07 15:58:40 +01:00
|
|
|
|
|
|
|
|
|
|
validate_route_permission_with_client(
|
|
|
|
|
|
mocker,
|
2022-01-04 18:33:23 +00:00
|
|
|
|
client_request,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"GET",
|
2017-07-07 15:58:40 +01:00
|
|
|
|
200,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
url_for("main.inbox", service_id=service_one["id"]),
|
|
|
|
|
|
["view_activity"],
|
2017-07-07 15:58:40 +01:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-07-07 15:51:59 +01:00
|
|
|
|
def test_view_inbox_updates(
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request,
|
2017-07-07 15:51:59 +01:00
|
|
|
|
service_one,
|
|
|
|
|
|
mocker,
|
2018-04-04 15:57:31 +01:00
|
|
|
|
mock_get_most_recent_inbound_sms_with_no_messages,
|
2017-07-07 15:51:59 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] += ["inbound_sms"]
|
2017-07-07 15:51:59 +01:00
|
|
|
|
|
|
|
|
|
|
mock_get_partials = mocker.patch(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"app.main.views.dashboard.get_inbox_partials",
|
|
|
|
|
|
return_value={"messages": "foo"},
|
2017-07-07 15:51:59 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2021-12-31 12:08:14 +00:00
|
|
|
|
response = client_request.get_response(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.inbox_updates",
|
|
|
|
|
|
service_id=SERVICE_ONE_ID,
|
2021-12-31 12:08:14 +00:00
|
|
|
|
)
|
2017-07-07 15:51:59 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert json.loads(response.get_data(as_text=True)) == {"messages": "foo"}
|
2017-07-07 15:51:59 +01:00
|
|
|
|
|
|
|
|
|
|
mock_get_partials.assert_called_once_with(SERVICE_ONE_ID)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-11-16 12:24:27 -08:00
|
|
|
|
@freeze_time("2016-07-01 16:00")
|
2017-10-17 11:41:12 +01:00
|
|
|
|
def test_download_inbox(
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request,
|
2017-10-17 11:41:12 +01:00
|
|
|
|
mock_get_inbound_sms,
|
|
|
|
|
|
):
|
2021-12-31 12:08:14 +00:00
|
|
|
|
response = client_request.get_response(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.inbox_download",
|
2021-12-31 12:08:14 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
2017-10-17 11:41:12 +01:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert response.headers["Content-Type"] == ("text/csv; " "charset=utf-8")
|
|
|
|
|
|
assert response.headers["Content-Disposition"] == (
|
2024-03-18 15:10:26 -07:00
|
|
|
|
"inline; " 'filename="Received text messages 07-01-2016.csv"'
|
2017-10-17 11:41:12 +01:00
|
|
|
|
)
|
|
|
|
|
|
assert response.get_data(as_text=True) == (
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"Phone number,Message,Received\r\n"
|
2024-08-23 12:59:00 -07:00
|
|
|
|
"(202) 867-5300,message-1,07-01-2016 11:00 America/New_York\r\n"
|
|
|
|
|
|
"(202) 867-5300,message-2,07-01-2016 10:59 America/New_York\r\n"
|
|
|
|
|
|
"(202) 867-5300,message-3,07-01-2016 10:59 America/New_York\r\n"
|
|
|
|
|
|
"(202) 867-5302,message-4,07-01-2016 08:59 America/New_York\r\n"
|
|
|
|
|
|
"+33(0)1 12345678,message-5,07-01-2016 06:59 America/New_York\r\n"
|
|
|
|
|
|
"(202) 555-0104,message-6,07-01-2016 04:59 America/New_York\r\n"
|
|
|
|
|
|
"(202) 555-0104,message-7,07-01-2016 02:59 America/New_York\r\n"
|
|
|
|
|
|
"+68212345,message-8,07-01-2016 02:59 America/New_York\r\n"
|
2017-10-17 11:41:12 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@freeze_time("2016-07-01 13:00")
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
2023-09-15 09:48:35 -04:00
|
|
|
|
("message_content", "expected_cell"),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
[
|
|
|
|
|
|
("=2+5", "2+5"),
|
|
|
|
|
|
("==2+5", "2+5"),
|
|
|
|
|
|
("-2+5", "2+5"),
|
|
|
|
|
|
("+2+5", "2+5"),
|
|
|
|
|
|
("@2+5", "2+5"),
|
|
|
|
|
|
("looks safe,=2+5", '"looks safe,=2+5"'),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-10-17 11:41:12 +01:00
|
|
|
|
def test_download_inbox_strips_formulae(
|
|
|
|
|
|
mocker,
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request,
|
2017-10-17 11:41:12 +01:00
|
|
|
|
fake_uuid,
|
|
|
|
|
|
message_content,
|
|
|
|
|
|
expected_cell,
|
|
|
|
|
|
):
|
|
|
|
|
|
mocker.patch(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"app.service_api_client.get_inbound_sms",
|
2018-03-21 15:08:03 +00:00
|
|
|
|
return_value={
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"has_next": False,
|
|
|
|
|
|
"data": [
|
|
|
|
|
|
{
|
|
|
|
|
|
"user_number": "elevenchars",
|
|
|
|
|
|
"notify_number": "foo",
|
|
|
|
|
|
"content": message_content,
|
|
|
|
|
|
"created_at": datetime.utcnow().isoformat(),
|
|
|
|
|
|
"id": fake_uuid,
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
2018-03-21 15:08:03 +00:00
|
|
|
|
},
|
2017-10-17 11:41:12 +01:00
|
|
|
|
)
|
2021-12-31 12:16:12 +00:00
|
|
|
|
response = client_request.get_response(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.inbox_download",
|
2021-12-31 12:08:14 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
2017-10-17 11:41:12 +01:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert expected_cell in response.get_data(as_text=True).split("\r\n")[1]
|
2017-10-17 11:41:12 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_show_recent_templates_on_dashboard(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mock_template_stats = mocker.patch(
|
|
|
|
|
|
"app.template_statistics_client.get_template_statistics_for_service",
|
|
|
|
|
|
return_value=copy.deepcopy(stub_template_stats),
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2016-01-06 16:51:35 +00:00
|
|
|
|
|
2017-02-03 12:07:21 +00:00
|
|
|
|
mock_template_stats.assert_called_once_with(SERVICE_ONE_ID, limit_days=7)
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
headers = [
|
|
|
|
|
|
header.text.strip() for header in page.find_all("h2") + page.find_all("h1")
|
|
|
|
|
|
]
|
2024-08-14 16:11:00 -04:00
|
|
|
|
assert "Total messages" in headers
|
2016-05-11 15:05:40 +01:00
|
|
|
|
|
2025-01-20 14:34:11 -08:00
|
|
|
|
table_rows = page.find_all("tbody")[1].find_all("tr")
|
|
|
|
|
|
assert len(table_rows) == 2
|
2016-04-20 14:09:38 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"stats",
|
2023-09-15 09:48:35 -04:00
|
|
|
|
[
|
2023-08-25 09:12:23 -07:00
|
|
|
|
pytest.param(
|
|
|
|
|
|
[stub_template_stats[0]],
|
|
|
|
|
|
),
|
|
|
|
|
|
pytest.param(
|
|
|
|
|
|
[stub_template_stats[0], stub_template_stats[1]],
|
2024-07-04 13:07:35 -04:00
|
|
|
|
# marks=pytest.mark.xfail(raises=AssertionError),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
),
|
2023-09-15 09:48:35 -04:00
|
|
|
|
],
|
2023-08-25 09:12:23 -07:00
|
|
|
|
)
|
2019-10-25 15:52:22 +01:00
|
|
|
|
def test_should_not_show_recent_templates_on_dashboard_if_only_one_template_used(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2019-10-25 15:52:22 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2019-10-25 15:52:22 +01:00
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
stats,
|
|
|
|
|
|
):
|
|
|
|
|
|
mock_template_stats = mocker.patch(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"app.template_statistics_client.get_template_statistics_for_service",
|
2019-10-25 15:52:22 +01:00
|
|
|
|
return_value=stats,
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
main = page.select_one("main").text
|
2019-10-25 15:52:22 +01:00
|
|
|
|
|
|
|
|
|
|
mock_template_stats.assert_called_once_with(SERVICE_ONE_ID, limit_days=7)
|
|
|
|
|
|
|
2024-07-11 12:59:14 -04:00
|
|
|
|
assert (
|
|
|
|
|
|
stats[0]["template_name"] == "one"
|
|
|
|
|
|
), f"Expected template_name to be 'one', but got {stats[0]['template_name']}"
|
2024-07-04 13:07:35 -04:00
|
|
|
|
|
|
|
|
|
|
# Check that "one" is not in the main content
|
2024-07-11 12:59:14 -04:00
|
|
|
|
assert (
|
|
|
|
|
|
stats[0]["template_name"] in main
|
|
|
|
|
|
), f"Expected 'one' to not be in main, but it was found in: {main}"
|
2019-10-25 15:52:22 +01:00
|
|
|
|
|
|
|
|
|
|
# count appears as total, but not per template
|
2023-08-25 09:12:23 -07:00
|
|
|
|
expected_count = stats[0]["count"]
|
2024-07-04 13:07:35 -04:00
|
|
|
|
assert expected_count == 50, f"Expected count to be 50, but got {expected_count}"
|
2019-10-25 15:52:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-11-24 15:20:40 +00:00
|
|
|
|
@freeze_time("2016-07-01 12:00") # 4 months into 2016 financial year
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"extra_args",
|
|
|
|
|
|
[
|
|
|
|
|
|
{},
|
|
|
|
|
|
{"year": "2016"},
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-11-24 15:20:40 +00:00
|
|
|
|
def test_should_show_redirect_from_template_history(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
|
|
|
|
|
extra_args,
|
2017-11-24 15:20:40 +00:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.template_history",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
_expected_status=301,
|
|
|
|
|
|
**extra_args,
|
2017-11-24 15:20:40 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-03-27 10:10:56 -06:00
|
|
|
|
@freeze_time("2017-01-01 12:00")
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"extra_args",
|
|
|
|
|
|
[
|
|
|
|
|
|
{},
|
2024-02-07 09:38:18 -07:00
|
|
|
|
{"year": "2017"},
|
2023-08-25 09:12:23 -07:00
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-02-16 15:08:16 +00:00
|
|
|
|
def test_should_show_monthly_breakdown_of_template_usage(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-11-24 15:20:40 +00:00
|
|
|
|
mock_get_monthly_template_usage,
|
2019-03-26 12:35:32 +00:00
|
|
|
|
extra_args,
|
2016-04-20 14:09:38 +01:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.template_usage", service_id=SERVICE_ONE_ID, **extra_args
|
2017-02-16 15:08:16 +00:00
|
|
|
|
)
|
2016-04-20 14:09:38 +01:00
|
|
|
|
|
2024-02-07 09:38:18 -07:00
|
|
|
|
mock_get_monthly_template_usage.assert_called_once_with(SERVICE_ONE_ID, 2017)
|
2016-04-20 14:09:38 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
table_rows = page.select("tbody tr")
|
2016-04-20 14:09:38 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert " ".join(table_rows[0].text.split()) == (
|
|
|
|
|
|
"My first template " "Text message template " "2"
|
2017-02-16 15:08:16 +00:00
|
|
|
|
)
|
2016-04-20 14:09:38 +01:00
|
|
|
|
|
2024-02-07 09:38:18 -07:00
|
|
|
|
assert len(table_rows) == len(["January"])
|
2024-03-27 10:10:56 -06:00
|
|
|
|
# October is the only month with data, thus it's not in the list.
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert len(page.select(".table-no-data")) == len(
|
2024-02-07 09:38:18 -07:00
|
|
|
|
[
|
|
|
|
|
|
"January",
|
|
|
|
|
|
"February",
|
|
|
|
|
|
"March",
|
|
|
|
|
|
"April",
|
|
|
|
|
|
"May",
|
|
|
|
|
|
"June",
|
|
|
|
|
|
"July",
|
|
|
|
|
|
"August",
|
|
|
|
|
|
"September",
|
|
|
|
|
|
"November",
|
2024-03-27 10:10:56 -06:00
|
|
|
|
"December",
|
2024-02-07 09:38:18 -07:00
|
|
|
|
]
|
2023-08-25 09:12:23 -07:00
|
|
|
|
)
|
2016-04-06 15:06:02 +01:00
|
|
|
|
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
2017-07-07 15:58:40 +01:00
|
|
|
|
def test_anyone_can_see_monthly_breakdown(
|
2022-01-04 18:33:23 +00:00
|
|
|
|
client_request,
|
2017-07-07 15:58:40 +01:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_monthly_notification_stats,
|
|
|
|
|
|
):
|
|
|
|
|
|
validate_route_permission_with_client(
|
|
|
|
|
|
mocker,
|
2022-01-04 18:33:23 +00:00
|
|
|
|
client_request,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"GET",
|
2017-07-07 15:58:40 +01:00
|
|
|
|
200,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
url_for("main.monthly", service_id=service_one["id"]),
|
|
|
|
|
|
["view_activity"],
|
2017-07-07 15:58:40 +01:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"endpoint",
|
|
|
|
|
|
[
|
|
|
|
|
|
"main.monthly",
|
|
|
|
|
|
"main.template_usage",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2018-04-03 18:13:38 +01:00
|
|
|
|
@freeze_time("2015-01-01 15:15:15.000000")
|
|
|
|
|
|
def test_stats_pages_show_last_3_years(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
mock_get_monthly_notification_stats,
|
|
|
|
|
|
mock_get_monthly_template_usage,
|
|
|
|
|
|
):
|
|
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
endpoint,
|
|
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert normalize_spaces(page.select_one(".pill").text) == (
|
2024-02-07 09:38:18 -07:00
|
|
|
|
"2015 to 2016 fiscal year "
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"2014 to 2015 fiscal year "
|
2024-02-07 09:38:18 -07:00
|
|
|
|
"2013 to 2014 fiscal year"
|
2018-04-03 18:13:38 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-01-11 14:47:40 +00:00
|
|
|
|
def test_monthly_has_equal_length_tables(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_monthly_notification_stats,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.monthly", service_id=service_one["id"])
|
2018-01-11 14:47:40 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert page.select_one(".table-field-headings th").get("width") == "33%"
|
2018-01-11 14:47:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
2023-11-16 12:24:27 -08:00
|
|
|
|
@freeze_time("2016-01-01 11:09:00.061258")
|
2016-08-09 10:39:57 +01:00
|
|
|
|
def test_should_show_upcoming_jobs_on_dashboard(
|
2024-01-08 14:53:34 -08:00
|
|
|
|
mocker,
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2016-08-09 10:39:57 +01:00
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2016-08-09 10:39:57 +01:00
|
|
|
|
mock_get_jobs,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_scheduled_job_stats,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2016-08-09 10:39:57 +01:00
|
|
|
|
):
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2022-09-09 17:02:48 -07:00
|
|
|
|
|
2024-01-26 11:16:45 -08:00
|
|
|
|
mock_get_jobs.assert_called_with(SERVICE_ONE_ID)
|
|
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_scheduled_job_stats.assert_called_once_with(SERVICE_ONE_ID)
|
2016-10-05 17:45:04 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert normalize_spaces(page.select_one("main h2").text) == ("In the next few days")
|
2016-08-09 10:39:57 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert normalize_spaces(page.select_one("a.banner-dashboard").text) == (
|
2024-08-23 12:59:00 -07:00
|
|
|
|
"2 files waiting to send " "- sending starts today at 06:09 America/New_York"
|
2020-02-20 11:38:43 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert page.select_one("a.banner-dashboard")["href"] == url_for(
|
|
|
|
|
|
"main.uploads", service_id=SERVICE_ONE_ID
|
2020-02-20 11:38:43 +00:00
|
|
|
|
)
|
2016-08-09 10:39:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
2020-09-28 14:28:23 +01:00
|
|
|
|
def test_should_not_show_upcoming_jobs_on_dashboard_if_count_is_0(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_statistics,
|
|
|
|
|
|
mock_has_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.job_api_client.get_scheduled_job_stats",
|
|
|
|
|
|
return_value={
|
|
|
|
|
|
"count": 0,
|
|
|
|
|
|
"soonest_scheduled_for": None,
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2020-09-28 14:28:23 +01:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2020-09-28 14:28:23 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_has_jobs.assert_called_once_with(SERVICE_ONE_ID)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "In the next few days" not in page.select_one("main").text
|
|
|
|
|
|
assert "files waiting to send " not in page.select_one("main").text
|
2020-09-28 14:28:23 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_should_not_show_upcoming_jobs_on_dashboard_if_service_has_no_jobs(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_statistics,
|
|
|
|
|
|
mock_has_no_jobs,
|
2020-10-06 11:53:00 +01:00
|
|
|
|
mock_get_scheduled_job_stats,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2020-09-28 14:28:23 +01:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2020-09-28 14:28:23 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_has_no_jobs.assert_called_once_with(SERVICE_ONE_ID)
|
2020-10-06 11:53:00 +01:00
|
|
|
|
assert mock_get_scheduled_job_stats.called is False
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "In the next few days" not in page.select_one("main").text
|
|
|
|
|
|
assert "files waiting to send " not in page.select_one("main").text
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-09-15 09:48:35 -04:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"permissions",
|
|
|
|
|
|
[
|
|
|
|
|
|
("email", "sms"),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"totals",
|
|
|
|
|
|
[
|
|
|
|
|
|
(
|
|
|
|
|
|
{
|
|
|
|
|
|
"email": {"requested": 0, "delivered": 0, "failed": 0},
|
|
|
|
|
|
"sms": {"requested": 99999, "delivered": 0, "failed": 0},
|
|
|
|
|
|
},
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
{
|
|
|
|
|
|
"email": {"requested": 0, "delivered": 0, "failed": 0},
|
|
|
|
|
|
"sms": {"requested": 0, "delivered": 0, "failed": 0},
|
|
|
|
|
|
},
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-11-09 17:17:50 +00:00
|
|
|
|
def test_correct_font_size_for_big_numbers(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2017-11-09 17:17:50 +00:00
|
|
|
|
service_one,
|
|
|
|
|
|
permissions,
|
|
|
|
|
|
totals,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = permissions
|
2017-11-09 17:17:50 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch("app.main.views.dashboard.get_dashboard_totals", return_value=totals)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-07-30 10:45:53 -04:00
|
|
|
|
# mocker.patch(
|
|
|
|
|
|
# "app.notification_api_client.get_notifications_for_service",
|
|
|
|
|
|
# return_value=FAKE_ONE_OFF_NOTIFICATION,
|
|
|
|
|
|
# page = client_request.get(
|
|
|
|
|
|
# "main.service_dashboard",
|
|
|
|
|
|
# service_id=service_one["id"],
|
|
|
|
|
|
# )
|
|
|
|
|
|
|
|
|
|
|
|
# assert (
|
|
|
|
|
|
# (len(page.select_one("[data-key=totals]").select(".grid-col-12")))
|
|
|
|
|
|
# == (
|
|
|
|
|
|
# # len(page.select_one('[data-key=usage]').select('.grid-col-6'))
|
|
|
|
|
|
# # ) == (
|
|
|
|
|
|
# len(page.select(".big-number-with-status .big-number-smaller"))
|
|
|
|
|
|
# )
|
|
|
|
|
|
# == 1
|
|
|
|
|
|
# )
|
2017-11-09 17:17:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2020-02-24 18:06:22 +00:00
|
|
|
|
def test_should_not_show_jobs_on_dashboard_for_users_with_uploads_page(
|
2024-01-08 14:53:34 -08:00
|
|
|
|
mocker,
|
2020-02-24 18:06:22 +00:00
|
|
|
|
client_request,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_statistics,
|
|
|
|
|
|
mock_get_jobs,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_get_scheduled_job_stats,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2020-02-24 18:06:22 +00:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
):
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2020-02-24 18:06:22 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.service_dashboard",
|
2020-02-24 18:06:22 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2024-01-26 11:16:45 -08:00
|
|
|
|
mock_get_jobs.assert_called_with(SERVICE_ONE_ID)
|
|
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2020-02-24 18:06:22 +00:00
|
|
|
|
for filename in {
|
|
|
|
|
|
"export 1/1/2016.xls",
|
|
|
|
|
|
"all email addresses.xlsx",
|
|
|
|
|
|
"applicants.ods",
|
|
|
|
|
|
"thisisatest.csv",
|
|
|
|
|
|
}:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert filename not in page.select_one("main").text
|
2020-02-24 18:06:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-25 15:59:06 +00:00
|
|
|
|
@freeze_time("2012-03-31 12:12:12")
|
2016-09-29 18:44:10 +01:00
|
|
|
|
def test_usage_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_monthly_usage_for_service,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_monthly_notification_stats,
|
2016-09-29 18:44:10 +01:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.usage",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
2016-09-29 18:44:10 +01:00
|
|
|
|
|
2024-02-07 09:38:18 -07:00
|
|
|
|
mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2012)
|
|
|
|
|
|
mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2012)
|
|
|
|
|
|
mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID)
|
2016-09-29 18:44:10 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
nav = page.find("ul", {"class": "pill"})
|
|
|
|
|
|
unselected_nav_links = nav.select("a:not(.pill-item--selected)")
|
|
|
|
|
|
assert (
|
|
|
|
|
|
normalize_spaces(nav.find("a", {"aria-current": "page"}).text)
|
2024-02-07 09:38:18 -07:00
|
|
|
|
== "2012 to 2013 fiscal year"
|
2023-08-25 09:12:23 -07:00
|
|
|
|
)
|
2024-02-07 09:38:18 -07:00
|
|
|
|
assert normalize_spaces(unselected_nav_links[0].text) == "2011 to 2012 fiscal year"
|
|
|
|
|
|
assert normalize_spaces(unselected_nav_links[1].text) == "2010 to 2011 fiscal year"
|
2022-04-26 15:26:08 +01:00
|
|
|
|
|
2023-10-02 15:12:36 -04:00
|
|
|
|
annual_usage = page.find_all("div", {"class": "keyline-block"})
|
2022-04-26 15:26:08 +01:00
|
|
|
|
|
|
|
|
|
|
# annual stats are shown in two rows, each with three column; email is col 1
|
2022-12-02 10:30:37 -05:00
|
|
|
|
# email_column = normalize_spaces(annual_usage[0].text + annual_usage[2].text)
|
|
|
|
|
|
# assert 'Emails' in email_column
|
|
|
|
|
|
# assert '1,000 sent' in email_column
|
2022-04-26 15:26:08 +01:00
|
|
|
|
|
2023-07-28 11:03:37 -04:00
|
|
|
|
sms_column = normalize_spaces(annual_usage[0].text)
|
2023-10-02 15:12:36 -04:00
|
|
|
|
assert (
|
2024-01-25 14:55:17 -05:00
|
|
|
|
"You have sent 251,800 text message parts of your 250,000 free message parts allowance."
|
|
|
|
|
|
" You have 0 message parts remaining." in sms_column
|
2023-10-02 15:12:36 -04:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "$29.85 spent" not in sms_column
|
2023-10-02 15:12:36 -04:00
|
|
|
|
assert "1,500 at 1.65 pence" not in sms_column
|
|
|
|
|
|
assert "300 at 1.70 pence" not in sms_column
|
2022-04-26 15:26:08 +01:00
|
|
|
|
|
2022-10-17 13:42:36 +00:00
|
|
|
|
|
2022-04-26 17:37:34 +01:00
|
|
|
|
@freeze_time("2012-03-31 12:12:12")
|
|
|
|
|
|
def test_usage_page_no_sms_spend(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_monthly_usage_for_service,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_monthly_notification_stats,
|
2022-04-26 17:37:34 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.billing_api_client.get_annual_usage_for_service",
|
|
|
|
|
|
return_value=[
|
|
|
|
|
|
{
|
|
|
|
|
|
"notification_type": "sms",
|
|
|
|
|
|
"chargeable_units": 1000,
|
|
|
|
|
|
"charged_units": 0,
|
|
|
|
|
|
"rate": 0.0165,
|
|
|
|
|
|
"cost": 0,
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2022-04-26 17:37:34 +01:00
|
|
|
|
|
|
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.usage",
|
2022-04-26 17:37:34 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2023-10-02 15:12:36 -04:00
|
|
|
|
annual_usage = page.find_all("div", {"class": "keyline-block"})
|
2023-07-28 11:03:37 -04:00
|
|
|
|
sms_column = normalize_spaces(annual_usage[0].text)
|
2023-10-02 15:12:36 -04:00
|
|
|
|
assert (
|
2024-01-25 14:55:17 -05:00
|
|
|
|
"You have sent 1,000 text message parts of your 250,000 free message parts allowance."
|
|
|
|
|
|
" You have 249,000 message parts remaining." in sms_column
|
2023-10-02 15:12:36 -04:00
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "$0.00 spent" not in sms_column
|
|
|
|
|
|
assert "pence per message" not in sms_column
|
2022-04-26 17:37:34 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-12-20 16:28:40 +00:00
|
|
|
|
@freeze_time("2012-03-31 12:12:12")
|
2022-04-26 15:19:24 +01:00
|
|
|
|
def test_usage_page_monthly_breakdown(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2017-12-20 16:28:40 +00:00
|
|
|
|
service_one,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_monthly_usage_for_service,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
mock_get_monthly_notification_stats,
|
2017-12-20 16:28:40 +00:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.usage", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
monthly_breakdown = normalize_spaces(page.find("table").text)
|
2022-04-26 15:19:24 +01:00
|
|
|
|
|
2024-02-07 09:38:18 -07:00
|
|
|
|
assert "January" in monthly_breakdown
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "October" in monthly_breakdown
|
|
|
|
|
|
assert "February" in monthly_breakdown
|
|
|
|
|
|
assert "March" in monthly_breakdown
|
2022-04-29 17:48:01 +01:00
|
|
|
|
|
2018-10-03 11:18:46 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
2023-09-15 09:48:35 -04:00
|
|
|
|
("now", "expected_number_of_months"),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
[
|
2024-02-07 09:38:18 -07:00
|
|
|
|
(freeze_time("2017-03-31 11:09:00.061258"), 12),
|
|
|
|
|
|
(freeze_time("2017-01-01 11:09:00.061258"), 12),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
],
|
2022-05-03 15:24:13 +01:00
|
|
|
|
)
|
|
|
|
|
|
def test_usage_page_monthly_breakdown_shows_months_so_far(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_monthly_usage_for_service,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_monthly_notification_stats,
|
2022-05-03 15:24:13 +01:00
|
|
|
|
now,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
expected_number_of_months,
|
2022-05-03 15:24:13 +01:00
|
|
|
|
):
|
|
|
|
|
|
with now:
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.usage", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
rows = page.find("table").find_all("tr", class_="table-row")
|
2022-05-03 15:24:13 +01:00
|
|
|
|
assert len(rows) == expected_number_of_months
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-04-20 10:49:59 +01:00
|
|
|
|
def test_usage_page_with_0_free_allowance(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_monthly_usage_for_service,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_monthly_notification_stats,
|
2022-04-20 10:49:59 +01:00
|
|
|
|
):
|
|
|
|
|
|
mocker.patch(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"app.billing_api_client.get_free_sms_fragment_limit_for_year",
|
2022-04-26 15:23:01 +01:00
|
|
|
|
return_value=0,
|
2022-04-20 10:49:59 +01:00
|
|
|
|
)
|
|
|
|
|
|
page = client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.usage",
|
2022-04-20 10:49:59 +01:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
year=2020,
|
|
|
|
|
|
)
|
2022-04-26 17:37:34 +01:00
|
|
|
|
|
2023-10-02 15:12:36 -04:00
|
|
|
|
annual_usage = page.select("main .grid-col-12 .keyline-block")
|
2022-12-02 10:30:37 -05:00
|
|
|
|
sms_column = normalize_spaces(annual_usage[0].text)
|
2022-04-26 17:37:34 +01:00
|
|
|
|
|
2023-10-02 15:12:36 -04:00
|
|
|
|
assert (
|
2024-01-25 14:55:17 -05:00
|
|
|
|
"You have sent 251,800 text message parts of your 0 free message parts allowance. You have"
|
2023-10-02 15:12:36 -04:00
|
|
|
|
in sms_column
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "free allowance remaining" not in sms_column
|
2022-04-20 10:49:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-25 15:59:06 +00:00
|
|
|
|
def test_usage_page_with_year_argument(
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_monthly_usage_for_service,
|
2017-10-31 11:22:57 +00:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_monthly_notification_stats,
|
2017-01-25 15:59:06 +00:00
|
|
|
|
):
|
2021-12-31 12:08:14 +00:00
|
|
|
|
client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.usage",
|
2021-12-31 12:08:14 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
year=2000,
|
|
|
|
|
|
)
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_monthly_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2000)
|
|
|
|
|
|
mock_get_annual_usage_for_service.assert_called_once_with(SERVICE_ONE_ID, 2000)
|
2024-02-07 09:38:18 -07:00
|
|
|
|
mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID)
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_monthly_notification_stats.assert_called_with(SERVICE_ONE_ID, 2000)
|
2017-01-25 15:59:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-09-29 18:44:10 +01:00
|
|
|
|
def test_usage_page_for_invalid_year(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2016-09-29 18:44:10 +01:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.usage",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
year="abcd",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
_expected_status=404,
|
|
|
|
|
|
)
|
2016-09-29 18:44:10 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
@freeze_time("2012-03-31 12:12:12")
|
2017-05-02 14:10:56 +01:00
|
|
|
|
def test_future_usage_page(
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service_in_future,
|
|
|
|
|
|
mock_get_monthly_usage_for_service_in_future,
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mock_get_monthly_notification_stats,
|
2017-05-02 14:10:56 +01:00
|
|
|
|
):
|
2019-03-26 12:35:32 +00:00
|
|
|
|
client_request.get(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"main.usage",
|
2019-03-26 12:35:32 +00:00
|
|
|
|
service_id=SERVICE_ONE_ID,
|
|
|
|
|
|
year=2014,
|
|
|
|
|
|
)
|
2017-05-02 14:10:56 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mock_get_monthly_usage_for_service_in_future.assert_called_once_with(
|
|
|
|
|
|
SERVICE_ONE_ID, 2014
|
|
|
|
|
|
)
|
|
|
|
|
|
mock_get_annual_usage_for_service_in_future.assert_called_once_with(
|
|
|
|
|
|
SERVICE_ONE_ID, 2014
|
|
|
|
|
|
)
|
2024-02-07 09:38:18 -07:00
|
|
|
|
mock_get_free_sms_fragment_limit.assert_called_with(SERVICE_ONE_ID)
|
2022-12-02 11:27:41 -05:00
|
|
|
|
mock_get_monthly_notification_stats.assert_called_with(SERVICE_ONE_ID, 2014)
|
2017-05-02 14:10:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
2022-01-04 10:56:25 +00:00
|
|
|
|
def _test_dashboard_menu(client_request, mocker, usr, service, permissions):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
usr["permissions"][str(service["id"])] = permissions
|
|
|
|
|
|
usr["services"] = [service["id"]]
|
|
|
|
|
|
mocker.patch("app.user_api_client.check_verify_code", return_value=(True, ""))
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_services", return_value={"data": [service]}
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch("app.user_api_client.get_user", return_value=usr)
|
|
|
|
|
|
mocker.patch("app.user_api_client.get_user_by_email", return_value=usr)
|
|
|
|
|
|
mocker.patch("app.service_api_client.get_service", return_value={"data": service})
|
2022-01-04 10:56:25 +00:00
|
|
|
|
client_request.login(usr)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return client_request.get("main.service_dashboard", service_id=service["id"])
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2024-01-05 12:07:20 -05:00
|
|
|
|
def _test_settings_menu(client_request, mocker, usr, service, permissions):
|
|
|
|
|
|
usr["permissions"][str(service["id"])] = permissions
|
|
|
|
|
|
usr["services"] = [service["id"]]
|
|
|
|
|
|
mocker.patch("app.user_api_client.check_verify_code", return_value=(True, ""))
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_services", return_value={"data": [service]}
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch("app.user_api_client.get_user", return_value=usr)
|
|
|
|
|
|
mocker.patch("app.user_api_client.get_user_by_email", return_value=usr)
|
|
|
|
|
|
mocker.patch("app.service_api_client.get_service", return_value={"data": service})
|
|
|
|
|
|
client_request.login(usr)
|
|
|
|
|
|
return client_request.get("main.service_dashboard", service_id=service["id"])
|
|
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_menu_send_messages(
|
2022-01-04 10:56:25 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
2021-05-12 14:57:21 +01:00
|
|
|
|
notify_admin,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2017-11-09 13:18:09 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = ["email", "sms"]
|
2019-08-09 08:44:11 +01:00
|
|
|
|
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = _test_dashboard_menu(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
2024-07-16 13:01:12 -07:00
|
|
|
|
["view_activity", "send_texts", "send_emails", "manage_service"],
|
2022-01-04 10:56:25 +00:00
|
|
|
|
)
|
|
|
|
|
|
page = str(page)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
"main.choose_template",
|
|
|
|
|
|
service_id=service_one["id"],
|
|
|
|
|
|
)
|
|
|
|
|
|
in page
|
|
|
|
|
|
)
|
2024-01-04 15:23:01 -05:00
|
|
|
|
assert url_for("main.manage_users", service_id=service_one["id"]) not in page
|
|
|
|
|
|
assert url_for("main.service_settings", service_id=service_one["id"]) in page
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_menu_manage_service(
|
2022-01-04 10:56:25 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2017-11-09 13:18:09 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = _test_dashboard_menu(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
["view_activity", "manage_templates", "manage_users", "manage_settings"],
|
|
|
|
|
|
)
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = str(page)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
"main.choose_template",
|
|
|
|
|
|
service_id=service_one["id"],
|
|
|
|
|
|
)
|
|
|
|
|
|
in page
|
|
|
|
|
|
)
|
2024-01-05 12:07:20 -05:00
|
|
|
|
assert url_for(".service_dashboard", service_id=service_one["id"]) in page
|
|
|
|
|
|
assert url_for(".choose_template", service_id=service_one["id"]) in page
|
|
|
|
|
|
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
2024-01-05 12:07:20 -05:00
|
|
|
|
def test_menu_main_settings(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_has_no_jobs,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_statistics,
|
|
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2024-01-05 12:07:20 -05:00
|
|
|
|
page = _test_settings_menu(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
["view_activity", "user_profile", "manage_users", "manage_settings"],
|
|
|
|
|
|
)
|
|
|
|
|
|
page = str(page)
|
|
|
|
|
|
assert (
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
"main.service_settings",
|
|
|
|
|
|
service_id=service_one["id"],
|
|
|
|
|
|
)
|
|
|
|
|
|
in page
|
|
|
|
|
|
)
|
|
|
|
|
|
assert url_for("main.service_settings", service_id=service_one["id"]) in page
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_menu_manage_api_keys(
|
2022-01-04 10:56:25 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2017-11-09 13:18:09 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = _test_dashboard_menu(
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
2024-08-29 12:24:44 -07:00
|
|
|
|
["view_activity"],
|
2023-08-25 09:12:23 -07:00
|
|
|
|
)
|
2018-01-25 15:29:05 +00:00
|
|
|
|
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = str(page)
|
2016-03-09 12:10:50 +00:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
url_for(
|
|
|
|
|
|
"main.choose_template",
|
|
|
|
|
|
service_id=service_one["id"],
|
|
|
|
|
|
)
|
|
|
|
|
|
in page
|
|
|
|
|
|
)
|
2016-03-17 10:46:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_menu_all_services_for_platform_admin_user(
|
2022-01-04 10:56:25 +00:00
|
|
|
|
client_request,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mocker,
|
|
|
|
|
|
platform_admin_user,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2017-11-09 13:18:09 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = _test_dashboard_menu(
|
2023-08-25 09:12:23 -07:00
|
|
|
|
client_request, mocker, platform_admin_user, service_one, []
|
|
|
|
|
|
)
|
2022-01-04 10:56:25 +00:00
|
|
|
|
page = str(page)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert url_for("main.choose_template", service_id=service_one["id"]) in page
|
2024-07-31 11:34:19 -04:00
|
|
|
|
assert url_for("main.service_settings", service_id=service_one["id"]) in page
|
2024-08-02 14:50:52 -04:00
|
|
|
|
assert url_for("main.api_keys", service_id=service_one["id"]) not in page
|
2016-04-12 14:19:51 +01:00
|
|
|
|
|
2016-03-23 12:15:57 +00:00
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_route_for_service_permissions(
|
|
|
|
|
|
mocker,
|
2021-05-12 14:57:21 +01:00
|
|
|
|
notify_admin,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
api_user_active,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service,
|
|
|
|
|
|
mock_get_user,
|
|
|
|
|
|
mock_get_service_templates,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_template_statistics,
|
2018-05-09 13:53:02 +01:00
|
|
|
|
mock_get_service_statistics,
|
2024-02-07 14:43:39 -07:00
|
|
|
|
mock_get_monthly_usage_for_service,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2024-02-07 14:43:39 -07:00
|
|
|
|
mock_create_or_update_free_sms_fragment_limit,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2020-02-12 14:19:21 +00:00
|
|
|
|
mock_get_inbound_sms_summary,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2021-05-12 14:57:21 +01:00
|
|
|
|
with notify_admin.test_request_context():
|
2023-10-27 11:08:12 -06:00
|
|
|
|
|
|
|
|
|
|
def _get(mocker):
|
|
|
|
|
|
return {"count": 0}
|
|
|
|
|
|
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_global_notification_count", side_effect=_get
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2016-11-02 16:53:40 +00:00
|
|
|
|
validate_route_permission(
|
|
|
|
|
|
mocker,
|
2021-05-12 14:57:21 +01:00
|
|
|
|
notify_admin,
|
2016-11-02 16:53:40 +00:00
|
|
|
|
"GET",
|
|
|
|
|
|
200,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
url_for("main.service_dashboard", service_id=service_one["id"]),
|
|
|
|
|
|
["view_activity"],
|
2016-11-02 16:53:40 +00:00
|
|
|
|
api_user_active,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one,
|
|
|
|
|
|
)
|
2016-04-06 15:48:04 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_aggregate_template_stats():
|
2019-01-15 16:19:23 +00:00
|
|
|
|
expected = aggregate_template_usage(copy.deepcopy(stub_template_stats))
|
2022-12-05 15:33:44 -05:00
|
|
|
|
assert len(expected) == 2
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert expected[0]["template_name"] == "two"
|
|
|
|
|
|
assert expected[0]["count"] == 200
|
|
|
|
|
|
assert expected[0]["template_id"] == "id-2"
|
|
|
|
|
|
assert expected[0]["template_type"] == "email"
|
|
|
|
|
|
assert expected[1]["template_name"] == "one"
|
|
|
|
|
|
assert expected[1]["count"] == 100
|
|
|
|
|
|
assert expected[1]["template_id"] == "id-1"
|
|
|
|
|
|
assert expected[1]["template_type"] == "sms"
|
2016-07-19 13:53:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-01-16 10:54:52 +00:00
|
|
|
|
def test_aggregate_notifications_stats():
|
|
|
|
|
|
expected = aggregate_notifications_stats(copy.deepcopy(stub_template_stats))
|
|
|
|
|
|
assert expected == {
|
|
|
|
|
|
"sms": {"requested": 100, "delivered": 50, "failed": 0},
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"email": {"requested": 200, "delivered": 0, "failed": 100},
|
2019-01-16 10:54:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-07-20 14:12:03 +01:00
|
|
|
|
def test_get_dashboard_totals_adds_percentages():
|
|
|
|
|
|
stats = {
|
2023-08-25 09:12:23 -07:00
|
|
|
|
"sms": {"requested": 3, "delivered": 0, "failed": 2},
|
|
|
|
|
|
"email": {"requested": 0, "delivered": 0, "failed": 0},
|
2016-07-20 14:12:03 +01:00
|
|
|
|
}
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert get_dashboard_totals(stats)["sms"]["failed_percentage"] == "66.7"
|
|
|
|
|
|
assert get_dashboard_totals(stats)["email"]["failed_percentage"] == "0"
|
2016-07-20 14:12:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-09-15 09:48:35 -04:00
|
|
|
|
@pytest.mark.parametrize(("failures", "expected"), [(2, False), (3, False), (4, True)])
|
2016-07-20 14:12:03 +01:00
|
|
|
|
def test_get_dashboard_totals_adds_warning(failures, expected):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
stats = {"sms": {"requested": 100, "delivered": 0, "failed": failures}}
|
|
|
|
|
|
assert get_dashboard_totals(stats)["sms"]["show_warning"] == expected
|
2016-07-28 18:09:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-30 17:27:09 +00:00
|
|
|
|
def test_format_monthly_stats_empty_case():
|
|
|
|
|
|
assert format_monthly_stats_to_list({}) == []
|
2016-07-28 18:09:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-30 17:27:09 +00:00
|
|
|
|
def test_format_monthly_stats_labels_month():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
resp = format_monthly_stats_to_list({"2016-07": {}})
|
|
|
|
|
|
assert resp[0]["name"] == "July"
|
2016-07-28 18:09:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-01-30 17:27:09 +00:00
|
|
|
|
def test_format_monthly_stats_has_stats_with_failure_rate():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
resp = format_monthly_stats_to_list({"2016-07": {"sms": _stats(3, 1, 2)}})
|
|
|
|
|
|
assert resp[0]["sms_counts"] == {
|
|
|
|
|
|
"failed": 2,
|
|
|
|
|
|
"failed_percentage": "66.7",
|
|
|
|
|
|
"requested": 3,
|
|
|
|
|
|
"show_warning": True,
|
2016-07-28 18:09:17 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-12-05 15:33:44 -05:00
|
|
|
|
def test_format_monthly_stats_works_for_email():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
resp = format_monthly_stats_to_list(
|
|
|
|
|
|
{
|
|
|
|
|
|
"2016-07": {
|
|
|
|
|
|
"sms": {},
|
|
|
|
|
|
"email": {},
|
|
|
|
|
|
}
|
2017-01-30 17:27:09 +00:00
|
|
|
|
}
|
2023-08-25 09:12:23 -07:00
|
|
|
|
)
|
|
|
|
|
|
assert isinstance(resp[0]["sms_counts"], dict)
|
|
|
|
|
|
assert isinstance(resp[0]["email_counts"], dict)
|
2016-07-28 18:09:17 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _stats(requested, delivered, failed):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
return {"requested": requested, "delivered": delivered, "failed": failed}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2023-09-15 09:48:35 -04:00
|
|
|
|
("dict_in", "expected_failed", "expected_requested"),
|
2023-08-25 09:12:23 -07:00
|
|
|
|
[
|
|
|
|
|
|
({}, 0, 0),
|
|
|
|
|
|
(
|
|
|
|
|
|
{"temporary-failure": 1, "permanent-failure": 1, "technical-failure": 1},
|
|
|
|
|
|
3,
|
|
|
|
|
|
3,
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
{"created": 1, "pending": 1, "sending": 1, "delivered": 1},
|
|
|
|
|
|
0,
|
|
|
|
|
|
4,
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2017-01-30 17:27:09 +00:00
|
|
|
|
def test_aggregate_status_types(dict_in, expected_failed, expected_requested):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
sms_counts = aggregate_status_types({"sms": dict_in})["sms_counts"]
|
|
|
|
|
|
assert sms_counts["failed"] == expected_failed
|
|
|
|
|
|
assert sms_counts["requested"] == expected_requested
|
2017-01-30 17:27:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-03-16 14:46:27 +00:00
|
|
|
|
def test_get_tuples_of_financial_years():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert list(
|
|
|
|
|
|
get_tuples_of_financial_years(
|
|
|
|
|
|
lambda year: "http://example.com?year={}".format(year),
|
|
|
|
|
|
start=2040,
|
|
|
|
|
|
end=2041,
|
|
|
|
|
|
)
|
|
|
|
|
|
) == [
|
|
|
|
|
|
("fiscal year", 2041, "http://example.com?year=2041", "2041 to 2042"),
|
|
|
|
|
|
("fiscal year", 2040, "http://example.com?year=2040", "2040 to 2041"),
|
2017-03-16 14:46:27 +00:00
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_get_tuples_of_financial_years_defaults_to_2015():
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert (
|
|
|
|
|
|
2015
|
|
|
|
|
|
in list(
|
|
|
|
|
|
get_tuples_of_financial_years(
|
|
|
|
|
|
lambda year: "http://example.com?year={}".format(year),
|
|
|
|
|
|
end=2040,
|
|
|
|
|
|
)
|
|
|
|
|
|
)[-1]
|
|
|
|
|
|
)
|
2017-04-07 11:08:40 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-20 09:53:21 +01:00
|
|
|
|
def test_org_breadcrumbs_do_not_show_if_service_has_no_org(
|
2024-01-08 14:53:34 -08:00
|
|
|
|
mocker,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
client_request,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert not page.select(".navigation-organization-link")
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_org_breadcrumbs_do_not_show_if_user_is_not_an_org_member(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
active_caseworking_user,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
mock_get_template_folders,
|
2021-04-13 13:59:51 +01:00
|
|
|
|
mock_get_api_keys,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
):
|
|
|
|
|
|
# active_caseworking_user is not an org member
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one_json = service_json(
|
|
|
|
|
|
SERVICE_ONE_ID,
|
|
|
|
|
|
users=[active_caseworking_user["id"]],
|
|
|
|
|
|
restricted=False,
|
|
|
|
|
|
organization_id=ORGANISATION_ID,
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_service", return_value={"data": service_one_json}
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
client_request.login(active_caseworking_user, service=service_one_json)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get(
|
|
|
|
|
|
"main.service_dashboard", service_id=SERVICE_ONE_ID, _follow_redirects=True
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert not page.select(".navigation-organization-link")
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_org_breadcrumbs_show_if_user_is_a_member_of_the_services_org(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
active_user_with_permissions,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
):
|
|
|
|
|
|
# active_user_with_permissions (used by the client_request) is an org member
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one_json = service_json(
|
|
|
|
|
|
SERVICE_ONE_ID,
|
|
|
|
|
|
users=[active_user_with_permissions["id"]],
|
|
|
|
|
|
restricted=False,
|
|
|
|
|
|
organization_id=ORGANISATION_ID,
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_service", return_value={"data": service_one_json}
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.organizations_client.get_organization",
|
|
|
|
|
|
return_value=organization_json(
|
|
|
|
|
|
id_=ORGANISATION_ID,
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
assert page.select_one(".navigation-organization-link")["href"] == url_for(
|
|
|
|
|
|
"main.organization_dashboard",
|
2019-06-21 14:12:19 +01:00
|
|
|
|
org_id=ORGANISATION_ID,
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-20 16:58:53 +01:00
|
|
|
|
def test_org_breadcrumbs_do_not_show_if_user_is_a_member_of_the_services_org_but_service_is_in_trial_mode(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2019-06-20 16:58:53 +01:00
|
|
|
|
active_user_with_permissions,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
):
|
|
|
|
|
|
# active_user_with_permissions (used by the client_request) is an org member
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one_json = service_json(
|
|
|
|
|
|
SERVICE_ONE_ID,
|
|
|
|
|
|
users=[active_user_with_permissions["id"]],
|
|
|
|
|
|
organization_id=ORGANISATION_ID,
|
|
|
|
|
|
)
|
2019-06-20 16:58:53 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_service", return_value={"data": service_one_json}
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch("app.models.service.Organization")
|
2019-06-20 16:58:53 +01:00
|
|
|
|
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
2019-06-20 16:58:53 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert not page.select(".navigation-breadcrumb")
|
2019-06-20 16:58:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
2019-06-20 09:53:21 +01:00
|
|
|
|
def test_org_breadcrumbs_show_if_user_is_platform_admin(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
platform_admin_user,
|
2021-12-30 16:13:49 +00:00
|
|
|
|
client_request,
|
2019-06-20 09:53:21 +01:00
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one_json = service_json(
|
|
|
|
|
|
SERVICE_ONE_ID,
|
|
|
|
|
|
users=[platform_admin_user["id"]],
|
|
|
|
|
|
organization_id=ORGANISATION_ID,
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_service", return_value={"data": service_one_json}
|
|
|
|
|
|
)
|
|
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.organizations_client.get_organization",
|
|
|
|
|
|
return_value=organization_json(
|
|
|
|
|
|
id_=ORGANISATION_ID,
|
|
|
|
|
|
),
|
|
|
|
|
|
)
|
2019-06-20 09:53:21 +01:00
|
|
|
|
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2021-12-30 16:13:49 +00:00
|
|
|
|
client_request.login(platform_admin_user, service_one_json)
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
assert page.select_one(".navigation-organization-link")["href"] == url_for(
|
|
|
|
|
|
"main.organization_dashboard",
|
2019-06-21 14:12:19 +01:00
|
|
|
|
org_id=ORGANISATION_ID,
|
|
|
|
|
|
)
|
2019-10-25 13:27:46 +01:00
|
|
|
|
|
|
|
|
|
|
|
2021-04-19 17:46:42 +01:00
|
|
|
|
def test_breadcrumb_shows_if_service_is_suspended(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_get_service_templates_when_no_templates_exist,
|
|
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2021-04-19 17:46:42 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
active_user_with_permissions,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
):
|
|
|
|
|
|
service_one_json = service_json(
|
|
|
|
|
|
SERVICE_ONE_ID,
|
|
|
|
|
|
active=False,
|
2023-08-25 09:12:23 -07:00
|
|
|
|
users=[active_user_with_permissions["id"]],
|
2021-04-19 17:46:42 +01:00
|
|
|
|
)
|
|
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_service", return_value={"data": service_one_json}
|
|
|
|
|
|
)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
2021-04-19 17:46:42 +01:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
assert "Suspended" in page.select_one(".navigation-service-name").text
|
2021-04-19 17:46:42 +01:00
|
|
|
|
|
|
|
|
|
|
|
2023-09-15 09:48:35 -04:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"permissions",
|
|
|
|
|
|
[
|
|
|
|
|
|
("email", "sms"),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2022-04-26 15:26:08 +01:00
|
|
|
|
def test_service_dashboard_shows_usage(
|
2023-11-21 15:38:41 -05:00
|
|
|
|
mocker,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
client_request,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
2020-09-28 14:28:23 +01:00
|
|
|
|
mock_has_no_jobs,
|
2022-04-29 16:25:58 +01:00
|
|
|
|
mock_get_annual_usage_for_service,
|
2019-10-25 13:27:46 +01:00
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
permissions,
|
|
|
|
|
|
):
|
2023-11-21 15:38:41 -05:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.service_api_client.get_global_notification_count",
|
|
|
|
|
|
return_value={
|
|
|
|
|
|
"count": 500,
|
|
|
|
|
|
},
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-08-09 14:29:14 -07:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2023-11-21 15:38:41 -05:00
|
|
|
|
|
2023-08-25 09:12:23 -07:00
|
|
|
|
service_one["permissions"] = permissions
|
|
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
|
|
|
|
|
|
2024-01-05 12:45:21 -08:00
|
|
|
|
usage_table = page.find("table", class_="usage-table")
|
|
|
|
|
|
|
2024-03-28 15:58:02 -04:00
|
|
|
|
# Check if the "Usage" table doesn't exist
|
|
|
|
|
|
assert usage_table is None
|
2022-04-27 17:08:44 +01:00
|
|
|
|
|
2024-01-08 15:33:24 -08:00
|
|
|
|
|
2022-04-27 17:08:44 +01:00
|
|
|
|
def test_service_dashboard_shows_free_allowance(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_has_no_jobs,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
|
|
|
|
|
):
|
2023-08-25 09:12:23 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.billing_api_client.get_annual_usage_for_service",
|
|
|
|
|
|
return_value=[
|
|
|
|
|
|
{
|
|
|
|
|
|
"notification_type": "sms",
|
|
|
|
|
|
"chargeable_units": 1000,
|
|
|
|
|
|
"charged_units": 0,
|
|
|
|
|
|
"rate": 0.0165,
|
|
|
|
|
|
"cost": 0,
|
|
|
|
|
|
}
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-01-08 14:53:34 -08:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2022-04-27 17:08:44 +01:00
|
|
|
|
|
2024-01-09 15:48:16 -08:00
|
|
|
|
|
|
|
|
|
|
def test_service_dashboard_shows_batched_jobs(
|
|
|
|
|
|
mocker,
|
|
|
|
|
|
client_request,
|
|
|
|
|
|
service_one,
|
|
|
|
|
|
mock_get_service_templates,
|
|
|
|
|
|
mock_get_template_statistics,
|
|
|
|
|
|
mock_has_no_jobs,
|
|
|
|
|
|
mock_get_annual_usage_for_service,
|
|
|
|
|
|
mock_get_free_sms_fragment_limit,
|
2024-01-12 13:58:56 -08:00
|
|
|
|
):
|
2024-01-26 09:43:41 -08:00
|
|
|
|
mocker.patch("app.job_api_client.get_jobs", return_value=MOCK_JOBS)
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats", return_value=mock_daily_stats
|
|
|
|
|
|
)
|
2024-01-09 15:48:16 -08:00
|
|
|
|
|
2024-08-09 15:04:56 -07:00
|
|
|
|
mocker.patch(
|
|
|
|
|
|
"app.main.views.dashboard.get_daily_stats_by_user",
|
|
|
|
|
|
return_value=mock_daily_stats_by_user,
|
|
|
|
|
|
)
|
2024-01-09 15:48:16 -08:00
|
|
|
|
|
2024-08-09 14:29:14 -07:00
|
|
|
|
page = client_request.get("main.service_dashboard", service_id=SERVICE_ONE_ID)
|
2024-02-12 15:29:26 -08:00
|
|
|
|
job_table_body = page.find("table", class_="job-table")
|
2024-01-09 15:48:16 -08:00
|
|
|
|
|
2024-02-12 15:29:26 -08:00
|
|
|
|
rows = job_table_body.find_all("tbody")[0].find_all("tr")
|
2025-01-20 14:34:11 -08:00
|
|
|
|
assert len(rows) == 1
|
2024-08-13 15:29:19 -04:00
|
|
|
|
|
2024-02-12 15:29:26 -08:00
|
|
|
|
assert job_table_body is not None
|