Projet

Général

Profil

0003-toulouse-maelis-manage-XML-soap-fault-detail-content.patch

Nicolas Roche, 13 janvier 2023 20:57

Télécharger (5,09 ko)

Voir les différences:

Subject: [PATCH 3/3] toulouse-maelis: manage XML soap fault detail content
 (#73411)

 passerelle/utils/soap.py      |  3 +++
 tests/test_toulouse_maelis.py | 36 ++++++++++++++++++++++++++++++++---
 2 files changed, 36 insertions(+), 3 deletions(-)
passerelle/utils/soap.py
11 11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 12
# GNU Affero General Public License for more details.
13 13
#
14 14
# You should have received a copy of the GNU Affero General Public License
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17 17
from urllib import parse as urlparse
18 18

  
19
from lxml import etree
19 20
from requests import RequestException
20 21
from zeep import Client
21 22
from zeep.cache import InMemoryCache
22 23
from zeep.exceptions import Error as ZeepError
23 24
from zeep.exceptions import Fault, TransportError
24 25
from zeep.proxy import OperationProxy, ServiceProxy
25 26
from zeep.transports import Transport
26 27

  
......
43 44
            },
44 45
        )
45 46

  
46 47

  
47 48
class SOAPFault(SOAPError):
48 49
    log_error = False
49 50

  
50 51
    def __init__(self, client, fault):
52
        if hasattr(fault, 'detail') and isinstance(fault.detail, etree._Element):
53
            fault.detail = etree.tostring(fault.detail).decode()
51 54
        super().__init__(
52 55
            f'SOAP service at {client.wsdl.location} returned an error "{fault.message or fault.code}"',
53 56
            data={
54 57
                'soap_fault': fault.__dict__,
55 58
            },
56 59
        )
57 60

  
58 61

  
tests/test_toulouse_maelis.py
188 188
        match='The security token could not be authenticated or authorized',
189 189
    ) as e:
190 190
        con.call('Family', 'isWSRunning')
191 191
    assert e.value.__dict__ == {
192 192
        'err': 1,
193 193
        'log_error': False,
194 194
        'http_status': 200,
195 195
        'err_code': 'Family-isWSRunning-ns1:FailedAuthentication',
196
        'data': {
197
            'soap_fault': {
198
                'message': 'The security token could not be authenticated or authorized',
199
                'code': 'ns1:FailedAuthentication',
200
                'actor': None,
201
                'detail': None,
202
                'subcodes': None,
203
            }
204
        },
196 205
    }
197 206

  
198 207

  
199 208
def test_call(family_service, con):
200 209
    family_service.add_soap_response('isWSRunning', get_xml_file('R_is_ws_running.xml') % b'true')
201 210
    resp = con.call('Family', 'isWSRunning')
202 211
    assert resp is True
203 212

  
......
4416 4425
    assert len(resp.json['data']) == 8
4417 4426
    for item in resp.json['data']:
4418 4427
        assert 'id' in item
4419 4428
        assert 'text' in item
4420 4429

  
4421 4430

  
4422 4431
def test_read_school_list_address_and_level_soap_error(site_service, con, app):
4423 4432
    site_service.add_soap_response(
4424
        'readSchoolForAdressAndLevel', get_xml_file('R_read_school_for_adress_and_level_soap_error.xml'), status=500,
4433
        'readSchoolForAdressAndLevel',
4434
        get_xml_file('R_read_school_for_adress_and_level_soap_error.xml'),
4435
        status=500,
4425 4436
    )
4426 4437
    url = get_endpoint('read-schools-for-address-and-level')
4427
    with pytest.raises(TypeError, match='Object of type _Element is not JSON serializable') as e:
4428
        resp = app.get(url, params={'id_street': '', 'num': '', 'year': ''})
4438
    resp = app.get(url, params={'id_street': '', 'num': '', 'year': ''})
4439
    assert resp.json['err'] == 'Site-readSchoolForAdressAndLevel-soap:Server'
4440
    assert (
4441
        resp.json['err_desc']
4442
        == 'SOAP service at https://example.org/SiteService?wsdl returned an error "E19 : La voie est obligatoire"'
4443
    )
4444
    assert resp.json['data'] == {
4445
        'soap_fault': {
4446
            'message': 'E19 : La voie est obligatoire',
4447
            'code': 'soap:Server',
4448
            'actor': None,
4449
            'detail': '<detail xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
4450
            + '\n        <ns1:MaelisSiteException xmlns:ns1="site.ws.maelis.sigec.com">'
4451
            + '\n          <message xmlns:ns2="site.ws.maelis.sigec.com">E19 : La voie est obligatoire</message>'
4452
            + '\n          <code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
4453
            + ' xmlns:ns2="site.ws.maelis.sigec.com" xsi:nil="true"/>'
4454
            + '\n        </ns1:MaelisSiteException>\n      </detail>'
4455
            + '\n    ',
4456
            'subcodes': None,
4457
        }
4458
    }
4429 4459

  
4430 4460

  
4431 4461
def test_read_school_list_child_and_level(family_service, con, app):
4432 4462
    family_service.add_soap_response(
4433 4463
        'readSchoolForChildAndLevel', get_xml_file('R_read_school_for_child_and_level.xml')
4434 4464
    )
4435 4465
    url = get_endpoint('read-schools-for-child-and-level')
4436 4466
    resp = app.get(url, params={'child_id': '190115', 'year': '2023'})
4437
-