Merge branch 'master' into remove-code-that-handled-old-new-job-api

Conflicts:
	app/main/views/jobs.py
	app/notify_client/job_api_client.py
This commit is contained in:
Martyn Inglis
2016-09-05 14:29:58 +01:00
64 changed files with 1455 additions and 814 deletions

View File

@@ -0,0 +1,22 @@
import pytest
from app.main.forms import ChooseTimeForm
from freezegun import freeze_time
@freeze_time("2016-01-01 11:09:00.061258")
def test_form_contains_next_24h(app_):
choices = ChooseTimeForm().scheduled_for.choices
assert choices[0] == ('', 'Now')
assert choices[1] == ('2016-01-01T12:00:00.061258', 'Midday')
assert choices[23] == ('2016-01-02T10:00:00.061258', '10am')
with pytest.raises(IndexError):
assert choices[24]
@freeze_time("2016-01-01 11:09:00.061258")
def test_form_defaults_to_now(app_):
assert ChooseTimeForm().scheduled_for.data == ''

View File

@@ -137,8 +137,8 @@ def test_sms_sender_form_validation(app_, mock_get_user_by_email):
form.sms_sender.data = 'morethanelevenchars'
form.validate()
assert "Text message sender can't be longer than 11 characters" == form.errors['sms_sender'][0]
assert "Enter fewer than 11 characters" == form.errors['sms_sender'][0]
form.sms_sender.data = '###########'
form.validate()
assert 'Text message sender can only contain alpha-numeric characters' == form.errors['sms_sender'][0]
assert 'Use letters and numbers only' == form.errors['sms_sender'][0]

View File

@@ -39,7 +39,7 @@ def test_should_show_api_keys_page(app_,
resp_data = response.get_data(as_text=True)
assert 'some key name' in resp_data
assert 'another key name' in resp_data
assert 'Revoked 1 January at 01:00' in resp_data
assert 'Revoked 1 January at 1:00am' in resp_data
mock_get_api_keys.assert_called_once_with(service_id=fake_uuid)

View File

@@ -107,7 +107,7 @@ def test_should_show_recent_templates_on_dashboard(app_,
assert 'Test Service' in headers
assert 'In the last 7 days' in headers
table_rows = page.find_all('tbody')[0].find_all('tr')
table_rows = page.find_all('tbody')[1].find_all('tr')
assert len(table_rows) == 2
@@ -159,20 +159,20 @@ def test_should_show_all_templates_on_template_statistics_page(
@freeze_time("2016-01-01 11:09:00.061258")
def test_should_show_recent_jobs_on_dashboard(
app_,
mocker,
api_user_active,
mock_get_service,
mock_get_service_templates,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_get_template_statistics,
mock_get_detailed_service,
mock_get_jobs,
mock_has_permissions,
mock_get_usage
def test_should_show_upcoming_jobs_on_dashboard(
app_,
mocker,
api_user_active,
mock_get_service,
mock_get_service_templates,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_get_template_statistics,
mock_get_detailed_service,
mock_get_jobs,
mock_has_permissions,
mock_get_usage
):
with app_.test_request_context(), app_.test_client() as client:
client.login(api_user_active)
@@ -182,7 +182,43 @@ def test_should_show_recent_jobs_on_dashboard(
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
table_rows = page.find_all('tbody')[1].find_all('tr')
table_rows = page.find_all('tbody')[0].find_all('tr')
assert len(table_rows) == 2
assert 'send_me_later.csv' in table_rows[0].find_all('th')[0].text
assert 'Sending at 11:09am' in table_rows[0].find_all('th')[0].text
assert table_rows[0].find_all('td')[0].text.strip() == '1'
assert 'even_later.csv' in table_rows[1].find_all('th')[0].text
assert 'Sending at 11:09pm' in table_rows[1].find_all('th')[0].text
assert table_rows[1].find_all('td')[0].text.strip() == '1'
@freeze_time("2016-01-01 11:09:00.061258")
def test_should_show_recent_jobs_on_dashboard(
app_,
mocker,
api_user_active,
mock_get_service,
mock_get_service_templates,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_get_template_statistics,
mock_get_detailed_service,
mock_get_jobs,
mock_has_permissions,
mock_get_usage
):
with app_.test_request_context(), app_.test_client() as client:
client.login(api_user_active)
response = client.get(url_for('main.service_dashboard', service_id=SERVICE_ONE_ID))
mock_get_jobs.assert_called_once_with(SERVICE_ONE_ID, limit_days=7)
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
table_rows = page.find_all('tbody')[2].find_all('tr')
assert "Test message" not in page.text
assert len(table_rows) == 4
@@ -194,7 +230,7 @@ def test_should_show_recent_jobs_on_dashboard(
"thisisatest.csv",
)):
assert filename in table_rows[index].find_all('th')[0].text
assert 'Uploaded 1 January at 11:09' in table_rows[index].find_all('th')[0].text
assert 'Sent 1 January at 11:09' in table_rows[index].find_all('th')[0].text
for column_index, count in enumerate((1, 0, 0)):
assert table_rows[index].find_all('td')[column_index].text.strip() == str(count)

View File

@@ -78,7 +78,7 @@ def test_should_show_page_for_one_job(
'{}: Your vehicle tax is about to expire'.format(service_one['name'])
)
assert ' '.join(page.find('tbody').find('tr').text.split()) == (
'07123456789 1 January at 11:10 Delivered'
'07123456789 1 January at 11:10am Delivered'
)
assert page.find('div', {'data-key': 'notifications'})['data-resource'] == url_for(
'main.view_job_updates',
@@ -126,6 +126,29 @@ def test_should_show_job_in_progress(
assert page.find('p', {'class': 'hint'}).text.strip() == 'Report is 50% complete…'
def test_should_show_scheduled_job(
app_,
service_one,
active_user_with_permissions,
mock_get_service_template,
mock_get_scheduled_job,
mocker,
mock_get_notifications,
fake_uuid
):
with app_.test_request_context(), app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
response = client.get(url_for(
'main.view_job',
service_id=service_one['id'],
job_id=fake_uuid
))
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.find('main').find_all('p')[2].text.strip() == 'Sending will start at midnight'
def test_should_show_not_show_csv_download_in_tour(
app_,
service_one,
@@ -160,7 +183,7 @@ def test_should_show_not_show_csv_download_in_tour(
) not in response.get_data(as_text=True)
@freeze_time("2016-01-01 11:09:00.061258")
@freeze_time("2016-01-01 00:00:00.000001")
def test_should_show_updates_for_one_job_as_json(
app_,
service_one,
@@ -185,8 +208,8 @@ def test_should_show_updates_for_one_job_as_json(
assert '07123456789' in content['notifications']
assert 'Status' in content['notifications']
assert 'Delivered' in content['notifications']
assert '11:10' in content['notifications']
assert 'Uploaded by Test User on 1 January at 11:09' in content['status']
assert '12:01am' in content['notifications']
assert 'Uploaded by Test User on 1 January at midnight' in content['status']
@pytest.mark.parametrize(
@@ -335,7 +358,7 @@ def test_should_download_notifications_for_a_job(app_,
assert response.status_code == 200
assert response.get_data(as_text=True) == csv_content
assert 'text/csv' in response.headers['Content-Type']
assert 'sample template - 1 January at 11:09.csv"' in response.headers['Content-Disposition']
assert 'sample template - 1 January at 11:09am.csv"' in response.headers['Content-Disposition']
@pytest.mark.parametrize(

View File

@@ -2,10 +2,13 @@ from datetime import date
from flask import url_for
from freezegun import freeze_time
import pytest
from bs4 import BeautifulSoup
from tests.conftest import mock_get_user
from tests import service_json
from app.main.views.platform_admin import get_statistics, format_stats_by_service
from app.main.views.platform_admin import get_statistics, format_stats_by_service, create_global_stats
def test_should_redirect_if_not_logged_in(app_):
@@ -27,12 +30,44 @@ def test_should_403_if_not_platform_admin(app_, active_user_with_permissions, mo
assert response.status_code == 403
@pytest.mark.parametrize('restricted, research_mode, displayed', [
(True, False, ''),
(False, False, 'Live'),
(False, True, 'research mode'),
(True, True, 'research mode')
])
def test_should_show_research_and_restricted_mode(
restricted,
research_mode,
displayed,
app_,
platform_admin_user,
mocker,
mock_get_detailed_services,
fake_uuid
):
services = [service_json(fake_uuid, 'My Service', [], restricted=restricted, research_mode=research_mode)]
services[0]['statistics'] = create_stats()
mock_get_detailed_services.return_value = {'data': services}
with app_.test_request_context():
with app_.test_client() as client:
mock_get_user(mocker, user=platform_admin_user)
client.login(platform_admin_user)
response = client.get(url_for('main.platform_admin'))
assert response.status_code == 200
mock_get_detailed_services.assert_called_once_with({'detailed': True})
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
# get second column, which contains flags as text.
assert page.tbody.select('td:nth-of-type(2)')[0].text.strip() == displayed
def test_should_render_platform_admin_page(
app_,
platform_admin_user,
mocker,
mock_get_services,
mock_get_all_service_statistics
mock_get_detailed_services,
):
with app_.test_request_context():
with app_.test_client() as client:
@@ -40,33 +75,49 @@ def test_should_render_platform_admin_page(
client.login(platform_admin_user)
response = client.get(url_for('main.platform_admin'))
assert response.status_code == 200
resp_data = response.get_data(as_text=True)
assert 'Platform admin' in resp_data
assert 'Today' in resp_data
assert 'Services' in resp_data
assert response.status_code == 200
resp_data = response.get_data(as_text=True)
assert 'Platform admin' in resp_data
assert 'Today' in resp_data
assert 'Services' in resp_data
mock_get_detailed_services.assert_called_once_with({'detailed': True})
def test_get_statistics_should_summarise_all_stats(mock_get_all_service_statistics, mock_get_services):
resp = get_statistics()['global_stats']
def test_create_global_stats_sets_failure_rates(fake_uuid):
services = [
service_json(fake_uuid, 'a', []),
service_json(fake_uuid, 'b', [])
]
services[0]['statistics'] = create_stats(
emails_requested=1,
emails_delivered=1,
emails_failed=0,
)
services[1]['statistics'] = create_stats(
emails_requested=2,
emails_delivered=1,
emails_failed=1,
)
assert 'emails_delivered' in resp
assert 'emails_failed' in resp
assert 'emails_failure_rate' in resp
assert 'sms_delivered' in resp
assert 'sms_failed' in resp
assert 'sms_failure_rate' in resp
stats = create_global_stats(services)
@freeze_time('2000-06-30T23:30:00', tz_offset=0)
def test_get_statistics_should_query_for_today_forced_to_GMT(mock_get_all_service_statistics, mock_get_services):
get_statistics()
mock_get_all_service_statistics.assert_called_once_with(date(2000, 7, 1))
assert stats == {
'email': {
'delivered': 2,
'failed': 1,
'requested': 3,
'failure_rate': '33.3'
},
'sms': {
'delivered': 0,
'failed': 0,
'requested': 0,
'failure_rate': '0'
}
}
def create_stats(
service,
emails_requested=0,
emails_delivered=0,
emails_failed=0,
@@ -75,59 +126,31 @@ def create_stats(
sms_failed=0
):
return {
'service': service,
'emails_requested': emails_requested,
'emails_delivered': emails_delivered,
'emails_failed': emails_failed,
'sms_requested': sms_requested,
'sms_delivered': sms_delivered,
'sms_failed': sms_failed,
'sms': {
'requested': sms_requested,
'delivered': sms_delivered,
'failed': sms_failed,
},
'email': {
'requested': emails_requested,
'delivered': emails_delivered,
'failed': emails_failed,
}
}
def test_format_stats_by_service_gets_correct_stats_for_each_service():
services = [
{'name': 'a', 'id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'restricted': False, 'research_mode': True},
{'name': 'b', 'id': 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'restricted': True, 'research_mode': False}
]
all_stats = [
create_stats('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', emails_requested=1),
create_stats('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', emails_requested=2)
]
def test_format_stats_by_service_sums_values_for_sending(fake_uuid):
services = [service_json(fake_uuid, 'a', [])]
services[0]['statistics'] = create_stats(
emails_requested=10,
emails_delivered=3,
emails_failed=5,
sms_requested=50,
sms_delivered=7,
sms_failed=11
)
ret = format_stats_by_service(all_stats, services)
assert len(ret) == 2
assert ret[0]['name'] == 'a'
assert ret[0]['sending'] == 1
assert ret[0]['delivered'] == 0
assert ret[0]['failed'] == 0
assert ret[0]['restricted'] is False
assert ret[1]['name'] == 'b'
assert ret[1]['sending'] == 2
assert ret[1]['delivered'] == 0
assert ret[1]['failed'] == 0
assert ret[1]['restricted'] is True
def test_format_stats_by_service_sums_values_for_sending():
services = [
{'name': 'a', 'id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'restricted': False, 'research_mode': False},
]
all_stats = [
create_stats(
'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
emails_requested=10,
emails_delivered=3,
emails_failed=5,
sms_requested=50,
sms_delivered=7,
sms_failed=11
)
]
ret = format_stats_by_service(all_stats, services)
ret = list(format_stats_by_service(services))
assert len(ret) == 1
assert ret[0]['sending'] == 34

View File

@@ -322,6 +322,46 @@ def test_upload_csvfile_with_valid_phone_shows_all_numbers(
mock_get_detailed_service_for_today.assert_called_once_with(fake_uuid)
def test_test_message_can_only_be_sent_now(
app_,
mocker,
api_user_active,
mock_login,
mock_get_service,
mock_get_service_template,
mock_s3_download,
mock_has_permissions,
mock_get_users_by_service,
mock_get_detailed_service_for_today,
fake_uuid
):
with app_.test_request_context(), app_.test_client() as client:
client.login(api_user_active)
with client.session_transaction() as session:
session['upload_data'] = {
'original_file_name': 'Test message',
'template_id': fake_uuid,
'notification_count': 1,
'valid': True
}
response = client.get(url_for(
'main.check_messages',
service_id=fake_uuid,
upload_id=fake_uuid,
template_type='sms',
from_test=True
))
content = response.get_data(as_text=True)
assert 'name="scheduled_for"' not in content
@pytest.mark.parametrize(
'when', [
'', '2016-08-25T13:04:21.767198'
]
)
def test_create_job_should_call_api(
app_,
service_one,
@@ -331,7 +371,8 @@ def test_create_job_should_call_api(
mock_get_notifications,
mock_get_service_template,
mocker,
fake_uuid
fake_uuid,
when
):
service_id = service_one['id']
data = mock_get_job(service_one['id'], fake_uuid)['data']
@@ -339,20 +380,28 @@ def test_create_job_should_call_api(
original_file_name = data['original_file_name']
template_id = data['template']
notification_count = data['notification_count']
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
with client.session_transaction() as session:
session['upload_data'] = {'original_file_name': original_file_name,
'template_id': template_id,
'notification_count': notification_count,
'valid': True}
url = url_for('main.start_job', service_id=service_one['id'], upload_id=job_id)
response = client.post(url, data={}, follow_redirects=True)
with app_.test_request_context(), app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
with client.session_transaction() as session:
session['upload_data'] = {
'original_file_name': original_file_name,
'template_id': template_id,
'notification_count': notification_count,
'valid': True
}
url = url_for('main.start_job', service_id=service_one['id'], upload_id=job_id)
response = client.post(url, data={'scheduled_for': when}, follow_redirects=True)
assert response.status_code == 200
assert original_file_name in response.get_data(as_text=True)
mock_create_job.assert_called_with(job_id, service_id, template_id, original_file_name, notification_count)
assert response.status_code == 200
assert original_file_name in response.get_data(as_text=True)
mock_create_job.assert_called_with(
job_id,
service_id,
template_id,
original_file_name,
notification_count,
scheduled_for=when
)
def test_check_messages_should_revalidate_file_when_uploading_file(

View File

@@ -9,19 +9,49 @@ from unittest.mock import ANY, Mock
from werkzeug.exceptions import InternalServerError
def test_should_show_overview(app_,
active_user_with_permissions,
mocker,
service_one):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
response = client.get(url_for(
'main.service_settings', service_id=service_one['id']))
assert response.status_code == 200
resp_data = response.get_data(as_text=True)
assert 'Service settings' in resp_data
app.service_api_client.get_service.assert_called_with(service_one['id'])
def test_should_show_overview(
app_,
active_user_with_permissions,
mocker,
service_one,
mock_get_organisation
):
with app_.test_request_context(), app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
response = client.get(url_for(
'main.service_settings', service_id=service_one['id']
))
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
assert page.find('h1').text == 'Settings'
for index, row in enumerate([
'Service name service one Change',
'Email reply to address None Change',
'Text message sender 40604 Change'
]):
assert row == " ".join(page.find_all('tr')[index + 1].text.split())
app.service_api_client.get_service.assert_called_with(service_one['id'])
def test_should_show_overview_for_service_with_more_things_set(
app_,
active_user_with_permissions,
mocker,
service_with_reply_to_addresses,
mock_get_organisation
):
with app_.test_request_context(), app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_with_reply_to_addresses)
response = client.get(url_for(
'main.service_settings', service_id=service_with_reply_to_addresses['id']
))
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
for index, row in enumerate([
'Service name service one Change',
'Email reply to address test@example.com Change',
'Text message sender elevenchars Change'
]):
assert row == " ".join(page.find_all('tr')[index + 1].text.split())
def test_should_show_service_name(app_,
@@ -63,14 +93,17 @@ def test_should_redirect_after_change_service_name(app_,
assert mock_get_services.called
def test_switch_service_to_live(app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_service,
mock_update_service,
mock_has_permissions):
def test_switch_service_to_live(
app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_service,
mock_update_service,
mock_has_permissions,
mock_get_organisation
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions)
@@ -87,14 +120,17 @@ def test_switch_service_to_live(app_,
)
def test_switch_service_to_restricted(app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_live_service,
mock_update_service,
mock_has_permissions):
def test_switch_service_to_restricted(
app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_live_service,
mock_update_service,
mock_has_permissions,
mock_get_organisation
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions)
@@ -148,12 +184,15 @@ def test_should_show_service_name_confirmation(app_,
app.service_api_client.get_service.assert_called_with(service_one['id'])
def test_should_redirect_after_service_name_confirmation(app_,
active_user_with_permissions,
service_one,
mocker,
mock_update_service,
mock_verify_password):
def test_should_redirect_after_service_name_confirmation(
app_,
active_user_with_permissions,
service_one,
mocker,
mock_update_service,
mock_verify_password,
mock_get_organisation
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
@@ -222,12 +261,13 @@ def test_should_show_request_to_go_live(app_,
def test_should_redirect_after_request_to_go_live(
app_,
api_user_active,
mock_get_user,
mock_get_service,
mock_has_permissions,
mocker
app_,
api_user_active,
mock_get_user,
mock_get_service,
mock_has_permissions,
mock_get_organisation,
mocker
):
mock_post = mocker.patch(
'app.main.views.feedback.requests.post',
@@ -262,12 +302,12 @@ def test_should_redirect_after_request_to_go_live(
def test_log_error_on_request_to_go_live(
app_,
api_user_active,
mock_get_user,
mock_get_service,
mock_has_permissions,
mocker
app_,
api_user_active,
mock_get_user,
mock_get_service,
mock_has_permissions,
mocker
):
mock_post = mocker.patch(
'app.main.views.service_settings.requests.post',
@@ -293,95 +333,6 @@ def test_log_error_on_request_to_go_live(
)
def test_should_show_status_page(app_,
api_user_active,
mock_get_service,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_has_permissions,
fake_uuid):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
service_id = fake_uuid
response = client.get(url_for(
'main.service_status_change', service_id=service_id))
assert response.status_code == 200
resp_data = response.get_data(as_text=True)
assert 'Suspend API keys' in resp_data
assert mock_get_service.called
def test_should_show_redirect_after_status_change(app_,
api_user_active,
mock_get_service,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_has_permissions,
fake_uuid):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
service_id = fake_uuid
response = client.post(url_for(
'main.service_status_change', service_id=service_id))
assert response.status_code == 302
redirect_url = url_for(
'main.service_status_change_confirm', service_id=service_id, _external=True)
assert redirect_url == response.location
assert mock_get_service.called
def test_should_show_status_confirmation(app_,
api_user_active,
mock_get_service,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_has_permissions,
fake_uuid):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
service_id = fake_uuid
response = client.get(url_for(
'main.service_status_change_confirm', service_id=service_id))
assert response.status_code == 200
resp_data = response.get_data(as_text=True)
assert 'Turn off all outgoing notifications' in resp_data
assert mock_get_service.called
def test_should_redirect_after_status_confirmation(app_,
api_user_active,
mock_get_service,
mock_update_service,
mock_get_user,
mock_get_user_by_email,
mock_login,
mock_verify_password,
mock_has_permissions,
fake_uuid):
with app_.test_request_context():
with app_.test_client() as client:
client.login(api_user_active)
service_id = fake_uuid
response = client.post(url_for(
'main.service_status_change_confirm', service_id=service_id))
assert response.status_code == 302
settings_url = url_for(
'main.service_settings', service_id=service_id, _external=True)
assert settings_url == response.location
assert mock_get_service.called
assert mock_update_service.called
def test_should_show_delete_page(app_,
api_user_active,
mock_login,
@@ -468,14 +419,12 @@ def test_should_redirect_delete_confirmation(app_,
assert mock_delete_service.called
def test_route_permissions(mocker, app_, api_user_active, service_one):
def test_route_permissions(mocker, app_, api_user_active, service_one, mock_get_organisation):
routes = [
'main.service_settings',
'main.service_name_change',
'main.service_name_change_confirm',
'main.service_request_to_go_live',
'main.service_status_change',
'main.service_status_change_confirm',
'main.service_delete',
'main.service_delete_confirm']
with app_.test_request_context():
@@ -491,7 +440,7 @@ def test_route_permissions(mocker, app_, api_user_active, service_one):
service_one)
def test_route_invalid_permissions(mocker, app_, api_user_active, service_one):
def test_route_invalid_permissions(mocker, app_, api_user_active, service_one, mock_get_organisation):
routes = [
'main.service_settings',
'main.service_name_change',
@@ -499,8 +448,6 @@ def test_route_invalid_permissions(mocker, app_, api_user_active, service_one):
'main.service_request_to_go_live',
'main.service_switch_live',
'main.service_switch_research_mode',
'main.service_status_change',
'main.service_status_change_confirm',
'main.service_delete',
'main.service_delete_confirm']
with app_.test_request_context():
@@ -516,14 +463,12 @@ def test_route_invalid_permissions(mocker, app_, api_user_active, service_one):
service_one)
def test_route_for_platform_admin(mocker, app_, platform_admin_user, service_one):
def test_route_for_platform_admin(mocker, app_, platform_admin_user, service_one, mock_get_organisation):
routes = [
'main.service_settings',
'main.service_name_change',
'main.service_name_change_confirm',
'main.service_request_to_go_live',
'main.service_status_change',
'main.service_status_change_confirm',
'main.service_delete',
'main.service_delete_confirm'
]
@@ -557,11 +502,13 @@ def test_route_for_platform_admin_update_service(mocker, app_, platform_admin_us
def test_set_reply_to_email_address(
app_,
active_user_with_permissions,
mocker,
mock_update_service,
service_one):
app_,
active_user_with_permissions,
mocker,
mock_update_service,
service_one,
mock_get_organisation
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
@@ -650,14 +597,16 @@ def test_switch_service_from_research_mode_to_normal(
def test_shows_research_mode_indicator(
app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_service,
mock_has_permissions,
mocker):
app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_service,
mock_has_permissions,
mock_get_organisation,
mocker
):
with app_.test_request_context():
with app_.test_client() as client:
service = service_json(
@@ -682,14 +631,16 @@ def test_shows_research_mode_indicator(
def test_does_not_show_research_mode_indicator(
app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_service,
mock_has_permissions,
mocker):
app_,
service_one,
mock_login,
mock_get_user,
active_user_with_permissions,
mock_get_service,
mock_has_permissions,
mock_get_organisation,
mocker
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions)
@@ -702,11 +653,13 @@ def test_does_not_show_research_mode_indicator(
def test_set_text_message_sender(
app_,
active_user_with_permissions,
mocker,
mock_update_service,
service_one):
app_,
active_user_with_permissions,
mocker,
mock_update_service,
service_one,
mock_get_organisation
):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
@@ -737,34 +690,6 @@ def test_if_sms_sender_set_then_form_populated(app_,
assert page.find(id='sms_sender')['value'] == 'elevenchars'
@pytest.mark.parametrize("sender, expected_flash_message", [
("elevenchars", 'Text message sender set to elevenchars'),
('', 'Text message sender removed')
])
def test_set_text_message_sender_flash_messages(
app_,
active_user_with_permissions,
mocker,
mock_update_service,
service_one,
sender,
expected_flash_message):
with app_.test_request_context():
with app_.test_client() as client:
client.login(active_user_with_permissions, mocker, service_one)
data = {"sms_sender": sender}
response = client.post(url_for('main.service_set_sms_sender', service_id=service_one['id']),
data=data,
follow_redirects=True)
assert response.status_code == 200
page = BeautifulSoup(response.data.decode('utf-8'), 'html.parser')
element = page.find('div', {"class": "banner-default-with-tick"})
assert element.text.strip() == expected_flash_message
def test_should_show_branding(
mocker, app_, platform_admin_user, service_one, mock_get_organisations
):

View File

@@ -20,13 +20,36 @@ def test_client_creates_job_data_correctly(mocker, fake_uuid):
expected_url = '/service/{}/job'.format(service_id)
client = JobApiClient()
mock_post = mocker.patch('app.notify_client.job_api_client.JobApiClient.post')
mock_post = mocker.patch(
'app.notify_client.job_api_client.JobApiClient.post',
return_value={'data': dict(statistics=[], **expected_data)}
)
client.create_job(job_id, service_id, template_id, original_file_name, notification_count)
result = client.create_job(job_id, service_id, template_id, original_file_name, notification_count)
assert result['data']['notifications_requested'] == 0
assert result['data']['notifications_sent'] == 0
assert result['data']['notification_count'] == 1
assert result['data']['notifications_failed'] == 0
mock_post.assert_called_once_with(url=expected_url, data=expected_data)
def test_client_schedules_job(mocker, fake_uuid):
mocker.patch('app.notify_client.current_user', id='1')
mock_post = mocker.patch('app.notify_client.job_api_client.JobApiClient.post')
when = '2016-08-25T13:04:21.767198'
JobApiClient().create_job(
fake_uuid, fake_uuid, fake_uuid, fake_uuid, 1, scheduled_for=when
)
assert mock_post.call_args[1]['data']['scheduled_for'] == when
def test_client_gets_job_by_service_and_job(mocker):
mocker.patch('app.notify_client.current_user', id='1')
@@ -151,6 +174,187 @@ def test_client_parses_job_stats(mocker):
result = client.get_job(service_id, job_id)
mock_get.assert_called_once_with(url=expected_url, params={})
assert result['data']['notifications_requested'] == 80
assert result['data']['notifications_sent'] == 50
assert result['data']['notification_count'] == 80
assert result['data']['notifications_failed'] == 40
def test_client_parses_empty_job_stats(mocker):
mocker.patch('app.notify_client.current_user', id='1')
service_id = 'service_id'
job_id = 'job_id'
expected_data = {'data': {
'status': 'finished',
'template_version': 3,
'id': job_id,
'updated_at': '2016-08-24T08:29:28.332972+00:00',
'service': service_id,
'processing_finished': '2016-08-24T08:11:48.676365+00:00',
'statistics': [],
'original_file_name': 'test-notify-email.csv',
'created_by': {
'name': 'test-user@digital.cabinet-office.gov.uk',
'id': '3571f2ae-7a39-4fb4-9ad7-8453f5257072'
},
'created_at': '2016-08-24T08:09:56.371073+00:00',
'template': 'c0309261-9c9e-4530-8fed-5f67b02260d2',
'notification_count': 80,
'processing_started': '2016-08-24T08:09:57.661246+00:00'
}}
expected_url = '/service/{}/job/{}'.format(service_id, job_id)
client = JobApiClient()
mock_get = mocker.patch('app.notify_client.job_api_client.JobApiClient.get', return_value=expected_data)
result = client.get_job(service_id, job_id)
mock_get.assert_called_once_with(url=expected_url, params={})
assert result['data']['notifications_requested'] == 0
assert result['data']['notifications_sent'] == 0
assert result['data']['notification_count'] == 80
assert result['data']['notifications_failed'] == 0
def test_client_parses_job_stats_for_service(mocker):
mocker.patch('app.notify_client.current_user', id='1')
service_id = 'service_id'
job_1_id = 'job_id_1'
job_2_id = 'job_id_2'
expected_data = {'data': [{
'status': 'finished',
'template_version': 3,
'id': job_1_id,
'updated_at': '2016-08-24T08:29:28.332972+00:00',
'service': service_id,
'processing_finished': '2016-08-24T08:11:48.676365+00:00',
'statistics': [
{'status': 'failed', 'count': 10},
{'status': 'technical-failure', 'count': 10},
{'status': 'temporary-failure', 'count': 10},
{'status': 'permanent-failure', 'count': 10},
{'status': 'created', 'count': 10},
{'status': 'sending', 'count': 10},
{'status': 'pending', 'count': 10},
{'status': 'delivered', 'count': 10}
],
'original_file_name': 'test-notify-email.csv',
'created_by': {
'name': 'test-user@digital.cabinet-office.gov.uk',
'id': '3571f2ae-7a39-4fb4-9ad7-8453f5257072'
},
'created_at': '2016-08-24T08:09:56.371073+00:00',
'template': 'c0309261-9c9e-4530-8fed-5f67b02260d2',
'notification_count': 80,
'processing_started': '2016-08-24T08:09:57.661246+00:00'
}, {
'status': 'finished',
'template_version': 3,
'id': job_2_id,
'updated_at': '2016-08-24T08:29:28.332972+00:00',
'service': service_id,
'processing_finished': '2016-08-24T08:11:48.676365+00:00',
'statistics': [
{'status': 'failed', 'count': 5},
{'status': 'technical-failure', 'count': 5},
{'status': 'temporary-failure', 'count': 5},
{'status': 'permanent-failure', 'count': 5},
{'status': 'created', 'count': 5},
{'status': 'sending', 'count': 5},
{'status': 'pending', 'count': 5},
{'status': 'delivered', 'count': 5}
],
'original_file_name': 'test-notify-email.csv',
'created_by': {
'name': 'test-user@digital.cabinet-office.gov.uk',
'id': '3571f2ae-7a39-4fb4-9ad7-8453f5257072'
},
'created_at': '2016-08-24T08:09:56.371073+00:00',
'template': 'c0309261-9c9e-4530-8fed-5f67b02260d2',
'notification_count': 40,
'processing_started': '2016-08-24T08:09:57.661246+00:00'
}]}
expected_url = '/service/{}/job'.format(service_id)
client = JobApiClient()
mock_get = mocker.patch('app.notify_client.job_api_client.JobApiClient.get', return_value=expected_data)
result = client.get_job(service_id)
mock_get.assert_called_once_with(url=expected_url, params={})
assert result['data'][0]['id'] == job_1_id
assert result['data'][0]['notifications_requested'] == 80
assert result['data'][0]['notifications_sent'] == 50
assert result['data'][0]['notification_count'] == 80
assert result['data'][0]['notifications_failed'] == 40
assert result['data'][1]['id'] == job_2_id
assert result['data'][1]['notifications_requested'] == 40
assert result['data'][1]['notifications_sent'] == 25
assert result['data'][1]['notification_count'] == 40
assert result['data'][1]['notifications_failed'] == 20
def test_client_parses_empty_job_stats_for_service(mocker):
mocker.patch('app.notify_client.current_user', id='1')
service_id = 'service_id'
job_1_id = 'job_id_1'
job_2_id = 'job_id_2'
expected_data = {'data': [{
'status': 'finished',
'template_version': 3,
'id': job_1_id,
'updated_at': '2016-08-24T08:29:28.332972+00:00',
'service': service_id,
'processing_finished': '2016-08-24T08:11:48.676365+00:00',
'statistics': [],
'original_file_name': 'test-notify-email.csv',
'created_by': {
'name': 'test-user@digital.cabinet-office.gov.uk',
'id': '3571f2ae-7a39-4fb4-9ad7-8453f5257072'
},
'created_at': '2016-08-24T08:09:56.371073+00:00',
'template': 'c0309261-9c9e-4530-8fed-5f67b02260d2',
'notification_count': 80,
'processing_started': '2016-08-24T08:09:57.661246+00:00'
}, {
'status': 'finished',
'template_version': 3,
'id': job_2_id,
'updated_at': '2016-08-24T08:29:28.332972+00:00',
'service': service_id,
'processing_finished': '2016-08-24T08:11:48.676365+00:00',
'statistics': [],
'original_file_name': 'test-notify-email.csv',
'created_by': {
'name': 'test-user@digital.cabinet-office.gov.uk',
'id': '3571f2ae-7a39-4fb4-9ad7-8453f5257072'
},
'created_at': '2016-08-24T08:09:56.371073+00:00',
'template': 'c0309261-9c9e-4530-8fed-5f67b02260d2',
'notification_count': 40,
'processing_started': '2016-08-24T08:09:57.661246+00:00'
}]}
expected_url = '/service/{}/job'.format(service_id)
client = JobApiClient()
mock_get = mocker.patch('app.notify_client.job_api_client.JobApiClient.get', return_value=expected_data)
result = client.get_job(service_id)
mock_get.assert_called_once_with(url=expected_url, params={})
assert result['data'][0]['id'] == job_1_id
assert result['data'][0]['notifications_requested'] == 0
assert result['data'][0]['notifications_sent'] == 0
assert result['data'][0]['notification_count'] == 80
assert result['data'][0]['notifications_failed'] == 0
assert result['data'][1]['id'] == job_2_id
assert result['data'][1]['notifications_requested'] == 0
assert result['data'][1]['notifications_sent'] == 0
assert result['data'][1]['notification_count'] == 40
assert result['data'][1]['notifications_failed'] == 0

View File

@@ -25,7 +25,7 @@ def test_email_safe_return_dot_separated_email_domain():
('permanent-failure', 'sms', 'Phone number doesnt exist')
]
)
@freeze_time("2016-01-01 11:09:00.061258")
@freeze_time("2016-01-01 15:09:00.061258")
def test_generate_csv_from_notifications(
app_,
service_one,
@@ -46,5 +46,5 @@ def test_generate_csv_from_notifications(
)
for row in DictReader(StringIO(csv_content)):
assert row['Time'] == 'Friday 01 January 2016 at 11:09'
assert row['Time'] == 'Friday 01 January 2016 at 15:09'
assert row['Status'] == expected_status