mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-16 20:49:00 -04:00
Group form tests in a directory
This makes it clearer we have tests for the code in forms.py, which I missed initially. In future we could also split up forms.py in a similar way, as it's currently _very long_. As part of grouping tests for code in forms.py, I've extracted some from test_validators.py, so that what remains is focussed on testing the code in validators.py.
This commit is contained in:
45
tests/app/main/forms/test_choose_time_form.py
Normal file
45
tests/app/main/forms/test_choose_time_form.py
Normal file
@@ -0,0 +1,45 @@
|
||||
import pytest
|
||||
from freezegun import freeze_time
|
||||
|
||||
from app.main.forms import ChooseTimeForm
|
||||
|
||||
|
||||
@freeze_time("2016-01-01 11:09:00.061258")
|
||||
def test_form_contains_next_24h(notify_admin):
|
||||
|
||||
choices = ChooseTimeForm().scheduled_for.choices
|
||||
|
||||
# Friday
|
||||
assert choices[0] == ('', 'Now')
|
||||
assert choices[1] == ('2016-01-01T12:00:00', 'Today at midday')
|
||||
assert choices[13] == ('2016-01-02T00:00:00', 'Today at midnight')
|
||||
|
||||
# Saturday
|
||||
assert choices[14] == ('2016-01-02T01:00:00', 'Tomorrow at 1am')
|
||||
assert choices[37] == ('2016-01-03T00:00:00', 'Tomorrow at midnight')
|
||||
|
||||
# Sunday
|
||||
assert choices[38] == ('2016-01-03T01:00:00', 'Sunday at 1am')
|
||||
|
||||
# Monday
|
||||
assert choices[84] == ('2016-01-04T23:00:00', 'Monday at 11pm')
|
||||
assert choices[85] == ('2016-01-05T00:00:00', 'Monday at midnight')
|
||||
|
||||
with pytest.raises(IndexError):
|
||||
assert choices[
|
||||
12 + # hours left in the day
|
||||
(3 * 24) + # 3 days
|
||||
2 # magic number
|
||||
]
|
||||
|
||||
|
||||
@freeze_time("2016-01-01 11:09:00.061258")
|
||||
def test_form_defaults_to_now(notify_admin):
|
||||
assert ChooseTimeForm().scheduled_for.data == ''
|
||||
|
||||
|
||||
@freeze_time("2016-01-01 11:09:00.061258")
|
||||
def test_form_contains_next_three_days(notify_admin):
|
||||
assert ChooseTimeForm().scheduled_for.categories == [
|
||||
'Later today', 'Tomorrow', 'Sunday', 'Monday'
|
||||
]
|
||||
50
tests/app/main/forms/test_create_key_form.py
Normal file
50
tests/app/main/forms/test_create_key_form.py
Normal file
@@ -0,0 +1,50 @@
|
||||
import pytest
|
||||
from werkzeug.datastructures import MultiDict
|
||||
|
||||
from app.main.forms import CreateKeyForm
|
||||
|
||||
|
||||
@pytest.mark.parametrize('expiry_date, expected_errors', (
|
||||
(None, ['A key with this name already exists']),
|
||||
('2001-01-01 01:01:01', None),
|
||||
))
|
||||
def test_return_validation_error_when_key_name_exists(
|
||||
client_request,
|
||||
expiry_date,
|
||||
expected_errors,
|
||||
):
|
||||
_existing_keys = [
|
||||
{
|
||||
'name': 'some key',
|
||||
'expiry_date': expiry_date,
|
||||
},
|
||||
{
|
||||
'name': 'another key',
|
||||
'expiry_date': None,
|
||||
},
|
||||
]
|
||||
|
||||
form = CreateKeyForm(
|
||||
_existing_keys,
|
||||
formdata=MultiDict([('key_name', 'Some key')])
|
||||
)
|
||||
|
||||
form.key_type.choices = [('a', 'a'), ('b', 'b')]
|
||||
form.validate()
|
||||
assert form.errors.get('key_name') == expected_errors
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
'key_type, expected_error', [
|
||||
('', 'Select the type of key'),
|
||||
('invalid', 'Select the type of key')
|
||||
]
|
||||
)
|
||||
def test_return_validation_error_when_key_type_not_chosen(client_request, key_type, expected_error):
|
||||
|
||||
form = CreateKeyForm(
|
||||
[],
|
||||
formdata=MultiDict([('key_name', 'Some key'), ('key_type', key_type)]))
|
||||
form.key_type.choices = [('a', 'a'), ('b', 'b')]
|
||||
form.validate()
|
||||
assert form.errors['key_type'] == [expected_error]
|
||||
71
tests/app/main/forms/test_placeholder_form.py
Normal file
71
tests/app/main/forms/test_placeholder_form.py
Normal file
@@ -0,0 +1,71 @@
|
||||
import pytest
|
||||
|
||||
from app.main.forms import get_placeholder_form_instance
|
||||
|
||||
|
||||
def test_form_class_not_mutated(notify_admin):
|
||||
|
||||
with notify_admin.test_request_context(
|
||||
method='POST',
|
||||
data={'placeholder_value': ''}
|
||||
):
|
||||
form1 = get_placeholder_form_instance('name', {}, 'sms')
|
||||
form2 = get_placeholder_form_instance('city', {}, 'sms')
|
||||
|
||||
assert not form1.validate_on_submit()
|
||||
assert not form2.validate_on_submit()
|
||||
|
||||
assert str(form1.placeholder_value.label) == '<label for="placeholder_value">name</label>'
|
||||
assert str(form2.placeholder_value.label) == '<label for="placeholder_value">city</label>'
|
||||
|
||||
|
||||
@pytest.mark.parametrize('service_can_send_international_sms, placeholder_name, template_type, value, expected_error', [
|
||||
|
||||
(False, 'email address', 'email', '', 'Cannot be empty'),
|
||||
(False, 'email address', 'email', '12345', 'Enter a valid email address'),
|
||||
(False, 'email address', 'email', '“bad”@email-address.com', 'Enter a valid email address'),
|
||||
(False, 'email address', 'email', 'test@example.com', None),
|
||||
(False, 'email address', 'email', 'test@example.gov.uk', None),
|
||||
|
||||
(False, 'phone number', 'sms', '', 'Cannot be empty'),
|
||||
(False, 'phone number', 'sms', '+1-2345-678890', 'Not a UK mobile number'),
|
||||
(False, 'phone number', 'sms', '07900900123', None),
|
||||
(False, 'phone number', 'sms', '+44(0)7900 900-123', None),
|
||||
|
||||
(True, 'phone number', 'sms', '+123', 'Not enough digits'),
|
||||
(True, 'phone number', 'sms', '+44(0)7900 900-123', None),
|
||||
(True, 'phone number', 'sms', '+1-2345-678890', None),
|
||||
|
||||
(False, 'anything else', 'sms', '', 'Cannot be empty'),
|
||||
(False, 'anything else', 'email', '', 'Cannot be empty'),
|
||||
|
||||
(True, 'phone number', 'sms', 'invalid', 'Must not contain letters or symbols'),
|
||||
(True, 'phone number', 'email', 'invalid', None),
|
||||
(True, 'phone number', 'letter', 'invalid', None),
|
||||
(True, 'email address', 'sms', 'invalid', None),
|
||||
|
||||
])
|
||||
def test_validates_recipients(
|
||||
notify_admin,
|
||||
placeholder_name,
|
||||
template_type,
|
||||
value,
|
||||
service_can_send_international_sms,
|
||||
expected_error,
|
||||
):
|
||||
with notify_admin.test_request_context(
|
||||
method='POST',
|
||||
data={'placeholder_value': value}
|
||||
):
|
||||
form = get_placeholder_form_instance(
|
||||
placeholder_name,
|
||||
{},
|
||||
template_type,
|
||||
allow_international_phone_numbers=service_can_send_international_sms,
|
||||
)
|
||||
|
||||
if expected_error:
|
||||
assert not form.validate_on_submit()
|
||||
assert form.placeholder_value.errors[0] == expected_error
|
||||
else:
|
||||
assert form.validate_on_submit()
|
||||
61
tests/app/main/forms/test_register_user_form.py
Normal file
61
tests/app/main/forms/test_register_user_form.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import pytest
|
||||
|
||||
from app.main.forms import RegisterUserForm
|
||||
|
||||
|
||||
@pytest.mark.parametrize('password', [
|
||||
'govuknotify', '11111111', 'kittykat', 'blackbox'
|
||||
])
|
||||
def test_should_raise_validation_error_for_password(
|
||||
client_request,
|
||||
mock_get_user_by_email,
|
||||
password,
|
||||
):
|
||||
form = RegisterUserForm()
|
||||
form.name.data = 'test'
|
||||
form.email_address.data = 'teset@example.gov.uk'
|
||||
form.mobile_number.data = '441231231231'
|
||||
form.password.data = password
|
||||
|
||||
form.validate()
|
||||
assert 'Choose a password that’s harder to guess' in form.errors['password']
|
||||
|
||||
|
||||
def test_valid_email_not_in_valid_domains(
|
||||
client_request,
|
||||
mock_get_organisations,
|
||||
):
|
||||
form = RegisterUserForm(email_address="test@test.com", mobile_number='441231231231')
|
||||
assert not form.validate()
|
||||
assert "Enter a public sector email address" in form.errors['email_address'][0]
|
||||
|
||||
|
||||
def test_valid_email_in_valid_domains(
|
||||
client_request,
|
||||
):
|
||||
form = RegisterUserForm(
|
||||
name="test",
|
||||
email_address="test@my.gov.uk",
|
||||
mobile_number='4407888999111',
|
||||
password='an uncommon password')
|
||||
form.validate()
|
||||
assert form.errors == {}
|
||||
|
||||
|
||||
def test_invalid_email_address_error_message(
|
||||
client_request,
|
||||
mock_get_organisations,
|
||||
):
|
||||
form = RegisterUserForm(
|
||||
name="test",
|
||||
email_address="test.com",
|
||||
mobile_number='4407888999111',
|
||||
password='1234567890')
|
||||
assert not form.validate()
|
||||
|
||||
form = RegisterUserForm(
|
||||
name="test",
|
||||
email_address="test.com",
|
||||
mobile_number='4407888999111',
|
||||
password='1234567890')
|
||||
assert not form.validate()
|
||||
92
tests/app/main/forms/test_service_contact_details_form.py
Normal file
92
tests/app/main/forms/test_service_contact_details_form.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import pytest
|
||||
|
||||
from app.main.forms import ServiceContactDetailsForm
|
||||
|
||||
|
||||
def test_form_fails_validation_with_no_radio_buttons_selected(notify_admin):
|
||||
with notify_admin.test_request_context(method='POST', data={}):
|
||||
form = ServiceContactDetailsForm()
|
||||
|
||||
assert not form.validate_on_submit()
|
||||
assert len(form.errors) == 1
|
||||
assert form.errors['contact_details_type'] == ['Select an option']
|
||||
|
||||
|
||||
@pytest.mark.parametrize('selected_radio_button, selected_text_box, text_box_data', [
|
||||
('email_address', 'url', 'http://www.example.com'),
|
||||
('phone_number', 'url', 'http://www.example.com'),
|
||||
('url', 'email_address', 'user@example.com'),
|
||||
('phone_number', 'email_address', 'user@example.com'),
|
||||
('url', 'phone_number', '0207 123 4567'),
|
||||
('email_address', 'phone_number', '0207 123 4567'),
|
||||
])
|
||||
def test_form_fails_validation_when_radio_button_selected_and_text_box_filled_in_do_not_match(
|
||||
notify_admin,
|
||||
selected_radio_button,
|
||||
selected_text_box,
|
||||
text_box_data
|
||||
):
|
||||
data = {'contact_details_type': selected_radio_button, selected_text_box: text_box_data}
|
||||
|
||||
with notify_admin.test_request_context(method='POST', data=data):
|
||||
form = ServiceContactDetailsForm()
|
||||
|
||||
assert not form.validate_on_submit()
|
||||
assert len(form.errors) == 1
|
||||
assert form.errors[selected_radio_button] == ['This field is required.']
|
||||
|
||||
|
||||
@pytest.mark.parametrize('selected_field, url, email_address, phone_number', [
|
||||
('url', 'http://www.example.com', 'invalid-email.com', 'phone'),
|
||||
('email_address', 'www.invalid-url.com', 'me@example.com', 'phone'),
|
||||
('phone_number', 'www.invalid-url.com', 'invalid-email.com', '0207 123 4567'),
|
||||
])
|
||||
def test_form_only_validates_the_field_which_matches_the_selected_radio_button(
|
||||
notify_admin,
|
||||
selected_field,
|
||||
url,
|
||||
email_address,
|
||||
phone_number,
|
||||
):
|
||||
data = {'contact_details_type': selected_field,
|
||||
'url': url,
|
||||
'email_address': email_address,
|
||||
'phone_number': phone_number}
|
||||
|
||||
with notify_admin.test_request_context(method='POST', data=data):
|
||||
form = ServiceContactDetailsForm()
|
||||
|
||||
assert form.validate_on_submit()
|
||||
|
||||
|
||||
def test_form_url_validation_fails_with_invalid_url_field(notify_admin):
|
||||
data = {'contact_details_type': 'url', 'url': 'www.example.com'}
|
||||
|
||||
with notify_admin.test_request_context(method='POST', data=data):
|
||||
form = ServiceContactDetailsForm()
|
||||
|
||||
assert not form.validate_on_submit()
|
||||
assert len(form.errors) == 1
|
||||
assert len(form.errors['url']) == 1
|
||||
|
||||
|
||||
def test_form_email_validation_fails_with_invalid_email_address_field(notify_admin):
|
||||
data = {'contact_details_type': 'email_address', 'email_address': '1@co'}
|
||||
|
||||
with notify_admin.test_request_context(method='POST', data=data):
|
||||
form = ServiceContactDetailsForm()
|
||||
|
||||
assert not form.validate_on_submit()
|
||||
assert len(form.errors) == 1
|
||||
assert len(form.errors['email_address']) == 2
|
||||
|
||||
|
||||
def test_form_phone_number_validation_fails_with_invalid_phone_number_field(notify_admin):
|
||||
data = {'contact_details_type': 'phone_number', 'phone_number': '1235 A'}
|
||||
|
||||
with notify_admin.test_request_context(method='POST', data=data):
|
||||
form = ServiceContactDetailsForm()
|
||||
|
||||
assert not form.validate_on_submit()
|
||||
assert len(form.errors) == 1
|
||||
assert form.errors['phone_number'] == ['Must be a valid phone number']
|
||||
37
tests/app/main/forms/test_service_sms_senders_form.py
Normal file
37
tests/app/main/forms/test_service_sms_senders_form.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import pytest
|
||||
|
||||
from app.main.forms import ServiceSmsSenderForm
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"sms_sender,error_expected,error_message",
|
||||
[
|
||||
('', True, 'Cannot be empty'),
|
||||
('22', True, 'Enter 3 characters or more'),
|
||||
('333', False, None),
|
||||
('elevenchars', False, None), # 11 chars
|
||||
('twelvecharas', True, 'Enter 11 characters or fewer'), # 12 chars
|
||||
('###', True, 'Use letters and numbers only'),
|
||||
('00111222333', True, 'Cannot start with 00'),
|
||||
('UK_GOV', False, None), # Underscores are allowed
|
||||
('UK.GOV', False, None), # Full stops are allowed
|
||||
("'UC'", False, None), # Straight single quotes are allowed
|
||||
]
|
||||
)
|
||||
def test_sms_sender_form_validation(
|
||||
client_request,
|
||||
mock_get_user_by_email,
|
||||
sms_sender,
|
||||
error_expected,
|
||||
error_message
|
||||
):
|
||||
form = ServiceSmsSenderForm()
|
||||
form.sms_sender.data = sms_sender
|
||||
|
||||
form.validate()
|
||||
|
||||
if error_expected:
|
||||
assert form.errors
|
||||
assert error_message == form.errors['sms_sender'][0]
|
||||
else:
|
||||
assert not form.errors
|
||||
32
tests/app/main/forms/test_strip_whitespace.py
Normal file
32
tests/app/main/forms/test_strip_whitespace.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import pytest
|
||||
from wtforms import Form, StringField
|
||||
|
||||
from app.main.forms import StripWhitespaceForm, StripWhitespaceStringField
|
||||
|
||||
|
||||
class ExampleForm(StripWhitespaceForm):
|
||||
foo = StringField('Foo')
|
||||
|
||||
|
||||
class ExampleFormSpecialField(Form):
|
||||
foo = StripWhitespaceStringField('foo')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('submitted_data', [
|
||||
'bar',
|
||||
' bar ',
|
||||
"""
|
||||
\t bar
|
||||
""",
|
||||
' \u180E\u200B \u200C bar \u200D \u2060\uFEFF ',
|
||||
])
|
||||
@pytest.mark.parametrize('form', [
|
||||
ExampleForm,
|
||||
ExampleFormSpecialField,
|
||||
])
|
||||
def test_form_strips_all_whitespace(
|
||||
notify_admin,
|
||||
form,
|
||||
submitted_data,
|
||||
):
|
||||
assert form(foo=submitted_data).foo.data == 'bar'
|
||||
80
tests/app/main/forms/test_two_factor_form.py
Normal file
80
tests/app/main/forms/test_two_factor_form.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import pytest
|
||||
|
||||
from app import user_api_client
|
||||
from app.main.forms import TwoFactorForm
|
||||
|
||||
|
||||
def _check_code(code):
|
||||
return user_api_client.check_verify_code('1', code, "sms")
|
||||
|
||||
|
||||
@pytest.mark.parametrize('post_data', [
|
||||
{'sms_code': '12345'},
|
||||
{'sms_code': ' 12345 '},
|
||||
{'sms_code': '12 34 5'},
|
||||
{'sms_code': '1-23-45'},
|
||||
])
|
||||
def test_form_is_valid_returns_no_errors(
|
||||
notify_admin,
|
||||
mock_check_verify_code,
|
||||
post_data,
|
||||
):
|
||||
with notify_admin.test_request_context(method='POST', data=post_data):
|
||||
form = TwoFactorForm(_check_code)
|
||||
assert form.validate() is True
|
||||
assert form.errors == {}
|
||||
mock_check_verify_code.assert_called_once_with('1', '12345', 'sms')
|
||||
|
||||
|
||||
@pytest.mark.parametrize('post_data, expected_error', (
|
||||
(
|
||||
{'sms_code': '1234'},
|
||||
'Not enough numbers',
|
||||
),
|
||||
(
|
||||
{'sms_code': '123456'},
|
||||
'Too many numbers',
|
||||
),
|
||||
(
|
||||
{},
|
||||
'Cannot be empty',
|
||||
),
|
||||
(
|
||||
{'sms_code': '12E45'},
|
||||
'Numbers only',
|
||||
),
|
||||
(
|
||||
{'sms_code': ' ! 2 3 4 5'},
|
||||
'Numbers only',
|
||||
),
|
||||
))
|
||||
def test_check_verify_code_returns_errors(
|
||||
notify_admin,
|
||||
post_data,
|
||||
expected_error,
|
||||
mock_check_verify_code,
|
||||
):
|
||||
with notify_admin.test_request_context(method='POST', data=post_data):
|
||||
form = TwoFactorForm(_check_code)
|
||||
assert form.validate() is False
|
||||
assert form.errors == {'sms_code': [expected_error]}
|
||||
|
||||
|
||||
def test_check_verify_code_returns_error_when_code_has_expired(
|
||||
notify_admin,
|
||||
mock_check_verify_code_code_expired,
|
||||
):
|
||||
with notify_admin.test_request_context(method='POST', data={'sms_code': '99999'}):
|
||||
form = TwoFactorForm(_check_code)
|
||||
assert form.validate() is False
|
||||
assert form.errors == {'sms_code': ['Code has expired']}
|
||||
|
||||
|
||||
def test_check_verify_code_returns_error_when_code_was_not_found(
|
||||
notify_admin,
|
||||
mock_check_verify_code_code_not_found,
|
||||
):
|
||||
with notify_admin.test_request_context(method='POST', data={'sms_code': '99999'}):
|
||||
form = TwoFactorForm(_check_code)
|
||||
assert form.validate() is False
|
||||
assert form.errors == {'sms_code': ['Code not found']}
|
||||
Reference in New Issue
Block a user