misc: add validation for local mobile phone number (#73498) #325

Merged
fpeters merged 1 commits from wip/73498-mobile-validation into main 2023-05-26 07:43:10 +02:00
3 changed files with 76 additions and 0 deletions

View File

@ -1,5 +1,6 @@
import copy
import datetime
import os
import shutil
import mechanize
@ -942,6 +943,48 @@ def test_wcsextrastringwidget_phone_fr():
assert 'type="tel"' in str(widget.render())
def test_wcsextrastringwidget_mobile_local():
class FakeField:
pass
fakefield = FakeField()
# check validation
fakefield.validation = {'type': 'mobile-local'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '06 30 98 67 89'})
assert not widget.has_error()
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '01 23 45 67 89'})
assert widget.has_error()
assert widget.error == 'Invalid phone number'
pub.load_site_options()
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'default-country-code', 'BE')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
fakefield.validation = {'type': 'mobile-local'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '06 30 98 67 89'})
assert widget.has_error()
fakefield.validation = {'type': 'mobile-local'}
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': '04 75 98 67 89'})
assert not widget.has_error()
# and check it gets a special HTML input type
assert 'type="tel"' in str(widget.render())
def test_wcsextrastringwidget_siren_validation():
class FakeField:
pass

View File

@ -1219,6 +1219,16 @@ class ValidationWidget(CompositeWidget):
'normalize_for_fts': misc.normalize_phone_number_for_fts,
},
),
(
'mobile-local',
{
'title': _('Mobile Phone Number (local)'),
'function': 'validate_mobile_phone_local',
'error_message': _('Invalid phone number'),
'html_input_type': 'tel',
'normalize_for_fts': misc.normalize_phone_number_for_fts,
},
),
(
'zipcode-fr',
{

View File

@ -854,6 +854,29 @@ def validate_phone_fr(string_value):
return bool(phonenumbers.is_valid_number(pn) and pn.country_code in french_country_codes)
def validate_mobile_phone_local(string_value):
region_code = get_publisher().get_site_option('default-country-code') or 'FR'
country_codes = []
if region_code == 'FR':
country_codes = [33, 262, 508, 590, 594, 596]
Review

Cas particulier ici pour être similaire à ce qu'on fait pour la validation "téléphone (français)".

Cas particulier ici pour être similaire à ce qu'on fait pour la validation "téléphone (français)".
else:
for country_code, region_codes in phonenumbers.COUNTRY_CODE_TO_REGION_CODE.items():
if region_code in region_codes:
country_codes = [country_code]
break
pn = None
try:
pn = phonenumbers.parse(string_value, region_code)
except phonenumbers.NumberParseException:
return False
return bool(
phonenumbers.is_valid_number(pn)
and phonenumbers.number_type(pn)
in (phonenumbers.PhoneNumberType.MOBILE, phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE)
Review

Il y a des pays où ça n'est pas possible de distinguer le côté mobile, c'est là que vient FIXED_LINE_OR_MOBILE :

    # In some regions (e.g. the USA), it is impossible to distinguish between
    # fixed-line and mobile numbers by looking at the phone number itself.
    FIXED_LINE_OR_MOBILE = 2
Il y a des pays où ça n'est pas possible de distinguer le côté mobile, c'est là que vient FIXED_LINE_OR_MOBILE : ``` # In some regions (e.g. the USA), it is impossible to distinguish between # fixed-line and mobile numbers by looking at the phone number itself. FIXED_LINE_OR_MOBILE = 2 ```
and (pn.country_code in country_codes or not country_codes)
)
def get_formatted_phone(number, country_code=None):
if not country_code:
country_code = get_publisher().get_site_option('default-country-code') or 'FR'