Files
notifications-admin/tests/app/test_utils.py
2017-07-28 15:19:20 +01:00

303 lines
8.3 KiB
Python

from pathlib import Path
from io import StringIO
from collections import OrderedDict
from csv import DictReader
from freezegun import freeze_time
import pytest
from app.utils import (
email_safe,
generate_notifications_csv,
generate_previous_dict,
generate_next_dict,
Spreadsheet,
get_letter_timings,
get_cdn_domain
)
def _get_notifications_csv(
service_id,
page=1,
row_number=1,
recipient='foo@bar.com',
template_name='foo',
template_type='sms',
job_name='bar.csv',
status='Delivered',
created_at='Thursday 19 April at 12:00',
rows=1,
with_links=False
):
links = {}
if with_links:
links = {
'prev': '/service/{}/notifications?page=0'.format(service_id),
'next': '/service/{}/notifications?page=1'.format(service_id),
'last': '/service/{}/notifications?page=2'.format(service_id)
}
data = {
'notifications': [{
"row_number": row_number,
"recipient": recipient,
"template_name": template_name,
"template_type": template_type,
"job_name": job_name,
"status": status,
"created_at": created_at
} for i in range(rows)],
'total': rows,
'page_size': 50,
'links': links
}
return data
@pytest.fixture(scope='function')
def _get_notifications_csv_mock(
mocker,
api_user_active
):
return mocker.patch(
'app.notification_api_client.get_notifications_for_service',
side_effect=_get_notifications_csv
)
@pytest.mark.parametrize('service_name, safe_email', [
('name with spaces', 'name.with.spaces'),
('singleword', 'singleword'),
('UPPER CASE', 'upper.case'),
('Service - with dash', 'service.with.dash'),
('lots of spaces', 'lots.of.spaces'),
('name.with.dots', 'name.with.dots'),
('name-with-other-delimiters', 'namewithotherdelimiters'),
('.leading', 'leading'),
('trailing.', 'trailing'),
('üńïçödë wördś', 'unicode.words'),
])
def test_email_safe_return_dot_separated_email_domain(service_name, safe_email):
assert email_safe(service_name) == safe_email
def test_generate_previous_dict(client):
ret = generate_previous_dict('main.view_jobs', 'foo', 2, {})
assert 'page=1' in ret['url']
assert ret['title'] == 'Previous page'
assert ret['label'] == 'page 1'
def test_generate_next_dict(client):
ret = generate_next_dict('main.view_jobs', 'foo', 2, {})
assert 'page=3' in ret['url']
assert ret['title'] == 'Next page'
assert ret['label'] == 'page 3'
def test_generate_previous_next_dict_adds_other_url_args(client):
ret = generate_next_dict('main.view_notifications', 'foo', 2, {'message_type': 'blah'})
assert 'notifications/blah' in ret['url']
def test_can_create_spreadsheet_from_large_excel_file():
with open(str(Path.cwd() / 'tests' / 'spreadsheet_files' / 'excel 2007.xlsx'), 'rb') as xl:
ret = Spreadsheet.from_file(xl, filename='xl.xlsx')
assert ret.as_csv_data
def test_can_create_spreadsheet_from_dict():
assert Spreadsheet.from_dict(OrderedDict(
foo='bar',
name='Jane',
)).as_csv_data == (
"foo,name\r\n"
"bar,Jane\r\n"
)
def test_can_create_spreadsheet_from_dict_with_filename():
assert Spreadsheet.from_dict({}, filename='empty.csv').as_dict['file_name'] == "empty.csv"
def test_generate_notifications_csv_returns_correct_csv_file(_get_notifications_csv_mock):
csv_content = generate_notifications_csv(service_id='1234')
csv_file = DictReader(StringIO('\n'.join(csv_content)))
assert csv_file.fieldnames == ['Row number', 'Recipient', 'Template', 'Type', 'Job', 'Status', 'Time']
def test_generate_notifications_csv_only_calls_once_if_no_next_link(_get_notifications_csv_mock):
list(generate_notifications_csv(service_id='1234'))
assert _get_notifications_csv_mock.call_count == 1
def test_generate_notifications_csv_calls_twice_if_next_link(mocker):
service_id = '1234'
response_with_links = _get_notifications_csv(service_id, rows=7, with_links=True)
response_with_no_links = _get_notifications_csv(service_id, rows=3, with_links=False)
mock_get_notifications = mocker.patch(
'app.notification_api_client.get_notifications_for_service',
side_effect=[
response_with_links,
response_with_no_links,
]
)
csv_content = generate_notifications_csv(service_id=service_id)
csv = DictReader(StringIO('\n'.join(csv_content)))
assert len(list(csv)) == 10
assert mock_get_notifications.call_count == 2
# mock_calls[0][2] is the kwargs from first call
assert mock_get_notifications.mock_calls[0][2]['page'] == 1
assert mock_get_notifications.mock_calls[1][2]['page'] == 2
@freeze_time('2017-07-14 14:59:59') # Friday, before print deadline
@pytest.mark.parametrize('upload_time, expected_print_time, is_printed, expected_earliest, expected_latest', [
# BST
# ==================================================================
# First thing Monday
(
'2017-07-10 00:00:01',
'Tuesday 15:00',
True,
'Thursday 2017-07-13',
'Friday 2017-07-14'
),
# Monday at 16:59 BST
(
'2017-07-10 15:59:59',
'Tuesday 15:00',
True,
'Thursday 2017-07-13',
'Friday 2017-07-14'
),
# Monday at 17:00 BST
(
'2017-07-10 16:00:01',
'Wednesday 15:00',
True,
'Friday 2017-07-14',
'Saturday 2017-07-15'
),
# Tuesday before 17:00 BST
(
'2017-07-11 12:00:00',
'Wednesday 15:00',
True,
'Friday 2017-07-14',
'Saturday 2017-07-15'
),
# Wednesday before 17:00 BST
(
'2017-07-12 12:00:00',
'Thursday 15:00',
True,
'Saturday 2017-07-15',
'Monday 2017-07-17'
),
# Thursday before 17:00 BST
(
'2017-07-13 12:00:00',
'Friday 15:00',
True, # WRONG
'Monday 2017-07-17',
'Tuesday 2017-07-18'
),
# Friday anytime
(
'2017-07-14 00:00:00',
'Monday 15:00',
False,
'Wednesday 2017-07-19',
'Thursday 2017-07-20'
),
(
'2017-07-14 12:00:00',
'Monday 15:00',
False,
'Wednesday 2017-07-19',
'Thursday 2017-07-20'
),
(
'2017-07-14 22:00:00',
'Monday 15:00',
False,
'Wednesday 2017-07-19',
'Thursday 2017-07-20'
),
# Saturday anytime
(
'2017-07-14 12:00:00',
'Monday 15:00',
False,
'Wednesday 2017-07-19',
'Thursday 2017-07-20'
),
# Sunday before 1700 BST
(
'2017-07-15 15:59:59',
'Monday 15:00',
False,
'Wednesday 2017-07-19',
'Thursday 2017-07-20'
),
# Sunday after 17:00 BST
(
'2017-07-16 16:00:01',
'Tuesday 15:00',
False,
'Thursday 2017-07-20',
'Friday 2017-07-21'
),
# GMT
# ==================================================================
# Monday at 16:59 GMT
(
'2017-01-02 16:59:59',
'Tuesday 15:00',
True,
'Thursday 2017-01-05',
'Friday 2017-01-06',
),
# Monday at 17:00 GMT
(
'2017-01-02 17:00:01',
'Wednesday 15:00',
True,
'Friday 2017-01-06',
'Saturday 2017-01-07',
),
])
def test_get_estimated_delivery_date_for_letter(
upload_time,
expected_print_time,
is_printed,
expected_earliest,
expected_latest,
):
timings = get_letter_timings(upload_time)
assert timings.printed_by.strftime('%A %H:%M') == expected_print_time
assert timings.is_printed == is_printed
assert timings.earliest_delivery.strftime('%A %Y-%m-%d') == expected_earliest
assert timings.latest_delivery.strftime('%A %Y-%m-%d') == expected_latest
def test_get_cdn_domain_on_localhost(client, mocker):
mocker.patch.dict('app.current_app.config', values={'ADMIN_BASE_URL': 'http://localhost:6012'})
domain = get_cdn_domain()
assert domain == 'static-logos.notify.tools'
def test_get_cdn_domain_on_non_localhost(client, mocker):
mocker.patch.dict('app.current_app.config', values={'ADMIN_BASE_URL': 'https://some.admintest.com'})
domain = get_cdn_domain()
assert domain == 'static-logos.admintest.com'