Projet

Général

Profil

0003-toulouse_maelis-add-child-webservices-68788.patch

Nicolas Roche, 13 septembre 2022 19:40

Télécharger (17 ko)

Voir les différences:

Subject: [PATCH 3/3] toulouse_maelis: add child webservices (#68788)

 passerelle/contrib/toulouse_maelis/models.py  |  60 +++++++
 passerelle/contrib/toulouse_maelis/schemas.py |  11 ++
 tests/data/toulouse_maelis/Q_create_child.xml |  25 +++
 tests/data/toulouse_maelis/Q_update_child.xml |  27 ++++
 tests/data/toulouse_maelis/R_create_child.xml |   9 ++
 .../toulouse_maelis/R_create_child_error.xml  |  11 ++
 tests/test_toulouse_maelis.py                 | 153 ++++++++++++++++++
 7 files changed, 296 insertions(+)
 create mode 100644 tests/data/toulouse_maelis/Q_create_child.xml
 create mode 100644 tests/data/toulouse_maelis/Q_update_child.xml
 create mode 100644 tests/data/toulouse_maelis/R_create_child.xml
 create mode 100644 tests/data/toulouse_maelis/R_create_child_error.xml
passerelle/contrib/toulouse_maelis/models.py
553 553
            'dossierNumber': family_id,
554 554
            'categorie': family['category'],
555 555
            'situation': family['situation'],
556 556
            'rl2': rl2,
557 557
        }
558 558
        self.call('Family', 'updateFamily', **payload)
559 559
        return {'data': 'ok'}
560 560

  
561
    @endpoint(
562
        display_category='Famille',
563
        description="Ajout d'un enfant",
564
        name='create-child',
565
        perm='can_access',
566
        parameters={
567
            'NameID': {'description': 'Publik NameID'},
568
            'force': {
569
                'description': 'boolean to bypass doublon error',
570
                'type': 'bool',
571
                'example_value': 'false',
572
            },
573
        },
574
        post={'request_body': {'schema': {'application/json': schemas.CREATE_CHILD_SCHEMA}}},
575
    )
576
    def create_child(self, request, NameID, post_data, force=False):
577
        family_id = self.get_link(NameID).family_id
578

  
579
        payload = {
580
            'numDossier': family_id,
581
            'isForceCreateChild': force,
582
            'child': post_data,
583
        }
584
        response = self.call('Family', 'createChild', **payload)
585
        data = serialize_object(response)
586
        child_id = data.get('number')
587
        if not child_id:
588
            errors = data.get('childErrorList') or []
589
            raise APIError(' ; '.join(errors), err_code='already-child')
590
        return {'data': {'child_id': child_id}}
591

  
592
    @endpoint(
593
        display_category='Famille',
594
        description="Modification d'un enfant",
595
        name='update-child',
596
        perm='can_access',
597
        parameters={
598
            'NameID': {'description': 'Publik NameID'},
599
            'child_id': {'description': "Numéro de l'enfant"},
600
        },
601
        post={'request_body': {'schema': {'application/json': schemas.UPDATE_CHILD_SCHEMA}}},
602
    )
603
    def update_child(self, request, NameID, child_id, post_data):
604
        family_id = self.get_link(NameID).family_id
605
        family = self.get_family_raw(family_id)
606
        if child_id not in [x['num'] for x in family['childList']]:
607
            raise APIError('No child %s to update on family' % child_id, err_code='no-child')
608
        self.replace_null_values(post_data)
609

  
610
        child = post_data
611
        child['num'] = child_id
612
        payload = {
613
            'dossierNumber': family_id,
614
            'categorie': family['category'],
615
            'situation': family['situation'],
616
            'childList': [child],
617
        }
618
        self.call('Family', 'updateFamily', **payload)
619
        return {'data': 'ok'}
620

  
561 621
    @endpoint(
562 622
        display_category='Famille',
563 623
        description="Mise à jour des coordonnées d'une personne",
564 624
        name='update-coordinate',
565 625
        perm='can_access',
566 626
        parameters={
567 627
            'NameID': {'description': 'Publik NameID'},
568 628
            'rl_id': {'description': 'Numéro du représentant légal'},
passerelle/contrib/toulouse_maelis/schemas.py
682 682
CREATE_RL2_SCHEMA = copy.deepcopy(RLINFO_SCHEMA)
683 683
CREATE_RL2_SCHEMA['unflatten'] = True
684 684
del CREATE_RL2_SCHEMA['properties']['contact']
685 685
del CREATE_RL2_SCHEMA['properties']['profession']
686 686
del CREATE_RL2_SCHEMA['properties']['CAFInfo']
687 687

  
688 688
UPDATE_RL2_SCHEMA = copy.deepcopy(UPDATE_RL1_SCHEMA)
689 689

  
690
CREATE_CHILD_SCHEMA = copy.deepcopy(CHILD_SCHEMA)
691
CREATE_CHILD_SCHEMA['unflatten'] = True
692
del CREATE_CHILD_SCHEMA['properties']['dietcode']
693
del CREATE_CHILD_SCHEMA['properties']['bPhoto']
694
del CREATE_CHILD_SCHEMA['properties']['bLeaveAlone']
695
del CREATE_CHILD_SCHEMA['properties']['fsl']
696
del CREATE_CHILD_SCHEMA['properties']['medicalRecord']
697
del CREATE_CHILD_SCHEMA['properties']['paiInfoBean']
698

  
699
UPDATE_CHILD_SCHEMA = copy.deepcopy(CREATE_CHILD_SCHEMA)
700

  
690 701
UPDATE_COORDINATE_SCHEMA = {
691 702
    '$schema': 'http://json-schema.org/draft-04/schema#',
692 703
    'title': 'Update coordinate',
693 704
    'description': "Mise à jour des coordonnées d'un responsable légal",
694 705
    'type': 'object',
695 706
    'properties': {
696 707
        'adresse': ADDRESS_SCHEMA,
697 708
        'contact': CONTACT_SCHEMA,
tests/data/toulouse_maelis/Q_create_child.xml
1
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
2
  <soap-env:Header>
3
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
4
      <wsse:UsernameToken>
5
        <wsse:Username>maelis-webservice</wsse:Username>
6
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
7
      </wsse:UsernameToken>
8
    </wsse:Security>
9
  </soap-env:Header>
10
  <soap-env:Body>
11
    <ns0:createChild xmlns:ns0="family.ws.maelis.sigec.com">
12
      <numDossier>1312</numDossier>
13
      <child>
14
        <firstname>JANNIS</firstname>
15
        <lastname>DOE</lastname>
16
        <sexe>F</sexe>
17
        <birth>
18
          <dateBirth>1943-01-19</dateBirth>
19
          <place>Port Arthur</place>
20
        </birth>
21
      </child>
22
      <isForceCreateChild>false</isForceCreateChild>
23
    </ns0:createChild>
24
  </soap-env:Body>
25
</soap-env:Envelope>
tests/data/toulouse_maelis/Q_update_child.xml
1
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
2
  <soap-env:Header>
3
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
4
      <wsse:UsernameToken>
5
        <wsse:Username>maelis-webservice</wsse:Username>
6
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
7
      </wsse:UsernameToken>
8
    </wsse:Security>
9
  </soap-env:Header>
10
  <soap-env:Body>
11
    <ns0:updateFamily xmlns:ns0="family.ws.maelis.sigec.com">
12
      <dossierNumber>1312</dossierNumber>
13
      <categorie>BI</categorie>
14
      <situation>M</situation>
15
      <childList>
16
        <num>613880</num>
17
        <lastname>DOE</lastname>
18
        <firstname>JANNIS</firstname>
19
        <sexe>F</sexe>
20
        <birth>
21
          <dateBirth>1943-01-19</dateBirth>
22
          <place>Port Arthur</place>
23
        </birth>
24
      </childList>
25
    </ns0:updateFamily>
26
  </soap-env:Body>
27
</soap-env:Envelope>
tests/data/toulouse_maelis/R_create_child.xml
1
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
  <soap:Body>
3
    <ns2:createChildResponse xmlns:ns2="family.ws.maelis.sigec.com">
4
      <resultBean>
5
        <number>613880</number>
6
      </resultBean>
7
    </ns2:createChildResponse>
8
  </soap:Body>
9
</soap:Envelope>
tests/data/toulouse_maelis/R_create_child_error.xml
1
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
2
  <soap:Body>
3
    <ns2:createChildResponse xmlns:ns2="family.ws.maelis.sigec.com">
4
      <resultBean>
5
        <number>0</number>
6
        <childErrorList>E54a : Il existe déjà un enfant correspondant au nom [DOE], prénom [JANNIS], date de naissance [19/01/1943] - Personne n°[613988] - Famille n°[196562]</childErrorList>
7
        <childErrorList>E54a : Il existe déjà un enfant correspondant au nom [DOE], prénom [JANNIS], date de naissance [19/01/1943] - Personne n°[613989] - Famille n°[196563]</childErrorList>
8
      </resultBean>
9
    </ns2:createChildResponse>
10
  </soap:Body>
11
</soap:Envelope>
tests/test_toulouse_maelis.py
57 57
IS_RL_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'true', status_code=200)
58 58
IS_RL_EXISTS_FALSE = FakedResponse(content=get_xml_file('R_is_rl_exists.xml') % b'false', status_code=200)
59 59
IS_CHILD_EXISTS_TRUE = FakedResponse(content=get_xml_file('R_is_child_exists.xml') % b'true', status_code=200)
60 60
IS_CHILD_EXISTS_FALSE = FakedResponse(
61 61
    content=get_xml_file('R_is_child_exists.xml') % b'false', status_code=200
62 62
)
63 63
CREATE_FAMILY = FakedResponse(content=get_xml_file('R_create_family.xml'), status_code=200)
64 64
CREATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_create_family_error.xml'), status_code=200)
65
CREATE_CHILD = FakedResponse(content=get_xml_file('R_create_child.xml'), status_code=200)
66
CREATE_CHILD_ERR = FakedResponse(content=get_xml_file('R_create_child_error.xml'), status_code=200)
65 67
UPDATE_FAMILY = FakedResponse(content=get_xml_file('R_update_family.xml'), status_code=200)
66 68
UPDATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_update_family_error.xml'), status_code=200)
67 69
UPDATE_FAMILY_500 = FakedResponse(content=get_xml_file('R_update_family_soap_error.xml'), status_code=500)
68 70

  
69 71

  
70 72
def assert_sent_payload(mocked_post, query_file):
71 73
    soap_sent = etree.tostring(etree.fromstring(mocked_post.call_args.kwargs['data']), pretty_print=True)
72 74
    expected = etree.tostring(etree.fromstring(get_xml_file(query_file)), pretty_print=True)
......
1399 1401
    }
1400 1402

  
1401 1403
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1402 1404
    resp = app.post_json(url + '?NameID=local', params=params)
1403 1405
    assert resp.json['err'] == 'no-rl2'
1404 1406
    assert resp.json['err_desc'] == 'No RL2 to update on family'
1405 1407

  
1406 1408

  
1409
@mock.patch('passerelle.utils.Request.get')
1410
@mock.patch('passerelle.utils.Request.post')
1411
def test_create_child(mocked_post, mocked_get, con, app):
1412
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1413
    mocked_post.return_value = CREATE_CHILD
1414
    url = get_endpoint('create-child')
1415
    params = {
1416
        'lastname': 'DOE',
1417
        'firstname': 'JANNIS',
1418
        'sexe': 'F',
1419
        'birth/dateBirth': '1943-01-19',
1420
        'birth/place': 'Port Arthur',
1421
    }
1422

  
1423
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1424
    resp = app.post_json(url + '?NameID=local', params=params)
1425
    assert_sent_payload(mocked_post, 'Q_create_child.xml')
1426
    assert resp.json['err'] == 0
1427
    assert resp.json['data'] == {'child_id': 613880}
1428

  
1429

  
1430
def test_create_child_not_linked_error(con, app):
1431
    url = get_endpoint('create-child')
1432
    params = {
1433
        'lastname': 'DOE',
1434
        'firstname': 'JANNIS',
1435
        'sexe': 'F',
1436
        'birth/dateBirth': '1943-01-19',
1437
        'birth/place': 'Port Arthur',
1438
    }
1439

  
1440
    resp = app.post_json(url + '?NameID=local', params=params)
1441
    assert resp.json['err'] == 'not-linked'
1442
    assert resp.json['err_desc'] == 'User not linked to family'
1443

  
1444

  
1445
@mock.patch('passerelle.utils.Request.get')
1446
@mock.patch('passerelle.utils.Request.post')
1447
def test_create_child_connection_error(mocked_post, mocked_get, con, app):
1448
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1449
    mocked_post.side_effect = CONNECTION_ERROR
1450
    url = get_endpoint('create-child')
1451
    params = {
1452
        'lastname': 'DOE',
1453
        'firstname': 'JANNIS',
1454
        'sexe': 'F',
1455
        'birth/dateBirth': '1943-01-19',
1456
        'birth/place': 'Port Arthur',
1457
    }
1458

  
1459
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1460
    resp = app.post_json(url + '?NameID=local', params=params, status=500)
1461
    assert resp.json['err']
1462
    assert resp.json['err_desc'] == 'No address associated with hostname'
1463

  
1464

  
1465
@mock.patch('passerelle.utils.Request.get')
1466
@mock.patch('passerelle.utils.Request.post')
1467
def test_create_child_maelis_error(mocked_post, mocked_get, con, app):
1468
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1469
    mocked_post.return_value = CREATE_CHILD_ERR
1470
    url = get_endpoint('create-child')
1471
    params = {
1472
        'lastname': 'DOE',
1473
        'firstname': 'JANNIS',
1474
        'sexe': 'F',
1475
        'birth/dateBirth': '1943-01-19',
1476
        'birth/place': 'Port Arthur',
1477
    }
1478

  
1479
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1480
    resp = app.post_json(url + '?NameID=local', params=params)
1481
    assert resp.json['err'] == 'already-child'
1482
    assert 'Il existe déjà' in resp.json['err_desc']
1483

  
1484

  
1485
@mock.patch('passerelle.utils.Request.get')
1486
@mock.patch('passerelle.utils.Request.post')
1487
def test_update_child(mocked_post, mocked_get, con, app):
1488
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1489
    mocked_post.side_effect = [READ_FAMILY, UPDATE_FAMILY]
1490
    url = get_endpoint('update-child')
1491
    params = {
1492
        'lastname': 'DOE',
1493
        'firstname': 'JANNIS',
1494
        'sexe': 'F',
1495
        'birth/dateBirth': '1943-01-19',
1496
        'birth/place': 'Port Arthur',
1497
    }
1498

  
1499
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1500
    resp = app.post_json(url + '?NameID=local&child_id=613880', params=params)
1501
    assert_sent_payload(mocked_post, 'Q_update_child.xml')
1502
    assert resp.json['err'] == 0
1503

  
1504

  
1505
def test_update_child_not_linked_error(con, app):
1506
    url = get_endpoint('update-child')
1507
    params = {
1508
        'lastname': 'DOE',
1509
        'firstname': 'JANNIS',
1510
        'sexe': 'F',
1511
        'birth/dateBirth': '1943-01-19',
1512
        'birth/place': 'Port Arthur',
1513
    }
1514

  
1515
    resp = app.post_json(url + '?NameID=local&child_id=613880', params=params)
1516
    assert resp.json['err'] == 'not-linked'
1517
    assert resp.json['err_desc'] == 'User not linked to family'
1518

  
1519

  
1520
@mock.patch('passerelle.utils.Request.get')
1521
@mock.patch('passerelle.utils.Request.post')
1522
def test_update_child_connection_error(mocked_post, mocked_get, con, app):
1523
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1524
    mocked_post.side_effect = CONNECTION_ERROR
1525
    url = get_endpoint('update-child')
1526
    params = {
1527
        'lastname': 'DOE',
1528
        'firstname': 'JANNIS',
1529
        'sexe': 'F',
1530
        'birth/dateBirth': '1943-01-19',
1531
        'birth/place': 'Port Arthur',
1532
    }
1533

  
1534
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1535
    resp = app.post_json(url + '?NameID=local&child_id=613880', params=params, status=500)
1536
    assert resp.json['err']
1537
    assert resp.json['err_desc'] == 'No address associated with hostname'
1538

  
1539

  
1540
@mock.patch('passerelle.utils.Request.get')
1541
@mock.patch('passerelle.utils.Request.post')
1542
def test_update_child_not_exists_error(mocked_post, mocked_get, con, app):
1543
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1544
    mocked_post.return_value = READ_RL1_FAMILY
1545
    url = get_endpoint('update-child')
1546
    params = {
1547
        'lastname': 'DOE',
1548
        'firstname': 'JANNIS',
1549
        'sexe': 'F',
1550
        'birth/dateBirth': '1943-01-19',
1551
        'birth/place': 'Port Arthur',
1552
    }
1553

  
1554
    Link.objects.create(resource=con, family_id='1312', name_id='local')
1555
    resp = app.post_json(url + '?NameID=local&child_id=42', params=params)
1556
    assert resp.json['err'] == 'no-child'
1557
    assert resp.json['err_desc'] == 'No child 42 to update on family'
1558

  
1559

  
1407 1560
@mock.patch('passerelle.utils.Request.get')
1408 1561
@mock.patch('passerelle.utils.Request.post')
1409 1562
def test_update_coordinate(mocked_post, mocked_get, con, app):
1410 1563
    mocked_get.return_value = FAMILY_SERVICE_WSDL
1411 1564
    mocked_post.return_value = UPDATE_FAMILY
1412 1565
    url = get_endpoint('update-coordinate')
1413 1566
    params = {
1414 1567
        'adresse/num': '169',
1415
-