0001-toulouse-maelis-add-RL1-webservices-68788.patch
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 |
- |