Merge branch 'master' of https://github.com/alphagov/notifications-admin into vb-free-sms-history

This commit is contained in:
venusbb
2017-11-09 09:24:49 +00:00
45 changed files with 916 additions and 157 deletions

View File

@@ -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 == "Theres something wrong with the link youve used."

View File

@@ -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

View File

@@ -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:;"

View File

@@ -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,

View File

@@ -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(

View File

@@ -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

View File

@@ -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', [

View File

@@ -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,

View File

@@ -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', [
("", "", "Cant be empty Cant 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 == 'Cant 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,
)

View File

@@ -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,

View File

@@ -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'