From a09f8f334f58df50916d760780d4acb4534af595 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Tue, 4 Oct 2022 00:07:39 +0200
Subject: [PATCH 4/5] toulouse-maelis: add endpoint to update child person
 (#69891)

---
 passerelle/contrib/toulouse_maelis/models.py  | 37 ++++++++
 .../toulouse_maelis/Q_update_child_person.xml | 37 ++++++++
 tests/test_toulouse_maelis.py                 | 87 +++++++++++++++++++
 3 files changed, 161 insertions(+)
 create mode 100644 tests/data/toulouse_maelis/Q_update_child_person.xml

diff --git a/passerelle/contrib/toulouse_maelis/models.py b/passerelle/contrib/toulouse_maelis/models.py
index 81e34e83..e6d636c1 100644
--- a/passerelle/contrib/toulouse_maelis/models.py
+++ b/passerelle/contrib/toulouse_maelis/models.py
@@ -878,16 +878,53 @@ class ToulouseMaelis(BaseResource, HTTPResource):
             'numPerson': child_id,
             'bLeaveAlone': child['bLeaveAlone'],
             'bPhoto': child['bPhoto'],
             'personList': personList,
         }
         self.call('Family', 'updateChildAutorization', updateChildAutorizationRequest=req)
         return {'data': 'ok'}
 
+    @endpoint(
+        display_category='Famille',
+        description="Mise à jour d'une personne autorisée à récupérer l'enfant",
+        name='update-child-person',
+        perm='can_access',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'child_id': {'description': "Numéro de l'enfant"},
+            'person_id': {'description': 'Numéro de la personne'},
+        },
+        post={'request_body': {'schema': {'application/json': schemas.CHILDPERSON2_SCHEMA}}},
+    )
+    def update_child_person(self, request, NameID, child_id, person_id, post_data):
+        family_id = self.get_link(NameID).family_id
+        child = self.get_child_raw(family_id, child_id)
+        self.replace_null_values(post_data)
+
+        personList = child['authorizedPersonList']
+        for i, person in enumerate(personList):
+            if str(person['personInfo']['num']) == person_id:
+                personList[i] = post_data
+                personList[i]['personInfo']['num'] = person_id
+                break
+        else:
+            raise APIError(
+                "No '%s' authorized person on '%s' child" % (person_id, child_id), err_code='not-found'
+            )
+        req = {
+            'numFamily': family_id,
+            'numPerson': child_id,
+            'bLeaveAlone': child['bLeaveAlone'],
+            'bPhoto': child['bPhoto'],
+            'personList': personList,
+        }
+        self.call('Family', 'updateChildAutorization', updateChildAutorizationRequest=req)
+        return {'data': 'ok'}
+
     @endpoint(
         display_category='Famille',
         description="Créer ou mettre à jour le régime alimentaire d'un enfant",
         name='update-child-dietcode',
         perm='can_access',
         parameters={
             'NameID': {'description': 'Publik NameID'},
             'child_id': {'description': "Numéro de l'enfant"},
diff --git a/tests/data/toulouse_maelis/Q_update_child_person.xml b/tests/data/toulouse_maelis/Q_update_child_person.xml
new file mode 100644
index 00000000..717a5a1a
--- /dev/null
+++ b/tests/data/toulouse_maelis/Q_update_child_person.xml
@@ -0,0 +1,37 @@
+<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap-env:Header>
+    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
+      <wsse:UsernameToken>
+        <wsse:Username>maelis-webservice</wsse:Username>
+        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
+      </wsse:UsernameToken>
+    </wsse:Security>
+  </soap-env:Header>
+  <soap-env:Body>
+    <ns0:updateChildAutorization xmlns:ns0="family.ws.maelis.sigec.com">
+      <updateChildAutorizationRequest>
+        <numFamily>1312</numFamily>
+        <numPerson>613880</numPerson>
+        <personList>
+          <personInfo>
+            <num>614719</num>
+            <civility>M.</civility>
+            <lastname>Bent</lastname>
+            <firstname>Angelo</firstname>
+            <dateBirth>1985-06-22</dateBirth>
+            <contact>
+              <phone>0102030405</phone>
+              <mobile/>
+              <mail/>
+            </contact>
+          </personInfo>
+          <personQuality>
+            <code>O</code>
+          </personQuality>
+        </personList>
+        <bLeaveAlone>false</bLeaveAlone>
+        <bPhoto>true</bPhoto>
+      </updateChildAutorizationRequest>
+    </ns0:updateChildAutorization>
+  </soap-env:Body>
+</soap-env:Envelope>
diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py
index bc681902..d443efef 100644
--- a/tests/test_toulouse_maelis.py
+++ b/tests/test_toulouse_maelis.py
@@ -1897,16 +1897,103 @@ def test_create_child_person_no_child_error(mocked_post, mocked_get, con, app):
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&child_id=42', params=params)
     assert resp.json['err'] == 'not-found'
     assert resp.json['err_desc'] == "no '42' child on '1312' family"
 
 
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_child_person(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
+    url = get_endpoint('update-child-person')
+    params = {
+        'personInfo/civility': 'M.',
+        'personInfo/firstname': 'Angelo',
+        'personInfo/lastname': 'Bent',
+        'personInfo/dateBirth': '1985-06-22',
+        'personInfo/contact/phone': '0102030405',
+        'personInfo/contact/mobile': None,
+        'personInfo/contact/mail': None,
+        'personQuality/code': 'O',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=614719', params=params)
+    assert_sent_payload(mocked_post, 'Q_update_child_person.xml')
+    assert resp.json['err'] == 0
+
+
+def test_update_child_person_not_linked_error(con, app):
+    url = get_endpoint('update-child-person')
+    params = {
+        'personInfo/civility': 'M.',
+        'personInfo/firstname': 'Angelo',
+        'personInfo/lastname': 'Bent',
+        'personInfo/dateBirth': '1985-06-22',
+        'personInfo/contact/phone': '0102030405',
+        'personInfo/contact/mobile': None,
+        'personInfo/contact/mail': None,
+        'personQuality/code': 'O',
+    }
+
+    resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=614719', params=params)
+    assert resp.json['err'] == 'not-linked'
+    assert resp.json['err_desc'] == 'User not linked to family'
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_child_person_no_child_error(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.side_effect = [READ_FAMILY]
+    url = get_endpoint('update-child-person')
+    params = {
+        'personInfo/civility': 'M.',
+        'personInfo/firstname': 'Angelo',
+        'personInfo/lastname': 'Bent',
+        'personInfo/dateBirth': '1985-06-22',
+        'personInfo/contact/phone': '0102030405',
+        'personInfo/contact/mobile': None,
+        'personInfo/contact/mail': None,
+        'personQuality/code': 'O',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&child_id=42&person_id=614719', params=params)
+    assert resp.json['err'] == 'not-found'
+    assert resp.json['err_desc'] == "no '42' child on '1312' family"
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_child_person_not_found(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.side_effect = [READ_FAMILY]
+    url = get_endpoint('update-child-person')
+    params = {
+        'personInfo/civility': 'M.',
+        'personInfo/firstname': 'Angelo',
+        'personInfo/lastname': 'Bent',
+        'personInfo/dateBirth': '1985-06-22',
+        'personInfo/contact/phone': '0102030405',
+        'personInfo/contact/mobile': None,
+        'personInfo/contact/mail': None,
+        'personQuality/code': 'O',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&child_id=613880&person_id=000000', params=params)
+    assert resp.json['err'] == 'not-found'
+    assert resp.json['err_desc'] == "No '000000' authorized person on '613880' child"
+
+
 @mock.patch('passerelle.utils.Request.get')
 @mock.patch('passerelle.utils.Request.post')
 def test_update_child_dietcode(mocked_post, mocked_get, con, app):
     mocked_get.return_value = FAMILY_SERVICE_WSDL
     mocked_post.return_value = UPDATE_DIETCODE
     url = get_endpoint('update-child-dietcode')
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
-- 
2.30.2

