2018-02-20 11:22:17 +00:00
|
|
|
|
from unittest.mock import Mock
|
|
|
|
|
|
|
2016-04-06 11:01:22 +01:00
|
|
|
|
import pytest
|
|
|
|
|
|
from wtforms import ValidationError
|
2018-02-20 11:22:17 +00:00
|
|
|
|
|
|
|
|
|
|
from app.main.forms import RegisterUserForm, ServiceSmsSenderForm
|
|
|
|
|
|
from app.main.validators import (
|
2019-11-08 17:12:32 +00:00
|
|
|
|
MustContainAlphanumericCharacters,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
NoCommasInPlaceHolders,
|
2019-05-03 15:13:39 +01:00
|
|
|
|
OnlySMSCharacters,
|
2018-02-20 11:22:17 +00:00
|
|
|
|
ValidGovEmail,
|
|
|
|
|
|
)
|
2015-12-01 15:51:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
2016-09-27 11:28:12 +01:00
|
|
|
|
@pytest.mark.parametrize('password', [
|
2019-02-15 12:59:23 +00:00
|
|
|
|
'govuknotify', '11111111', 'kittykat', 'blackbox'
|
2016-09-27 11:28:12 +01:00
|
|
|
|
])
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_should_raise_validation_error_for_password(
|
2017-02-03 12:07:21 +00:00
|
|
|
|
client,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_user_by_email,
|
|
|
|
|
|
password,
|
|
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
form = RegisterUserForm()
|
|
|
|
|
|
form.name.data = 'test'
|
|
|
|
|
|
form.email_address.data = 'teset@example.gov.uk'
|
|
|
|
|
|
form.mobile_number.data = '441231231231'
|
|
|
|
|
|
form.password.data = password
|
2015-12-01 15:51:09 +00:00
|
|
|
|
|
2017-02-03 12:07:21 +00:00
|
|
|
|
form.validate()
|
|
|
|
|
|
assert 'Choose a password that’s harder to guess' in form.errors['password']
|
2016-03-18 12:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_valid_email_not_in_valid_domains(
|
2019-05-28 16:11:54 +01:00
|
|
|
|
client,
|
|
|
|
|
|
mock_get_organisations,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
form = RegisterUserForm(email_address="test@test.com", mobile_number='441231231231')
|
|
|
|
|
|
assert not form.validate()
|
2020-03-26 12:41:46 +00:00
|
|
|
|
assert "Enter a public sector email address" in form.errors['email_address'][0]
|
2016-03-18 12:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_valid_email_in_valid_domains(
|
2017-02-03 12:07:21 +00:00
|
|
|
|
client
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
form = RegisterUserForm(
|
|
|
|
|
|
name="test",
|
|
|
|
|
|
email_address="test@my.gov.uk",
|
|
|
|
|
|
mobile_number='4407888999111',
|
|
|
|
|
|
password='an uncommon password')
|
|
|
|
|
|
form.validate()
|
|
|
|
|
|
assert form.errors == {}
|
2016-03-18 12:05:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_invalid_email_address_error_message(
|
2019-05-28 16:11:54 +01:00
|
|
|
|
client,
|
|
|
|
|
|
mock_get_organisations,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
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()
|
2016-04-06 11:01:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _gen_mock_field(x):
|
|
|
|
|
|
return Mock(data=x)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("email", [
|
|
|
|
|
|
'test@gov.uk',
|
2016-04-06 16:45:35 +01:00
|
|
|
|
'test@GOV.UK',
|
|
|
|
|
|
'test@gov.uK',
|
2016-04-06 11:01:22 +01:00
|
|
|
|
'test@test.test.gov.uk',
|
|
|
|
|
|
'test@test.gov.uk',
|
|
|
|
|
|
'test@nhs.uk',
|
|
|
|
|
|
'test@gov.nhs.uk',
|
|
|
|
|
|
'test@nhs.net',
|
|
|
|
|
|
'test@gov.nhs.net',
|
Prune the email domains list
We only need domains in here which either:
- don’t belong to a single organisation (eg gov.uk)
All other domains should be stored in the database.
This PR removes domains which are now in the database.
Before
---
```sql
select domain from domain where domain in ('gov.uk', 'mod.uk', 'mil.uk', 'd
dc-mod.org', 'gov.scot', 'parliament.scot', 'parliament.uk', 'nhs.uk', 'nhs.net', 'nhs.scot', 'police.uk', 'scotent.c
o.uk', 'assembly.wales', 'cjsm.net', 'gov.wales', 'ac.uk', 'sch.uk', 'onevoicewales.wales', 'mtvh.co.uk', 'wmca.org.u
k', 'suttonmail.org');
```
+-----------------+
| domain |
|-----------------+
| mtvh.co.uk |
| wmca.org.uk |
| gov.wales |
| gov.scot |
| parliament.uk |
| assembly.wales |
| mil.uk |
| mod.uk |
| ddc-mod.org |
| parliament.scot |
| scotent.co.uk |
+-----------------+
After
---
```sql
select domain from domain where domain in ('gov.uk', 'nhs.uk', 'nhs.ne
t', 'nhs.scot', 'police.uk', 'cjsm.net', 'ac.uk', 'sch.uk', 'onevoicewales.wales', 'suttonmail.org') ;
```
+----------+
| domain |
|----------|
+----------+
2021-06-04 11:32:56 +01:00
|
|
|
|
'test@nhs.scot',
|
2016-04-06 11:01:22 +01:00
|
|
|
|
'test@police.uk',
|
2016-04-06 16:45:35 +01:00
|
|
|
|
'test@gov.police.uk',
|
|
|
|
|
|
'test@GOV.PoliCe.uk',
|
2017-06-05 13:51:53 +01:00
|
|
|
|
'test@cjsm.net',
|
Prune the email domains list
We only need domains in here which either:
- don’t belong to a single organisation (eg gov.uk)
All other domains should be stored in the database.
This PR removes domains which are now in the database.
Before
---
```sql
select domain from domain where domain in ('gov.uk', 'mod.uk', 'mil.uk', 'd
dc-mod.org', 'gov.scot', 'parliament.scot', 'parliament.uk', 'nhs.uk', 'nhs.net', 'nhs.scot', 'police.uk', 'scotent.c
o.uk', 'assembly.wales', 'cjsm.net', 'gov.wales', 'ac.uk', 'sch.uk', 'onevoicewales.wales', 'mtvh.co.uk', 'wmca.org.u
k', 'suttonmail.org');
```
+-----------------+
| domain |
|-----------------+
| mtvh.co.uk |
| wmca.org.uk |
| gov.wales |
| gov.scot |
| parliament.uk |
| assembly.wales |
| mil.uk |
| mod.uk |
| ddc-mod.org |
| parliament.scot |
| scotent.co.uk |
+-----------------+
After
---
```sql
select domain from domain where domain in ('gov.uk', 'nhs.uk', 'nhs.ne
t', 'nhs.scot', 'police.uk', 'cjsm.net', 'ac.uk', 'sch.uk', 'onevoicewales.wales', 'suttonmail.org') ;
```
+----------+
| domain |
|----------|
+----------+
2021-06-04 11:32:56 +01:00
|
|
|
|
'test@example.ac.uk',
|
|
|
|
|
|
'test@example.sch.uk',
|
2016-04-06 11:01:22 +01:00
|
|
|
|
])
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_valid_list_of_white_list_email_domains(
|
2017-02-03 12:07:21 +00:00
|
|
|
|
client,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
email,
|
|
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
email_domain_validators = ValidGovEmail()
|
|
|
|
|
|
email_domain_validators(None, _gen_mock_field(email))
|
2016-04-06 11:01:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("email", [
|
|
|
|
|
|
'test@ukgov.uk',
|
|
|
|
|
|
'test@gov.uk.uk',
|
|
|
|
|
|
'test@gov.test.uk',
|
|
|
|
|
|
'test@ukmod.uk',
|
|
|
|
|
|
'test@mod.uk.uk',
|
|
|
|
|
|
'test@mod.test.uk',
|
|
|
|
|
|
'test@ukddc-mod.org',
|
|
|
|
|
|
'test@ddc-mod.org.uk',
|
|
|
|
|
|
'test@ddc-mod.uk.org',
|
|
|
|
|
|
'test@ukgov.scot',
|
|
|
|
|
|
'test@gov.scot.uk',
|
|
|
|
|
|
'test@gov.test.scot',
|
|
|
|
|
|
'test@ukparliament.uk',
|
|
|
|
|
|
'test@parliament.uk.uk',
|
|
|
|
|
|
'test@parliament.test.uk',
|
|
|
|
|
|
'test@uknhs.uk',
|
|
|
|
|
|
'test@nhs.uk.uk',
|
|
|
|
|
|
'test@uknhs.net',
|
|
|
|
|
|
'test@nhs.net.uk',
|
|
|
|
|
|
'test@nhs.test.net',
|
|
|
|
|
|
'test@ukpolice.uk',
|
|
|
|
|
|
'test@police.uk.uk',
|
2016-10-18 13:51:34 +01:00
|
|
|
|
'test@police.test.uk',
|
2017-08-10 12:47:56 +01:00
|
|
|
|
'test@ucds.com',
|
|
|
|
|
|
'test@123bl.uk',
|
2016-04-06 11:01:22 +01:00
|
|
|
|
])
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_invalid_list_of_white_list_email_domains(
|
2017-02-03 12:07:21 +00:00
|
|
|
|
client,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
email,
|
2019-05-28 16:11:54 +01:00
|
|
|
|
mock_get_organisations,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
email_domain_validators = ValidGovEmail()
|
|
|
|
|
|
with pytest.raises(ValidationError):
|
|
|
|
|
|
email_domain_validators(None, _gen_mock_field(email))
|
2016-04-07 16:02:06 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_for_commas_in_placeholders(
|
2017-02-03 12:07:21 +00:00
|
|
|
|
client
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2017-02-03 12:07:21 +00:00
|
|
|
|
with pytest.raises(ValidationError) as error:
|
|
|
|
|
|
NoCommasInPlaceHolders()(None, _gen_mock_field('Hello ((name,date))'))
|
2019-09-12 16:49:18 +01:00
|
|
|
|
assert str(error.value) == 'You cannot put commas between double brackets'
|
2017-02-03 12:07:21 +00:00
|
|
|
|
NoCommasInPlaceHolders()(None, _gen_mock_field('Hello ((name))'))
|
2016-07-01 13:47:22 +01:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-14 17:06:32 +00:00
|
|
|
|
@pytest.mark.parametrize('msg', ['The quick brown fox', 'Thé “quick” bröwn fox\u200B'])
|
2019-05-03 15:13:39 +01:00
|
|
|
|
def test_sms_character_validation(client, msg):
|
2020-07-03 15:46:00 +01:00
|
|
|
|
OnlySMSCharacters(template_type='sms')(None, _gen_mock_field(msg))
|
2017-02-14 17:06:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
2017-02-15 16:21:14 +00:00
|
|
|
|
@pytest.mark.parametrize('data, err_msg', [
|
|
|
|
|
|
(
|
|
|
|
|
|
'∆ abc 📲 def 📵 ghi',
|
|
|
|
|
|
(
|
2019-09-12 16:49:18 +01:00
|
|
|
|
'You cannot use ∆, 📲 or 📵 in text messages. '
|
|
|
|
|
|
'They will not show up properly on everyone’s phones.'
|
2017-02-15 16:21:14 +00:00
|
|
|
|
)
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
'📵',
|
|
|
|
|
|
(
|
2019-09-12 16:49:18 +01:00
|
|
|
|
'You cannot use 📵 in text messages. '
|
|
|
|
|
|
'It will not show up properly on everyone’s phones.'
|
2017-02-15 16:21:14 +00:00
|
|
|
|
)
|
|
|
|
|
|
),
|
|
|
|
|
|
])
|
2019-05-03 15:13:39 +01:00
|
|
|
|
def test_non_sms_character_validation(data, err_msg, client):
|
2017-02-14 17:06:32 +00:00
|
|
|
|
with pytest.raises(ValidationError) as error:
|
2020-07-03 15:46:00 +01:00
|
|
|
|
OnlySMSCharacters(template_type='sms')(None, _gen_mock_field(data))
|
2017-02-14 17:06:32 +00:00
|
|
|
|
|
2017-02-15 16:21:14 +00:00
|
|
|
|
assert str(error.value) == err_msg
|
2017-02-14 17:06:32 +00:00
|
|
|
|
|
|
|
|
|
|
|
2019-11-08 17:12:32 +00:00
|
|
|
|
@pytest.mark.parametrize("string", [".", "A.", ".8...."])
|
|
|
|
|
|
def test_if_string_does_not_contain_alphanumeric_characters_raises(string):
|
|
|
|
|
|
with pytest.raises(ValidationError) as error:
|
|
|
|
|
|
MustContainAlphanumericCharacters()(None, _gen_mock_field(string))
|
|
|
|
|
|
|
|
|
|
|
|
assert str(error.value) == "Must include at least two alphanumeric characters"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("string", [".A8", "AB.", ".42...."])
|
|
|
|
|
|
def test_if_string_contains_alphanumeric_characters_does_not_raise(string):
|
|
|
|
|
|
MustContainAlphanumericCharacters()(None, _gen_mock_field(string))
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-07-26 14:33:54 +01:00
|
|
|
|
@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
|
2021-07-26 15:10:57 +01:00
|
|
|
|
("'UC'", False, None), # Straight single quotes are allowed
|
2021-07-26 14:33:54 +01:00
|
|
|
|
]
|
|
|
|
|
|
)
|
2017-02-03 10:42:01 +00:00
|
|
|
|
def test_sms_sender_form_validation(
|
2017-02-03 12:07:21 +00:00
|
|
|
|
client,
|
2017-02-03 10:42:01 +00:00
|
|
|
|
mock_get_user_by_email,
|
2021-07-26 14:33:54 +01:00
|
|
|
|
sms_sender,
|
|
|
|
|
|
error_expected,
|
|
|
|
|
|
error_message
|
2017-02-03 10:42:01 +00:00
|
|
|
|
):
|
2017-10-30 14:30:43 +00:00
|
|
|
|
form = ServiceSmsSenderForm()
|
2021-07-26 14:33:54 +01:00
|
|
|
|
form.sms_sender.data = sms_sender
|
2016-07-01 13:47:22 +01:00
|
|
|
|
|
2018-02-15 16:39:42 +00:00
|
|
|
|
form.validate()
|
2018-02-28 11:50:41 +00:00
|
|
|
|
|
2021-07-26 14:33:54 +01:00
|
|
|
|
if error_expected:
|
|
|
|
|
|
assert form.errors
|
|
|
|
|
|
assert error_message == form.errors['sms_sender'][0]
|
|
|
|
|
|
else:
|
|
|
|
|
|
assert not form.errors
|