0001-toulouse-maelis-add-webservices-to-manage-childs-673.patch
passerelle/contrib/toulouse_maelis/models.py | ||
---|---|---|
320 | 320 |
if str(person['numPerson']) == person_id: |
321 | 321 |
break |
322 | 322 |
else: |
323 | 323 |
raise APIError( |
324 | 324 |
"no '%s' %s person on '%s' family" % (person_id, kind, family_id), err_code='not-found' |
325 | 325 |
) |
326 | 326 |
return {'data': person} |
327 | 327 | |
328 |
@endpoint( |
|
329 |
display_category=_('Family'), |
|
330 |
description="Informations sur un enfant", |
|
331 |
perm='can_access', |
|
332 |
name='read-child', |
|
333 |
parameters={ |
|
334 |
'NameID': {'description': _('Publik ID')}, |
|
335 |
'child_id': {'description': "Numéro de l'enfant"}, |
|
336 |
}, |
|
337 |
) |
|
338 |
def read_child(self, request, NameID, child_id): |
|
339 |
family_id = self.get_link(NameID).family_id |
|
340 |
data = self.get_family(family_id) |
|
341 |
for child in data['childList']: |
|
342 |
if child['num'] == child_id: |
|
343 |
break |
|
344 |
else: |
|
345 |
raise APIError("no '%s' child on '%s' family" % (child_id, family_id), err_code='not-found') |
|
346 |
return {'data': child} |
|
347 | ||
328 | 348 |
@endpoint( |
329 | 349 |
display_category=_('Family'), |
330 | 350 |
description="Vérifier qu'un responsable légal existe en base", |
331 | 351 |
perm='can_access', |
332 | 352 |
name='is-rl-exists', |
333 |
post={'request_body': {'schema': {'application/json': schemas.ISRLEXISTS_SCHEMA}}},
|
|
353 |
post={'request_body': {'schema': {'application/json': schemas.ISEXISTS_SCHEMA}}}, |
|
334 | 354 |
) |
335 | 355 |
def is_rl_exists(self, request, post_data): |
336 | 356 |
response = self.call('Family', 'isRLExists', **post_data) |
337 | 357 |
return {'data': response} |
338 | 358 | |
359 |
@endpoint( |
|
360 |
display_category=_('Family'), |
|
361 |
description="Vérifier qu'un responsable légal existe en base", |
|
362 |
perm='can_access', |
|
363 |
name='is-child-exists', |
|
364 |
post={'request_body': {'schema': {'application/json': schemas.ISEXISTS_SCHEMA}}}, |
|
365 |
) |
|
366 |
def is_child_exists(self, request, post_data): |
|
367 |
response = self.call('Family', 'isChildExists', **post_data) |
|
368 |
return {'data': response} |
|
369 | ||
339 | 370 |
@endpoint( |
340 | 371 |
display_category=_('Family'), |
341 | 372 |
description='Création de la famille', |
342 | 373 |
name='create-family', |
343 | 374 |
perm='can_access', |
344 | 375 |
parameters={'NameID': {'description': _('Publik ID')}}, |
345 | 376 |
post={'request_body': {'schema': {'application/json': schemas.FAMILY_SCHEMA}}}, |
346 | 377 |
) |
passerelle/contrib/toulouse_maelis/schemas.py | ||
---|---|---|
45 | 45 |
'dateBirth': { |
46 | 46 |
'description': 'Date de naissance du RL1', |
47 | 47 |
'type': 'string', |
48 | 48 |
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', |
49 | 49 |
}, |
50 | 50 |
}, |
51 | 51 |
} |
52 | 52 | |
53 |
ISRLEXISTS_SCHEMA = {
|
|
53 |
ISEXISTS_SCHEMA = { |
|
54 | 54 |
'$schema': 'http://json-schema.org/draft-04/schema#', |
55 | 55 |
'title': 'Link', |
56 | 56 |
'description': "Appairage d'un usager Publik à une famille dans Maelis", |
57 | 57 |
'type': 'object', |
58 | 58 |
'required': ['firstname', 'lastname', 'datebirth'], |
59 | 59 |
'properties': { |
60 | 60 |
'firstname': { |
61 | 61 |
'description': 'Prénom', |
... | ... | |
258 | 258 |
}, |
259 | 259 |
'adresse': ADDRESS_SCHEMA, |
260 | 260 |
'contact': CONTACT_SCHEMA, |
261 | 261 |
'profession': PROFESSION_SCHEMA, |
262 | 262 |
'CAFInfo': CAFINFO_SCHEMA, |
263 | 263 |
}, |
264 | 264 |
} |
265 | 265 | |
266 |
CHILDBIRTH_SCHEMA = { |
|
267 |
'$schema': 'http://json-schema.org/draft-04/schema#', |
|
268 |
'title': 'Child birth', |
|
269 |
'description': "Informations sur la naissance d'un enfant", |
|
270 |
'type': 'object', |
|
271 |
'required': ['dateBirth'], |
|
272 |
'properties': { |
|
273 |
'dateBirth': { |
|
274 |
'description': 'Date de naissance', |
|
275 |
'type': 'string', |
|
276 |
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', |
|
277 |
}, |
|
278 |
'place': { |
|
279 |
'description': 'Lieu de naissance', |
|
280 |
'oneOf': [{'type': 'null'}, {'type': 'string'}], |
|
281 |
}, |
|
282 |
}, |
|
283 |
} |
|
284 | ||
285 |
CHILD_SCHEMA = { |
|
286 |
'$schema': 'http://json-schema.org/draft-04/schema#', |
|
287 |
'title': 'Child', |
|
288 |
'description': "Informations sur la création d'un enfant", |
|
289 |
'type': 'object', |
|
290 |
'required': ['sexe', 'firstname', 'lastname'], |
|
291 |
'oneOf': [ |
|
292 |
{'required': ['dateBirth']}, # createFamily |
|
293 |
{'required': ['birth']}, # updateFamily |
|
294 |
], |
|
295 |
'properties': { |
|
296 |
'firstname': { |
|
297 |
'description': 'Prénom', |
|
298 |
'type': 'string', |
|
299 |
}, |
|
300 |
'lastname': { |
|
301 |
'description': 'Nom', |
|
302 |
'type': 'string', |
|
303 |
}, |
|
304 |
'sexe': { |
|
305 |
'description': 'Sexe', |
|
306 |
'type': 'string', |
|
307 |
}, |
|
308 |
'dateBirth': { |
|
309 |
'description': 'Date de naissance', |
|
310 |
'type': 'string', |
|
311 |
'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$', |
|
312 |
}, |
|
313 |
'birth': CHILDBIRTH_SCHEMA, |
|
314 |
'dietcode': { |
|
315 |
'description': 'Code de régime alimentaire', |
|
316 |
'oneOf': [{'type': 'null'}, {'type': 'string'}], |
|
317 |
}, |
|
318 |
'bPhoto': { |
|
319 |
'description': 'Autorisation photo', |
|
320 |
'oneOf': BOOLEAN_TYPES, |
|
321 |
}, |
|
322 |
'bLeaveAlone': { |
|
323 |
'description': 'Autorisation à partir seul', |
|
324 |
'oneOf': BOOLEAN_TYPES, |
|
325 |
}, |
|
326 |
}, |
|
327 |
} |
|
266 | 328 | |
267 | 329 |
CONTACTLIGHT_SCHEMA = { |
268 | 330 |
'$schema': 'http://json-schema.org/draft-04/schema#', |
269 | 331 |
'title': 'Contact', |
270 | 332 |
'description': "Informations de contact pour les personnes authorisées à récupérer les enfants ou à prévenir en cas d'urgence", |
271 | 333 |
'oneOf': [ |
272 | 334 |
{'type': 'null'}, |
273 | 335 |
{ |
... | ... | |
387 | 449 |
'oneOf': [ |
388 | 450 |
{'type': 'null'}, |
389 | 451 |
{ |
390 | 452 |
'type': 'array', |
391 | 453 |
'items': AUTHORIZEDPERSON_SCHEMA, |
392 | 454 |
}, |
393 | 455 |
], |
394 | 456 |
}, |
457 |
'childList': { |
|
458 |
'oneOf': [ |
|
459 |
{'type': 'null'}, |
|
460 |
{ |
|
461 |
'type': 'array', |
|
462 |
'items': CHILD_SCHEMA, |
|
463 |
}, |
|
464 |
], |
|
465 |
}, |
|
395 | 466 |
}, |
396 | 467 |
'unflatten': True, |
397 | 468 |
} |
398 | 469 | |
399 | 470 |
"""Schemas below describe parameters of Maelis wrapper around updateFamily endpoint""" |
400 | 471 | |
401 | 472 |
UPDATE_COORDINATE_SCHEMA = { |
402 | 473 |
'$schema': 'http://json-schema.org/draft-04/schema#', |
tests/data/toulouse_maelis/R_is_child_exists.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> |
|
3 |
<soap:Body> |
|
4 |
<ns2:isChildExistsResponse xmlns:ns2="family.ws.maelis.sigec.com"> |
|
5 |
<result>%s</result> |
|
6 |
</ns2:isChildExistsResponse> |
|
7 |
</soap:Body> |
|
8 |
</soap:Envelope> |
tests/test_toulouse_maelis.py | ||
---|---|---|
44 | 44 |
READ_FAMILY = FakedResponse(content=get_xml_file('R_read_family.xml'), status_code=200) |
45 | 45 |
READ_CATEGORIES = FakedResponse(content=get_xml_file('R_read_category_list.xml'), status_code=200) |
46 | 46 |
READ_CIVILITIES = FakedResponse(content=get_xml_file('R_read_civility_list.xml'), status_code=200) |
47 | 47 |
READ_CSP = FakedResponse(content=get_xml_file('R_read_csp_list.xml'), status_code=200) |
48 | 48 |
READ_QUALITIES = FakedResponse(content=get_xml_file('R_read_quality_list.xml'), status_code=200) |
49 | 49 |
READ_SITUATIONS = FakedResponse(content=get_xml_file('R_read_situation_list.xml'), status_code=200) |
50 | 50 |
IS_RL_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'true', status_code=200) |
51 | 51 |
IS_RL_EXISTS_FALSE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'false', status_code=200) |
52 |
IS_CHILD_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_child_exists.xml') % b'true', status_code=200) |
|
53 |
IS_CHILD_EXISTS_FALSE = FakedResponse( |
|
54 |
content=get_xml_file('R_is_child_exists.xml') % b'false', status_code=200 |
|
55 |
) |
|
52 | 56 |
CREATE_FAMILY = FakedResponse(content=get_xml_file('R_create_family.xml'), status_code=200) |
53 | 57 |
CREATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_create_family_error.xml'), status_code=200) |
54 | 58 |
UPDATE_FAMILY = FakedResponse(content=get_xml_file('R_update_family.xml'), status_code=200) |
55 | 59 |
UPDATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_update_family_error.xml'), status_code=200) |
56 | 60 |
UPDATE_FAMILY_500 = FakedResponse(content=get_xml_file('R_update_family_soap_error.xml'), status_code=500) |
57 | 61 | |
58 | 62 | |
59 | 63 |
def assert_sent_payload(mocked_post, query_file): |
... | ... | |
582 | 586 |
url = get_endpoint('read-person') |
583 | 587 |
Link.objects.create(resource=con, family_id='1312', name_id='local') |
584 | 588 | |
585 | 589 |
resp = app.get(url + '?NameID=local&person_id=000000&kind=emergency') |
586 | 590 |
assert resp.json['err'] == 'not-found' |
587 | 591 |
assert resp.json['err_desc'] == "no '000000' emergency person on '1312' family" |
588 | 592 | |
589 | 593 | |
594 |
@mock.patch('passerelle.utils.Request.get') |
|
595 |
@mock.patch('passerelle.utils.Request.post') |
|
596 |
def test_read_child(mocked_post, mocked_get, con, app): |
|
597 |
mocked_get.return_value = FAMILY_SERVICE_WSDL |
|
598 |
mocked_post.side_effect = [READ_FAMILY, READ_CATEGORIES, READ_SITUATIONS, READ_CIVILITIES, READ_QUALITIES] |
|
599 |
url = get_endpoint('read-child') |
|
600 |
Link.objects.create(resource=con, family_id='1312', name_id='local') |
|
601 | ||
602 |
resp = app.get(url + '?NameID=local&child_id=613880') |
|
603 |
assert resp.json['err'] == 0 |
|
604 |
assert resp.json['data']['firstname'] == 'CASSANDRA' |
|
605 | ||
606 | ||
607 |
def test_read_child_not_linked_error(con, app): |
|
608 |
url = get_endpoint('read-child') |
|
609 | ||
610 |
resp = app.get(url + '?NameID=local&child_id=613880') |
|
611 |
assert resp.json['err'] == 'not-linked' |
|
612 |
assert resp.json['err_desc'] == 'User not linked to family' |
|
613 | ||
614 | ||
615 |
@mock.patch('passerelle.utils.Request.get') |
|
616 |
@mock.patch('passerelle.utils.Request.post') |
|
617 |
def test_read_child_not_found(mocked_post, mocked_get, con, app): |
|
618 |
mocked_get.return_value = FAMILY_SERVICE_WSDL |
|
619 |
mocked_post.side_effect = [READ_FAMILY, READ_CATEGORIES, READ_SITUATIONS, READ_CIVILITIES, READ_QUALITIES] |
|
620 |
url = get_endpoint('read-child') |
|
621 |
Link.objects.create(resource=con, family_id='1312', name_id='local') |
|
622 | ||
623 |
resp = app.get(url + '?NameID=local&child_id=000000') |
|
624 |
assert resp.json['err'] == 'not-found' |
|
625 |
assert resp.json['err_desc'] == "no '000000' child on '1312' family" |
|
626 | ||
627 | ||
590 | 628 |
@pytest.mark.parametrize( |
591 | 629 |
'post_response, result', |
592 | 630 |
[ |
593 | 631 |
(IS_RL_EXISTS_TRUE, True), |
594 | 632 |
(IS_RL_EXISTS_FALSE, False), |
595 | 633 |
], |
596 | 634 |
) |
597 | 635 |
@mock.patch('passerelle.utils.Request.get') |
... | ... | |
619 | 657 |
'lastname': 'Costanze', |
620 | 658 |
'datebirth': '1980-10-07 more text', |
621 | 659 |
} |
622 | 660 |
resp = app.post_json(url, params=params, status=400) |
623 | 661 |
assert resp.json['err'] == 1 |
624 | 662 |
assert "does not match '^[0-9]{4}-[0-9]{2}-[0-9]{2}$'" in resp.json['err_desc'] |
625 | 663 | |
626 | 664 | |
665 |
@pytest.mark.parametrize( |
|
666 |
'post_response, result', |
|
667 |
[ |
|
668 |
(IS_CHILD_EXISTS_TRUE, True), |
|
669 |
(IS_CHILD_EXISTS_FALSE, False), |
|
670 |
], |
|
671 |
) |
|
672 |
@mock.patch('passerelle.utils.Request.get') |
|
673 |
@mock.patch('passerelle.utils.Request.post') |
|
674 |
def test_is_child_exists(mocked_post, mocked_get, post_response, result, con, app): |
|
675 |
mocked_get.return_value = FAMILY_SERVICE_WSDL |
|
676 |
mocked_post.return_value = post_response |
|
677 |
url = get_endpoint('is-child-exists') |
|
678 | ||
679 |
params = { |
|
680 |
'firstname': 'Cassandra', |
|
681 |
'lastname': 'Costanze', |
|
682 |
'datebirth': '2021-06-22', |
|
683 |
} |
|
684 |
resp = app.post_json(url, params=params) |
|
685 |
assert resp.json['err'] == 0 |
|
686 |
assert resp.json['data'] == result |
|
687 | ||
688 | ||
627 | 689 |
@mock.patch('passerelle.utils.Request.get') |
628 | 690 |
@mock.patch('passerelle.utils.Request.post') |
629 | 691 |
def test_create_family(mocked_post, mocked_get, con, app): |
630 | 692 |
mocked_get.return_value = FAMILY_SERVICE_WSDL |
631 | 693 |
mocked_post.return_value = CREATE_FAMILY |
632 | 694 |
url = get_endpoint('create-family') |
633 | 695 |
params = { |
634 | 696 |
'categorie': 'ACCEUI', |
635 |
- |