api: update phone drf field to handle E164 format (#69430)
gitea/authentic/pipeline/head Build started...
Details
gitea/authentic/pipeline/head Build started...
Details
This commit is contained in:
parent
a179cb1dc9
commit
b3036b4cc0
|
@ -24,6 +24,7 @@ import string
|
|||
import uuid
|
||||
from itertools import chain
|
||||
|
||||
import phonenumbers
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
|
@ -146,9 +147,24 @@ def get_title_choices():
|
|||
return app_settings.A2_ATTRIBUTE_KIND_TITLE_CHOICES or DEFAULT_TITLE_CHOICES
|
||||
|
||||
|
||||
validate_phone_number = RegexValidator(
|
||||
r'^\+?\d{,20}$', message=_('Phone number can start with a + and must contain only digits.')
|
||||
)
|
||||
def validate_phone_number(value):
|
||||
default_country = settings.PHONE_COUNTRY_CODES[settings.DEFAULT_COUNTRY_CODE]['lang']
|
||||
try:
|
||||
phonenumbers.parse(value)
|
||||
except phonenumbers.NumberParseException:
|
||||
try:
|
||||
phonenumbers.parse(
|
||||
value,
|
||||
default_country,
|
||||
)
|
||||
except phonenumbers.NumberParseException:
|
||||
raise ValidationError(
|
||||
_(
|
||||
'Phone number must be either in E.164 globally unique format or dialable from'
|
||||
' {code} country code ({country}).'
|
||||
).format(code=settings.DEFAULT_COUNTRY_CODE, country=default_country)
|
||||
)
|
||||
|
||||
|
||||
french_validate_phone_number = RegexValidator(
|
||||
r'^[0][0-9]{9}$', message=_('A french phone number must start with a zero then another nine digits.')
|
||||
|
@ -180,12 +196,23 @@ class PhoneNumberDRFField(serializers.CharField):
|
|||
default_validators = [validate_phone_number]
|
||||
|
||||
def to_internal_value(self, data):
|
||||
return clean_number(super().to_internal_value(data))
|
||||
if isinstance(data, (list, tuple)):
|
||||
data = data[0]
|
||||
data = super().to_internal_value(clean_number(data))
|
||||
default_country = settings.PHONE_COUNTRY_CODES[settings.DEFAULT_COUNTRY_CODE]['lang']
|
||||
try:
|
||||
pn = phonenumbers.parse(data)
|
||||
except phonenumbers.NumberParseException:
|
||||
pn = phonenumbers.parse(data, default_country)
|
||||
return phonenumbers.format_number(pn, phonenumbers.PhoneNumberFormat.E164)
|
||||
|
||||
|
||||
class FrenchPhoneNumberDRFField(PhoneNumberDRFField):
|
||||
class FrenchPhoneNumberDRFField(serializers.CharField):
|
||||
default_validators = [french_validate_phone_number]
|
||||
|
||||
def to_internal_value(self, data):
|
||||
return super().to_internal_value(clean_number(data))
|
||||
|
||||
|
||||
validate_fr_postcode = RegexValidator(r'^\d{5}$', message=_('The value must be a valid french postcode'))
|
||||
|
||||
|
|
|
@ -2267,7 +2267,29 @@ def test_phone_normalization_ok(settings, app, admin):
|
|||
}
|
||||
resp = app.post_json('/api/users/', headers=headers, params=payload, status=201)
|
||||
assert resp.json['extra_phone'] == '+33499985643'
|
||||
assert User.objects.get(username='janedoe').attributes.extra_phone == '+33499985643'
|
||||
user = User.objects.get(username='janedoe')
|
||||
assert user.attributes.extra_phone == '+33499985643'
|
||||
|
||||
user.delete()
|
||||
payload['extra_phone'] = ' + 334-99 98.56/433 '
|
||||
resp = app.post_json('/api/users/', headers=headers, params=payload, status=201)
|
||||
assert resp.json['extra_phone'] == '+334999856433'
|
||||
user = User.objects.get(username='janedoe')
|
||||
assert user.attributes.extra_phone == '+334999856433'
|
||||
|
||||
user.delete()
|
||||
payload['extra_phone'] = ' 04-99 98.56/433 '
|
||||
resp = app.post_json('/api/users/', headers=headers, params=payload, status=201)
|
||||
assert resp.json['extra_phone'] == '+334999856433'
|
||||
user = User.objects.get(username='janedoe')
|
||||
assert user.attributes.extra_phone == '+334999856433'
|
||||
|
||||
user.delete()
|
||||
payload['extra_phone'] = ''
|
||||
resp = app.post_json('/api/users/', headers=headers, params=payload, status=201)
|
||||
assert resp.json['extra_phone'] == ''
|
||||
user = User.objects.get(username='janedoe')
|
||||
assert user.attributes.extra_phone == ''
|
||||
|
||||
|
||||
def test_phone_normalization_nok(settings, app, admin):
|
||||
|
@ -2284,6 +2306,15 @@ def test_phone_normalization_nok(settings, app, admin):
|
|||
payload['extra_phone'] = '1#2'
|
||||
app.post_json('/api/users/', headers=headers, params=payload, status=400)
|
||||
|
||||
payload['extra_phone'] = '+33499985643343434343'
|
||||
app.post_json('/api/users/', headers=headers, params=payload, status=400)
|
||||
|
||||
payload['extra_phone'] = '+334-99 98\\56/43'
|
||||
app.post_json('/api/users/', headers=headers, params=payload, status=400)
|
||||
|
||||
payload['extra_phone'] = '+334'
|
||||
app.post_json('/api/users/', headers=headers, params=payload, status=400)
|
||||
|
||||
|
||||
def test_fr_phone_normalization_ok(settings, app, admin):
|
||||
headers = basic_authorization_header(admin)
|
||||
|
|
|
@ -56,7 +56,8 @@ def test_phone_number_change_invalid_number(settings, app, simple_user):
|
|||
|
||||
resp = resp.form.submit()
|
||||
assert (
|
||||
'Phone number can start with a + and must contain only digits.' in resp.pyquery('div.error')[0].text
|
||||
'Phone number must be either in E.164 globally unique format or dialable from'
|
||||
in resp.pyquery('div.error')[0].text
|
||||
)
|
||||
|
||||
resp.form['mobile_1'] = '612345678'
|
||||
|
|
Loading…
Reference in New Issue