From c9a16830f4991d68840408d315b206c99f5cf580 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 20 Dec 2019 15:05:55 +0100
Subject: [PATCH 2/3] toulouse_axel: handle handicap fields (#38543)

---
 functests/toulouse_axel/test_toulouse_axel.py |  2 +
 passerelle/contrib/toulouse_axel/models.py    | 25 ++++++--
 .../flat_update_family_info.json              |  6 ++
 .../toulouse_axel/update_family_info.json     |  6 ++
 tests/test_toulouse_axel.py                   | 63 +++++++++++++++++++
 5 files changed, 98 insertions(+), 4 deletions(-)

diff --git a/functests/toulouse_axel/test_toulouse_axel.py b/functests/toulouse_axel/test_toulouse_axel.py
index f18a996f..3a572168 100644
--- a/functests/toulouse_axel/test_toulouse_axel.py
+++ b/functests/toulouse_axel/test_toulouse_axel.py
@@ -54,11 +54,13 @@ def test_link(conn, user):
             'maj:enfant_%s_sanitaire_medecin' % i,
             'maj:enfant_%s_sanitaire_vaccin' % i,
             'maj:enfant_%s_sanitaire_allergie' % i,
+            'maj:enfant_%s_sanitaire_handicap' % i,
             'maj:enfant_%s_assurance' % i,
             'maj:enfant_%s_contact' % i,
         ]
     for key in flags:
         payload[key] = True
+    payload['maj:enfant_0_sanitaire_handicap'] = False
 
     print("Update family info with the following payload:")
     pprint.pprint(payload)
diff --git a/passerelle/contrib/toulouse_axel/models.py b/passerelle/contrib/toulouse_axel/models.py
index c12904ab..ee647c28 100644
--- a/passerelle/contrib/toulouse_axel/models.py
+++ b/passerelle/contrib/toulouse_axel/models.py
@@ -286,6 +286,7 @@ class ToulouseAxel(BaseResource):
             'maj:enfant_%s_sanitaire_medecin' % i: 'ENFANT/%s/SANITAIRE/MEDECIN' % i,
             'maj:enfant_%s_sanitaire_vaccin' % i: 'ENFANT/%s/SANITAIRE/VACCIN' % i,
             'maj:enfant_%s_sanitaire_allergie' % i: 'ENFANT/%s/SANITAIRE/ALLERGIE' % i,
+            'maj:enfant_%s_sanitaire_handicap' % i: 'ENFANT/%s/SANITAIRE/HANDICAP' % i,
             'maj:enfant_%s_assurance' % i: 'ENFANT/%s/ASSURANCE' % i,
             'maj:enfant_%s_contact' % i: 'ENFANT/%s/CONTACT' % i,
         })
@@ -518,15 +519,19 @@ class ToulouseAxel(BaseResource):
                 # empty all subelements
                 for k in data[element_to_remove].keys():
                     data[element_to_remove][k] = None
-            elif element_to_remove == 'CONTACT':
+            elif element_to_remove in ['CONTACT', 'HANDICAP']:
                 # get the correct child
                 child_data = post_data['ENFANT'][elements[1]]
                 child_id = child_data['IDPERSONNE']
-                # and reset the contacts
+                # get family info
                 if family_data is None:
                     family_data = self.get_family_data(name_id)
                 for child in family_data['ENFANT']:
-                    if child['IDPERSONNE'] == child_id:
+                    # find the correct child in family info
+                    if child['IDPERSONNE'] != child_id:
+                        continue
+                    if element_to_remove == 'CONTACT':
+                        # reset the contacts
                         if child.get('CONTACT'):
                             child_data['CONTACT'] = child['CONTACT']
                             # XXX set LIENPARENTE because if empty the contact is deleted
@@ -535,7 +540,19 @@ class ToulouseAxel(BaseResource):
                                     contact['LIENPARENTE'] = 'BABY'
                         elif 'CONTACT' in child_data:
                             child_data.pop('CONTACT')
-                        break
+                    else:
+                        # reset handicap related fields
+                        handicap_fields = [
+                            'AUTREDIFFICULTE',
+                            'ECOLESPECIALISEE',
+                            'INDICATEURAUXILIAIREVS',
+                            'INDICATEURECOLE',
+                            'INDICATEURHANDICAP',
+                            'INDICATEURNOTIFMDPH',
+                        ]
+                        for key in handicap_fields:
+                            child_data['SANITAIRE'][key] = child['SANITAIRE'][key]
+                    break
             elif element_to_remove in data:
                 # remove block
                 data.pop(element_to_remove)
diff --git a/tests/data/toulouse_axel/flat_update_family_info.json b/tests/data/toulouse_axel/flat_update_family_info.json
index 4c5e0c19..fa732693 100644
--- a/tests/data/toulouse_axel/flat_update_family_info.json
+++ b/tests/data/toulouse_axel/flat_update_family_info.json
@@ -161,6 +161,7 @@
   "maj:enfant_0_sanitaire_allergie": "OUI",
   "maj:enfant_0_sanitaire_medecin": "OUI",
   "maj:enfant_0_sanitaire_vaccin": "OUI",
+  "maj:enfant_0_sanitaire_handicap": "OUI",
   "maj:enfant_1": "OUI",
   "maj:enfant_1_assurance": "OUI",
   "maj:enfant_1_contact": "OUI",
@@ -168,6 +169,7 @@
   "maj:enfant_1_sanitaire_allergie": "OUI",
   "maj:enfant_1_sanitaire_medecin": "OUI",
   "maj:enfant_1_sanitaire_vaccin": "OUI",
+  "maj:enfant_1_sanitaire_handicap": "OUI",
   "maj:enfant_2": "OUI",
   "maj:enfant_2_assurance": "OUI",
   "maj:enfant_2_contact": "OUI",
@@ -175,6 +177,7 @@
   "maj:enfant_2_sanitaire_allergie": "OUI",
   "maj:enfant_2_sanitaire_medecin": "OUI",
   "maj:enfant_2_sanitaire_vaccin": "OUI",
+  "maj:enfant_2_sanitaire_handicap": "OUI",
   "maj:enfant_3": "OUI",
   "maj:enfant_3_assurance": "OUI",
   "maj:enfant_3_contact": "OUI",
@@ -182,6 +185,7 @@
   "maj:enfant_3_sanitaire_allergie": "OUI",
   "maj:enfant_3_sanitaire_medecin": "OUI",
   "maj:enfant_3_sanitaire_vaccin": "OUI",
+  "maj:enfant_3_sanitaire_handicap": "OUI",
   "maj:enfant_4": "OUI",
   "maj:enfant_4_assurance": "OUI",
   "maj:enfant_4_contact": "OUI",
@@ -189,6 +193,7 @@
   "maj:enfant_4_sanitaire_allergie": "OUI",
   "maj:enfant_4_sanitaire_medecin": "OUI",
   "maj:enfant_4_sanitaire_vaccin": "OUI",
+  "maj:enfant_4_sanitaire_handicap": "OUI",
   "maj:enfant_5": "OUI",
   "maj:enfant_5_assurance": "OUI",
   "maj:enfant_5_contact": "OUI",
@@ -196,6 +201,7 @@
   "maj:enfant_5_sanitaire_allergie": "OUI",
   "maj:enfant_5_sanitaire_medecin": "OUI",
   "maj:enfant_5_sanitaire_vaccin": "OUI",
+  "maj:enfant_5_sanitaire_handicap": "OUI",
   "maj:revenus": "OUI",
   "maj:rl1": "OUI",
   "maj:rl1_adresse_employeur": "OUI",
diff --git a/tests/data/toulouse_axel/update_family_info.json b/tests/data/toulouse_axel/update_family_info.json
index 596f0b7a..9ddbed65 100644
--- a/tests/data/toulouse_axel/update_family_info.json
+++ b/tests/data/toulouse_axel/update_family_info.json
@@ -219,6 +219,7 @@
     "maj:enfant_0_sanitaire_allergie": "OUI",
     "maj:enfant_0_sanitaire_medecin": "OUI",
     "maj:enfant_0_sanitaire_vaccin": "OUI",
+    "maj:enfant_0_sanitaire_handicap": "OUI",
     "maj:enfant_1": "OUI",
     "maj:enfant_1_assurance": "OUI",
     "maj:enfant_1_contact": "OUI",
@@ -226,6 +227,7 @@
     "maj:enfant_1_sanitaire_allergie": "OUI",
     "maj:enfant_1_sanitaire_medecin": "OUI",
     "maj:enfant_1_sanitaire_vaccin": "OUI",
+    "maj:enfant_1_sanitaire_handicap": "OUI",
     "maj:enfant_2": "OUI",
     "maj:enfant_2_assurance": "OUI",
     "maj:enfant_2_contact": "OUI",
@@ -233,6 +235,7 @@
     "maj:enfant_2_sanitaire_allergie": "OUI",
     "maj:enfant_2_sanitaire_medecin": "OUI",
     "maj:enfant_2_sanitaire_vaccin": "OUI",
+    "maj:enfant_2_sanitaire_handicap": "OUI",
     "maj:enfant_3": "OUI",
     "maj:enfant_3_assurance": "OUI",
     "maj:enfant_3_contact": "OUI",
@@ -240,6 +243,7 @@
     "maj:enfant_3_sanitaire_allergie": "OUI",
     "maj:enfant_3_sanitaire_medecin": "OUI",
     "maj:enfant_3_sanitaire_vaccin": "OUI",
+    "maj:enfant_3_sanitaire_handicap": "OUI",
     "maj:enfant_4": "OUI",
     "maj:enfant_4_assurance": "OUI",
     "maj:enfant_4_contact": "OUI",
@@ -247,6 +251,7 @@
     "maj:enfant_4_sanitaire_allergie": "OUI",
     "maj:enfant_4_sanitaire_medecin": "OUI",
     "maj:enfant_4_sanitaire_vaccin": "OUI",
+    "maj:enfant_4_sanitaire_handicap": "OUI",
     "maj:enfant_5": "OUI",
     "maj:enfant_5_assurance": "OUI",
     "maj:enfant_5_contact": "OUI",
@@ -254,6 +259,7 @@
     "maj:enfant_5_sanitaire_allergie": "OUI",
     "maj:enfant_5_sanitaire_medecin": "OUI",
     "maj:enfant_5_sanitaire_vaccin": "OUI",
+    "maj:enfant_5_sanitaire_handicap": "OUI",
     "maj:revenus": "OUI",
     "maj:rl1": "OUI",
     "maj:rl1_adresse_employeur": "OUI",
diff --git a/tests/test_toulouse_axel.py b/tests/test_toulouse_axel.py
index 6b267cf3..99d49906 100644
--- a/tests/test_toulouse_axel.py
+++ b/tests/test_toulouse_axel.py
@@ -969,8 +969,64 @@ def test_sanitize_update_family_data_enfant_n_sanitaire_vaccin(app, resource, up
     assert 'VACCIN' in partial_update_params['ENFANT'][1]['SANITAIRE']
 
 
+def test_sanitize_update_family_data_enfant_n_sanitaire_handicap(app, resource, update_params):
+    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
+
+    # test maj:enfant_n_contact
+    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
+    with open(filepath) as xml:
+        content = xml.read()
+    partial_update_params = copy.deepcopy(update_params)
+    partial_update_params['maj:enfant_0_sanitaire_handicap'] = False
+    # reset fields
+    handicap_fields = [
+        'AUTREDIFFICULTE',
+        'ECOLESPECIALISEE',
+        'INDICATEURAUXILIAIREVS',
+        'INDICATEURECOLE',
+        'INDICATEURHANDICAP',
+        'INDICATEURNOTIFMDPH',
+    ]
+    for key in handicap_fields:
+        partial_update_params['ENFANT'][0]['SANITAIRE'][key] = None
+    partial_update_params['maj:enfant_1'] = False
+    with mock_getdata(content, 'RefFamilleDui'):
+        resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
+        original_values = resource.get_family_data(name_id='yyy')['ENFANT'][0]['SANITAIRE']
+    assert len(partial_update_params['ENFANT']) == 1
+    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
+    # fields were set with origin values found in Axel
+    new_values = partial_update_params['ENFANT'][0]['SANITAIRE']
+    for key in handicap_fields:
+        assert new_values[key] == original_values[key]
+    # combine with maj:enfant_n_sanitaire
+    partial_update_params = copy.deepcopy(update_params)
+    partial_update_params['maj:enfant_1_sanitaire'] = False
+    partial_update_params['maj:enfant_1_sanitaire_handicap'] = False
+    partial_update_params['maj:enfant_0'] = False
+    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
+    assert len(partial_update_params['ENFANT']) == 1
+    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
+    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
+    # combine with maj:enfant_n
+    partial_update_params = copy.deepcopy(update_params)
+    partial_update_params['maj:enfant_1'] = False
+    partial_update_params['maj:enfant_1_sanitaire_sanitaire'] = False
+    partial_update_params['maj:enfant_0'] = False
+    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
+    assert 'ENFANT' not in partial_update_params
+
+    # test maj:enfant_n_sanitaire_handicap not set
+    partial_update_params = copy.deepcopy(update_params)
+    partial_update_params['maj:enfant_0_sanitaire_handicap'] = None
+    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
+        resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
+    assert operation.call_args_list == []
+
+
 def test_sanitize_update_family_data_axel_error(app, resource, update_params):
     Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
+
     partial_update_params = copy.deepcopy(update_params)
     partial_update_params['maj:enfant_0_contact'] = False
     with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
@@ -978,6 +1034,13 @@ def test_sanitize_update_family_data_axel_error(app, resource, update_params):
         with pytest.raises(APIError, match='Axel error: FooBar'):
             resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
 
+    partial_update_params = copy.deepcopy(update_params)
+    partial_update_params['maj:enfant_0_sanitaire_handicap'] = False
+    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
+        operation.side_effect = AxelError('FooBar')
+        with pytest.raises(APIError, match='Axel error: FooBar'):
+            resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
+
 
 def test_update_family_info_endpoint_sanitize_axel_error(app, resource, update_params):
     Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
-- 
2.20.1

