forms: provide stricter PhoneField validation (#73345)
This commit is contained in:
parent
5616322fa3
commit
043c7abf6d
|
@ -244,5 +244,7 @@ class PhoneField(MultiValueField):
|
|||
pn = phonenumbers.parse(''.join(data_list), dial)
|
||||
except phonenumbers.NumberParseException:
|
||||
raise ValidationError(_('Invalid phone number.'))
|
||||
if not phonenumbers.is_valid_number(pn):
|
||||
raise ValidationError(_('Invalid phone number.'))
|
||||
return phonenumbers.format_number(pn, phonenumbers.PhoneNumberFormat.E164)
|
||||
return ''
|
||||
|
|
|
@ -234,11 +234,11 @@ def test_phone_number(db, app, admin, mailoutbox, settings):
|
|||
|
||||
form = response.form
|
||||
form.set('phone_number_0', '33')
|
||||
form.set('phone_number_1', '12345')
|
||||
form.set('phone_number_1', '123456789')
|
||||
form.set('password1', '12345abcdA')
|
||||
form.set('password2', '12345abcdA')
|
||||
response = form.submit().follow()
|
||||
assert qs.get().attributes.phone_number == '+3312345'
|
||||
assert qs.get().attributes.phone_number == '+33123456789'
|
||||
qs.delete()
|
||||
|
||||
url = register_john()
|
||||
|
@ -247,11 +247,11 @@ def test_phone_number(db, app, admin, mailoutbox, settings):
|
|||
form.set('first_name', 'John')
|
||||
form.set('last_name', 'Doe')
|
||||
form.set('phone_number_0', '32')
|
||||
form.set('phone_number_1', '12345')
|
||||
form.set('phone_number_1', '081000000')
|
||||
form.set('password1', '12345abcdA')
|
||||
form.set('password2', '12345abcdA')
|
||||
response = form.submit().follow()
|
||||
assert qs.get().attributes.phone_number == '+3212345'
|
||||
assert qs.get().attributes.phone_number == '+3281000000'
|
||||
qs.delete()
|
||||
|
||||
url = register_john()
|
||||
|
@ -273,11 +273,11 @@ def test_phone_number(db, app, admin, mailoutbox, settings):
|
|||
form.set('first_name', 'John')
|
||||
form.set('last_name', 'Doe')
|
||||
form.set('phone_number_0', '33')
|
||||
form.set('phone_number_1', '1 2 3 4 5')
|
||||
form.set('phone_number_1', '1 234 5678 9')
|
||||
form.set('password1', '12345abcdA')
|
||||
form.set('password2', '12345abcdA')
|
||||
response = form.submit().follow()
|
||||
assert qs.get().attributes.phone_number == '+3312345'
|
||||
assert qs.get().attributes.phone_number == '+33123456789'
|
||||
qs.delete()
|
||||
|
||||
|
||||
|
|
|
@ -191,8 +191,8 @@ def test_bom_character(profile, user_csv_importer_factory):
|
|||
def test_run(profile, user_csv_importer_factory):
|
||||
assert User.objects.count() == 0
|
||||
content = '''email key,first_name,last_name,phone update
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
fpeters@entrouvert.com,Frédéric,Péters,5678
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789
|
||||
fpeters@entrouvert.com,Frédéric,Péters,+3281005678
|
||||
x,x,x,x'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
|
@ -226,7 +226,7 @@ x,x,x,x'''
|
|||
assert thomas.last_name == 'Noël'
|
||||
assert thomas.attributes.last_name == 'Noël'
|
||||
# phonenumbers' e.164 representation from a settings.DEFAULT_COUNTRY_CODE dial:
|
||||
assert thomas.attributes.phone == '+331234'
|
||||
assert thomas.attributes.phone == '+33123456789'
|
||||
assert thomas.password
|
||||
|
||||
fpeters = User.objects.get(email='fpeters@entrouvert.com')
|
||||
|
@ -237,14 +237,14 @@ x,x,x,x'''
|
|||
assert fpeters.last_name == 'Péters'
|
||||
assert fpeters.attributes.last_name == 'Péters'
|
||||
# phonenumbers' e.164 representation from a settings.DEFAULT_COUNTRY_CODE dial:
|
||||
assert fpeters.attributes.phone == '+335678'
|
||||
assert fpeters.attributes.phone == '+3281005678'
|
||||
|
||||
|
||||
def test_simulate(profile, user_csv_importer_factory):
|
||||
assert User.objects.count() == 0
|
||||
content = '''email key,first_name,last_name,phone update
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
fpeters@entrouvert.com,Frédéric,Péters,5678
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789
|
||||
fpeters@entrouvert.com,Frédéric,Péters,+3281005678
|
||||
x,x,x,x'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
|
@ -275,11 +275,11 @@ x,x,x,x'''
|
|||
def test_create_unique_error(profile, user_csv_importer_factory):
|
||||
|
||||
content = '''email key verified,first_name,last_name,phone unique
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
user = User.objects.create(ou=get_default_ou())
|
||||
user.attributes.phone = '+331234'
|
||||
user.attributes.phone = '+33123456789'
|
||||
|
||||
assert importer.run()
|
||||
|
||||
|
@ -296,11 +296,11 @@ tnoel@entrouvert.com,Thomas,Noël,1234'''
|
|||
def test_create_unique_in_ou(profile, user_csv_importer_factory):
|
||||
|
||||
content = '''email key verified,first_name,last_name,phone unique
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
user = User.objects.create()
|
||||
user.attributes.phone = '+331234'
|
||||
user.attributes.phone = '+33123456789'
|
||||
|
||||
assert importer.run()
|
||||
|
||||
|
@ -316,11 +316,11 @@ tnoel@entrouvert.com,Thomas,Noël,1234'''
|
|||
def test_create_unique_globally_error(profile, user_csv_importer_factory):
|
||||
|
||||
content = '''email key verified,first_name,last_name,phone globally-unique
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
user = User.objects.create()
|
||||
user.attributes.phone = '+331234'
|
||||
user.attributes.phone = '+33123456789'
|
||||
|
||||
assert importer.run()
|
||||
|
||||
|
@ -336,8 +336,8 @@ tnoel@entrouvert.com,Thomas,Noël,1234'''
|
|||
|
||||
def test_create_key_self_reference_error(profile, user_csv_importer_factory):
|
||||
content = '''email key,first_name,last_name,phone
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
tnoel@entrouvert.com,Frédéric,Péters,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0606060606
|
||||
tnoel@entrouvert.com,Frédéric,Péters,+3281123456'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
assert importer.run()
|
||||
|
@ -354,11 +354,11 @@ tnoel@entrouvert.com,Frédéric,Péters,1234'''
|
|||
|
||||
def test_update_unique_error(profile, user_csv_importer_factory):
|
||||
content = '''email key verified,first_name,last_name,phone unique update
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
user = User.objects.create(ou=get_default_ou())
|
||||
user.attributes.phone = '+331234'
|
||||
user.attributes.phone = '+33123456789'
|
||||
|
||||
user = User.objects.create(email='tnoel@entrouvert.com', ou=get_default_ou())
|
||||
|
||||
|
@ -376,11 +376,11 @@ tnoel@entrouvert.com,Thomas,Noël,1234'''
|
|||
|
||||
def test_update_unique_globally_error(profile, user_csv_importer_factory):
|
||||
content = '''email key verified,first_name,last_name,phone globally-unique update
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
user = User.objects.create()
|
||||
user.attributes.phone = '+331234'
|
||||
user.attributes.phone = '+33123456789'
|
||||
|
||||
User.objects.create(email='tnoel@entrouvert.com', ou=get_default_ou())
|
||||
|
||||
|
@ -398,11 +398,11 @@ tnoel@entrouvert.com,Thomas,Noël,1234'''
|
|||
|
||||
def test_update_unique_globally(profile, user_csv_importer_factory):
|
||||
content = '''email key verified no-update,first_name no-update,last_name no-update,phone unique update
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234'''
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
user = User.objects.create()
|
||||
user.attributes.phone = '+331234'
|
||||
user.attributes.phone = '+33123456789'
|
||||
|
||||
thomas = User.objects.create(email='tnoel@entrouvert.com', ou=get_default_ou())
|
||||
|
||||
|
@ -420,14 +420,14 @@ tnoel@entrouvert.com,Thomas,Noël,1234'''
|
|||
thomas.refresh_from_db()
|
||||
assert not thomas.first_name
|
||||
assert not thomas.last_name
|
||||
assert thomas.attributes.phone == '+331234'
|
||||
assert thomas.attributes.phone == '+33123456789'
|
||||
|
||||
|
||||
def test_external_id(profile, user_csv_importer_factory):
|
||||
assert User.objects.count() == 0
|
||||
content = '''_source_name,_source_id,email,first_name,last_name,phone
|
||||
app1,1,tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
app1,2,tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
app1,1,tnoel@entrouvert.com,Thomas,Noël,0606060606
|
||||
app1,2,tnoel@entrouvert.com,Thomas,Noël,0606060606
|
||||
'''
|
||||
importer = user_csv_importer_factory(content)
|
||||
|
||||
|
@ -451,7 +451,7 @@ app1,2,tnoel@entrouvert.com,Thomas,Noël,1234
|
|||
assert thomas.attributes.first_name == 'Thomas'
|
||||
assert thomas.last_name == 'Noël'
|
||||
assert thomas.attributes.last_name == 'Noël'
|
||||
assert thomas.attributes.phone == '+331234'
|
||||
assert thomas.attributes.phone == '+33606060606'
|
||||
|
||||
importer = user_csv_importer_factory(content)
|
||||
assert importer.run(), importer.errors
|
||||
|
@ -464,7 +464,7 @@ def test_user_roles_csv(profile, user_csv_importer_factory):
|
|||
role = Role.objects.create(name=role_name, slug=role_slug, ou=get_default_ou())
|
||||
role2 = Role.objects.create(name='test2', ou=get_default_ou())
|
||||
base_header = 'email key,first_name,last_name,phone,'
|
||||
base_user = 'tnoel@entrouvert.com,Thomas,Noël,1234,'
|
||||
base_user = 'tnoel@entrouvert.com,Thomas,Noël,0123456789,'
|
||||
|
||||
content_name_add = '\n'.join((base_header + '_role_name', base_user + role_name))
|
||||
importer = user_csv_importer_factory(content_name_add)
|
||||
|
|
|
@ -28,9 +28,9 @@ def test_phonenumber_field(settings):
|
|||
|
||||
positive = [
|
||||
{'input': ['33', '01 01 01 01 01'], 'output': '+33101010101'},
|
||||
# undialable numbers are still parsed and usable as identifiers
|
||||
{'input': ['33', '01 01 01'], 'output': '+33010101'},
|
||||
{'input': ['33', '01 01 01 010101'], 'output': '+3310101010101'},
|
||||
{'input': ['33', '0101010101'], 'output': '+33101010101'},
|
||||
{'input': ['33', '0666666666'], 'output': '+33666666666'},
|
||||
{'input': ['32', '081 00 0000'], 'output': '+3281000000'},
|
||||
]
|
||||
# positive
|
||||
for value in positive:
|
||||
|
@ -43,6 +43,8 @@ def test_phonenumber_field(settings):
|
|||
['33', '+01 01 01 01 01'],
|
||||
['33', ' + 01/01.01-01.01'],
|
||||
['33', '+01/01.01-01.01'],
|
||||
['33', '01 01 01'],
|
||||
['33', '01 01 01 010101'],
|
||||
]:
|
||||
with pytest.raises(ValidationError):
|
||||
field.clean(value)
|
||||
|
|
|
@ -31,8 +31,8 @@ def profile(transactional_db):
|
|||
|
||||
def test_user_import(transactional_db, profile):
|
||||
content = '''email key verified,first_name,last_name,phone no-create
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
fpeters@entrouvert.com,Frédéric,Péters,5678
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789
|
||||
fpeters@entrouvert.com,Frédéric,Péters,+3281123456
|
||||
x,x,x,x'''
|
||||
fd = io.BytesIO(content.encode('utf-8'))
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ def test_account_edit_view(app, simple_user):
|
|||
)
|
||||
|
||||
resp = old_resp = app.get(url, status=200)
|
||||
resp.form['phone_1'] = '1234'
|
||||
resp.form['phone_1'] = '123456789'
|
||||
assert resp.form['phone_1'].attrs['type'] == 'text'
|
||||
resp.form['title'] = 'Mrs'
|
||||
resp.form['agreement'] = False
|
||||
|
@ -56,7 +56,7 @@ def test_account_edit_view(app, simple_user):
|
|||
resp = resp.form.submit()
|
||||
# verify that missing next_url in POST is ok
|
||||
assert resp['Location'].endswith(reverse('account_management'))
|
||||
assert phone.get_value(simple_user) == '+331234'
|
||||
assert phone.get_value(simple_user) == '+33123456789'
|
||||
assert title.get_value(simple_user) == 'Mrs'
|
||||
assert agreement.get_value(simple_user) is False
|
||||
assert language.get_value(simple_user) == 'fr'
|
||||
|
@ -70,7 +70,7 @@ def test_account_edit_view(app, simple_user):
|
|||
('First name', 'Jôhn'),
|
||||
('Last name', 'Dôe'),
|
||||
('Email address', 'user@example.net'),
|
||||
('Phone', '+331234'),
|
||||
('Phone', '+33123456789'),
|
||||
('Title', 'Mrs'),
|
||||
('Language', 'French'),
|
||||
]
|
||||
|
|
|
@ -500,9 +500,9 @@ def test_user_import(encoding, transactional_db, app, admin, ou1, admin_ou1):
|
|||
Upload(
|
||||
'users.csv',
|
||||
'''email key verified,first_name,last_name,phone
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
fpeters@entrouvert.com,Frédéric,Péters,+325678
|
||||
john.doe@entrouvert.com,John,Doe,9101112
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789
|
||||
fpeters@entrouvert.com,Frédéric,Péters,+3281123456
|
||||
john.doe@entrouvert.com,John,Doe,0910111213
|
||||
x,x,x,x'''.encode(
|
||||
encoding
|
||||
),
|
||||
|
@ -582,7 +582,7 @@ x,x,x,x'''.encode(
|
|||
email='tnoel@entrouvert.com',
|
||||
first_name='Thomas',
|
||||
last_name='Noël',
|
||||
attribute_values__content='+331234',
|
||||
attribute_values__content='+33123456789',
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
|
@ -591,7 +591,7 @@ x,x,x,x'''.encode(
|
|||
email='fpeters@entrouvert.com',
|
||||
first_name='Frédéric',
|
||||
last_name='Péters',
|
||||
attribute_values__content='+325678',
|
||||
attribute_values__content='+3281123456',
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
|
@ -600,7 +600,7 @@ x,x,x,x'''.encode(
|
|||
email='john.doe@entrouvert.com',
|
||||
first_name='John',
|
||||
last_name='Doe',
|
||||
attribute_values__content='+339101112',
|
||||
attribute_values__content='+33910111213',
|
||||
).count()
|
||||
== 1
|
||||
)
|
||||
|
@ -623,9 +623,9 @@ def test_user_import_legacy_encoding(transactional_db, app, admin, ou1, admin_ou
|
|||
Upload(
|
||||
'users.csv',
|
||||
'''email key verified,first_name,last_name,phone
|
||||
tnoel@entrouvert.com,Thomas,Noël,1234
|
||||
fpeters@entrouvert.com,Frédéric,Péters,5678
|
||||
john.doe@entrouvert.com,John,Doe,9101112
|
||||
tnoel@entrouvert.com,Thomas,Noël,0123456789
|
||||
fpeters@entrouvert.com,Frédéric,Péters,+3281123456
|
||||
john.doe@entrouvert.com,John,Doe,0910111213
|
||||
x,x,x,x'''.encode(),
|
||||
'application/octet-stream',
|
||||
),
|
||||
|
@ -720,7 +720,7 @@ def test_user_import_attributes(transactional_db, app, admin):
|
|||
|
||||
csv_lines = [
|
||||
"email key verified,first_name,last_name,more,title,bike,saintsday,birthdate,zip,phone",
|
||||
"elliot@universalpictures.com,Elliott,Thomas,petit,Mr,True,2019-7-20,1972-05-26,75014,1234",
|
||||
"elliot@universalpictures.com,Elliott,Thomas,petit,Mr,True,2019-7-20,1972-05-26,75014,0123456789",
|
||||
"et@universalpictures.com,ET,the Extra-Terrestrial,long,??,False,1/2/3/4,0002-2-22,42,home",
|
||||
]
|
||||
response = import_csv('\n'.join(csv_lines), app)
|
||||
|
@ -739,9 +739,9 @@ def test_user_import_attributes(transactional_db, app, admin):
|
|||
assert elliot.attributes.values['saintsday'].content == '2019-07-20'
|
||||
assert elliot.attributes.values['birthdate'].content == '1972-05-26'
|
||||
assert elliot.attributes.values['zip'].content == '75014'
|
||||
assert elliot.attributes.values['phone'].content == '+331234'
|
||||
assert elliot.attributes.values['phone'].content == '+33123456789'
|
||||
|
||||
csv_lines[2] = "et@universalpictures.com,ET,the Extra-Terrestrial,,,,,,42000,+888 5678"
|
||||
csv_lines[2] = "et@universalpictures.com,ET,the Extra-Terrestrial,,,,,,42000,+3281123456"
|
||||
response = import_csv('\n'.join(csv_lines), app)
|
||||
assert '0 rows have errors' in response.text
|
||||
|
||||
|
@ -753,7 +753,7 @@ def test_user_import_attributes(transactional_db, app, admin):
|
|||
assert 'saintsday' not in et.attributes.values
|
||||
assert 'birthdate' not in et.attributes.values
|
||||
assert et.attributes.values['zip'].content == '42000'
|
||||
assert et.attributes.values['phone'].content == '+8885678'
|
||||
assert et.attributes.values['phone'].content == '+3281123456'
|
||||
|
||||
|
||||
def test_detail_view(app, admin, simple_user):
|
||||
|
|
Loading…
Reference in New Issue