mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-07 02:58:24 -04:00
Merge branch 'master' of https://github.com/alphagov/notifications-admin into vb-free-sms-history
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
from flask import Response
|
||||
import pytest
|
||||
from bs4 import BeautifulSoup
|
||||
from notifications_python_client.errors import HTTPError
|
||||
|
||||
|
||||
def test_bad_url_returns_page_not_found(client):
|
||||
@@ -6,3 +9,32 @@ def test_bad_url_returns_page_not_found(client):
|
||||
assert response.status_code == 404
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.string.strip() == 'Page could not be found'
|
||||
|
||||
|
||||
def test_load_service_before_request_handles_404(client_request, mocker):
|
||||
exc = HTTPError(Response(status=404), 'Not found')
|
||||
get_service = mocker.patch('app.service_api_client.get_service', side_effect=exc)
|
||||
|
||||
client_request.get(
|
||||
'main.service_dashboard',
|
||||
service_id='00000000-0000-0000-0000-000000000000',
|
||||
_expected_status=404
|
||||
)
|
||||
|
||||
get_service.assert_called_once_with('00000000-0000-0000-0000-000000000000')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('url', [
|
||||
'/invitation/MALFORMED_TOKEN',
|
||||
'/new-password/MALFORMED_TOKEN',
|
||||
'/user-profile/email/confirm/MALFORMED_TOKEN',
|
||||
'/verify-email/MALFORMED_TOKEN'
|
||||
])
|
||||
def test_malformed_token_returns_page_not_found(logged_in_client, url):
|
||||
response = logged_in_client.get(url)
|
||||
|
||||
assert response.status_code == 404
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.string.strip() == 'Page could not be found'
|
||||
flash_banner = page.find('div', class_='banner-dangerous').string.strip()
|
||||
assert flash_banner == "There’s something wrong with the link you’ve used."
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from flask import url_for
|
||||
from bs4 import BeautifulSoup
|
||||
from unittest.mock import ANY
|
||||
from itsdangerous import SignatureExpired
|
||||
|
||||
import app
|
||||
|
||||
@@ -13,14 +14,14 @@ def test_existing_user_accept_invite_calls_api_and_redirects_to_dashboard(
|
||||
client,
|
||||
service_one,
|
||||
api_user_active,
|
||||
sample_invite,
|
||||
mock_get_service,
|
||||
mock_check_invite_token,
|
||||
mock_get_user_by_email,
|
||||
mock_get_users_by_service,
|
||||
mock_accept_invite,
|
||||
mock_add_user_to_service,
|
||||
mocker,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
expected_service = service_one['id']
|
||||
expected_redirect_location = 'http://localhost/services/{}/dashboard'.format(expected_service)
|
||||
@@ -47,8 +48,8 @@ def test_existing_user_with_no_permissions_accept_invite(
|
||||
mock_get_user_by_email,
|
||||
mock_get_users_by_service,
|
||||
mock_add_user_to_service,
|
||||
mock_get_service,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
expected_service = service_one['id']
|
||||
sample_invite['permissions'] = ''
|
||||
@@ -67,6 +68,7 @@ def test_if_existing_user_accepts_twice_they_redirect_to_sign_in(
|
||||
sample_invite,
|
||||
mock_get_service,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
sample_invite['status'] = 'accepted'
|
||||
invite = InvitedUser(**sample_invite)
|
||||
@@ -93,6 +95,7 @@ def test_existing_user_of_service_get_redirected_to_signin(
|
||||
mock_get_user_by_email,
|
||||
mock_accept_invite,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
sample_invite['email_address'] = api_user_active.email_address
|
||||
invite = InvitedUser(**sample_invite)
|
||||
mocker.patch('app.invite_api_client.check_token', return_value=invite)
|
||||
@@ -122,7 +125,9 @@ def test_existing_signed_out_user_accept_invite_redirects_to_sign_in(
|
||||
mock_add_user_to_service,
|
||||
mock_accept_invite,
|
||||
mock_get_service,
|
||||
mocker,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
expected_service = service_one['id']
|
||||
expected_permissions = ['send_messages', 'manage_service', 'manage_api_keys']
|
||||
@@ -153,7 +158,9 @@ def test_new_user_accept_invite_calls_api_and_redirects_to_registration(
|
||||
mock_add_user_to_service,
|
||||
mock_get_users_by_service,
|
||||
mock_get_service,
|
||||
mocker,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
expected_redirect_location = 'http://localhost/register-from-invite'
|
||||
|
||||
@@ -174,7 +181,9 @@ def test_new_user_accept_invite_calls_api_and_views_registration_page(
|
||||
mock_add_user_to_service,
|
||||
mock_get_users_by_service,
|
||||
mock_get_service,
|
||||
mocker,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'), follow_redirects=True)
|
||||
|
||||
@@ -209,6 +218,7 @@ def test_cancelled_invited_user_accepts_invited_redirect_to_cancelled_invitation
|
||||
mock_get_user,
|
||||
mock_get_service,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
cancelled_invitation = create_sample_invite(mocker, service_one, status='cancelled')
|
||||
mock_check_token_invite(mocker, cancelled_invitation)
|
||||
response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'))
|
||||
@@ -233,7 +243,9 @@ def test_new_user_accept_invite_completes_new_registration_redirects_to_verify(
|
||||
mock_get_users_by_service,
|
||||
mock_add_user_to_service,
|
||||
mock_get_service,
|
||||
mocker,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
expected_service = service_one['id']
|
||||
expected_email = sample_invite['email_address']
|
||||
@@ -282,6 +294,7 @@ def test_signed_in_existing_user_cannot_use_anothers_invite(
|
||||
mock_accept_invite,
|
||||
mock_get_service,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
invite = InvitedUser(**sample_invite)
|
||||
mocker.patch('app.invite_api_client.check_token', return_value=invite)
|
||||
mocker.patch('app.user_api_client.get_users_for_service', return_value=[api_user_active])
|
||||
@@ -322,7 +335,9 @@ def test_new_invited_user_verifies_and_added_to_service(
|
||||
mock_get_users_by_service,
|
||||
mock_get_detailed_service,
|
||||
mock_get_usage,
|
||||
mocker,
|
||||
):
|
||||
mocker.patch('app.main.views.invites.check_token')
|
||||
|
||||
# visit accept token page
|
||||
response = client.get(url_for('main.accept_invite', token='thisisnotarealtoken'))
|
||||
@@ -354,3 +369,21 @@ def test_new_invited_user_verifies_and_added_to_service(
|
||||
raw_html = response.data.decode('utf-8')
|
||||
page = BeautifulSoup(raw_html, 'html.parser')
|
||||
assert page.find('h1').text == 'Dashboard'
|
||||
|
||||
|
||||
def test_gives_message_if_token_has_expired(
|
||||
app_,
|
||||
client,
|
||||
mock_check_invite_token,
|
||||
mocker,
|
||||
):
|
||||
check_token = mocker.patch('app.main.views.invites.check_token', side_effect=SignatureExpired('this is too old'))
|
||||
|
||||
response = client.get(url_for('main.accept_invite', token='a really old token'))
|
||||
raw_html = response.data.decode('utf-8')
|
||||
page = BeautifulSoup(raw_html, 'html.parser')
|
||||
|
||||
check_token.assert_called_once_with(ANY, ANY, ANY, 3600 * 24 * 2)
|
||||
assert response.status_code == 400
|
||||
assert 'Your invitation to GOV.UK Notify has expired' in page.find('h1').text
|
||||
assert not mock_check_invite_token.called
|
||||
|
||||
@@ -10,6 +10,7 @@ def test_owasp_useful_headers_set(client, mocker):
|
||||
assert response.headers['Content-Security-Policy'] == (
|
||||
"default-src 'self' 'unsafe-inline';"
|
||||
"script-src 'self' *.google-analytics.com 'unsafe-inline' 'unsafe-eval' data:;"
|
||||
"connect-src 'self' *.google-analytics.com;"
|
||||
"object-src 'self';"
|
||||
"font-src 'self' data:;"
|
||||
"img-src 'self' *.google-analytics.com *.notifications.service.gov.uk static-logos.test.com data:;"
|
||||
|
||||
@@ -18,7 +18,7 @@ def test_logged_in_user_redirects_to_choose_service(
|
||||
|
||||
@pytest.mark.parametrize('view', [
|
||||
'cookies', 'using_notify', 'pricing', 'terms', 'integration_testing', 'roadmap',
|
||||
'features', 'information_risk_management'
|
||||
'features', 'information_risk_management', 'callbacks'
|
||||
])
|
||||
def test_static_pages(
|
||||
client,
|
||||
|
||||
@@ -10,6 +10,7 @@ from tests.conftest import (
|
||||
SERVICE_ONE_ID,
|
||||
active_user_with_permissions,
|
||||
active_user_view_permissions,
|
||||
active_user_no_mobile,
|
||||
active_user_manage_template_permission,
|
||||
)
|
||||
|
||||
@@ -55,6 +56,94 @@ def test_should_show_overview_page(
|
||||
app.user_api_client.get_users_for_service.assert_called_once_with(service_id=SERVICE_ONE_ID)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, extra_args, service_has_email_auth, auth_options_hidden', [
|
||||
(
|
||||
'main.edit_user_permissions',
|
||||
{'user_id': 0},
|
||||
True,
|
||||
False
|
||||
),
|
||||
(
|
||||
'main.edit_user_permissions',
|
||||
{'user_id': 0},
|
||||
False,
|
||||
True
|
||||
),
|
||||
(
|
||||
'main.invite_user',
|
||||
{},
|
||||
True,
|
||||
False
|
||||
),
|
||||
(
|
||||
'main.invite_user',
|
||||
{},
|
||||
False,
|
||||
True
|
||||
)
|
||||
])
|
||||
def test_service_with_no_email_auth_hides_auth_type_options(
|
||||
client_request,
|
||||
endpoint,
|
||||
extra_args,
|
||||
service_has_email_auth,
|
||||
auth_options_hidden,
|
||||
service_one
|
||||
):
|
||||
if service_has_email_auth:
|
||||
service_one['permissions'].append('email_auth')
|
||||
page = client_request.get(endpoint, service_id=service_one['id'], **extra_args)
|
||||
assert (page.find('input', attrs={"name": "login_authentication"}) is None) == auth_options_hidden
|
||||
|
||||
|
||||
@pytest.mark.parametrize('service_has_email_auth, displays_auth_type', [
|
||||
(True, True),
|
||||
(False, False)
|
||||
])
|
||||
def test_manage_users_page_shows_member_auth_type_if_service_has_email_auth_activated(
|
||||
client_request,
|
||||
service_has_email_auth,
|
||||
service_one,
|
||||
mock_get_users_by_service,
|
||||
mock_get_invites_for_service,
|
||||
displays_auth_type
|
||||
):
|
||||
if service_has_email_auth:
|
||||
service_one['permissions'].append('email_auth')
|
||||
page = client_request.get('main.manage_users', service_id=service_one['id'])
|
||||
assert bool(page.select_one('.tick-cross-list-hint')) == displays_auth_type
|
||||
|
||||
|
||||
@pytest.mark.parametrize('user, sms_option_disabled', [
|
||||
(
|
||||
active_user_no_mobile,
|
||||
True,
|
||||
),
|
||||
(
|
||||
active_user_with_permissions,
|
||||
False,
|
||||
),
|
||||
])
|
||||
def test_user_with_no_mobile_number_cant_be_set_to_sms_auth(
|
||||
client_request,
|
||||
user,
|
||||
sms_option_disabled,
|
||||
service_one,
|
||||
mocker
|
||||
):
|
||||
service_one['permissions'].append('email_auth')
|
||||
test_user = mocker.patch('app.user_api_client.get_user', return_value=user(mocker))
|
||||
|
||||
page = client_request.get(
|
||||
'main.edit_user_permissions',
|
||||
service_id=service_one['id'],
|
||||
user_id=test_user.id
|
||||
)
|
||||
|
||||
sms_auth_radio_button = page.select_one('input[value="sms_auth"]')
|
||||
assert sms_auth_radio_button.has_attr("disabled") == sms_option_disabled
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, extra_args, expected_checkboxes', [
|
||||
(
|
||||
'main.edit_user_permissions',
|
||||
@@ -167,6 +256,60 @@ def test_edit_some_user_permissions(
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('auth_type', ['email_auth', 'sms_auth'])
|
||||
def test_edit_user_permissions_including_authentication_with_email_auth_service(
|
||||
logged_in_client,
|
||||
active_user_with_permissions,
|
||||
mocker,
|
||||
mock_get_invites_for_service,
|
||||
mock_set_user_permissions,
|
||||
mock_update_user_attribute,
|
||||
service_one,
|
||||
auth_type
|
||||
):
|
||||
service_one['permissions'].append('email_auth')
|
||||
|
||||
response = logged_in_client.post(
|
||||
url_for(
|
||||
'main.edit_user_permissions',
|
||||
service_id=service_one['id'],
|
||||
user_id=active_user_with_permissions.id
|
||||
),
|
||||
data={
|
||||
'email_address': active_user_with_permissions.email_address,
|
||||
'send_messages': 'y',
|
||||
'manage_templates': 'y',
|
||||
'manage_service': 'y',
|
||||
'manage_api_keys': 'y',
|
||||
'login_authentication': auth_type
|
||||
}
|
||||
)
|
||||
|
||||
mock_set_user_permissions.assert_called_with(
|
||||
str(active_user_with_permissions.id),
|
||||
service_one['id'],
|
||||
permissions={
|
||||
'send_texts',
|
||||
'send_emails',
|
||||
'send_letters',
|
||||
'manage_users',
|
||||
'manage_templates',
|
||||
'manage_settings',
|
||||
'manage_api_keys',
|
||||
'view_activity'
|
||||
}
|
||||
)
|
||||
mock_update_user_attribute.assert_called_with(
|
||||
str(active_user_with_permissions.id),
|
||||
auth_type=auth_type
|
||||
)
|
||||
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for(
|
||||
'main.manage_users', service_id=service_one['id'], _external=True
|
||||
)
|
||||
|
||||
|
||||
def test_should_show_page_for_inviting_user(
|
||||
logged_in_client,
|
||||
active_user_with_permissions,
|
||||
@@ -220,7 +363,60 @@ def test_invite_user(
|
||||
app.invite_api_client.create_invite.assert_called_once_with(sample_invite['from_user'],
|
||||
sample_invite['service'],
|
||||
email_address,
|
||||
expected_permissions)
|
||||
expected_permissions,
|
||||
'sms_auth')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('auth_type', [
|
||||
('sms_auth'),
|
||||
('email_auth')
|
||||
])
|
||||
@pytest.mark.parametrize('email_address, gov_user', [
|
||||
('test@example.gov.uk', True),
|
||||
('test@nonwhitelist.com', False)
|
||||
])
|
||||
def test_invite_user_with_email_auth_service(
|
||||
logged_in_client,
|
||||
active_user_with_permissions,
|
||||
sample_invite,
|
||||
email_address,
|
||||
gov_user,
|
||||
mocker,
|
||||
service_one,
|
||||
auth_type
|
||||
):
|
||||
service_one['permissions'].append('email_auth')
|
||||
sample_invite['email_address'] = 'test@example.gov.uk'
|
||||
|
||||
data = [InvitedUser(**sample_invite)]
|
||||
assert is_gov_user(email_address) == gov_user
|
||||
mocker.patch('app.invite_api_client.get_invites_for_service', return_value=data)
|
||||
mocker.patch('app.user_api_client.get_users_for_service', return_value=[active_user_with_permissions])
|
||||
mocker.patch('app.invite_api_client.create_invite', return_value=InvitedUser(**sample_invite))
|
||||
response = logged_in_client.post(
|
||||
url_for('main.invite_user', service_id=service_one['id']),
|
||||
data={'email_address': email_address,
|
||||
'send_messages': 'y',
|
||||
'manage_templates': 'y',
|
||||
'manage_service': 'y',
|
||||
'manage_api_keys': 'y',
|
||||
'login_authentication': auth_type},
|
||||
follow_redirects=True
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.string.strip() == 'Team members'
|
||||
flash_banner = page.find('div', class_='banner-default-with-tick').string.strip()
|
||||
assert flash_banner == 'Invite sent to test@example.gov.uk'
|
||||
|
||||
expected_permissions = 'manage_api_keys,manage_settings,manage_templates,manage_users,send_emails,send_letters,send_texts,view_activity' # noqa
|
||||
|
||||
app.invite_api_client.create_invite.assert_called_once_with(sample_invite['from_user'],
|
||||
sample_invite['service'],
|
||||
email_address,
|
||||
expected_permissions,
|
||||
auth_type)
|
||||
|
||||
|
||||
def test_cancel_invited_user_cancels_user_invitations(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from itsdangerous import SignatureExpired
|
||||
from flask import url_for
|
||||
from notifications_utils.url_safe_token import generate_token
|
||||
|
||||
@@ -69,13 +70,13 @@ def test_should_redirect_index_if_user_has_already_changed_password(
|
||||
def test_should_redirect_to_forgot_password_with_flash_message_when_token_is_expired(
|
||||
app_,
|
||||
client,
|
||||
mock_get_user_by_email_request_password_reset,
|
||||
mock_login,
|
||||
mocker
|
||||
):
|
||||
app_.config['TOKEN_MAX_AGE_SECONDS'] = -1000
|
||||
user = mock_get_user_by_email_request_password_reset.return_value
|
||||
token = generate_token(user.email_address, app_.config['SECRET_KEY'], app_.config['DANGEROUS_SALT'])
|
||||
response = client.post(url_for('.new_password', token=token), data={'new_password': 'a-new_password'})
|
||||
mocker.patch('app.main.views.new_password.check_token', side_effect=SignatureExpired('expired'))
|
||||
token = generate_token('foo@bar.com', app_.config['SECRET_KEY'], app_.config['DANGEROUS_SALT'])
|
||||
|
||||
response = client.get(url_for('.new_password', token=token))
|
||||
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for('.forgot_password', _external=True)
|
||||
app_.config['TOKEN_MAX_AGE_SECONDS'] = 3600
|
||||
|
||||
@@ -97,7 +97,7 @@ def test_should_render_platform_admin_page(
|
||||
response = client.get(url_for(endpoint))
|
||||
assert response.status_code == 200
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert len(page.select('tbody tr')) == expected_services_shown * 2 # one row for SMS, one for email
|
||||
assert len(page.select('tbody tr')) == expected_services_shown * 3 # one row for SMS, one for email, one for letter
|
||||
mock_get_detailed_services.assert_called_once_with({'detailed': True,
|
||||
'include_from_test_key': True,
|
||||
'only_active': False})
|
||||
@@ -543,7 +543,7 @@ def test_should_show_correct_sent_totals_for_platform_admin(
|
||||
|
||||
assert email_total == 60
|
||||
assert sms_total == 40
|
||||
assert letter_total == 45
|
||||
assert letter_total == 60
|
||||
|
||||
|
||||
@pytest.mark.parametrize('endpoint, restricted, research_mode', [
|
||||
|
||||
@@ -27,6 +27,10 @@ from tests.conftest import (
|
||||
mock_get_live_service,
|
||||
multiple_reply_to_email_addresses,
|
||||
no_reply_to_email_addresses,
|
||||
multiple_sms_senders,
|
||||
no_sms_senders,
|
||||
multiple_sms_senders_with_diff_default,
|
||||
multiple_sms_senders_no_inbound
|
||||
)
|
||||
|
||||
template_types = ['email', 'sms']
|
||||
@@ -43,6 +47,12 @@ test_non_spreadsheet_files = glob(path.join('tests', 'non_spreadsheet_files', '*
|
||||
'Choose where to send replies',
|
||||
'Select an email address that recipients can reply to'
|
||||
),
|
||||
(
|
||||
mock_get_service_template,
|
||||
multiple_sms_senders,
|
||||
'Chose text message sender',
|
||||
'Select a text message sender that the recipients can reply to'
|
||||
)
|
||||
])
|
||||
def test_show_correct_title_and_description_for_sender_type(
|
||||
client_request,
|
||||
@@ -67,12 +77,47 @@ def test_show_correct_title_and_description_for_sender_type(
|
||||
assert normalize_spaces(page.select_one('legend').text) == expected_description
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_mock, sender_data', [
|
||||
(
|
||||
mock_get_service_email_template,
|
||||
multiple_reply_to_email_addresses,
|
||||
),
|
||||
(
|
||||
mock_get_service_template,
|
||||
multiple_sms_senders_with_diff_default
|
||||
),
|
||||
(
|
||||
mock_get_service_template,
|
||||
multiple_sms_senders_no_inbound
|
||||
)
|
||||
])
|
||||
def test_default_sender_is_checked_and_has_hint(
|
||||
client_request,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mock_get_service_email_template,
|
||||
multiple_reply_to_email_addresses
|
||||
template_mock,
|
||||
sender_data,
|
||||
mocker
|
||||
):
|
||||
template_mock(mocker)
|
||||
sender_data(mocker)
|
||||
page = client_request.get(
|
||||
'.set_sender',
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid
|
||||
)
|
||||
|
||||
assert page.select('.multiple-choice input')[0].has_attr('checked')
|
||||
assert normalize_spaces(page.select_one('.multiple-choice label .block-label-hint').text) == "(Default)"
|
||||
assert not page.select('.multiple-choice input')[1].has_attr('checked')
|
||||
|
||||
|
||||
def test_default_inbound_sender_is_checked_and_has_hint_with_default_and_receives_text(
|
||||
client_request,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mock_get_service_template,
|
||||
multiple_sms_senders
|
||||
):
|
||||
page = client_request.get(
|
||||
'.set_sender',
|
||||
@@ -81,18 +126,52 @@ def test_default_sender_is_checked_and_has_hint(
|
||||
)
|
||||
|
||||
assert page.select('.multiple-choice input')[0].has_attr('checked')
|
||||
assert normalize_spaces(page.select_one('.multiple-choice label .block-label-hint').text) == "Default"
|
||||
assert normalize_spaces(
|
||||
page.select_one('.multiple-choice label .block-label-hint').text) == "(Default and receives replies)"
|
||||
assert not page.select('.multiple-choice input')[1].has_attr('checked')
|
||||
assert not page.select('.multiple-choice input')[2].has_attr('checked')
|
||||
|
||||
|
||||
def test_sms_sender_has_receives_replies_hint(
|
||||
client_request,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mock_get_service_template,
|
||||
multiple_sms_senders
|
||||
):
|
||||
page = client_request.get(
|
||||
'.set_sender',
|
||||
service_id=service_one['id'],
|
||||
template_id=fake_uuid
|
||||
)
|
||||
|
||||
assert page.select('.multiple-choice input')[0].has_attr('checked')
|
||||
assert normalize_spaces(
|
||||
page.select_one('.multiple-choice label .block-label-hint').text) == "(Default and receives replies)"
|
||||
assert not page.select('.multiple-choice input')[1].has_attr('checked')
|
||||
assert not page.select('.multiple-choice input')[2].has_attr('checked')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('template_mock, sender_data', [
|
||||
(
|
||||
mock_get_service_email_template,
|
||||
multiple_reply_to_email_addresses,
|
||||
),
|
||||
(
|
||||
mock_get_service_template,
|
||||
multiple_sms_senders
|
||||
)
|
||||
])
|
||||
def test_sender_session_is_present_after_selected(
|
||||
logged_in_client,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mock_get_service_email_template,
|
||||
multiple_reply_to_email_addresses
|
||||
template_mock,
|
||||
sender_data,
|
||||
mocker
|
||||
):
|
||||
template_mock(mocker)
|
||||
sender_data(mocker)
|
||||
logged_in_client.post(
|
||||
url_for('.set_sender', service_id=service_one['id'], template_id=fake_uuid),
|
||||
data={'sender': '1234'}
|
||||
@@ -107,6 +186,10 @@ def test_sender_session_is_present_after_selected(
|
||||
mock_get_service_email_template,
|
||||
no_reply_to_email_addresses,
|
||||
),
|
||||
(
|
||||
mock_get_service_template,
|
||||
no_sms_senders
|
||||
)
|
||||
])
|
||||
def test_set_sender_redirects_if_no_sender_data(
|
||||
logged_in_client,
|
||||
|
||||
@@ -45,6 +45,7 @@ from freezegun import freeze_time
|
||||
'Label Value Action',
|
||||
'Send text messages On Change',
|
||||
'Text message sender GOVUK Manage',
|
||||
'Text messages start with service name On Change',
|
||||
'International text messages Off Change',
|
||||
'Receive text messages Off Change',
|
||||
|
||||
@@ -64,6 +65,7 @@ from freezegun import freeze_time
|
||||
'Label Value Action',
|
||||
'Send text messages On Change',
|
||||
'Text message sender GOVUK Manage',
|
||||
'Text messages start with service name On Change',
|
||||
'International text messages Off Change',
|
||||
'Receive text messages Off Change',
|
||||
|
||||
@@ -121,9 +123,10 @@ def test_should_show_overview(
|
||||
'Label Value Action',
|
||||
'Send text messages On Change',
|
||||
'Text message sender GOVUK Manage',
|
||||
'Text messages start with service name On Change',
|
||||
'International text messages On Change',
|
||||
'Receive text messages On Change',
|
||||
'API endpoint for received text messages Not set Change',
|
||||
'Callback URL for received text messages Not set Change',
|
||||
|
||||
'Label Value Action',
|
||||
'Send letters Off Change',
|
||||
@@ -140,6 +143,7 @@ def test_should_show_overview(
|
||||
'Label Value Action',
|
||||
'Send text messages On Change',
|
||||
'Text message sender GOVUK Manage',
|
||||
'Text messages start with service name On Change',
|
||||
'International text messages Off Change',
|
||||
'Receive text messages Off Change',
|
||||
|
||||
@@ -209,7 +213,7 @@ def test_service_settings_show_elided_api_url_if_needed(
|
||||
|
||||
non_empty_trs = [tr.find_all('td') for tr in page.find_all('tr') if tr.find_all('td')]
|
||||
api_url = [api_setting[1].text.strip() for api_setting in non_empty_trs
|
||||
if api_setting[0].text.strip() == 'API endpoint for received text messages'][0]
|
||||
if api_setting[0].text.strip() == 'Callback URL for received text messages'][0]
|
||||
assert api_url == elided_url
|
||||
assert mocked_get_fn.called is True
|
||||
|
||||
@@ -715,7 +719,7 @@ def test_and_more_hint_appears_on_settings_with_more_than_just_a_single_sender(
|
||||
|
||||
assert get_row(page, 2) == "Email reply to addresses test@example.com …and 2 more Manage"
|
||||
assert get_row(page, 4) == "Text message sender Example …and 2 more Manage"
|
||||
assert get_row(page, 8) == "Sender addresses 1 Example Street …and 2 more Manage"
|
||||
assert get_row(page, 9) == "Sender addresses 1 Example Street …and 2 more Manage"
|
||||
|
||||
|
||||
@pytest.mark.parametrize('sender_list_page, expected_output', [
|
||||
@@ -763,7 +767,7 @@ def test_api_ids_dont_show_on_option_pages_with_a_single_sender(
|
||||
), (
|
||||
'main.service_sms_senders',
|
||||
multiple_sms_senders,
|
||||
'Example (default and recieves replies) Change 1234',
|
||||
'Example (default and receives replies) Change 1234',
|
||||
'Example 2 Change 5678',
|
||||
'Example 3 Change 9457'
|
||||
),
|
||||
@@ -1274,7 +1278,7 @@ def test_does_not_show_research_mode_indicator(
|
||||
|
||||
@pytest.mark.parametrize('url, bearer_token, expected_errors', [
|
||||
("", "", "Can’t be empty Can’t be empty"),
|
||||
("http://not_https.com", "1234567890", "Must be a valid https url"),
|
||||
("http://not_https.com", "1234567890", "Must be a valid https URL"),
|
||||
("https://test.com", "123456789", "Must be at least 10 characters"),
|
||||
])
|
||||
def test_set_inbound_api_validation(
|
||||
@@ -2075,3 +2079,46 @@ def test_empty_letter_contact_block_returns_error(
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
error_message = page.find('span', class_='error-message').text.strip()
|
||||
assert error_message == 'Can’t be empty'
|
||||
|
||||
|
||||
def test_show_sms_prefixing_setting_page(
|
||||
client_request,
|
||||
mock_update_service,
|
||||
):
|
||||
page = client_request.get(
|
||||
'main.service_set_sms_prefix', service_id=SERVICE_ONE_ID
|
||||
)
|
||||
assert normalize_spaces(page.select_one('legend').text) == (
|
||||
'Start all text messages with ‘service one:’'
|
||||
)
|
||||
radios = page.select('input[type=radio]')
|
||||
assert len(radios) == 2
|
||||
assert radios[0]['value'] == 'on'
|
||||
assert radios[0]['checked'] == ''
|
||||
assert radios[1]['value'] == 'off'
|
||||
with pytest.raises(KeyError):
|
||||
assert radios[1]['checked']
|
||||
|
||||
|
||||
@pytest.mark.parametrize('post_value, expected_api_argument', [
|
||||
('on', True),
|
||||
('off', False),
|
||||
])
|
||||
def test_updates_sms_prefixing(
|
||||
client_request,
|
||||
mock_update_service,
|
||||
post_value,
|
||||
expected_api_argument,
|
||||
):
|
||||
client_request.post(
|
||||
'main.service_set_sms_prefix', service_id=SERVICE_ONE_ID,
|
||||
_data={'enabled': post_value},
|
||||
_expected_redirect=url_for(
|
||||
'main.service_settings', service_id=SERVICE_ONE_ID,
|
||||
_external=True
|
||||
)
|
||||
)
|
||||
mock_update_service.assert_called_once_with(
|
||||
service_id=SERVICE_ONE_ID,
|
||||
prefix_sms=expected_api_argument,
|
||||
)
|
||||
|
||||
@@ -335,13 +335,14 @@ def test_should_not_allow_creation_of_a_template_without_correct_permission(
|
||||
|
||||
@pytest.mark.parametrize('fixture, expected_status_code', [
|
||||
(mock_get_service_email_template, 200),
|
||||
(mock_get_service_template, 302),
|
||||
(mock_get_service_template, 200),
|
||||
(mock_get_service_letter_template, 302),
|
||||
])
|
||||
def test_should_redirect_to_one_off_if_template_type_is_not_email(
|
||||
def test_should_redirect_to_one_off_if_template_type_is_letter(
|
||||
logged_in_client,
|
||||
active_user_with_permissions,
|
||||
multiple_reply_to_email_addresses,
|
||||
multiple_sms_senders,
|
||||
service_one,
|
||||
fake_uuid,
|
||||
mocker,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import uuid
|
||||
import json
|
||||
|
||||
from itsdangerous import SignatureExpired
|
||||
from flask import url_for
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
@@ -97,7 +98,7 @@ def test_verify_email_redirects_to_verify_if_token_valid(
|
||||
mock_send_verify_code,
|
||||
mock_check_verify_code,
|
||||
):
|
||||
token_data = {"user_id": api_user_pending.id, "secret_code": 12345}
|
||||
token_data = {"user_id": api_user_pending.id, "secret_code": 'UNUSED'}
|
||||
mocker.patch('app.main.views.verify.check_token', return_value=json.dumps(token_data))
|
||||
|
||||
with client.session_transaction() as session:
|
||||
@@ -108,39 +109,20 @@ def test_verify_email_redirects_to_verify_if_token_valid(
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for('main.verify', _external=True)
|
||||
|
||||
assert not mock_check_verify_code.called
|
||||
mock_send_verify_code.assert_called_once_with(api_user_pending.id, 'sms', api_user_pending.mobile_number)
|
||||
|
||||
with client.session_transaction() as session:
|
||||
assert session['user_details'] == {'email': api_user_pending.email_address, 'id': api_user_pending.id}
|
||||
|
||||
|
||||
def test_verify_email_redirects_to_email_sent_if_token_expired(
|
||||
client,
|
||||
mocker,
|
||||
api_user_pending,
|
||||
mock_check_verify_code,
|
||||
):
|
||||
from itsdangerous import SignatureExpired
|
||||
mocker.patch('app.main.views.verify.check_token', side_effect=SignatureExpired('expired'))
|
||||
|
||||
with client.session_transaction() as session:
|
||||
session['user_details'] = {'email_address': api_user_pending.email_address, 'id': api_user_pending.id}
|
||||
|
||||
response = client.get(url_for('main.verify_email', token='notreal'))
|
||||
|
||||
assert response.status_code == 302
|
||||
assert response.location == url_for('main.resend_email_verification', _external=True)
|
||||
|
||||
|
||||
def test_verify_email_redirects_to_email_sent_if_token_used(
|
||||
client,
|
||||
mocker,
|
||||
api_user_pending,
|
||||
mock_get_user_pending,
|
||||
mock_send_verify_code,
|
||||
mock_check_verify_code_code_expired,
|
||||
):
|
||||
from itsdangerous import SignatureExpired
|
||||
mocker.patch('app.main.views.verify.check_token', side_effect=SignatureExpired('expired'))
|
||||
|
||||
with client.session_transaction() as session:
|
||||
session['user_details'] = {'email_address': api_user_pending.email_address, 'id': api_user_pending.id}
|
||||
|
||||
response = client.get(url_for('main.verify_email', token='notreal'))
|
||||
|
||||
assert response.status_code == 302
|
||||
@@ -158,9 +140,6 @@ def test_verify_email_redirects_to_sign_in_if_user_active(
|
||||
token_data = {"user_id": api_user_active.id, "secret_code": 12345}
|
||||
mocker.patch('app.main.views.verify.check_token', return_value=json.dumps(token_data))
|
||||
|
||||
with client.session_transaction() as session:
|
||||
session['user_details'] = {'email_address': api_user_active.email_address, 'id': api_user_active.id}
|
||||
|
||||
response = client.get(url_for('main.verify_email', token='notreal'), follow_redirects=True)
|
||||
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
|
||||
assert page.h1.text == 'Sign in'
|
||||
|
||||
Reference in New Issue
Block a user