Merge with master.

This commit is contained in:
Nicholas Staples
2016-02-29 14:59:15 +00:00
60 changed files with 881 additions and 510 deletions

View File

@@ -11,7 +11,6 @@ def test_client_creates_job_data_correctly(mocker):
expected_data = {
"id": job_id,
"service": service_id,
"template": template_id,
"original_file_name": original_file_name,
"bucket_name": "service-{}-notify".format(service_id),

View File

@@ -9,4 +9,4 @@ def test_form_should_have_errors_when_duplicate_service_is_added(app_):
form = AddServiceForm(_get_form_names,
formdata=MultiDict([('name', 'some service')]))
form.validate()
assert {'name': ['Service name already exists']} == form.errors
assert {'name': ['This service name is already in use']} == form.errors

View File

@@ -14,7 +14,7 @@ def test_get_should_render_add_service_template(app_,
client.login(api_user_active)
response = client.get(url_for('main.add_service'))
assert response.status_code == 200
assert 'Add a new service' in response.get_data(as_text=True)
assert 'Which service do you want to set up notifications for?' in response.get_data(as_text=True)
def test_should_add_service_and_redirect_to_next_page(app_,
@@ -31,48 +31,8 @@ def test_should_add_service_and_redirect_to_next_page(app_,
url_for('main.add_service'),
data={'name': 'testing the post'})
assert response.status_code == 302
assert response.location == url_for('main.add_from_address', _external=True)
def test_should_confirm_add_service(
app_,
mock_login,
mock_get_services,
api_user_active,
mock_get_user,
mock_get_user_by_email
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
with client.session_transaction() as session:
session['service_name'] = 'Renew Your Pet Passport'
response = client.get(url_for('main.add_from_address'))
assert response.status_code == 200
assert 'Preview your service name' in response.get_data(as_text=True)
assert 'Renew Your Pet Passport' in response.get_data(as_text=True)
assert 'renew.your.pet.passport@notifications.service.gov.uk' in response.get_data(as_text=True)
def test_should_add_service_after_confirmation(
app_,
mock_login,
mock_create_service,
mock_get_services,
api_user_active,
mock_get_user,
mock_get_user_by_email
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
with client.session_transaction() as session:
session['service_name'] = 'Renew Your Pet Passport'
response = client.post(url_for('main.add_from_address'))
assert response.status_code == 302
assert response.location == url_for('main.service_dashboard', service_id=101, _external=True)
assert mock_create_service.called
assert mock_get_services.called
def test_should_return_form_errors_when_service_name_is_empty(app_,
@@ -87,7 +47,7 @@ def test_should_return_form_errors_when_service_name_is_empty(app_,
client.login(api_user_active)
response = client.post(url_for('main.add_service'), data={})
assert response.status_code == 200
assert 'Service name can not be empty' in response.get_data(as_text=True)
assert 'Service name cant be empty' in response.get_data(as_text=True)
def test_should_return_form_errors_with_duplicate_service_name(app_,
@@ -102,5 +62,5 @@ def test_should_return_form_errors_with_duplicate_service_name(app_,
response = client.post(
url_for('main.add_service'), data={'name': 'service_one'})
assert response.status_code == 200
assert 'Service name already exists' in response.get_data(as_text=True)
assert 'This service name is already in use' in response.get_data(as_text=True)
assert mock_get_services.called

View File

@@ -27,6 +27,7 @@ def test_should_show_page_for_one_job(app_,
mock_login,
mock_get_user,
mock_get_user_by_email,
mock_get_service,
mock_get_service_template,
job_data,
mock_get_job):

View File

@@ -1,12 +1,15 @@
import json
from flask import url_for
from bs4 import BeautifulSoup
def test_should_show_overview_page(
app_,
api_user_active,
mock_login,
mock_get_service
mock_get_service,
mock_get_users_by_service,
mock_get_invites_for_service
):
with app_.test_request_context():
with app_.test_client() as client:
@@ -15,6 +18,7 @@ def test_should_show_overview_page(
assert 'Manage team' in response.get_data(as_text=True)
assert response.status_code == 200
mock_get_users_by_service.assert_called_once_with(service_id='55555')
def test_should_show_page_for_one_user(
@@ -35,7 +39,9 @@ def test_redirect_after_saving_user(
app_,
api_user_active,
mock_login,
mock_get_service
mock_get_service,
mock_get_users_by_service,
mock_get_invites_for_service
):
with app_.test_request_context():
with app_.test_client() as client:
@@ -67,18 +73,34 @@ def test_should_show_page_for_inviting_user(
def test_invite_user(
app_,
service_one,
api_user_active,
mock_login,
mock_get_service
mock_get_users_by_service,
mock_create_invite,
mock_get_invites_for_service
):
from_user = api_user_active.id
service_id = service_one['id']
email_address = 'test@example.gov.uk'
permissions = 'send_messages,manage_service,manage_api_keys'
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
response = client.post(
url_for('main.invite_user', service_id=55555),
data={'email_address': 'test@example.gov.uk'},
url_for('main.invite_user', service_id=service_id),
data={'email_address': email_address,
'send_messages': 'yes',
'manage_service': 'yes',
'manage_api_keys': 'yes'},
follow_redirects=True
)
assert response.status_code == 200
assert 'Invite sent to test@example.gov.uk' in response.get_data(as_text=True)
mock_create_invite.assert_called_with(from_user, service_id, email_address, permissions)
mock_get_invites_for_service.assert_called_with(service_id=service_id)
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.h1.string.strip() == 'Manage team'
flash_banner = page.find('div', class_='banner-default-with-tick').string.strip()
assert flash_banner == 'Invite sent to test@example.gov.uk'

View File

@@ -1,67 +1,85 @@
import pytest
from io import BytesIO
from flask import url_for
from unittest.mock import ANY
import moto
template_types = ['email', 'sms']
def test_choose_sms_template(app_,
api_user_active,
mock_login,
mock_get_user,
mock_check_verify_code,
mock_get_service_templates,
mock_get_jobs):
@pytest.mark.parametrize("template_type", template_types)
def test_choose_template(
template_type,
app_,
api_user_active,
mock_login,
mock_get_user,
mock_get_service,
mock_check_verify_code,
mock_get_service_templates,
mock_get_jobs
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
response = client.get(url_for('main.choose_sms_template', service_id=12345))
response = client.get(url_for('main.choose_template', template_type=template_type, service_id=12345))
assert response.status_code == 200
content = response.get_data(as_text=True)
assert 'template_one' in content
assert 'template one content' in content
assert 'template_two' in content
assert 'template two content' in content
assert '{}_template_one'.format(template_type) in content
assert '{} template one content'.format(template_type) in content
assert '{}_template_two'.format(template_type) in content
assert '{} template two content'.format(template_type) in content
def test_upload_empty_csvfile_returns_to_upload_page(app_,
api_user_active,
mock_login,
mock_get_user,
mock_get_service_templates,
mock_check_verify_code,
mock_get_service_template):
def test_upload_empty_csvfile_returns_to_upload_page(
app_,
api_user_active,
mock_login,
mock_get_user,
mock_get_service,
mock_get_service_templates,
mock_check_verify_code,
mock_get_service_template
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
upload_data = {'file': (BytesIO(''.encode('utf-8')), 'emtpy.csv')}
response = client.post(url_for('main.send_sms', service_id=12345, template_id=54321),
data=upload_data, follow_redirects=True)
response = client.post(
url_for('main.send_messages', service_id=12345, template_id=54321),
data=upload_data,
follow_redirects=True
)
assert response.status_code == 200
content = response.get_data(as_text=True)
assert 'The file emtpy.csv contained no data' in content
@moto.mock_s3
def test_upload_csvfile_with_invalid_phone_shows_check_page_with_errors(app_,
mocker,
api_user_active,
mock_login,
mock_get_user,
mock_get_user_by_email,
mock_get_service_template):
def test_upload_csvfile_with_invalid_phone_shows_check_page_with_errors(
app_,
api_user_active,
mocker,
mock_login,
mock_get_service,
mock_get_service_template,
mock_s3_upload
):
contents = 'phone\n+44 123\n+44 456'
contents = 'to,name\n+44 123,test1\n+44 456,test2'
file_data = (BytesIO(contents.encode('utf-8')), 'invalid.csv')
mocker.patch('app.main.views.send.s3download', return_value=contents)
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
upload_data = {'file': file_data}
response = client.post(url_for('main.send_sms', service_id=12345, template_id=54321),
data=upload_data,
follow_redirects=True)
response = client.post(
url_for('main.send_messages', service_id=12345, template_id=54321),
data=upload_data,
follow_redirects=True
)
assert response.status_code == 200
content = response.get_data(as_text=True)
assert 'Your CSV file contained missing or invalid data' in content
@@ -70,38 +88,68 @@ def test_upload_csvfile_with_invalid_phone_shows_check_page_with_errors(app_,
assert 'Upload a CSV file' in content
@moto.mock_s3
def test_upload_csvfile_removes_empty_lines_and_trailing_commas(
app_,
api_user_active,
mocker,
mock_login,
mock_get_service,
mock_get_service_template,
mock_s3_upload
):
contents = 'to,name,,,\n++44 7700 900981,test1,,,\n+44 7700 900981,test2,,,\n ,,, \n ,,, \t \t \n'
file_data = (BytesIO(contents.encode('utf-8')), 'invalid.csv')
expected_data = {'data': ['to,name', '++44 7700 900981,test1', '+44 7700 900981,test2'],
'file_name': 'invalid.csv'}
mocker.patch('app.main.views.send.s3download',
return_value='to,name\n++44 7700 900981,test1\n+44 7700 900981,test2')
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
upload_data = {'file': file_data}
response = client.post(
url_for('main.send_messages', service_id=12345, template_id=54321),
data=upload_data,
follow_redirects=True
)
assert response.status_code == 200
mock_s3_upload.assert_called_with(ANY, '12345', expected_data, 'eu-west-1')
def test_send_test_message_to_self(
app_,
mocker,
api_user_active,
mock_login,
mock_get_user,
mock_get_user_by_email,
mock_get_service_template
mock_get_service,
mock_get_service_template,
mock_s3_upload
):
expected_data = {'data': ['to', '+4412341234'], 'file_name': 'Test run'}
mocker.patch('app.main.views.send.s3download', return_value='to\r\n+4412341234')
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
response = client.get(
url_for('main.send_sms_to_self', service_id=12345, template_id=54321),
url_for('main.send_message_to_self', service_id=12345, template_id=54321),
follow_redirects=True
)
assert response.status_code == 200
content = response.get_data(as_text=True)
assert 'Test run' in content
assert '+4412341234' in content
mock_s3_upload.assert_called_with(ANY, '12345', expected_data, 'eu-west-1')
@moto.mock_s3
def test_download_example_csv(
app_,
mocker,
api_user_active,
mock_login,
mock_get_user,
mock_get_user_by_email,
mock_get_service,
mock_get_service_template
):
@@ -113,28 +161,29 @@ def test_download_example_csv(
follow_redirects=True
)
assert response.status_code == 200
assert response.get_data(as_text=True) == 'phone\r\n+4412341234\r\n'
assert response.get_data(as_text=True) == 'to\r\n+4412341234\r\n'
assert 'text/csv' in response.headers['Content-Type']
@moto.mock_s3
def test_upload_csvfile_with_valid_phone_shows_all_numbers(app_,
mocker,
api_user_active,
mock_login,
mock_get_user,
mock_get_user_by_email,
mock_get_service_template):
contents = 'phone\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986' # noqa
def test_upload_csvfile_with_valid_phone_shows_all_numbers(
app_,
mocker,
api_user_active,
mock_login,
mock_get_service,
mock_get_service_template,
mock_s3_upload
):
contents = 'to\n+44 7700 900981\n+44 7700 900982\n+44 7700 900983\n+44 7700 900984\n+44 7700 900985\n+44 7700 900986' # noqa
file_data = (BytesIO(contents.encode('utf-8')), 'valid.csv')
mocker.patch('app.main.views.send.s3download', return_value=contents)
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
upload_data = {'file': file_data}
response = client.post(url_for('main.send_sms', service_id=12345, template_id=54321),
response = client.post(url_for('main.send_messages', service_id=12345, template_id=54321),
data=upload_data,
follow_redirects=True)
with client.session_transaction() as sess:
@@ -153,17 +202,17 @@ def test_upload_csvfile_with_valid_phone_shows_all_numbers(app_,
assert '+44 7700 900986' in content
@moto.mock_s3
def test_create_job_should_call_api(app_,
service_one,
api_user_active,
mock_get_user,
mock_get_user_by_email,
mock_login,
job_data,
mock_create_job,
mock_get_job,
mock_get_service_template):
def test_create_job_should_call_api(
app_,
service_one,
api_user_active,
mock_login,
job_data,
mock_create_job,
mock_get_job,
mock_get_service,
mock_get_service_template
):
service_id = service_one['id']
job_id = job_data['id']
@@ -178,7 +227,7 @@ def test_create_job_should_call_api(app_,
session['upload_data'] = {'original_file_name': original_file_name,
'template_id': template_id,
'notification_count': notification_count}
url = url_for('main.check_sms', service_id=service_one['id'], upload_id=job_id)
url = url_for('main.check_messages', service_id=service_one['id'], upload_id=job_id)
response = client.post(url, data=job_data, follow_redirects=True)
assert response.status_code == 200

View File

@@ -90,3 +90,26 @@ def test_should_return_redirect_when_user_is_pending(app_,
'password': 'val1dPassw0rd!'})
assert response.status_code == 302
assert response.location == url_for('main.verify', _external=True)
def test_not_fresh_session_login(app_,
api_user_active,
mock_login,
mock_get_user_by_email,
mock_verify_password,
mock_get_services_with_one_service):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
with client.session_transaction() as session:
assert session['_fresh']
session['_fresh'] = False
# This should skip the two factor
response = client.post(
url_for('main.sign_in'), data={
'email_address': api_user_active.email_address,
'password': 'val1dPassw0rd!'})
assert response.status_code == 302
service_dct = mock_get_services_with_one_service(api_user_active.id)['data'][0]
assert response.location == url_for(
'main.service_dashboard', service_id=service_dct['id'], _external=True)

View File

@@ -7,7 +7,7 @@ def test_render_sign_out_redirects_to_sign_in(app_):
url_for('main.sign_out'))
assert response.status_code == 302
assert response.location == url_for(
'main.sign_in', _external=True, next=url_for('main.sign_out'))
'main.sign_in', _external=True)
def test_sign_out_user(app_,
@@ -22,9 +22,9 @@ def test_sign_out_user(app_,
email = 'valid@example.gov.uk'
password = 'val1dPassw0rd!'
with app_.test_client() as client:
with client.session_transaction() as session:
print('session: {}'.format(session))
client.login(api_user_active)
with client.session_transaction() as session:
assert session.get('user_id') is not None
# Check we are logged in
response = client.get(
url_for('main.service_dashboard', service_id="123"))
@@ -32,5 +32,6 @@ def test_sign_out_user(app_,
response = client.get(url_for('main.sign_out'))
assert response.status_code == 302
assert response.location == url_for(
'main.index', _external=True)
assert session.get('ItsdangerousSession') is None
'main.sign_in', _external=True)
with client.session_transaction() as session:
assert session.get('user_id') is None

View File

@@ -4,24 +4,6 @@ import uuid
from flask import url_for
def test_should_return_list_of_all_templates(app_,
api_user_active,
mock_get_service_templates,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_get_jobs):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
service_id = str(uuid.uuid4())
response = client.get(url_for(
'.manage_service_templates', service_id=service_id), follow_redirects=True)
assert response.status_code == 200
mock_get_service_templates.assert_called_with(service_id)
def test_should_show_page_for_one_templates(app_,
api_user_active,
mock_get_service_template,
@@ -62,8 +44,9 @@ def test_should_redirect_when_saving_a_template(app_,
data = {
'id': template_id,
'name': name,
"template_content": content,
"service": service_id
'template_content': content,
'type': 'sms',
'service': service_id
}
response = client.post(url_for(
'.edit_service_template',
@@ -72,7 +55,7 @@ def test_should_redirect_when_saving_a_template(app_,
assert response.status_code == 302
assert response.location == url_for(
'.choose_sms_template', service_id=service_id, _external=True)
'.choose_template', service_id=service_id, template_type='sms', _external=True)
mock_update_service_template.assert_called_with(
template_id, name, 'sms', content, service_id)
@@ -127,12 +110,13 @@ def test_should_redirect_when_deleting_a_template(app_,
response = client.post(url_for(
'.delete_service_template',
service_id=service_id,
template_id=template_id), data=data)
template_id=template_id
), data=data)
assert response.status_code == 302
assert response.location == url_for(
'.manage_service_templates',
service_id=service_id, _external=True)
'.choose_template',
service_id=service_id, template_type=type_, _external=True)
mock_get_service_template.assert_called_with(
service_id, template_id)
mock_delete_service_template.assert_called_with(

View File

@@ -92,3 +92,20 @@ def test_should_login_user_when_multiple_valid_codes_exist(app_,
response = client.post(url_for('main.two_factor'),
data={'sms_code': '23456'})
assert response.status_code == 302
def test_remember_me_set(app_,
api_user_active,
mock_get_user,
mock_get_user_by_email,
mock_check_verify_code,
mock_get_services_with_one_service):
with app_.test_request_context():
with app_.test_client() as client:
with client.session_transaction() as session:
session['user_details'] = {
'id': api_user_active.id,
'email': api_user_active.email_address}
response = client.post(url_for('main.two_factor'),
data={'sms_code': '23456', 'remember_me': True})
assert response.status_code == 302