Projet

Général

Profil

0001-attribute_kinds-add-french-phone-number-type-45422.patch

Paul Marillonnet, 05 août 2021 14:54

Télécharger (9,53 ko)

Voir les différences:

Subject: [PATCH] attribute_kinds: add french phone number type (#45422)

 src/authentic2/attribute_kinds.py |  37 ++++++++
 tests/test_api.py                 |  29 +++++++
 tests/test_attribute_kinds.py     | 139 ++++++++++++++++++++++++++++++
 3 files changed, 205 insertions(+)
src/authentic2/attribute_kinds.py
151 151
    r'^\+?\d{,20}$', message=_('Phone number can start with a + and must contain only digits.')
152 152
)
153 153

  
154
french_validate_phone_number = RegexValidator(
155
    r'^[0]\d{9}$', message=_('Phone number must start with a zero and contain nine other digits.')
156
)
157

  
154 158

  
155 159
def clean_number(number):
156 160
    cleaned_number = re.sub(r'[-.\s/]', '', number)
......
172 176
        return value
173 177

  
174 178

  
179
class FrenchPhoneNumberField(forms.CharField):
180
    widget = widgets.PhoneNumberInput
181

  
182
    def __init__(self, *args, **kwargs):
183
        kwargs['max_length'] = 30
184
        kwargs['min_length'] = 10
185
        kwargs.setdefault('help_text', _('ex.: 0699999999, 01 23 45 67 89, 09.87.65.43.21'))
186
        super().__init__(*args, **kwargs)
187

  
188
    def clean(self, value):
189
        if value not in self.empty_values:
190
            value = clean_number(value)
191
        value = super().clean(value)
192
        return value
193

  
194
    def validate(self, value):
195
        super().validate(value)
196
        if not value.startswith('0'):
197
            raise ValidationError(_('French phone number starts with \'0\''))
198
        if not len(value) == 10:
199
            raise ValidationError(_('French phone number is 10-digit long'))
200

  
201

  
175 202
class PhoneNumberDRFField(serializers.CharField):
176 203
    default_validators = [validate_phone_number]
177 204

  
......
179 206
        return clean_number(super().to_internal_value(data))
180 207

  
181 208

  
209
class FrenchPhoneNumberDRFField(PhoneNumberDRFField):
210
    default_validators = [french_validate_phone_number]
211

  
212

  
182 213
validate_fr_postcode = RegexValidator(r'^\d{5}$', message=_('The value must be a valid french postcode'))
183 214

  
184 215

  
......
340 371
        'field_class': PhoneNumberField,
341 372
        'rest_framework_field_class': PhoneNumberDRFField,
342 373
    },
374
    {
375
        'label': _('french phone number'),
376
        'name': 'fr_phone_number',
377
        'field_class': FrenchPhoneNumberField,
378
        'rest_framework_field_class': FrenchPhoneNumberDRFField,
379
    },
343 380
    {
344 381
        'label': _('profile image'),
345 382
        'name': 'profile_image',
tests/test_api.py
2211 2211
    app.post_json('/api/users/', headers=headers, params=payload, status=400)
2212 2212

  
2213 2213

  
2214
def test_fr_phone_normalization_ok(settings, app, admin):
2215
    headers = basic_authorization_header(admin)
2216
    Attribute.objects.create(name='phone', label='phone', kind='fr_phone_number')
2217
    payload = {
2218
        'username': 'janedoe',
2219
        'phone': ' 04-99 98.56/43',
2220
        'first_name': 'Jane',
2221
        'last_name': 'Doe',
2222
    }
2223
    resp = app.post_json('/api/users/', headers=headers, params=payload, status=201)
2224
    assert resp.json['phone'] == '0499985643'
2225
    assert User.objects.get(username='janedoe').attributes.phone == '0499985643'
2226

  
2227

  
2228
def test_fr_phone_normalization_nok(settings, app, admin):
2229
    headers = basic_authorization_header(admin)
2230
    Attribute.objects.create(name='phone', label='phone', kind='fr_phone_number')
2231
    payload = {
2232
        'username': 'janedoe',
2233
        'phone': '+33499985643',
2234
        'first_name': 'Jane',
2235
        'last_name': 'Doe',
2236
    }
2237
    app.post_json('/api/users/', headers=headers, params=payload, status=400)
2238

  
2239
    payload['phone'] = '1#2'
2240
    app.post_json('/api/users/', headers=headers, params=payload, status=400)
2241

  
2242

  
2214 2243
def test_api_users_create_user_delete(app, settings, admin):
2215 2244
    email = 'foo@example.net'
2216 2245
    user1 = User.objects.create(username='foo', email=email)
tests/test_attribute_kinds.py
267 267
    qs.delete()
268 268

  
269 269

  
270
def test_french_phone_number(db, app, admin, mailoutbox, settings):
271
    settings.A2_EMAILS_ADDRESS_RATELIMIT = None
272

  
273
    def register_john():
274
        response = app.get('/accounts/register/')
275
        form = response.form
276
        form.set('email', 'john.doe@example.com')
277
        response = form.submit().follow()
278
        assert 'john.doe@example.com' in response
279
        return get_link_from_mail(mailoutbox[-1])
280

  
281
    Attribute.objects.create(
282
        name='phone_number', label='phone', kind='fr_phone_number', asked_on_registration=True
283
    )
284
    qs = User.objects.filter(first_name='John')
285

  
286
    url = register_john()
287
    response = app.get(url)
288
    form = response.form
289
    form.set('first_name', 'John')
290
    form.set('last_name', 'Doe')
291
    form.set('phone_number', 'abc')
292
    form.set('password1', '12345abcdA')
293
    form.set('password2', '12345abcdA')
294
    response = form.submit()
295
    assert response.pyquery.find('.form-field-error #id_phone_number')
296

  
297
    form = response.form
298
    assert response.pyquery('#id_phone_number').attr('maxlength') == '30'
299
    assert response.pyquery('#id_phone_number').attr('minlength') == '10'
300
    form.set('phone_number', '1234512345' * 10)
301
    form.set('password1', '12345abcdA')
302
    form.set('password2', '12345abcdA')
303
    response = form.submit()
304
    assert response.pyquery.find('.form-field-error #id_phone_number')
305

  
306
    form = response.form
307
    form.set('phone_number', '12345')
308
    form.set('password1', '12345abcdA')
309
    form.set('password2', '12345abcdA')
310
    response = form.submit()
311
    assert response.pyquery.find('.form-field-error #id_phone_number')
312

  
313
    form = response.form
314
    form.set('first_name', 'John')
315
    form.set('last_name', 'Doe')
316
    form.set('phone_number', '+12345')
317
    form.set('password1', '12345abcdA')
318
    form.set('password2', '12345abcdA')
319
    response = form.submit()
320
    assert response.pyquery.find('.form-field-error #id_phone_number')
321

  
322
    form = response.form
323
    form.set('first_name', 'John')
324
    form.set('last_name', 'Doe')
325
    form.set('phone_number', '')
326
    form.set('password1', '12345abcdA')
327
    form.set('password2', '12345abcdA')
328
    response = form.submit()
329
    assert response.pyquery.find('.form-field-error #id_phone_number')
330

  
331
    form = response.form
332
    form.set('phone_number', ' +  1.2-3  4 5 ')
333
    form.set('password1', '12345abcdA')
334
    form.set('password2', '12345abcdA')
335
    response = form.submit()
336
    assert response.pyquery.find('.form-field-error #id_phone_number')
337

  
338
    form = response.form
339
    form.set('phone_number', '1234567890')
340
    form.set('password1', '12345abcdA')
341
    form.set('password2', '12345abcdA')
342
    response = form.submit()
343
    assert response.pyquery.find('.form-field-error #id_phone_number')
344

  
345
    form = response.form
346
    form.set('phone_number', '')
347
    form.set('password1', '12345abcdA')
348
    form.set('password2', '12345abcdA')
349
    response = form.submit()
350
    assert response.pyquery.find('.form-field-error #id_phone_number')
351

  
352
    form = response.form
353
    form.set('phone_number', '0123456789')
354
    form.set('password1', '12345abcdA')
355
    form.set('password2', '12345abcdA')
356
    response = form.submit().follow()
357
    assert qs.get().attributes.phone_number == '0123456789'
358
    qs.delete()
359

  
360
    url = register_john()
361
    response = app.get(url)
362
    form = response.form
363
    form.set('first_name', 'John')
364
    form.set('last_name', 'Doe')
365
    form.set('phone_number', '01 23 45 67 89')
366
    form.set('password1', '12345abcdA')
367
    form.set('password2', '12345abcdA')
368
    response = form.submit().follow()
369
    assert qs.get().attributes.phone_number == '0123456789'
370
    qs.delete()
371

  
372
    url = register_john()
373
    response = app.get(url)
374
    form = response.form
375
    form.set('first_name', 'John')
376
    form.set('last_name', 'Doe')
377
    form.set('phone_number', '01-23-45-67-89')
378
    form.set('password1', '12345abcdA')
379
    form.set('password2', '12345abcdA')
380
    response = form.submit().follow()
381
    assert qs.get().attributes.phone_number == '0123456789'
382
    qs.delete()
383

  
384
    url = register_john()
385
    response = app.get(url)
386
    form = response.form
387
    form.set('first_name', 'John')
388
    form.set('last_name', 'Doe')
389
    form.set('phone_number', '06.99.99.99.99')
390
    form.set('password1', '12345abcdA')
391
    form.set('password2', '12345abcdA')
392
    response = form.submit().follow()
393
    assert qs.get().attributes.phone_number == '0699999999'
394
    qs.delete()
395

  
396
    url = register_john()
397
    response = app.get(url)
398
    form = response.form
399
    form.set('first_name', 'John')
400
    form.set('last_name', 'Doe')
401
    form.set('phone_number', '0699999999')
402
    form.set('password1', '12345abcdA')
403
    form.set('password2', '12345abcdA')
404
    response = form.submit().follow()
405
    assert qs.get().attributes.phone_number == '0699999999'
406
    qs.delete()
407

  
408

  
270 409
def test_birthdate(db, app, admin, mailoutbox, freezer):
271 410
    def register_john():
272 411
        response = app.get('/accounts/register/')
273
-