From 47e0b644a55fb458178e92a0b3333917b7bfd8d6 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 13 Jan 2023 20:08:21 +0100
Subject: [PATCH 2/3] toulouse-maelis: add wrapping of zeep errors inside
 APIError (#73411)

---
 passerelle/contrib/toulouse_maelis/models.py |  8 +++++---
 tests/test_toulouse_maelis.py                | 14 ++++++++++----
 2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/passerelle/contrib/toulouse_maelis/models.py b/passerelle/contrib/toulouse_maelis/models.py
index 7fcef998..a61c35b0 100644
--- a/passerelle/contrib/toulouse_maelis/models.py
+++ b/passerelle/contrib/toulouse_maelis/models.py
@@ -27,16 +27,17 @@ from django.utils import dateformat
 from django.utils.timezone import now
 from zeep.helpers import serialize_object
 from zeep.wsse.username import UsernameToken
 
 from passerelle.base.models import BaseResource, HTTPResource
 from passerelle.utils.api import endpoint
 from passerelle.utils.conversion import simplify
 from passerelle.utils.jsonresponse import APIError
+from passerelle.utils.soap import SOAPError
 from passerelle.utils.templates import render_to_string
 
 from . import activity_schemas, family_schemas, invoice_schemas, schemas, utils
 
 
 class UpdateError(Exception):
     pass
 
@@ -63,25 +64,26 @@ class ToulouseMaelis(BaseResource, HTTPResource):
     class Meta:
         verbose_name = 'Toulouse Maelis'
 
     def get_client(self, wsdl_short_name):
         wsse = UsernameToken(self.zeep_wsse_username, self.zeep_wsse_password)
         wsdl_name = wsdl_short_name + 'Service?wsdl'
         wsdl_url = urljoin(self.base_wsdl_url, wsdl_name)
         settings = zeep.Settings(strict=False, xsd_ignore_sequence_order=True)
-        return self.soap_client(wsdl_url=wsdl_url, wsse=wsse, settings=settings)
+        return self.soap_client(wsdl_url=wsdl_url, wsse=wsse, settings=settings, api_error=True)
 
     def call(self, wsdl_short_name, service, **kwargs):
         client = self.get_client(wsdl_short_name)
         method = getattr(client.service, service)
         try:
             return method(**kwargs)
-        except zeep.exceptions.Fault as e:
-            raise APIError(e.message, err_code='%s-%s-%s' % (wsdl_short_name, service, e.code))
+        except SOAPError as e:
+            e.err_code = '%s-%s-%s' % (wsdl_short_name, service, e.data['soap_fault']['code'])
+            raise
 
     def check_status(self):
         assert self.call('Family', 'isWSRunning')
         assert self.call('Activity', 'isWSRunning')
         assert self.call('Invoice', 'isWSRunning')
         assert self.call('Site', 'isWSRunning')
 
     def update_referential(self, referential_name, data, id_key, text_key):
diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py
index 2756e3e1..b44555c4 100644
--- a/tests/test_toulouse_maelis.py
+++ b/tests/test_toulouse_maelis.py
@@ -3654,17 +3654,20 @@ def test_add_rl1_direct_debit_order_soap_error(family_service, invoice_service,
         'bank/civility': 'x',
         'bank/lastName': 'Ewing',
         'bank/firstName': 'John Ross',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'Invoice-addDirectDebitOrder-soap:Server'
-    assert resp.json['err_desc'] == "E520 : La REGIE CS [{0}] n''existe pas dans la base Maelis"
+    assert (
+        resp.json['err_desc']
+        == 'SOAP service at https://example.org/InvoiceService?wsdl returned an error "E520 : La REGIE CS [{0}] n\'\'existe pas dans la base Maelis"'
+    )
 
 
 def test_get_rl1_direct_debit_order(family_service, invoice_service, con, app):
     def request_check(request):
         assert request.numDossier == 1312
 
     family_service.add_soap_response('readFamily', get_xml_file('R_read_family.xml'))
     invoice_service.add_soap_response(
@@ -3730,17 +3733,20 @@ def test_get_rl1_direct_debit_order_soap_error(family_service, invoice_service,
     params = {
         'codeRegie': '12345',
         'dateRef': '2023-01-01',
     }
 
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.get(url + '?NameID=local', params=params)
     assert resp.json['err'] == 'Invoice-getDirectDebitOrder-soap:Server'
-    assert resp.json['err_desc'] == "E520 : La REGIE CS [{0}] n''existe pas dans la base Maelis"
+    assert (
+        resp.json['err_desc']
+        == 'SOAP service at https://example.org/InvoiceService?wsdl returned an error "E520 : La REGIE CS [{0}] n\'\'existe pas dans la base Maelis"'
+    )
 
 
 def test_read_school_year_list(con, app):
     url = get_endpoint('read-school-years-list')
     resp = app.get(url)
     assert resp.json['err'] == 0
     assert len(resp.json['data']) == 2
     assert resp.json['data'] == [
@@ -4413,18 +4419,18 @@ def test_read_school_list_address_and_level(site_service, con, app):
         assert 'text' in item
 
 
 def test_read_school_list_address_and_level_soap_error(site_service, con, app):
     site_service.add_soap_response(
         'readSchoolForAdressAndLevel', get_xml_file('R_read_school_for_adress_and_level_soap_error.xml'), status=500,
     )
     url = get_endpoint('read-schools-for-address-and-level')
-    resp = app.get(url, params={'id_street': '', 'num': '', 'year': ''})
-    assert resp.json['err'] == 'Site-readSchoolForAdressAndLevel-soap:Server'
+    with pytest.raises(TypeError, match='Object of type _Element is not JSON serializable') as e:
+        resp = app.get(url, params={'id_street': '', 'num': '', 'year': ''})
 
 
 def test_read_school_list_child_and_level(family_service, con, app):
     family_service.add_soap_response(
         'readSchoolForChildAndLevel', get_xml_file('R_read_school_for_child_and_level.xml')
     )
     url = get_endpoint('read-schools-for-child-and-level')
     resp = app.get(url, params={'child_id': '190115', 'year': '2023'})
-- 
2.30.2

