Remove contact-list references from code

This commit is contained in:
Ryan Ahearn
2023-04-12 15:35:14 -04:00
parent 6587ed5223
commit de668d7aba
31 changed files with 11 additions and 2441 deletions

View File

@@ -6,13 +6,11 @@ from io import BytesIO
from itertools import repeat
from os import path
from random import randbytes
from unittest.mock import ANY
from uuid import uuid4
from zipfile import BadZipFile
import pytest
from flask import url_for
from freezegun import freeze_time
from notifications_python_client.errors import HTTPError
from notifications_utils.recipients import RecipientCSV
from notifications_utils.template import SMSPreviewTemplate
@@ -1034,7 +1032,6 @@ def test_send_one_off_step_redirects_to_start_if_session_not_setup(
mock_get_service_statistics,
mock_get_users_by_service,
mock_has_no_jobs,
mock_get_no_contact_lists,
fake_uuid,
template_type,
):
@@ -1093,7 +1090,6 @@ def test_send_one_off_has_correct_page_title(
client_request,
service_one,
mock_has_no_jobs,
mock_get_no_contact_lists,
fake_uuid,
mocker,
user,
@@ -1135,7 +1131,6 @@ def test_send_one_off_shows_placeholders_in_correct_order(
client_request,
fake_uuid,
mock_has_no_jobs,
mock_get_no_contact_lists,
mock_get_service_template_with_multiple_placeholders,
step_index,
prefilled,
@@ -1180,7 +1175,6 @@ def test_send_one_off_has_skip_link(
fake_uuid,
mock_get_service_email_template,
mock_has_no_jobs,
mock_get_no_contact_lists,
mocker,
template_type,
expected_link_text,
@@ -1221,7 +1215,6 @@ def test_send_one_off_has_sticky_header_for_email(
client_request,
fake_uuid,
mock_has_no_jobs,
mock_get_no_contact_lists,
template_type,
expected_sticky,
):
@@ -1249,7 +1242,6 @@ def test_skip_link_will_not_show_on_sms_one_off_if_service_has_no_mobile_number(
fake_uuid,
mock_get_service_template,
mock_has_no_jobs,
mock_get_no_contact_lists,
mocker,
user,
):
@@ -1279,7 +1271,6 @@ def test_send_one_off_offers_link_to_upload(
fake_uuid,
mock_get_service_template,
mock_has_jobs,
mock_get_no_contact_lists,
user,
):
client_request.login(user)
@@ -1307,7 +1298,6 @@ def test_send_one_off_has_link_to_use_existing_list(
client_request,
mock_get_service_template,
mock_has_jobs,
mock_get_contact_lists,
fake_uuid,
):
page = client_request.get(
@@ -1328,14 +1318,6 @@ def test_send_one_off_has_link_to_use_existing_list(
template_id=fake_uuid,
),
),
(
'Use an emergency list',
url_for(
'main.choose_from_contact_list',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
),
),
(
'Use my phone number',
url_for(
@@ -1347,33 +1329,6 @@ def test_send_one_off_has_link_to_use_existing_list(
]
def test_no_link_to_use_existing_list_for_service_without_lists(
mocker,
client_request,
mock_get_service_template,
mock_has_jobs,
platform_admin_user,
fake_uuid,
):
mocker.patch(
'app.models.contact_list.ContactLists.client_method',
return_value=[],
)
client_request.login(platform_admin_user)
page = client_request.get(
'main.send_one_off',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
_follow_redirects=True,
)
assert [
link.text for link in page.select('form a')
] == [
'Upload a list of phone numbers',
'Use my phone number',
]
@pytest.mark.parametrize('user', (
create_active_user_with_permissions(),
create_active_caseworking_user(),
@@ -1590,7 +1545,6 @@ def test_send_one_off_step_0_back_link(
mock_get_service,
mock_get_service_template_with_placeholders,
mock_has_no_jobs,
mock_get_contact_lists,
permissions,
expected_back_link_endpoint,
extra_args,
@@ -1671,7 +1625,6 @@ def test_send_one_off_sms_message_puts_submitted_data_in_session(
mock_get_service_template_with_placeholders,
mock_get_users_by_service,
mock_get_service_statistics,
mock_get_contact_lists,
fake_uuid,
):
with client_request.session_transaction() as session:
@@ -1847,32 +1800,6 @@ def test_upload_csvfile_with_international_validates(
assert mock_recipients.call_args[1]['allow_international_sms'] == should_allow_international
def test_job_from_contact_list_knows_where_its_come_from(
client_request,
mocker,
service_one,
mock_get_service_template,
mock_s3_download,
mock_get_users_by_service,
mock_get_service_statistics,
mock_get_job_doesnt_exist,
mock_get_jobs,
mock_s3_get_metadata,
mock_s3_set_metadata,
fake_uuid
):
page = client_request.get(
'main.check_messages',
service_id=service_one['id'],
upload_id=fake_uuid,
template_id=fake_uuid,
contact_list_id=unchanging_fake_uuid,
)
assert page.select_one(
'form input[type=hidden][name=contact_list_id]'
)['value'] == str(unchanging_fake_uuid)
def test_test_message_can_only_be_sent_now(
client_request,
mocker,
@@ -1932,9 +1859,6 @@ def test_send_button_is_correctly_labelled(
@pytest.mark.parametrize('when', [
'', '2016-08-25T13:04:21.767198'
])
@pytest.mark.parametrize('contact_list_id', [
'', unchanging_fake_uuid,
])
def test_create_job_should_call_api(
client_request,
mock_create_job,
@@ -1945,7 +1869,6 @@ def test_create_job_should_call_api(
mocker,
fake_uuid,
when,
contact_list_id,
):
data = mock_get_job(SERVICE_ONE_ID, fake_uuid)['data']
job_id = data['id']
@@ -1968,7 +1891,6 @@ def test_create_job_should_call_api(
original_file_name=original_file_name,
_data={
'scheduled_for': when,
'contact_list_id': contact_list_id,
},
_follow_redirects=True,
_expected_status=200,
@@ -1980,7 +1902,6 @@ def test_create_job_should_call_api(
job_id,
SERVICE_ONE_ID,
scheduled_for=when,
contact_list_id=str(contact_list_id),
)
@@ -2724,7 +2645,6 @@ def test_reply_to_is_previewed_if_chosen(
mock_get_service_statistics,
mock_get_job_doesnt_exist,
mock_get_jobs,
mock_get_no_contact_lists,
get_default_reply_to_email_address,
fake_uuid,
endpoint,
@@ -2777,7 +2697,6 @@ def test_sms_sender_is_previewed(
mock_get_service_statistics,
mock_get_job_doesnt_exist,
mock_get_jobs,
mock_get_no_contact_lists,
get_default_sms_sender,
fake_uuid,
endpoint,
@@ -2838,163 +2757,6 @@ def test_redirects_to_template_if_job_exists_already(
)
@pytest.mark.parametrize((
'template_type, '
'expected_list_id, '
'expected_filenames, '
'expected_time, '
'expected_count'
), (
(
'email',
'6ce466d0-fd6a-11e5-82f5-e0accb9d11a6',
['EmergencyContactList.xls'],
'Uploaded today at 5:59am',
'100 email addresses',
),
(
'sms',
'd7b0bd1a-d1c7-4621-be5c-3c1b4278a2ad',
['phone number list.csv', 'UnusedList.tsv'],
'Uploaded today at 8:00am',
'123 phone numbers',
),
))
@freeze_time('2020-06-13 13:00')
def test_choose_from_contact_list(
mocker,
client_request,
mock_get_contact_lists,
fake_uuid,
template_type,
expected_list_id,
expected_filenames,
expected_time,
expected_count,
):
template = create_template(template_type=template_type)
mocker.patch(
'app.service_api_client.get_service_template',
return_value={'data': template},
)
page = client_request.get(
'main.choose_from_contact_list',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
)
assert [
normalize_spaces(filename.text)
for filename in page.select('.file-list-filename-large')
] == expected_filenames
assert page.select_one('a.file-list-filename-large')['href'] == url_for(
'main.send_from_contact_list',
service_id=SERVICE_ONE_ID,
template_id=template['id'],
contact_list_id=expected_list_id,
)
assert normalize_spaces(page.select_one('.file-list-hint-large').text) == (
expected_time
)
assert normalize_spaces(page.select_one('.big-number-smallest').text) == (
expected_count
)
def test_choose_from_contact_list_with_personalised_template(
mocker,
client_request,
mock_get_contact_lists,
fake_uuid,
):
template = create_template(
content="Hey ((name)) ((thing)) is happening"
)
mocker.patch(
'app.service_api_client.get_service_template',
return_value={'data': template},
)
page = client_request.get(
'main.choose_from_contact_list',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
)
assert [
normalize_spaces(p.text) for p in page.select('main p')
] == [
'You cannot use an emergency contact list with this template because '
'it is personalized with ((name)) and ((thing)).',
'Emergency contact lists can only include email addresses or phone numbers.',
]
assert not page.select('table')
def test_choose_from_contact_list_with_no_lists(
mocker,
client_request,
mock_get_service_template,
fake_uuid,
):
mocker.patch(
'app.models.contact_list.ContactLists.client_method',
return_value=[],
)
page = client_request.get(
'main.choose_from_contact_list',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
)
assert [
normalize_spaces(p.text) for p in page.select('main p')
] == [
'You have not saved any lists of phone numbers yet.',
'To upload and save an emergency contact list, go to the uploads page.',
]
assert page.select_one('main p a')['href'] == url_for(
'main.uploads',
service_id=SERVICE_ONE_ID,
)
assert not page.select('table')
@pytest.mark.skip(reason="Need to figure out how to handle cross-bucket copies.")
def test_send_from_contact_list(
mocker,
client_request,
fake_uuid,
mock_get_contact_list,
):
new_uuid = uuid.uuid4()
mock_download = mocker.patch('app.models.contact_list.get_s3_contents', return_value='contents')
mock_get_metadata = mocker.patch('app.models.contact_list.get_s3_metadata', return_value={
'example_key': 'example value',
})
mock_upload = mocker.patch('app.models.contact_list.s3upload', return_value=new_uuid)
mock_set_metadata = mocker.patch('app.models.contact_list.set_metadata_on_csv_upload')
client_request.get(
'main.send_from_contact_list',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
contact_list_id=fake_uuid,
_expected_status=302,
_expected_redirect=url_for(
'main.check_messages',
service_id=SERVICE_ONE_ID,
template_id=fake_uuid,
upload_id=new_uuid,
contact_list_id=fake_uuid,
)
)
mock_download.assert_called_once()
mock_get_metadata.assert_called_once()
mock_upload.assert_called_once_with(
SERVICE_ONE_ID, {'data': 'contents'}, ANY
)
mock_set_metadata.assert_called_once_with(
SERVICE_ONE_ID, new_uuid, example_key='example value'
)
def test_send_to_myself_sets_placeholder_and_redirects_for_email(
mocker, client_request, fake_uuid, mock_get_service_email_template
):

View File

@@ -1,714 +0,0 @@
import uuid
from io import BytesIO
from unittest.mock import ANY
import pytest
from flask import url_for
from freezegun import freeze_time
from app.formatters import normalize_spaces
from tests import contact_list_json
from tests.conftest import SERVICE_ONE_ID
def test_upload_contact_list_page(client_request):
page = client_request.get(
'main.upload_contact_list',
service_id=SERVICE_ONE_ID,
)
assert 'action' not in page.select_one('form')
assert page.select_one('form input')['name'] == 'file'
assert page.select_one('form input')['type'] == 'file'
assert page.select_one('form input')['accept'] == '.csv,.xlsx,.xls,.ods,.xlsm,.tsv'
assert normalize_spaces(page.select('.spreadsheet')[0].text) == (
'Example A '
'1 email address '
'2 test@example.gsa.gov'
)
assert normalize_spaces(page.select('.spreadsheet')[1].text) == (
'Example A '
'1 phone number '
'2 555-867-5309'
)
@pytest.mark.parametrize('file_contents, expected_error, expected_thead, expected_tbody,', [
(
"""
telephone,name
+12028675109
""",
(
'Your file has too many columns '
'It needs to have 1 column, called email address or phone number. '
'Right now it has 2 columns called telephone and name.'
),
'Row in file 1 telephone name',
'2 +12028675109',
),
(
"""
phone number, email address
+12028675109, test@example.com
""",
(
'Your file has too many columns '
'It needs to have 1 column, called email address or phone number. '
'Right now it has 2 columns called phone number and email address.'
),
'Row in file 1 phone number email address',
'2 +12028675109 test@example.com',
),
(
"""
email address
+12028675109
""",
(
'Theres a problem with invalid.csv '
'You need to fix 1 email address.'
),
'Row in file 1 email address',
'2 Not a valid email address +12028675109',
),
(
"""
phone number
test@example.com
""",
(
'Theres a problem with invalid.csv '
'You need to fix 1 phone number.'
),
'Row in file 1 phone number',
'2 The string supplied did not seem to be a phone number. test@example.com',
),
(
"""
phone number, phone number, PHONE_NUMBER
+12027900111,+12027900222,+12027900333,
""",
(
'Your file has too many columns '
'It needs to have 1 column, called email address or phone number. '
'Right now it has 3 columns called phone number, phone number and PHONE_NUMBER.'
),
'Row in file 1 phone number phone number PHONE_NUMBER',
'2 +12027900333 +12027900333 +12027900333',
),
(
"""
phone number
""",
(
'Your file is missing some rows '
'It needs at least one row of data.'
),
'Row in file 1 phone number',
'',
),
(
"+12028675109",
(
'Your file is missing some rows '
'It needs at least one row of data, in a column called '
'email address or phone number.'
),
'Row in file 1 +12028675109',
'',
),
(
"",
(
'Your file is missing some rows '
'It needs at least one row of data, in a column called '
'email address or phone number.'
),
'Row in file 1',
'',
),
(
"""
phone number
+12028675109
+12028675109
""",
(
'Theres a problem with invalid.csv '
'You need to enter missing data in 1 row.'
),
'Row in file 1 phone number',
(
'3 Missing'
)
),
(
"""
phone number
+12027900
""",
(
'Theres a problem with invalid.csv '
'You need to fix 1 phone number.'
),
'Row in file 1 phone number',
'2 Not enough digits +12027900',
),
(
"""
email address
ok@example.com
bad@example1
bad@example2
""",
(
'Theres a problem with invalid.csv '
'You need to fix 2 email addresses.'
),
'Row in file 1 email address',
(
'3 Not a valid email address bad@example1 '
'4 Not a valid email address bad@example2'
),
),
])
def test_upload_csv_file_shows_error_banner(
client_request,
mocker,
notify_admin,
mock_s3_upload,
mock_get_job_doesnt_exist,
mock_get_users_by_service,
fake_uuid,
file_contents,
expected_error,
expected_thead,
expected_tbody,
):
mocker.patch('app.models.contact_list.uuid4', return_value=fake_uuid)
mock_upload = mocker.patch('app.models.contact_list.utils_s3upload')
mock_download = mocker.patch(
'app.models.contact_list.get_s3_contents',
return_value=file_contents,
)
mock_set_metadata = mocker.patch('app.models.contact_list.set_s3_metadata')
mock_get_metadata = mocker.patch(
'app.models.contact_list.get_s3_metadata',
return_value={'original_file_name': 'invalid.csv'},
)
page = client_request.post(
'main.upload_contact_list',
service_id=SERVICE_ONE_ID,
_data={'file': (BytesIO(''.encode('utf-8')), 'invalid.csv')},
_follow_redirects=True,
)
bucket_creds = notify_admin.config['CONTACT_LIST_BUCKET']
mock_upload.assert_called_once_with(
filedata='',
region=bucket_creds['region'],
bucket_name=bucket_creds['bucket'],
file_location=f"service-{SERVICE_ONE_ID}-notify/{fake_uuid}.csv",
access_key=bucket_creds['access_key_id'],
secret_key=bucket_creds['secret_access_key'],
)
mock_set_metadata.assert_called_once_with(
ANY,
original_file_name='invalid.csv'
)
mock_download.assert_called_once()
mock_get_metadata.assert_called_once()
assert normalize_spaces(page.select_one('.banner-dangerous').text) == expected_error
assert page.select_one('form')['action'] == url_for(
'main.upload_contact_list',
service_id=SERVICE_ONE_ID,
)
assert page.select_one('form input')['type'] == 'file'
assert page.select_one('form input')['accept'] == '.csv,.xlsx,.xls,.ods,.xlsm,.tsv'
assert normalize_spaces(page.select_one('thead').text) == expected_thead
assert normalize_spaces(page.select_one('tbody').text) == expected_tbody
def test_upload_csv_file_shows_error_banner_for_too_many_rows(
client_request,
mocker,
mock_s3_upload,
mock_get_job_doesnt_exist,
mock_get_users_by_service,
fake_uuid,
):
mocker.patch('app.models.contact_list.utils_s3upload', return_value=fake_uuid)
mocker.patch('app.models.contact_list.set_s3_metadata')
mocker.patch('app.models.contact_list.get_s3_contents', return_value='\n'.join(
['phone number'] + (['2028675309'] * 100_001)
))
mocker.patch('app.models.contact_list.get_s3_metadata',
return_value={'original_file_name': 'invalid.csv'})
page = client_request.post(
'main.upload_contact_list',
service_id=SERVICE_ONE_ID,
_data={'file': (BytesIO(''.encode('utf-8')), 'invalid.csv')},
_follow_redirects=True,
)
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
'Your file has too many rows '
'Notify can store files up to 100,000 rows in size. '
'Your file has 100,001 rows.'
)
assert len(page.select('tbody tr')) == 50
assert normalize_spaces(page.select_one('.table-show-more-link').text) == (
'Only showing the first 50 rows'
)
def test_upload_csv_shows_error_with_invalid_extension(
client_request,
):
page = client_request.post(
'main.upload_contact_list',
service_id=SERVICE_ONE_ID,
_data={'file': (BytesIO(''.encode('utf-8')), 'invalid.txt')},
_follow_redirects=True,
)
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
"invalid.txt is not a spreadsheet that Notify can read"
)
def test_upload_csv_file_sanitises_and_truncates_file_name_in_metadata(
client_request,
mocker,
mock_s3_upload,
mock_get_job_doesnt_exist,
mock_get_users_by_service,
fake_uuid,
):
mocker.patch('app.models.contact_list.utils_s3upload', return_value=fake_uuid)
mock_set_metadata = mocker.patch('app.models.contact_list.set_s3_metadata')
mocker.patch('app.models.contact_list.get_s3_contents', return_value='\n'.join(
['phone number'] + (['2028675309'] * 100_001)
))
filename = f"😁{'a' * 2000}.csv"
mocker.patch('app.models.contact_list.get_s3_metadata',
return_value={'original_file_name': filename})
client_request.post(
'main.upload_contact_list',
service_id=SERVICE_ONE_ID,
_data={'file': (BytesIO(''.encode('utf-8')), filename)},
_follow_redirects=False
)
assert len(
mock_set_metadata.call_args_list[0][1]['original_file_name']
) < len(filename)
assert mock_set_metadata.call_args_list[0][1]['original_file_name'].startswith('?')
def test_upload_csv_shows_trial_mode_error(
client_request,
mock_get_users_by_service,
mock_get_job_doesnt_exist,
fake_uuid,
mocker
):
mocker.patch('app.models.contact_list.utils_s3upload', return_value=fake_uuid)
mocker.patch('app.models.contact_list.get_s3_contents', return_value=(
'phone number\n'
'2028675209' # Not in team
))
mocker.patch('app.models.contact_list.get_s3_metadata',
return_value={'original_file_name': 'invalid.csv'})
page = client_request.get(
'main.check_contact_list',
service_id=SERVICE_ONE_ID,
upload_id=fake_uuid,
_test_page_title=False,
)
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
'You cannot save this phone number '
'In trial mode you can only send to yourself and members of your team'
)
assert page.select_one('.banner-dangerous a')['href'] == url_for(
'main.trial_mode_new'
)
def test_upload_csv_shows_ok_page(
client_request,
mock_get_live_service,
mock_get_users_by_service,
mock_get_job_doesnt_exist,
fake_uuid,
mocker
):
mocker.patch('app.models.contact_list.get_s3_contents', return_value='\n'.join(
['email address'] + ['test@example.com'] * 51
))
mocker.patch('app.models.contact_list.get_s3_metadata',
return_value={'original_file_name': 'good times.xlsx'})
mock_metadata_set = mocker.patch('app.models.contact_list.set_s3_metadata')
page = client_request.get(
'main.check_contact_list',
service_id=SERVICE_ONE_ID,
upload_id=fake_uuid,
_test_page_title=False,
)
mock_metadata_set.assert_called_once_with(
mocker.ANY,
row_count=51,
original_file_name='good times.xlsx',
template_type='email',
valid=True,
)
assert normalize_spaces(page.select_one('h1').text) == (
'good times.xlsx'
)
assert normalize_spaces(page.select_one('main p').text) == (
'51 email addresses found'
)
assert page.select_one('form')['action'] == url_for(
'main.save_contact_list',
service_id=SERVICE_ONE_ID,
upload_id=fake_uuid,
)
assert normalize_spaces(page.select_one('form [type=submit]').text) == (
'Save contact list'
)
assert normalize_spaces(page.select_one('thead').text) == (
'Row in file 1 email address'
)
assert len(page.select('tbody tr')) == 50
assert normalize_spaces(page.select_one('tbody tr').text) == (
'2 test@example.com'
)
assert normalize_spaces(page.select_one('.table-show-more-link').text) == (
'Only showing the first 50 rows'
)
def test_save_contact_list(
mocker,
client_request,
fake_uuid,
mock_create_contact_list,
):
mock_get_metadata = mocker.patch('app.models.contact_list.get_s3_metadata', return_value={
'row_count': 999,
'valid': True,
'original_file_name': 'example.csv',
'template_type': 'email'
})
client_request.post(
'main.save_contact_list',
service_id=SERVICE_ONE_ID,
upload_id=fake_uuid,
_expected_status=302,
_expected_redirect=url_for(
'main.uploads',
service_id=SERVICE_ONE_ID,
)
)
mock_get_metadata.assert_called_once()
mock_create_contact_list.assert_called_once_with(
service_id=SERVICE_ONE_ID,
upload_id=fake_uuid,
original_file_name='example.csv',
row_count=999,
template_type='email',
)
def test_cant_save_bad_contact_list(
mocker,
client_request,
fake_uuid,
mock_create_contact_list,
):
mocker.patch('app.models.contact_list.get_s3_metadata', return_value={
'row_count': 999,
'valid': False,
'original_file_name': 'example.csv',
'template_type': 'email'
})
client_request.post(
'main.save_contact_list',
service_id=SERVICE_ONE_ID,
upload_id=fake_uuid,
_expected_status=403,
)
assert mock_create_contact_list.called is False
@pytest.mark.parametrize('has_jobs, expected_empty_message', [
(False, 'Not used yet.'),
(True, 'Not used in the last 7 days.'),
])
@freeze_time('2020-06-13 16:51:56')
def test_view_contact_list(
mocker,
client_request,
mock_get_contact_list,
mock_get_no_jobs,
mock_get_service_data_retention,
fake_uuid,
has_jobs,
expected_empty_message,
):
mocker.patch(
'app.models.contact_list.contact_list_api_client.get_contact_list',
return_value=contact_list_json(
created_at='2020-03-03T17:12:12.000000Z',
service_id=SERVICE_ONE_ID,
has_jobs=has_jobs
)
)
mocker.patch('app.models.contact_list.get_s3_contents', return_value='\n'.join(
['email address'] + [
f'test-{i}@example.com' for i in range(51)
]
))
page = client_request.get(
'main.contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
)
mock_get_no_jobs.assert_called_once_with(
SERVICE_ONE_ID,
contact_list_id=fake_uuid,
limit_days=7,
statuses={
'finished',
'in progress',
'pending',
'ready to send',
'scheduled',
'sending limits exceeded',
'sent to dvla',
},
page=1,
)
assert normalize_spaces(page.select_one('h1').text) == (
'EmergencyContactList.xls'
)
assert normalize_spaces(page.select('main p')[0].text) == (
'Uploaded by Test User on 3 March at 12:12pm.'
)
assert normalize_spaces(page.select('main p')[1].text) == (
expected_empty_message
)
assert normalize_spaces(page.select_one('main h2').text) == (
'51 saved email addresses'
)
assert page.select_one('.js-stick-at-bottom-when-scrolling a[download]')['href'] == url_for(
'main.download_contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
)
assert len(page.select('tbody tr')) == 50
assert [
normalize_spaces(page.select('tbody tr')[0].text),
normalize_spaces(page.select('tbody tr')[1].text),
normalize_spaces(page.select('tbody tr')[48].text),
normalize_spaces(page.select('tbody tr')[49].text),
] == [
'test-0@example.com',
'test-1@example.com',
'test-48@example.com',
'test-49@example.com',
]
assert 'test-50@example.com' not in page.select_one('tbody').text
assert normalize_spaces(page.select_one('.table-show-more-link').text) == (
'Only showing the first 50 rows'
)
@freeze_time('2015-12-31 21:51:56')
def test_view_jobs_for_contact_list(
mocker,
client_request,
mock_get_jobs,
mock_get_service_data_retention,
fake_uuid,
):
mocker.patch(
'app.models.contact_list.contact_list_api_client.get_contact_list',
return_value={
'created_at': '2015-12-31 17:12:12',
'created_by': 'Test User',
'id': fake_uuid,
'original_file_name': 'EmergencyContactList.xls',
'row_count': 100,
'recent_job_count': 0,
'has_jobs': True,
'service_id': SERVICE_ONE_ID,
'template_type': 'email',
},
)
mocker.patch('app.models.contact_list.get_s3_contents', return_value='\n'.join(
['email address'] + ['test@example.com'] * 51
))
page = client_request.get(
'main.contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
)
assert normalize_spaces(page.select_one('h1').text) == (
'EmergencyContactList.xls'
)
assert normalize_spaces(page.select('main p')[0].text) == (
'Uploaded by Test User today at 12:12pm.'
)
assert normalize_spaces(page.select('main p')[1].text) == (
'Used 6 times in the last 7 days.'
)
assert [
normalize_spaces(row.text)
for row in page.select_one('table').select('tr')
] == [
'Template Status',
(
'Template Y '
'Sending tomorrow at 6:09pm '
'1 text message waiting to send'
),
(
'Template Z '
'Sending tomorrow at 6:09am '
'1 text message waiting to send'
),
(
'Template A '
'Sent today at 4:51pm '
'1 sending 0 delivered 0 failed'
),
(
'Template B '
'Sent today at 4:51pm '
'1 sending 0 delivered 0 failed'
),
(
'Template C '
'Sent today at 4:51pm '
'1 sending 0 delivered 0 failed'
),
(
'Template D '
'Sent today at 4:51pm '
'1 sending 0 delivered 0 failed'
),
]
assert page.select_one('table a')['href'] == url_for(
'main.view_job',
service_id=SERVICE_ONE_ID,
job_id=fake_uuid,
)
def test_view_contact_list_404s_for_non_existing_list(
client_request,
mock_get_no_contact_list,
fake_uuid,
):
client_request.get(
'main.contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=uuid.uuid4(),
_expected_status=404,
)
def test_download_contact_list(
mocker,
client_request,
fake_uuid,
mock_get_contact_list,
):
mocker.patch(
'app.models.contact_list.get_s3_contents',
return_value='phone number\n2028675209'
)
response = client_request.get_response(
'main.download_contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
)
assert response.headers['Content-Type'] == (
'text/csv; '
'charset=utf-8'
)
assert response.headers['Content-Disposition'] == (
'attachment; '
'filename=EmergencyContactList.csv'
)
assert response.get_data(as_text=True) == (
'phone number\n'
'2028675209'
)
def test_confirm_delete_contact_list(
mocker,
client_request,
fake_uuid,
mock_get_jobs,
mock_get_service_data_retention,
mock_get_contact_list,
):
mocker.patch(
'app.models.contact_list.get_s3_contents',
return_value='phone number\n2028675209'
)
page = client_request.get(
'main.delete_contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
)
assert normalize_spaces(page.select_one('.banner-dangerous').text) == (
'Are you sure you want to delete EmergencyContactList.xls? '
'Yes, delete'
)
assert 'action' not in page.select_one('form')
assert page.select_one('form')['method'] == 'post'
assert page.select_one('form button')['type'] == 'submit'
def test_delete_contact_list(
mocker,
client_request,
fake_uuid,
mock_get_contact_list,
):
mock_delete = mocker.patch(
'app.models.contact_list.contact_list_api_client.delete_contact_list'
)
client_request.post(
'main.delete_contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
_expected_redirect=url_for(
'main.uploads',
service_id=SERVICE_ONE_ID,
)
)
mock_delete.assert_called_once_with(
service_id=SERVICE_ONE_ID,
contact_list_id=fake_uuid,
)

View File

@@ -1,7 +1,4 @@
import re
import pytest
from flask import url_for
from freezegun import freeze_time
from app.formatters import normalize_spaces
@@ -9,31 +6,9 @@ from tests.conftest import (
SERVICE_ONE_ID,
create_active_caseworking_user,
create_active_user_with_permissions,
create_platform_admin_user,
)
@pytest.mark.skip(reason="Not sure that TTS needs this")
@pytest.mark.parametrize('user', (
create_platform_admin_user(),
create_active_user_with_permissions(),
))
def test_all_users_have_upload_contact_list(
client_request,
mock_get_uploads,
mock_get_jobs,
mock_get_no_contact_lists,
user,
):
client_request.login(user)
page = client_request.get('main.uploads', service_id=SERVICE_ONE_ID)
button = page.find('a', text=re.compile('Upload an emergency contact list'))
assert button
assert button['href'] == url_for(
'main.upload_contact_list', service_id=SERVICE_ONE_ID,
)
@pytest.mark.parametrize('extra_permissions, expected_empty_message', (
([], (
'You have not uploaded any files recently.'
@@ -44,7 +19,6 @@ def test_get_upload_hub_with_no_uploads(
client_request,
service_one,
mock_get_no_uploads,
mock_get_no_contact_lists,
extra_permissions,
expected_empty_message,
):
@@ -63,7 +37,6 @@ def test_get_upload_hub_page(
client_request,
service_one,
mock_get_uploads,
mock_get_no_contact_lists,
):
mocker.patch('app.job_api_client.get_jobs', return_value={'data': []})
page = client_request.get('main.uploads', service_id=SERVICE_ONE_ID)
@@ -93,7 +66,6 @@ def test_uploads_page_shows_scheduled_jobs(
client_request,
mock_get_no_uploads,
mock_get_jobs,
mock_get_no_contact_lists,
user,
):
client_request.login(user)
@@ -117,53 +89,3 @@ def test_uploads_page_shows_scheduled_jobs(
),
]
assert not page.select('.table-empty-message')
@freeze_time('2020-03-15')
def test_uploads_page_shows_contact_lists_first(
mocker,
client_request,
mock_get_no_uploads,
mock_get_jobs,
mock_get_contact_lists,
mock_get_service_data_retention,
):
page = client_request.get('main.uploads', service_id=SERVICE_ONE_ID)
assert [
normalize_spaces(row.text) for row in page.select('tr')
] == [
(
'File Status'
),
(
'phone number list.csv '
'Used twice in the last 7 days '
'123 saved phone numbers'
),
(
'EmergencyContactList.xls '
'Not used in the last 7 days '
'100 saved email addresses'
),
(
'UnusedList.tsv '
'Not used yet '
'1 saved phone number'
),
(
'even_later.csv '
'Sending 1 January 2016 at 6:09pm '
'1 text message waiting to send'
),
(
'send_me_later.csv '
'Sending 1 January 2016 at 6:09am '
'1 text message waiting to send'
),
]
assert page.select_one('.file-list-filename-large')['href'] == url_for(
'main.contact_list',
service_id=SERVICE_ONE_ID,
contact_list_id='d7b0bd1a-d1c7-4621-be5c-3c1b4278a2ad',
)