mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-20 22:40:31 -04:00
Merge branch 'master' into reinstate-new-rate-api
Conflicts: app/main/views/dashboard.py
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import pytest
|
||||
from app.main.forms import get_placeholder_form_instance
|
||||
from wtforms import Label
|
||||
|
||||
@@ -16,3 +17,46 @@ def test_form_class_not_mutated(app_):
|
||||
|
||||
assert str(form1.placeholder_value.label) == '<label for="placeholder_value">name</label>'
|
||||
assert str(form2.placeholder_value.label) == '<label for="placeholder_value">city</label>'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('service_can_send_international_sms, placeholder_name, value, expected_error', [
|
||||
|
||||
(False, 'email address', '', 'Can’t be empty'),
|
||||
(False, 'email address', '12345', 'Enter a valid email address'),
|
||||
(False, 'email address', 'test@example.com', None),
|
||||
(False, 'email address', 'test@example.gov.uk', None),
|
||||
|
||||
(False, 'phone number', '', 'Can’t be empty'),
|
||||
(False, 'phone number', '+1-2345-678890', 'Not a UK mobile number'),
|
||||
(False, 'phone number', '07900900123', None),
|
||||
(False, 'phone number', '+44(0)7900 900-123', None),
|
||||
|
||||
(True, 'phone number', '+123', 'Not enough digits'),
|
||||
(True, 'phone number', '+44(0)7900 900-123', None),
|
||||
(True, 'phone number', '+1-2345-678890', None),
|
||||
|
||||
(False, 'anything else', '', 'Can’t be empty'),
|
||||
|
||||
])
|
||||
def test_validates_recipients(
|
||||
app_,
|
||||
placeholder_name,
|
||||
value,
|
||||
service_can_send_international_sms,
|
||||
expected_error,
|
||||
):
|
||||
with app_.test_request_context(
|
||||
method='POST',
|
||||
data={'placeholder_value': value}
|
||||
):
|
||||
form = get_placeholder_form_instance(
|
||||
placeholder_name,
|
||||
{},
|
||||
allow_international_phone_numbers=service_can_send_international_sms,
|
||||
)
|
||||
|
||||
if expected_error:
|
||||
assert not form.validate_on_submit()
|
||||
assert form.placeholder_value.errors[0] == expected_error
|
||||
else:
|
||||
assert form.validate_on_submit()
|
||||
|
||||
@@ -90,6 +90,9 @@ def _gen_mock_field(x):
|
||||
'test@hmcts.net',
|
||||
'test@scotent.co.uk',
|
||||
'test@assembly.wales',
|
||||
'test@cjsm.net',
|
||||
'test@cqc.org.uk',
|
||||
'test@digital.cqc.org.uk',
|
||||
])
|
||||
def test_valid_list_of_white_list_email_domains(
|
||||
client,
|
||||
|
||||
@@ -5,6 +5,7 @@ from unittest.mock import call, ANY
|
||||
from flask import url_for
|
||||
import pytest
|
||||
from bs4 import BeautifulSoup
|
||||
from datetime import datetime, timedelta
|
||||
from freezegun import freeze_time
|
||||
|
||||
from app.main.views.dashboard import (
|
||||
@@ -18,7 +19,11 @@ from app.main.views.dashboard import (
|
||||
)
|
||||
|
||||
from tests import validate_route_permission
|
||||
from tests.conftest import SERVICE_ONE_ID
|
||||
from tests.conftest import (
|
||||
SERVICE_ONE_ID,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_inbound_sms_summary_with_no_messages,
|
||||
)
|
||||
from tests.app.test_utils import normalize_spaces
|
||||
|
||||
stub_template_stats = [
|
||||
@@ -44,6 +49,7 @@ def test_get_started(
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
mock_template_stats = mocker.patch('app.template_statistics_client.get_template_statistics_for_service',
|
||||
@@ -63,6 +69,7 @@ def test_get_started_is_hidden_once_templates_exist(
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
mock_template_stats = mocker.patch('app.template_statistics_client.get_template_statistics_for_service',
|
||||
@@ -74,6 +81,122 @@ def test_get_started_is_hidden_once_templates_exist(
|
||||
assert 'Get started' not in response.get_data(as_text=True)
|
||||
|
||||
|
||||
def test_inbound_messages_not_visible_to_service_without_permissions(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_service_templates_when_no_templates_exist,
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_template_statistics,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
|
||||
service_one['permissions'] = []
|
||||
|
||||
response = logged_in_client.get(url_for('main.service_dashboard', service_id=SERVICE_ONE_ID))
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert not page.select('.big-number-meta-wrapper')
|
||||
assert mock_get_inbound_sms_summary.called is False
|
||||
|
||||
|
||||
@pytest.mark.parametrize('inbound_summary_mock, expected_text', [
|
||||
(mock_get_inbound_sms_summary_with_no_messages, '0 text messages received'),
|
||||
(mock_get_inbound_sms_summary, '99 text messages received latest message just now'),
|
||||
])
|
||||
def test_inbound_messages_shows_count_of_messages(
|
||||
logged_in_client,
|
||||
mocker,
|
||||
service_one,
|
||||
mock_get_service_templates_when_no_templates_exist,
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_template_statistics,
|
||||
mock_get_usage,
|
||||
inbound_summary_mock,
|
||||
expected_text,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
|
||||
service_one['permissions'] = ['inbound_sms']
|
||||
inbound_summary_mock(mocker)
|
||||
|
||||
response = logged_in_client.get(url_for('main.service_dashboard', service_id=SERVICE_ONE_ID))
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert normalize_spaces(page.select('.big-number-meta-wrapper')[0].text) == expected_text
|
||||
assert page.select('.big-number-meta-wrapper a')[0]['href'] == url_for(
|
||||
'main.inbox', service_id=SERVICE_ONE_ID
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('index, expected_row', enumerate([
|
||||
'07900900000 foo 1 hour ago',
|
||||
'07900900001 foo 2 hours ago',
|
||||
'07900900002 foo 3 hours ago',
|
||||
'07900900003 foo 4 hours ago',
|
||||
'07900900004 foo 5 hours ago',
|
||||
]))
|
||||
def test_inbox_showing_inbound_messages(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_service_templates_when_no_templates_exist,
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_template_statistics,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms,
|
||||
index,
|
||||
expected_row,
|
||||
):
|
||||
|
||||
service_one['permissions'] = ['inbound_sms']
|
||||
|
||||
response = logged_in_client.get(url_for('main.inbox', service_id=SERVICE_ONE_ID))
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
|
||||
assert response.status_code == 200
|
||||
rows = page.select('tbody tr')
|
||||
assert len(rows) == 5
|
||||
assert normalize_spaces(rows[index].text) == expected_row
|
||||
|
||||
|
||||
def test_empty_inbox(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_service_templates_when_no_templates_exist,
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_template_statistics,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_with_no_messages,
|
||||
):
|
||||
|
||||
service_one['permissions'] = ['inbound_sms']
|
||||
|
||||
response = logged_in_client.get(url_for('main.inbox', service_id=SERVICE_ONE_ID))
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert normalize_spaces(page.select('tbody tr')) == (
|
||||
'When users text your service’s phone number (GOVUK) you’ll see the messages here'
|
||||
)
|
||||
|
||||
|
||||
def test_inbox_not_accessible_to_service_without_permissions(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
):
|
||||
service_one['permissions'] = []
|
||||
response = logged_in_client.get(url_for('main.inbox', service_id=SERVICE_ONE_ID))
|
||||
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_should_show_recent_templates_on_dashboard(
|
||||
logged_in_client,
|
||||
mocker,
|
||||
@@ -81,6 +204,7 @@ def test_should_show_recent_templates_on_dashboard(
|
||||
mock_get_jobs,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
mock_template_stats = mocker.patch('app.template_statistics_client.get_template_statistics_for_service',
|
||||
@@ -147,6 +271,7 @@ def test_should_show_upcoming_jobs_on_dashboard(
|
||||
mock_get_detailed_service,
|
||||
mock_get_jobs,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
response = logged_in_client.get(url_for('main.service_dashboard', service_id=SERVICE_ONE_ID))
|
||||
@@ -178,6 +303,7 @@ def test_should_show_recent_jobs_on_dashboard(
|
||||
mock_get_detailed_service,
|
||||
mock_get_jobs,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
response = logged_in_client.get(url_for('main.service_dashboard', service_id=SERVICE_ONE_ID))
|
||||
@@ -297,6 +423,7 @@ def test_menu_send_messages(
|
||||
mock_get_template_statistics,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
with app_.test_request_context():
|
||||
@@ -328,6 +455,7 @@ def test_menu_manage_service(
|
||||
mock_get_template_statistics,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
with app_.test_request_context():
|
||||
@@ -358,6 +486,7 @@ def test_menu_manage_api_keys(
|
||||
mock_get_template_statistics,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
with app_.test_request_context():
|
||||
@@ -388,6 +517,7 @@ def test_menu_all_services_for_platform_admin_user(
|
||||
mock_get_template_statistics,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
with app_.test_request_context():
|
||||
@@ -418,6 +548,7 @@ def test_route_for_service_permissions(
|
||||
mock_get_template_statistics,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
with app_.test_request_context():
|
||||
@@ -455,6 +586,7 @@ def test_service_dashboard_updates_gets_dashboard_totals(
|
||||
mock_get_detailed_service,
|
||||
mock_get_jobs,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
mocker.patch('app.main.views.dashboard.get_dashboard_totals', return_value={
|
||||
@@ -677,11 +809,13 @@ def test_should_show_all_jobs_with_valid_statuses(
|
||||
logged_in_client,
|
||||
mock_get_template_statistics,
|
||||
mock_get_detailed_service,
|
||||
mock_get_service_templates_when_no_templates_exist,
|
||||
mock_get_jobs,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
mock_get_yearly_sms_unit_count_and_cost
|
||||
):
|
||||
get_dashboard_partials(service_id=SERVICE_ONE_ID)
|
||||
logged_in_client.get(url_for('main.service_dashboard', service_id=SERVICE_ONE_ID))
|
||||
|
||||
first_call = mock_get_jobs.call_args_list[0]
|
||||
# first call - scheduled jobs only
|
||||
|
||||
@@ -17,9 +17,18 @@ def no_redirect():
|
||||
return lambda _external=True: None
|
||||
|
||||
|
||||
def test_get_support_index_page(client):
|
||||
resp = client.get(url_for('main.support'))
|
||||
assert resp.status_code == 200
|
||||
@pytest.mark.parametrize('endpoint', [
|
||||
'main.old_feedback',
|
||||
'main.support',
|
||||
])
|
||||
def test_get_support_index_page(
|
||||
client,
|
||||
endpoint,
|
||||
):
|
||||
response = client.get(url_for('main.support'), follow_redirects=True)
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.string.strip() == 'Support'
|
||||
|
||||
|
||||
@freeze_time('2016-12-12 12:00:00.000000')
|
||||
|
||||
@@ -8,6 +8,7 @@ from bs4 import BeautifulSoup
|
||||
|
||||
from app.main.views.jobs import get_time_left, get_status_filters
|
||||
from tests import notification_json
|
||||
from tests.conftest import SERVICE_ONE_ID
|
||||
from freezegun import freeze_time
|
||||
|
||||
|
||||
@@ -311,6 +312,13 @@ def test_should_show_updates_for_one_job_as_json(
|
||||
(None, 1)
|
||||
]
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
"to_argument, expected_to_argument", [
|
||||
('', ''),
|
||||
('+447900900123', '+447900900123'),
|
||||
('test@example.com', 'test@example.com'),
|
||||
]
|
||||
)
|
||||
def test_can_show_notifications(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
@@ -322,13 +330,17 @@ def test_can_show_notifications(
|
||||
expected_api_call,
|
||||
page_argument,
|
||||
expected_page_argument,
|
||||
to_argument,
|
||||
expected_to_argument,
|
||||
):
|
||||
response = logged_in_client.get(url_for(
|
||||
'main.view_notifications',
|
||||
service_id=service_one['id'],
|
||||
message_type=message_type,
|
||||
status=status_argument,
|
||||
page=page_argument))
|
||||
page=page_argument,
|
||||
to=to_argument,
|
||||
))
|
||||
assert response.status_code == 200
|
||||
content = response.get_data(as_text=True)
|
||||
notifications = notification_json(service_one['id'])
|
||||
@@ -348,13 +360,16 @@ def test_can_show_notifications(
|
||||
assert query_dict['status'] == [status_argument]
|
||||
if expected_page_argument:
|
||||
assert query_dict['page'] == [str(expected_page_argument)]
|
||||
if to_argument:
|
||||
assert query_dict['to'] == [to_argument]
|
||||
|
||||
mock_get_notifications.assert_called_with(
|
||||
limit_days=7,
|
||||
page=expected_page_argument,
|
||||
service_id=service_one['id'],
|
||||
status=expected_api_call,
|
||||
template_type=[message_type]
|
||||
template_type=[message_type],
|
||||
to=expected_to_argument,
|
||||
)
|
||||
|
||||
json_response = logged_in_client.get(url_for(
|
||||
@@ -367,6 +382,62 @@ def test_can_show_notifications(
|
||||
assert json_content.keys() == {'counts', 'notifications'}
|
||||
|
||||
|
||||
@pytest.mark.parametrize("initial_query_arguments, expected_status_field_value, expected_search_box_contents", [
|
||||
(
|
||||
{
|
||||
'message_type': 'sms',
|
||||
},
|
||||
'sending,delivered,failed',
|
||||
'',
|
||||
),
|
||||
(
|
||||
{
|
||||
'message_type': 'sms',
|
||||
'to': '+33(0)5-12-34-56-78',
|
||||
},
|
||||
'sending,delivered,failed',
|
||||
'+33(0)5-12-34-56-78',
|
||||
),
|
||||
(
|
||||
{
|
||||
'status': 'failed',
|
||||
'message_type': 'email',
|
||||
'page': '99',
|
||||
'to': 'test@example.com',
|
||||
},
|
||||
'failed',
|
||||
'test@example.com',
|
||||
),
|
||||
])
|
||||
def test_search_recipient_form(
|
||||
logged_in_client,
|
||||
mock_get_notifications,
|
||||
mock_get_detailed_service,
|
||||
initial_query_arguments,
|
||||
expected_status_field_value,
|
||||
expected_search_box_contents,
|
||||
):
|
||||
response = logged_in_client.get(url_for(
|
||||
'main.view_notifications',
|
||||
service_id=SERVICE_ONE_ID,
|
||||
**initial_query_arguments
|
||||
))
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
|
||||
action_url = page.find("form")['action']
|
||||
url = urlparse(action_url)
|
||||
assert url.path == '/services/{}/notifications/{}'.format(
|
||||
SERVICE_ONE_ID,
|
||||
initial_query_arguments['message_type']
|
||||
)
|
||||
query_dict = parse_qs(url.query)
|
||||
assert query_dict == {}
|
||||
|
||||
assert page.find("input", {'name': 'status'})['value'] == expected_status_field_value
|
||||
assert page.find("input", {'name': 'to'})['value'] == expected_search_box_contents
|
||||
|
||||
|
||||
def test_should_show_notifications_for_a_service_with_next_previous(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
|
||||
@@ -23,6 +23,7 @@ from tests.conftest import (
|
||||
mock_get_international_service,
|
||||
mock_get_service_template,
|
||||
mock_get_service_email_template,
|
||||
SERVICE_ONE_ID,
|
||||
)
|
||||
|
||||
template_types = ['email', 'sms']
|
||||
@@ -204,32 +205,6 @@ def test_upload_csv_invalid_extension(
|
||||
assert "invalid.txt isn’t a spreadsheet that Notify can read" in resp.get_data(as_text=True)
|
||||
|
||||
|
||||
def test_upload_valid_csv_shows_page_title(
|
||||
logged_in_client,
|
||||
mocker,
|
||||
mock_get_service_template_with_placeholders,
|
||||
mock_s3_upload,
|
||||
mock_get_users_by_service,
|
||||
mock_get_detailed_service_for_today,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
):
|
||||
|
||||
mocker.patch('app.main.views.send.s3download', return_value="""
|
||||
phone number,name\n07700900986,Jo
|
||||
""")
|
||||
|
||||
response = logged_in_client.post(
|
||||
url_for('main.send_messages', service_id=service_one['id'], template_id=fake_uuid),
|
||||
data={'file': (BytesIO(''.encode('utf-8')), 'valid.csv')},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.text.strip() == 'Preview of Two week reminder'
|
||||
|
||||
|
||||
def test_upload_valid_csv_shows_file_contents(
|
||||
logged_in_client,
|
||||
mocker,
|
||||
@@ -237,7 +212,6 @@ def test_upload_valid_csv_shows_file_contents(
|
||||
mock_s3_upload,
|
||||
mock_get_users_by_service,
|
||||
mock_get_detailed_service_for_today,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
):
|
||||
|
||||
@@ -247,15 +221,16 @@ def test_upload_valid_csv_shows_file_contents(
|
||||
""")
|
||||
|
||||
response = logged_in_client.post(
|
||||
url_for('main.send_messages', service_id=service_one['id'], template_id=fake_uuid),
|
||||
url_for('main.send_messages', service_id=SERVICE_ONE_ID, template_id=fake_uuid),
|
||||
data={'file': (BytesIO(''.encode('utf-8')), 'valid.csv')},
|
||||
follow_redirects=True,
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.text.strip() == 'Preview of Two week reminder'
|
||||
for index, cell in enumerate([
|
||||
'<td class="table-field-index"> <span>2</span> </td>',
|
||||
'<td class="table-field-index"> <span class=""> 2 </span> </td>',
|
||||
'<td class="table-field-center-aligned "> <div class=""> 07700900986 </div> </td>',
|
||||
'<td class="table-field-center-aligned "> <div class=""> Jo </div> </td>',
|
||||
(
|
||||
@@ -311,7 +286,6 @@ def test_send_test_sms_message(
|
||||
mock_get_detailed_service_for_today,
|
||||
):
|
||||
|
||||
expected_data = {'data': 'phone number\r\n07700 900762\r\n', 'file_name': 'Test message'}
|
||||
mocker.patch('app.main.views.send.s3download', return_value='phone number\r\n+4412341234')
|
||||
|
||||
response = logged_in_client.get(
|
||||
@@ -319,29 +293,174 @@ def test_send_test_sms_message(
|
||||
follow_redirects=True
|
||||
)
|
||||
assert response.status_code == 200
|
||||
mock_s3_upload.assert_called_with(service_one['id'], expected_data, 'eu-west-1')
|
||||
mock_s3_upload.assert_called_with(
|
||||
service_one['id'],
|
||||
{'data': 'phone number\r\n07700 900762\r\n', 'file_name': 'Report'},
|
||||
'eu-west-1'
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, template_mock, expected_session_contents', [
|
||||
('main.send_test_step', mock_get_service_template_with_placeholders, {'phone number': '07700 900762'}),
|
||||
('main.send_test_step', mock_get_service_email_template, {'email address': 'test@user.gov.uk'}),
|
||||
('main.send_test_step', mock_get_service_letter_template, {}),
|
||||
('main.send_one_off_step', mock_get_service_template, {}),
|
||||
('main.send_one_off_step', mock_get_service_email_template, {}),
|
||||
('main.send_one_off_step', mock_get_service_letter_template, {}),
|
||||
])
|
||||
def test_send_test_step_redirects_if_session_not_setup(
|
||||
mocker,
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_detailed_service_for_today,
|
||||
mock_get_users_by_service,
|
||||
fake_uuid,
|
||||
mock_get_service_email_template,
|
||||
endpoint,
|
||||
template_mock,
|
||||
expected_session_contents,
|
||||
):
|
||||
|
||||
template_mock(mocker)
|
||||
mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=99)
|
||||
|
||||
with logged_in_client.session_transaction() as session:
|
||||
assert 'send_test_values' not in session
|
||||
|
||||
response = logged_in_client.get(
|
||||
url_for('main.send_test_step', service_id=service_one['id'], template_id=fake_uuid, step_index=0),
|
||||
url_for(endpoint, service_id=SERVICE_ONE_ID, template_id=fake_uuid, step_index=0),
|
||||
follow_redirects=True
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
with logged_in_client.session_transaction() as session:
|
||||
assert session['send_test_values'] == {'email address': 'test@user.gov.uk'}
|
||||
assert session['send_test_values'] == expected_session_contents
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_mock, partial_url, expected_h1, tour_shown', [
|
||||
(
|
||||
mock_get_service_template_with_placeholders,
|
||||
partial(url_for, 'main.send_test'),
|
||||
'Send to one recipient',
|
||||
False,
|
||||
),
|
||||
(
|
||||
mock_get_service_template_with_placeholders,
|
||||
partial(url_for, 'main.send_one_off'),
|
||||
'Send to one recipient',
|
||||
False,
|
||||
),
|
||||
(
|
||||
mock_get_service_template_with_placeholders,
|
||||
partial(url_for, 'main.send_test', help=1),
|
||||
'Example text message',
|
||||
True,
|
||||
),
|
||||
(
|
||||
mock_get_service_email_template,
|
||||
partial(url_for, 'main.send_test', help=1),
|
||||
'Example text message',
|
||||
True,
|
||||
),
|
||||
(
|
||||
mock_get_service_email_template,
|
||||
partial(url_for, 'main.send_test'),
|
||||
'Send to one recipient',
|
||||
False,
|
||||
),
|
||||
(
|
||||
mock_get_service_email_template,
|
||||
partial(url_for, 'main.send_one_off'),
|
||||
'Send to one recipient',
|
||||
False,
|
||||
),
|
||||
(
|
||||
mock_get_service_letter_template,
|
||||
partial(url_for, 'main.send_test'),
|
||||
'Print a test letter',
|
||||
False,
|
||||
),
|
||||
(
|
||||
mock_get_service_letter_template,
|
||||
partial(url_for, 'main.send_one_off'),
|
||||
'Print a test letter',
|
||||
False,
|
||||
),
|
||||
])
|
||||
def test_send_one_off_or_test_has_correct_page_titles(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mocker,
|
||||
template_mock,
|
||||
partial_url,
|
||||
expected_h1,
|
||||
tour_shown,
|
||||
):
|
||||
|
||||
template_mock(mocker)
|
||||
mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=99)
|
||||
|
||||
response = logged_in_client.get(
|
||||
partial_url(service_id=service_one['id'], template_id=fake_uuid, step_index=0),
|
||||
follow_redirects=True,
|
||||
)
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
|
||||
assert response.status_code == 200
|
||||
assert page.h1.text.strip() == expected_h1
|
||||
|
||||
assert (len(page.select('.banner-tour')) == 1) == tour_shown
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_mock, expected_link_text, expected_link_url', [
|
||||
(mock_get_service_template, 'Use my phone number', partial(url_for, 'main.send_test')),
|
||||
(mock_get_service_email_template, 'Use my email address', partial(url_for, 'main.send_test')),
|
||||
(mock_get_service_letter_template, None, None),
|
||||
])
|
||||
def test_send_one_off_has_skip_link(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mock_get_service_email_template,
|
||||
mocker,
|
||||
template_mock,
|
||||
expected_link_text,
|
||||
expected_link_url,
|
||||
):
|
||||
|
||||
template_mock(mocker)
|
||||
mocker.patch('app.main.views.send.get_page_count_for_letter', return_value=99)
|
||||
|
||||
response = logged_in_client.get(
|
||||
url_for('main.send_one_off_step', service_id=service_one['id'], template_id=fake_uuid, step_index=0),
|
||||
follow_redirects=True
|
||||
)
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
skip_links = page.select('a.top-gutter-4-3')
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
if expected_link_text and expected_link_url:
|
||||
assert skip_links[0].text.strip() == expected_link_text
|
||||
assert skip_links[0]['href'] == expected_link_url(
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
)
|
||||
else:
|
||||
assert not skip_links
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, expected_redirect, send_test_values', [
|
||||
(
|
||||
'main.send_test_step',
|
||||
'main.send_test',
|
||||
{'name': 'foo'},
|
||||
),
|
||||
(
|
||||
'main.send_one_off_step',
|
||||
'main.send_one_off',
|
||||
{'name': 'foo', 'phone number': '07900900123'},
|
||||
),
|
||||
])
|
||||
def test_send_test_redirects_to_end_if_step_out_of_bounds(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
@@ -350,13 +469,16 @@ def test_send_test_redirects_to_end_if_step_out_of_bounds(
|
||||
mock_s3_upload,
|
||||
mock_get_users_by_service,
|
||||
mock_get_detailed_service_for_today,
|
||||
endpoint,
|
||||
send_test_values,
|
||||
expected_redirect,
|
||||
):
|
||||
|
||||
with logged_in_client.session_transaction() as session:
|
||||
session['send_test_values'] = {'name': 'foo'}
|
||||
session['send_test_values'] = send_test_values
|
||||
|
||||
response = logged_in_client.get(url_for(
|
||||
'main.send_test_step',
|
||||
endpoint,
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
step_index=999,
|
||||
@@ -376,6 +498,10 @@ def test_send_test_redirects_to_end_if_step_out_of_bounds(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, expected_redirect', [
|
||||
('main.send_test_step', 'main.send_test'),
|
||||
('main.send_one_off_step', 'main.send_one_off'),
|
||||
])
|
||||
def test_send_test_redirects_to_start_if_you_skip_steps(
|
||||
logged_in_platform_admin_client,
|
||||
service_one,
|
||||
@@ -385,6 +511,8 @@ def test_send_test_redirects_to_start_if_you_skip_steps(
|
||||
mock_get_users_by_service,
|
||||
mock_get_detailed_service_for_today,
|
||||
mocker,
|
||||
endpoint,
|
||||
expected_redirect,
|
||||
):
|
||||
|
||||
with logged_in_platform_admin_client.session_transaction() as session:
|
||||
@@ -392,20 +520,24 @@ def test_send_test_redirects_to_start_if_you_skip_steps(
|
||||
session['send_test_values'] = {'address_line_1': 'foo'}
|
||||
|
||||
response = logged_in_platform_admin_client.get(url_for(
|
||||
'main.send_test_step',
|
||||
endpoint,
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
step_index=7, # letter template has 7 placeholders – we’re at the end
|
||||
))
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for(
|
||||
'main.send_test',
|
||||
expected_redirect,
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
_external=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, expected_redirect', [
|
||||
('main.send_test_step', 'main.send_test'),
|
||||
('main.send_one_off_step', 'main.send_one_off'),
|
||||
])
|
||||
def test_send_test_redirects_to_start_if_index_out_of_bounds_and_some_placeholders_empty(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
@@ -414,13 +546,15 @@ def test_send_test_redirects_to_start_if_index_out_of_bounds_and_some_placeholde
|
||||
mock_s3_download,
|
||||
mock_get_users_by_service,
|
||||
mock_get_detailed_service_for_today,
|
||||
endpoint,
|
||||
expected_redirect,
|
||||
):
|
||||
|
||||
with logged_in_client.session_transaction() as session:
|
||||
session['send_test_values'] = {'name': 'foo'}
|
||||
|
||||
response = logged_in_client.get(url_for(
|
||||
'main.send_test_step',
|
||||
endpoint,
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
step_index=999,
|
||||
@@ -428,24 +562,30 @@ def test_send_test_redirects_to_start_if_index_out_of_bounds_and_some_placeholde
|
||||
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for(
|
||||
'main.send_test',
|
||||
expected_redirect,
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
_external=True,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, expected_redirect', [
|
||||
('main.send_test', 'main.send_test_step'),
|
||||
('main.send_one_off', 'main.send_one_off_step'),
|
||||
])
|
||||
def test_send_test_sms_message_redirects_with_help_argument(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
endpoint,
|
||||
expected_redirect,
|
||||
):
|
||||
response = logged_in_client.get(
|
||||
url_for('main.send_test', service_id=service_one['id'], template_id=fake_uuid, help=1)
|
||||
url_for(endpoint, service_id=service_one['id'], template_id=fake_uuid, help=1)
|
||||
)
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for(
|
||||
'main.send_test_step',
|
||||
expected_redirect,
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid,
|
||||
step_index=0,
|
||||
@@ -465,7 +605,6 @@ def test_send_test_email_message_without_placeholders(
|
||||
fake_uuid,
|
||||
):
|
||||
|
||||
expected_data = {'data': 'email address\r\ntest@user.gov.uk\r\n', 'file_name': 'Test message'}
|
||||
mocker.patch('app.main.views.send.s3download', return_value='email address\r\ntest@user.gov.uk')
|
||||
|
||||
response = logged_in_client.get(
|
||||
@@ -473,7 +612,11 @@ def test_send_test_email_message_without_placeholders(
|
||||
follow_redirects=True
|
||||
)
|
||||
assert response.status_code == 200
|
||||
mock_s3_upload.assert_called_with(service_one['id'], expected_data, 'eu-west-1')
|
||||
mock_s3_upload.assert_called_with(
|
||||
service_one['id'],
|
||||
{'data': 'email address\r\ntest@user.gov.uk\r\n', 'file_name': 'Report'},
|
||||
'eu-west-1'
|
||||
)
|
||||
|
||||
|
||||
def test_send_test_sms_message_with_placeholders_shows_first_field(
|
||||
@@ -692,7 +835,7 @@ def test_send_test_sms_message_puts_submitted_data_in_session_and_file(
|
||||
service_one['id'],
|
||||
{
|
||||
'data': 'name,phone number\r\nJo,07700 900762\r\n',
|
||||
'file_name': 'Test message'
|
||||
'file_name': 'Report'
|
||||
},
|
||||
'eu-west-1'
|
||||
)
|
||||
|
||||
@@ -92,6 +92,22 @@ def test_if_cant_send_letters_then_cant_see_letter_contact_block(
|
||||
assert 'Letter contact block' not in response.get_data(as_text=True)
|
||||
|
||||
|
||||
def test_if_can_receive_inbound_then_cant_change_sms_sender(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
):
|
||||
service_one['permissions'] = ['inbound_sms']
|
||||
service_one['sms_sender'] = 'SomeNumber'
|
||||
response = logged_in_client.get(url_for(
|
||||
'main.service_settings', service_id=service_one['id']
|
||||
))
|
||||
assert 'Text message sender SomeNumber Change' not in response.get_data(as_text=True)
|
||||
assert url_for('.service_set_sms_sender', service_id=service_one['id'],
|
||||
set_inbound_sms=False) not in response.get_data(as_text=True)
|
||||
assert 'SomeNumber' in response.get_data(as_text=True)
|
||||
|
||||
|
||||
def test_letter_contact_block_shows_none_if_not_set(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
@@ -615,6 +631,80 @@ def test_set_text_message_sender(
|
||||
)
|
||||
|
||||
|
||||
def test_set_text_message_sender_and_inbound_sms(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
mocker,
|
||||
):
|
||||
service_one['permissions'] = []
|
||||
update_service_mock = mocker.patch('app.service_api_client.update_service_with_properties',
|
||||
return_value=service_one)
|
||||
|
||||
data = {"sms_sender": "elevenchars"}
|
||||
response = logged_in_client.post(url_for('main.service_set_sms_sender', service_id=service_one['id'],
|
||||
set_inbound_sms=True),
|
||||
data=data,
|
||||
follow_redirects=True)
|
||||
assert response.status_code == 200
|
||||
|
||||
update_service_mock.assert_called_with(
|
||||
service_one['id'],
|
||||
{'permissions': ['inbound_sms'],
|
||||
'sms_sender': "elevenchars"}
|
||||
)
|
||||
assert app.current_service['permissions'] == ['inbound_sms']
|
||||
|
||||
|
||||
def test_turn_inbound_sms_off(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
mocker,
|
||||
):
|
||||
service_one['permissions'] = ['inbound_sms']
|
||||
update_service_mock = mocker.patch('app.service_api_client.update_service_with_properties',
|
||||
return_value=service_one)
|
||||
|
||||
data = {"sms_sender": "elevenchars"}
|
||||
response = logged_in_client.post(url_for('main.service_set_sms_sender', service_id=service_one['id'],
|
||||
set_inbound_sms=True),
|
||||
data=data,
|
||||
follow_redirects=True)
|
||||
assert response.status_code == 200
|
||||
|
||||
update_service_mock.assert_called_with(
|
||||
service_one['id'],
|
||||
{'permissions': [],
|
||||
'sms_sender': "elevenchars"}
|
||||
)
|
||||
assert app.current_service['permissions'] == []
|
||||
|
||||
|
||||
def test_set_text_message_sender_and_not_inbound_sms(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
mock_get_letter_organisations,
|
||||
mocker,
|
||||
):
|
||||
service_one['permissions'] = []
|
||||
update_service_mock = mocker.patch('app.service_api_client.update_service',
|
||||
return_value=service_one)
|
||||
|
||||
data = {"sms_sender": "elevenchars"}
|
||||
response = logged_in_client.post(url_for('main.service_set_sms_sender', service_id=service_one['id'],
|
||||
set_inbound_sms=False),
|
||||
data=data,
|
||||
follow_redirects=True)
|
||||
assert response.status_code == 200
|
||||
|
||||
update_service_mock.assert_called_with(
|
||||
service_one['id'],
|
||||
sms_sender="elevenchars"
|
||||
)
|
||||
assert app.current_service['permissions'] == []
|
||||
|
||||
|
||||
@pytest.mark.parametrize('content, expected_error', [
|
||||
("", "Can’t be empty"),
|
||||
("twelvecharss", "Enter 11 characters or fewer"),
|
||||
|
||||
@@ -25,6 +25,7 @@ def test_sign_out_user(
|
||||
mock_get_detailed_service,
|
||||
mock_get_yearly_sms_unit_count_and_cost,
|
||||
mock_get_usage,
|
||||
mock_get_inbound_sms_summary,
|
||||
):
|
||||
with logged_in_client.session_transaction() as session:
|
||||
assert session.get('user_id') is not None
|
||||
|
||||
@@ -44,11 +44,11 @@ def test_should_show_page_for_one_template(
|
||||
),
|
||||
(
|
||||
['send_texts', 'send_emails', 'send_letters'],
|
||||
['.send_messages', '.send_test']
|
||||
['.send_messages', '.send_one_off']
|
||||
),
|
||||
(
|
||||
['send_texts', 'send_emails', 'send_letters', 'manage_templates'],
|
||||
['.send_messages', '.send_test', '.edit_service_template']
|
||||
['.send_messages', '.send_one_off', '.edit_service_template']
|
||||
),
|
||||
])
|
||||
def test_should_be_able_to_view_a_template_with_links(
|
||||
|
||||
@@ -29,15 +29,15 @@ def test_from_utils_template_calls_through(
|
||||
@pytest.mark.parametrize('partial_call, expected_url', [
|
||||
(
|
||||
partial(TemplatePreview.from_database_object, filetype='bar'),
|
||||
'http://localhost:6013/preview.bar',
|
||||
'http://localhost:9999/preview.bar',
|
||||
),
|
||||
(
|
||||
partial(TemplatePreview.from_database_object, filetype='baz'),
|
||||
'http://localhost:6013/preview.baz',
|
||||
'http://localhost:9999/preview.baz',
|
||||
),
|
||||
(
|
||||
partial(TemplatePreview.from_database_object, filetype='bar', page=99),
|
||||
'http://localhost:6013/preview.bar?page=99',
|
||||
'http://localhost:9999/preview.bar?page=99',
|
||||
),
|
||||
])
|
||||
def test_from_database_object_makes_request(
|
||||
|
||||
@@ -156,5 +156,7 @@ def test_generate_notifications_csv_calls_twice_if_next_link(mocker):
|
||||
assert mock_get_notifications.mock_calls[1][2]['page'] == 2
|
||||
|
||||
|
||||
def normalize_spaces(string):
|
||||
return ' '.join(string.split())
|
||||
def normalize_spaces(input):
|
||||
if isinstance(input, str):
|
||||
return ' '.join(input.split())
|
||||
return normalize_spaces(' '.join(item.text for item in input))
|
||||
|
||||
Reference in New Issue
Block a user