fields: add nir and iban algorithms to string field validation (#35619)
This commit is contained in:
parent
aec1c32c9c
commit
d0842a5729
|
@ -690,6 +690,100 @@ def test_wcsextrastringwidget_siret_validation():
|
|||
assert widget.has_error()
|
||||
|
||||
|
||||
def test_wcsextrastringwidget_nir_validation():
|
||||
class FakeField: pass
|
||||
fakefield = FakeField()
|
||||
fakefield.validation = {'type': 'nir-fr'}
|
||||
|
||||
# regular cases
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
# https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France#/media/Fichier:CarteVitale2.jpg
|
||||
mock_form_submission(req, widget, {'test': '269054958815780'})
|
||||
assert not widget.has_error()
|
||||
|
||||
# corsica
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '269052A58815717'})
|
||||
assert not widget.has_error()
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '269052B58815744'})
|
||||
assert not widget.has_error()
|
||||
|
||||
# failing cases
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '42'})
|
||||
assert widget.has_error()
|
||||
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '269054958815700'})
|
||||
assert widget.has_error()
|
||||
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': 'hello 789012345'})
|
||||
assert widget.has_error()
|
||||
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '069054958815780'})
|
||||
assert widget.has_error()
|
||||
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '269004958815780'})
|
||||
assert widget.has_error()
|
||||
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '269054900015780'})
|
||||
assert widget.has_error()
|
||||
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': '269054958800080'})
|
||||
assert widget.has_error()
|
||||
|
||||
|
||||
def test_wcsextrastringwidget_iban_validation():
|
||||
class FakeField: pass
|
||||
fakefield = FakeField()
|
||||
fakefield.validation = {'type': 'iban'}
|
||||
|
||||
# regular cases
|
||||
for iban in ['BE71 0961 2345 6769', # Belgium
|
||||
'FR76 3000 6000 0112 3456 7890 189', # France
|
||||
'FR27 2004 1000 0101 2345 6Z02 068', # France (having letter)
|
||||
'DE91 1000 0000 0123 4567 89', # Germany
|
||||
'GR96 0810 0010 0000 0123 4567 890', # Greece
|
||||
'RO09 BCYP 0000 0012 3456 7890', # Romania
|
||||
'SA44 2000 0001 2345 6789 1234', # Saudi Arabia
|
||||
'ES79 2100 0813 6101 2345 6789', # Spain
|
||||
'CH56 0483 5012 3456 7800 9', # Switzerland
|
||||
'GB98 MIDL 0700 9312 3456 78', # United Kingdom
|
||||
]:
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
|
||||
assert not widget.has_error()
|
||||
|
||||
# failing cases
|
||||
for iban in ['42',
|
||||
'FR76 2004 1000 0101 2345 6Z02 068',
|
||||
'FR76 2004 1000 0101 2345 6%02 068',
|
||||
'FR76 hello 234 6789 1234 6789 123',
|
||||
'FRxx 2004 1000 0101 2345 6Z02 068',
|
||||
]:
|
||||
widget = WcsExtraStringWidget('test', value='foo', required=False)
|
||||
widget.field = fakefield
|
||||
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
|
||||
assert widget.has_error()
|
||||
|
||||
|
||||
def test_wcsextrastringwidget_django_validation():
|
||||
class FakeField: pass
|
||||
fakefield = FakeField()
|
||||
|
|
|
@ -908,6 +908,8 @@ class ValidationWidget(CompositeWidget):
|
|||
('zipcode-fr', {'title': N_('Zip Code (France)'), 'regex': '\d{5}'}),
|
||||
('siren-fr', {'title': N_('SIREN Code (France)'), 'function': 'validate_siren'}),
|
||||
('siret-fr', {'title': N_('SIRET Code (France)'), 'function': 'validate_siret'}),
|
||||
('nir-fr', {'title': N_('NIR (France)'), 'function': 'validate_nir'}),
|
||||
('iban', {'title': N_('IBAN'), 'function': 'validate_iban'}),
|
||||
('regex', {'title': N_('Regular Expression')}),
|
||||
('django', {'title': N_('Django Condition')}),
|
||||
])
|
||||
|
|
|
@ -654,3 +654,52 @@ def validate_siret(string_value):
|
|||
and sum(int(x) for x in string_value) % 5 == 0):
|
||||
return True
|
||||
return validate_luhn(string_value, length=14)
|
||||
|
||||
|
||||
def validate_nir(string_value):
|
||||
'''https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France'''
|
||||
if not string_value:
|
||||
return False
|
||||
if len(string_value) != 15:
|
||||
return False
|
||||
if string_value[0] == '0': # sex
|
||||
return False
|
||||
if string_value[7:10] == '000': # municipality
|
||||
return False
|
||||
if string_value[10:13] == '000': # order
|
||||
return False
|
||||
dept = string_value[5:7]
|
||||
if dept == '2A':
|
||||
string_value = string_value.replace('2A', '19', 1)
|
||||
elif dept == '2B':
|
||||
string_value = string_value.replace('2B', '18', 1)
|
||||
if not string_value.isdigit():
|
||||
return False
|
||||
month = int(string_value[3:5])
|
||||
if month < 50 and month not in range(1, 13) + [20] + range(30, 43):
|
||||
return False
|
||||
nir_key = string_value[13:]
|
||||
return int(nir_key) == 97 - int(string_value[:13]) % 97
|
||||
|
||||
|
||||
def validate_iban(string_value):
|
||||
'''https://fr.wikipedia.org/wiki/International_Bank_Account_Number'''
|
||||
if not string_value:
|
||||
return False
|
||||
country_code = string_value[:2]
|
||||
iban_key = string_value[2:4]
|
||||
bban = string_value[4:]
|
||||
if not (country_code.isalpha() and country_code.isupper()):
|
||||
return False
|
||||
if not iban_key.isdigit():
|
||||
return False
|
||||
dummy_iban = bban + country_code + '00'
|
||||
dummy_iban_converted = ''
|
||||
for car in dummy_iban:
|
||||
if car >= 'A' and car <= 'Z':
|
||||
dummy_iban_converted += str(ord(car) - ord('A') + 10)
|
||||
else:
|
||||
dummy_iban_converted += car
|
||||
if not dummy_iban_converted.isdigit():
|
||||
return False
|
||||
return int(iban_key) == 98 - int(dummy_iban_converted) % 97
|
||||
|
|
Loading…
Reference in New Issue