From 3b5e14cc0389177f183fad14dc3c3a601d33412e Mon Sep 17 00:00:00 2001
From: Paul Marillonnet <pmarillonnet@entrouvert.com>
Date: Tue, 25 Oct 2022 08:54:23 +0200
Subject: [PATCH 6/8] fields: prefill phone value (#69838)

---
 tests/form_pages/test_all.py | 77 ++++++++++++++++++++++++++++++++++++
 tests/test_prefill.py        | 48 +++++++++++++++++++++-
 wcs/fields.py                | 10 +++++
 3 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/tests/form_pages/test_all.py b/tests/form_pages/test_all.py
index 646cdc2e2..c540d4bb4 100644
--- a/tests/form_pages/test_all.py
+++ b/tests/form_pages/test_all.py
@@ -107,6 +107,7 @@ def create_user(pub):
     user = pub.user_class()
     user.name = 'User Name'
     user.email = 'foo@localhost'
+    user.phone = '+33123456789'
     user.store()
     account = PasswordAccount(id='foo')
     account.set_password('foo')
@@ -2064,6 +2065,82 @@ def test_form_tracking_code_as_user(pub, nocache):
     resp = app.get('/code/%s/load' % tracking_code, headers={'User-agent': 'Googlebot'}, status=403)
 
 
+def test_form_phone_prefill(pub, nocache):
+    create_user(pub)
+    formdef = create_formdef()
+    formdef.data_class().wipe()
+    formdef.fields = [fields.StringField(id='0', label='string', prefill={'type': 'user', 'value': 'phone'})]
+    formdef.store()
+
+    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
+    assert resp.pyquery('input#form_f0').val() == '+33123456789'
+    resp.forms[0]['f0'] = '+33987654321'
+    resp = resp.forms[0].submit('submit')
+    assert resp.pyquery('button.form-submit').val() == 'Submit'
+
+
+def test_form_phone_prefill_phone_fr_validation(pub, nocache):
+    create_user(pub)
+    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', 'FR')
+    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
+        pub.site_options.write(fd)
+    formdef = create_formdef()
+    formdef.data_class().wipe()
+    field = fields.StringField(id='0', label='string', prefill={'type': 'user', 'value': 'phone'})
+    field.validation = {'type': 'phone-fr'}
+    formdef.fields = [field]
+    formdef.store()
+
+    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
+    assert resp.pyquery('input#form_f0').val() == '01 23 45 67 89'
+    resp.forms[0]['f0'] = '0987654321'
+    resp = resp.forms[0].submit('submit')
+    assert resp.pyquery('button.form-submit').val() == 'Submit'
+
+
+def test_form_phone_prefill_phone_validation(pub, nocache):
+    user = create_user(pub)
+    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)
+    formdef = create_formdef()
+    formdef.data_class().wipe()
+    field = fields.StringField(id='0', label='string', prefill={'type': 'user', 'value': 'phone'})
+    field.validation = {'type': 'phone'}
+    formdef.fields = [field]
+    formdef.store()
+
+    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
+    assert resp.pyquery('input#form_f0').val() == '01 23 45 67 89'
+    resp.forms[0]['f0'] = '0987654321'
+    resp = resp.forms[0].submit('submit')
+    assert resp.pyquery('button.form-submit').val() == 'Submit'
+
+    user.phone = '+3281000000'
+    user.store()
+
+    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
+    assert resp.pyquery('input#form_f0').val() == '081 00 00 00'
+    resp.forms[0]['f0'] = '0987654321'
+    resp = resp.forms[0].submit('submit')
+    assert resp.pyquery('button.form-submit').val() == 'Submit'
+
+    user.phone = '+99981000000'
+    user.store()
+
+    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
+    assert resp.pyquery('input#form_f0').val() == '+99981000000'
+    resp.forms[0]['f0'] = '0987654321'
+    resp = resp.forms[0].submit('submit')
+    assert resp.pyquery('button.form-submit').val() == 'Submit'
+
+
 def test_form_tracking_code_prefill(pub, nocache):
     create_user(pub)
     formdef = create_formdef()
diff --git a/tests/test_prefill.py b/tests/test_prefill.py
index d7cbc3322..af7ca50d3 100644
--- a/tests/test_prefill.py
+++ b/tests/test_prefill.py
@@ -1,4 +1,5 @@
 import datetime
+import os
 import shutil
 
 import pytest
@@ -20,6 +21,7 @@ def setup_module(module):
 
     req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
     pub._set_request(req)
+    pub.write_cfg()
 
 
 @pytest.fixture
@@ -27,6 +29,7 @@ def user(request):
     pub.user_class.wipe()
     user = pub.user_class(name='user')
     user.email = 'test@example.net'
+    user.phone = '+33123456789'
     user.store()
     get_request()._user = user
     return user
@@ -66,12 +69,55 @@ def test_prefill_string_carddef():
     assert field.get_prefill_value() == ('{{cards|objects:"unknown"|first|get:"foo"}}', False)
 
 
-def test_prefill_user(user):
+def test_prefill_user_email(user):
     field = fields.Field()
     field.prefill = {'type': 'user', 'value': 'email'}
     assert field.get_prefill_value(user=get_request().user) == ('test@example.net', False)
 
 
+def test_prefill_user_phone(user):
+    field = fields.Field()
+    field.prefill = {'type': 'user', 'value': 'phone'}
+    assert field.get_prefill_value(user=get_request().user) == ('+33123456789', False)
+
+
+def test_prefill_user_phone_fr_validation(user):
+    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', 'FR')
+    with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
+        pub.site_options.write(fd)
+    field = fields.Field()
+    field.validation = {'type': 'phone-fr'}
+    field.prefill = {'type': 'user', 'value': 'phone'}
+    assert field.get_prefill_value(user=get_request().user) == ('01 23 45 67 89', False)
+
+
+def test_prefill_user_phone_validation(user):
+    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)
+    field = fields.Field()
+    field.validation = {'type': 'phone'}
+    field.prefill = {'type': 'user', 'value': 'phone'}
+    assert field.get_prefill_value(user=get_request().user) == ('01 23 45 67 89', False)
+
+    user = get_request().user
+    user.phone = '+3281000000'
+    user.store()
+
+    assert field.get_prefill_value(user=get_request().user) == ('081 00 00 00', False)
+
+    user.phone = '+99981000000'
+    user.store()
+
+    assert field.get_prefill_value(user=get_request().user) == ('+99981000000', False)
+
+
 def test_prefill_user_attribute(user):
     from wcs.admin.settings import UserFieldsFormDef
 
diff --git a/wcs/fields.py b/wcs/fields.py
index d256fdd09..f225e31fc 100644
--- a/wcs/fields.py
+++ b/wcs/fields.py
@@ -83,6 +83,7 @@ from .qommon.misc import (
     get_as_datetime,
     get_document_type_value_options,
     get_document_types,
+    get_local_number,
     strftime,
     strip_some_tags,
     xml_node_text,
@@ -539,6 +540,15 @@ class Field:
             x = self.prefill.get('value')
             if x == 'email':
                 return (user.email, explicit_lock or 'email' in (user.verified_fields or []))
+            elif x == 'phone':
+                phone = user.phone
+                if hasattr(self, 'validation'):
+                    validation_type = self.validation.get('type', None)
+                    if validation_type == 'phone-fr':
+                        phone = get_local_number(user.phone, country_code='FR') or user.phone
+                    elif validation_type == 'phone':
+                        phone = get_local_number(user.phone) or user.phone
+                return (phone, explicit_lock or 'phone' in (user.verified_fields or []))
             elif user.form_data:
                 userform = user.get_formdef()
                 for userfield in userform.fields:
-- 
2.38.1

