Projet

Général

Profil

0001-toulouse-maelis-add-RL1-webservices-68788.patch

Nicolas Roche, 13 septembre 2022 19:40

Télécharger (16,8 ko)

Voir les différences:

Subject: [PATCH 1/3] toulouse-maelis: add RL1 webservices (#68788)

 passerelle/contrib/toulouse_maelis/models.py  |  47 +++++++
 passerelle/contrib/toulouse_maelis/schemas.py |  17 +++
 tests/data/toulouse_maelis/Q_update_rl1.xml   |  32 +++++
 .../toulouse_maelis/R_create_family_error.xml |   1 +
 .../R_read_family_with_only_rl1.xml           |  39 ++++++
 tests/test_toulouse_maelis.py                 | 129 +++++++++++++++++-
 6 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 tests/data/toulouse_maelis/Q_update_rl1.xml
 create mode 100644 tests/data/toulouse_maelis/R_read_family_with_only_rl1.xml
passerelle/contrib/toulouse_maelis/models.py
456 456
        data = serialize_object(response)
457 457
        family_id = data.get('number')
458 458
        errors = data.get('childErrorList')
459 459
        if errors:
460 460
            err_codes = [x.split(':')[0][:4] for x in errors]
461 461
            raise APIError(' ; '.join(errors), err_code=', '.join(err_codes))
462 462
        return {'data': data}
463 463

  
464
    @endpoint(
465
        display_category='Famille',
466
        description='Création du RL1',
467
        name='create-rl1',
468
        perm='can_access',
469
        parameters={'NameID': {'description': 'Publik NameID'}},
470
        post={'request_body': {'schema': {'application/json': schemas.CREATE_RL1_SCHEMA}}},
471
    )
472
    def create_rl1(self, request, NameID, post_data):
473
        if self.link_set.filter(name_id=NameID).exists():
474
            raise APIError('User already linked to family', err_code='already-linked')
475

  
476
        response = self.call('Family', 'createFamily', **post_data)
477
        data = serialize_object(response)
478
        family_id = data.get('number')
479
        if not family_id:
480
            errors = data.get('rl1ErrorList') or []
481
            raise APIError(' ; '.join(errors), err_code='already-rl1')
482

  
483
        Link.objects.create(resource=self, name_id=NameID, family_id=family_id)
484
        return {'data': {'family_id': family_id}}
485

  
486
    @endpoint(
487
        display_category='Famille',
488
        description='Modification du RL1',
489
        name='update-rl1',
490
        perm='can_access',
491
        parameters={'NameID': {'description': 'Publik NameID'}},
492
        post={'request_body': {'schema': {'application/json': schemas.UPDATE_RL1_SCHEMA}}},
493
    )
494
    def update_rl1(self, request, NameID, post_data):
495
        family_id = self.get_link(NameID).family_id
496
        family = self.get_family_raw(family_id)
497
        self.replace_null_values(post_data)
498

  
499
        rl1 = post_data
500
        rl1['num'] = family['RL1']['num']
501
        rl1['adresse'] = family['RL1']['adresse']
502
        payload = {
503
            'dossierNumber': family_id,
504
            'categorie': family['category'],
505
            'situation': family['situation'],
506
            'rl1': rl1,
507
        }
508
        self.call('Family', 'updateFamily', **payload)
509
        return {'data': 'ok'}
510

  
464 511
    @endpoint(
465 512
        display_category='Famille',
466 513
        description="Mise à jour des coordonnées d'une personne",
467 514
        name='update-coordinate',
468 515
        perm='can_access',
469 516
        parameters={
470 517
            'NameID': {'description': 'Publik NameID'},
471 518
            'rl_id': {'description': 'Numéro du représentant légal'},
passerelle/contrib/toulouse_maelis/schemas.py
658 658

  
659 659

  
660 660
UPDATE_FAMILY_SCHEMA = copy.deepcopy(CREATE_FAMILY_SCHEMA)
661 661
UPDATE_FAMILY_SCHEMA['required'] = ['categorie', 'situation']
662 662

  
663 663

  
664 664
# Schemas below describe parameters of Maelis wrapper around updateFamily endpoint
665 665

  
666
CREATE_RL1_SCHEMA = copy.deepcopy(CREATE_FAMILY_SCHEMA)
667
del CREATE_RL1_SCHEMA['properties']['rl2']
668
del CREATE_RL1_SCHEMA['properties']['authorizedPersonList']
669
del CREATE_RL1_SCHEMA['properties']['emergencyPersonList']
670
del CREATE_RL1_SCHEMA['properties']['childList']
671
del CREATE_RL1_SCHEMA['properties']['rl1']['properties']['contact']
672
del CREATE_RL1_SCHEMA['properties']['rl1']['properties']['profession']
673
del CREATE_RL1_SCHEMA['properties']['rl1']['properties']['CAFInfo']
674

  
675
UPDATE_RL1_SCHEMA = copy.deepcopy(RLINFO_SCHEMA)
676
UPDATE_RL1_SCHEMA['required'] = ['firstname', 'lastname', 'civility', 'quality', 'dateBirth']
677
del UPDATE_RL1_SCHEMA['properties']['adresse']
678
del UPDATE_RL1_SCHEMA['properties']['contact']
679
del UPDATE_RL1_SCHEMA['properties']['profession']
680
del UPDATE_RL1_SCHEMA['properties']['CAFInfo']
681

  
682

  
666 683
UPDATE_COORDINATE_SCHEMA = {
667 684
    '$schema': 'http://json-schema.org/draft-04/schema#',
668 685
    'title': 'Update coordinate',
669 686
    'description': "Mise à jour des coordonnées d'un responsable légal",
670 687
    'type': 'object',
671 688
    'properties': {
672 689
        'adresse': ADDRESS_SCHEMA,
673 690
        'contact': CONTACT_SCHEMA,
tests/data/toulouse_maelis/Q_update_rl1.xml
1
<?xml version="1.0" encoding="utf-8"?>
2
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
3
  <soap-env:Header>
4
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
5
      <wsse:UsernameToken>
6
        <wsse:Username>maelis-webservice</wsse:Username>
7
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
8
      </wsse:UsernameToken>
9
    </wsse:Security>
10
  </soap-env:Header>
11
  <soap-env:Body>
12
    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
13
      <dossierNumber>1312</dossierNumber>
14
      <categorie>BI</categorie>
15
      <situation>M</situation>
16
      <rl1>
17
        <num>613878</num>
18
        <lastname>Doe</lastname>
19
        <firstname>Jhonny</firstname>
20
        <quality>PERE</quality>
21
        <civility>M.</civility>
22
        <dateBirth>1943-06-15</dateBirth>
23
        <adresse>
24
          <num>170</num>
25
          <street1>Chateau d'eau</street1>
26
          <town>Paris</town>
27
          <zipcode>75014</zipcode>
28
        </adresse>
29
      </rl1>
30
    </ns0:updateFamily>
31
  </soap-env:Body>
32
</soap-env:Envelope>
tests/data/toulouse_maelis/R_create_family_error.xml
1 1
<?xml version="1.0" encoding="utf-8"?>
2 2
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
3 3
  <soap:Body>
4 4
    <ns2:createFamilyResponse xmlns:ns2="family.ws.maelis.sigec.com">
5 5
      <createFamilyResult>
6 6
        <number>0</number>
7 7
        <rl1ErrorList>E54a : Il existe déjà un Responsable Légal correspondant au nom [DOE], prénom [JHON], date de naissance [26/07/1938] - Personne n°[613955] - Famille n°[196544]</rl1ErrorList>
8
        <rl1ErrorList>E54a : Il existe déjà un Responsable Légal correspondant au nom [DOE], prénom [JHON], date de naissance [26/07/1938] - Personne n°[613956] - Famille n°[196545]</rl1ErrorList>
8 9
      </createFamilyResult>
9 10
    </ns2:createFamilyResponse>
10 11
  </soap:Body>
11 12
</soap:Envelope>
tests/data/toulouse_maelis/R_read_family_with_only_rl1.xml
1
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
  <soap:Body>
3
    <ns2:readFamilyResponse xmlns:ns2="family.ws.maelis.sigec.com">
4
      <familyResult>
5
        <number>1312</number>
6
        <category>BI</category>
7
        <situation>M</situation>
8
        <flagCom>true</flagCom>
9
        <nbChild>2</nbChild>
10
        <RL1>
11
          <num>613878</num>
12
          <lastname>DOE</lastname>
13
          <firstname>JHON</firstname>
14
          <quality>PERE</quality>
15
          <civility>M.</civility>
16
          <dateBirth>1938-07-26T00:00:00+01:00</dateBirth>
17
          <adresse>
18
            <idStreet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
19
            <num>170</num>
20
            <street1>Chateau d'eau</street1>
21
            <town>Paris</town>
22
            <zipcode>75014</zipcode>
23
          </adresse>
24
          <contact>
25
            <phone>non</phone>
26
            <mobile>0777777777</mobile>
27
            <mail>djhon@example.org</mail>
28
            <isContactMail>true</isContactMail>
29
            <isContactSms>true</isContactSms>
30
            <isInvoicePdf>true</isInvoicePdf>
31
          </contact>
32
          <profession>
33
            <addressPro/>
34
          </profession>
35
        </RL1>
36
      </familyResult>
37
    </ns2:readFamilyResponse>
38
  </soap:Body>
39
</soap:Envelope>
tests/test_toulouse_maelis.py
38 38
CONNECTION_ERROR = ConnectionError('No address associated with hostname')
39 39
FAMILY_SERVICE_WSDL = FakedResponse(content=get_xml_file('FamilyService.wsdl'), status_code=200)
40 40
ACTIVITY_SERVICE_WSDL = FakedResponse(content=get_xml_file('ActivityService.wsdl'), status_code=200)
41 41
INVOICE_SERVICE_WSDL = FakedResponse(content=get_xml_file('InvoiceService.wsdl'), status_code=200)
42 42
FAILED_AUTH = FakedResponse(content=get_xml_file('R_failed_authentication.xml'), status_code=500)
43 43
ISWSRUNNING_TRUE = FakedResponse(content=get_xml_file('R_is_ws_running.xml') % b'true', status_code=200)
44 44
ISWSRUNNING_FALSE = FakedResponse(content=get_xml_file('R_is_ws_running.xml') % b'false', status_code=200)
45 45
READ_FAMILY = FakedResponse(content=get_xml_file('R_read_family.xml'), status_code=200)
46
READ_RL1_FAMILY = FakedResponse(content=get_xml_file('R_read_family_with_only_rl1.xml'), status_code=200)
46 47
READ_CATEGORIES = FakedResponse(content=get_xml_file('R_read_category_list.xml'), status_code=200)
47 48
READ_CIVILITIES = FakedResponse(content=get_xml_file('R_read_civility_list.xml'), status_code=200)
48 49
READ_CSP = FakedResponse(content=get_xml_file('R_read_csp_list.xml'), status_code=200)
49 50
READ_DIETCODE = FakedResponse(content=get_xml_file('R_read_dietcode_list.xml'), status_code=200)
50 51
READ_ORGAN = FakedResponse(content=get_xml_file('R_read_organ_list.xml'), status_code=200)
51 52
READ_PAI = FakedResponse(content=get_xml_file('R_read_pai_list.xml'), status_code=200)
52 53
READ_QUALITIES = FakedResponse(content=get_xml_file('R_read_quality_list.xml'), status_code=200)
53 54
READ_QUOTIENT = FakedResponse(content=get_xml_file('R_read_quotient_list.xml'), status_code=200)
......
1008 1009
        'rl1/quality': 'AU',
1009 1010
        'rl1/dateBirth': '1938-07-26',
1010 1011
        'rl1/adresse/street1': 'Chateau',
1011 1012
        'rl1/adresse/town': 'Paris',
1012 1013
        'rl1/adresse/zipcode': '75014',
1013 1014
    }
1014 1015

  
1015 1016
    resp = app.post_json(url + '?NameID=local', params=params)
1016
    assert resp.json['err'] == 'E54a'
1017
    assert resp.json['err'] == 'E54a, E54a'
1017 1018
    assert 'Il existe déjà' in resp.json['err_desc']
1018 1019

  
1019 1020

  
1020 1021
@mock.patch('passerelle.utils.Request.get')
1021 1022
@mock.patch('passerelle.utils.Request.post')
1022 1023
def test_update_family(mocked_post, mocked_get, con, app):
1023 1024
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1024 1025
    mocked_post.return_value = UPDATE_FAMILY
......
1105 1106
    }
1106 1107

  
1107 1108
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1108 1109
    resp = app.post_json(url + '?NameID=local', params=params)
1109 1110
    assert resp.json['err'] == 'Family-updateFamily-soap:Server'
1110 1111
    assert 'Une erreur est survenue' in resp.json['err_desc']
1111 1112

  
1112 1113

  
1114
@mock.patch('passerelle.utils.Request.get')
1115
@mock.patch('passerelle.utils.Request.post')
1116
def test_create_rl1(mocked_post, mocked_get, con, app):
1117
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1118
    mocked_post.return_value = CREATE_FAMILY
1119
    url = get_endpoint('create-rl1')
1120
    params = {
1121
        'categorie': 'ACCEUI',
1122
        'situation': 'C',
1123
        'rl1/civility': 'M.',
1124
        'rl1/firstname': 'Jhon',
1125
        'rl1/lastname': 'Doe',
1126
        'rl1/quality': 'AU',
1127
        'rl1/dateBirth': '1938-07-26',
1128
        'rl1/adresse/street1': 'Chateau',
1129
        'rl1/adresse/town': 'Paris',
1130
        'rl1/adresse/zipcode': '75014',
1131
    }
1132

  
1133
    resp = app.post_json(url + '?NameID=local', params=params)
1134
    assert_sent_payload(mocked_post, 'Q_create_family.xml')
1135
    assert resp.json['err'] == 0
1136
    assert resp.json['data'] == {'family_id': 196545}
1137
    assert Link.objects.get(resource=con, family_id='196545', name_id='local')
1138

  
1139

  
1140
def test_create_rl1_already_linked_error(con, app):
1141
    url = get_endpoint('create-rl1')
1142
    params = {
1143
        'categorie': 'ACCEUI',
1144
        'situation': 'C',
1145
        'rl1/civility': 'M.',
1146
        'rl1/firstname': 'Jhon',
1147
        'rl1/lastname': 'Doe',
1148
        'rl1/quality': 'AU',
1149
        'rl1/dateBirth': '1938-07-26',
1150
        'rl1/adresse/street1': 'Chateau',
1151
        'rl1/adresse/town': 'Paris',
1152
        'rl1/adresse/zipcode': '75014',
1153
    }
1154

  
1155
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1156
    resp = app.post_json(url + '?NameID=local', params=params)
1157
    assert resp.json['err'] == 'already-linked'
1158
    assert resp.json['err_desc'] == 'User already linked to family'
1159

  
1160

  
1161
@mock.patch('passerelle.utils.Request.get')
1162
@mock.patch('passerelle.utils.Request.post')
1163
def test_create_rl1_maelis_error(mocked_post, mocked_get, con, app):
1164
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1165
    mocked_post.return_value = CREATE_FAMILY_ERR
1166
    url = get_endpoint('create-rl1')
1167
    params = {
1168
        'categorie': 'ACCEUI',
1169
        'situation': 'C',
1170
        'rl1/civility': 'M.',
1171
        'rl1/firstname': 'Jhon',
1172
        'rl1/lastname': 'Doe',
1173
        'rl1/quality': 'AU',
1174
        'rl1/dateBirth': '1938-07-26',
1175
        'rl1/adresse/street1': 'Chateau',
1176
        'rl1/adresse/town': 'Paris',
1177
        'rl1/adresse/zipcode': '75014',
1178
    }
1179

  
1180
    resp = app.post_json(url + '?NameID=local', params=params)
1181
    assert resp.json['err'] == 'already-rl1'
1182
    assert 'Il existe déjà' in resp.json['err_desc']
1183

  
1184

  
1185
@mock.patch('passerelle.utils.Request.get')
1186
@mock.patch('passerelle.utils.Request.post')
1187
def test_update_rl1(mocked_post, mocked_get, con, app):
1188
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1189
    mocked_post.side_effect = [READ_RL1_FAMILY, UPDATE_FAMILY]
1190
    url = get_endpoint('update-rl1')
1191
    params = {
1192
        'civility': 'M.',
1193
        'firstname': 'Jhonny',
1194
        'lastname': 'Doe',
1195
        'quality': 'PERE',
1196
        'dateBirth': '1943-06-15',
1197
    }
1198

  
1199
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1200
    resp = app.post_json(url + '?NameID=local', params=params)
1201
    assert_sent_payload(mocked_post, 'Q_update_rl1.xml')
1202
    assert resp.json['err'] == 0
1203

  
1204

  
1205
def test_update_rl1_not_linked_error(con, app):
1206
    url = get_endpoint('update-rl1')
1207
    params = {
1208
        'civility': 'M.',
1209
        'firstname': 'Jhonny',
1210
        'lastname': 'Doe',
1211
        'quality': 'PERE',
1212
        'dateBirth': '1943-06-15',
1213
    }
1214

  
1215
    resp = app.post_json(url + '?NameID=local', params=params)
1216
    assert resp.json['err'] == 'not-linked'
1217
    assert resp.json['err_desc'] == 'User not linked to family'
1218

  
1219

  
1220
@mock.patch('passerelle.utils.Request.get')
1221
@mock.patch('passerelle.utils.Request.post')
1222
def test_update_rl1_connection_error(mocked_post, mocked_get, con, app):
1223
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1224
    mocked_post.side_effect = CONNECTION_ERROR
1225
    url = get_endpoint('update-rl1')
1226
    params = {
1227
        'civility': 'M.',
1228
        'firstname': 'Jhonny',
1229
        'lastname': 'Doe',
1230
        'quality': 'PERE',
1231
        'dateBirth': '1943-06-15',
1232
    }
1233

  
1234
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1235
    resp = app.post_json(url + '?NameID=local', params=params, status=500)
1236
    assert resp.json['err']
1237
    assert resp.json['err_desc'] == 'No address associated with hostname'
1238

  
1239

  
1113 1240
@mock.patch('passerelle.utils.Request.get')
1114 1241
@mock.patch('passerelle.utils.Request.post')
1115 1242
def test_update_coordinate(mocked_post, mocked_get, con, app):
1116 1243
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1117 1244
    mocked_post.return_value = UPDATE_FAMILY
1118 1245
    url = get_endpoint('update-coordinate')
1119 1246
    params = {
1120 1247
        'adresse/num': '169',
1121
-