Projet

Général

Profil

0001-toulouse_axel-partial-update-38543.patch

Lauréline Guérin, 06 janvier 2020 12:06

Télécharger (37,2 ko)

Voir les différences:

Subject: [PATCH 1/3] toulouse_axel: partial update (#38543)

 functests/toulouse_axel/test_toulouse_axel.py |  20 +-
 passerelle/contrib/toulouse_axel/models.py    | 145 ++++++-
 .../flat_update_family_info.json              |  56 ++-
 .../toulouse_axel/update_family_info.json     |  56 ++-
 tests/test_toulouse_axel.py                   | 367 ++++++++++++++++++
 5 files changed, 630 insertions(+), 14 deletions(-)
functests/toulouse_axel/test_toulouse_axel.py
35 35
    payload['N0TELEDOSSIER'] = '42'
36 36
    payload['DROITALIMAGE'] = 'NON'
37 37
    for key in ['MONTANTTOTAL', 'DATEVALIDITE', 'SFI', 'IREVENUS', 'RNF']:
38
        payload['REVENUS'].pop(key)
38
        payload['REVENUS'].pop(key, None)
39 39
    payload['REVENUS']['CHOIXREVENU'] = ''
40 40
    for enfant in payload['ENFANT']:
41 41
        for key in ['NOM', 'DATENAISSANCE', 'SEXE', 'PRENOMPERE', 'PRENOMMERE', 'NOMPERE', 'NOMMERE', 'RATTACHEAUTREDUI', 'PRENOM']:
42 42
            enfant.pop(key)
43 43
        enfant['AUTORISATIONURGENCEMEDICALE'] = 'OUI'
44
    flags = [
45
        'maj:adresse',
46
        'maj:rl1', 'maj:rl1_adresse_employeur',
47
        'maj:rl2', 'maj:rl2_adresse_employeur',
48
        'maj:revenus',
49
    ]
50
    for i in range(0, 6):
51
        flags += [
52
            'maj:enfant_%s' % i,
53
            'maj:enfant_%s_sanitaire' % i,
54
            'maj:enfant_%s_sanitaire_medecin' % i,
55
            'maj:enfant_%s_sanitaire_vaccin' % i,
56
            'maj:enfant_%s_sanitaire_allergie' % i,
57
            'maj:enfant_%s_assurance' % i,
58
            'maj:enfant_%s_contact' % i,
59
        ]
60
    for key in flags:
61
        payload[key] = True
44 62

  
45 63
    print("Update family info with the following payload:")
46 64
    pprint.pprint(payload)
passerelle/contrib/toulouse_axel/models.py
78 78
    _indent_children(tree, 0)
79 79

  
80 80

  
81
def encode_bool(obj):
82
    if obj is True or str(obj).lower() in ['true', 'oui', '1']:
83
        return 'OUI'
84
    if obj is False or str(obj).lower() in ['false', 'non', '0']:
85
        return 'NON'
86
    return obj
87

  
88

  
81 89
class AxelSchema(JSONSchemaFromXMLSchema):
82 90
    type_map = {
83 91
        '{urn:AllAxelTypes}DATEREQUIREDType': 'date',
......
126 134
        }
127 135

  
128 136
    def encode_bool(self, obj):
129
        if obj is True or str(obj).lower() in ['true', 'oui', '1']:
130
            return 'OUI'
131
        if obj is False or str(obj).lower() in ['false', 'non', '0']:
132
            return 'NON'
133
        return obj
137
        return encode_bool(obj)
134 138

  
135 139
    def decode_bool(self, data):
136 140
        value = False
......
261 265
    LINK_SCHEMA['properties'].pop('IDPERSONNE')
262 266
    LINK_SCHEMA['required'].remove('IDPERSONNE')
263 267

  
268
    UPDATE_FAMILY_FLAGS = {
269
        'maj:adresse': 'ADRESSE',
270
        'maj:rl1': 'RL1',
271
        'maj:rl1_adresse_employeur': 'RL1/ADREMPLOYEUR',
272
        'maj:rl2': 'RL2',
273
        'maj:rl2_adresse_employeur': 'RL2/ADREMPLOYEUR',
274
        'maj:revenus': 'REVENUS',
275
    }
276
    UPDATE_FAMILY_REQUIRED_FLAGS = [
277
        'maj:adresse',
278
        'maj:rl1',
279
        'maj:rl2',
280
        'maj:revenus',
281
    ]
282
    for i in range(0, 6):
283
        UPDATE_FAMILY_FLAGS.update({
284
            'maj:enfant_%s' % i: 'ENFANT/%s' % i,
285
            'maj:enfant_%s_sanitaire' % i: 'ENFANT/%s/SANITAIRE' % i,
286
            'maj:enfant_%s_sanitaire_medecin' % i: 'ENFANT/%s/SANITAIRE/MEDECIN' % i,
287
            'maj:enfant_%s_sanitaire_vaccin' % i: 'ENFANT/%s/SANITAIRE/VACCIN' % i,
288
            'maj:enfant_%s_sanitaire_allergie' % i: 'ENFANT/%s/SANITAIRE/ALLERGIE' % i,
289
            'maj:enfant_%s_assurance' % i: 'ENFANT/%s/ASSURANCE' % i,
290
            'maj:enfant_%s_contact' % i: 'ENFANT/%s/CONTACT' % i,
291
        })
292
        UPDATE_FAMILY_REQUIRED_FLAGS.append('maj:enfant_%s' % i)
264 293
    UPDATE_FAMILY_SCHEMA = copy.deepcopy(
265 294
        form_maj_famille_dui.request_schema['properties']['PORTAIL']['properties']['DUI'])
266 295
    UPDATE_FAMILY_SCHEMA['properties'].pop('IDDUI')
......
269 298
    UPDATE_FAMILY_SCHEMA['required'].remove('IDDUI')
270 299
    UPDATE_FAMILY_SCHEMA['required'].remove('DATEDEMANDE')
271 300
    UPDATE_FAMILY_SCHEMA['required'].remove('QUIACTUALISEDUI')
301
    for flag in sorted(UPDATE_FAMILY_FLAGS.keys()):
302
        flag_type = {
303
            'oneOf': [
304
                {'type': 'boolean'},
305
                {
306
                    'type': 'string',
307
                    'pattern': '[Oo][Uu][Ii]|[Nn][Oo][Nn]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|1|0',
308
                }
309
            ]
310
        }
311
        if flag not in UPDATE_FAMILY_REQUIRED_FLAGS:
312
            flag_type['oneOf'].append({'type': 'null'})
313
        UPDATE_FAMILY_SCHEMA['properties'][flag] = flag_type
314
        UPDATE_FAMILY_SCHEMA['required'].append(flag)
272 315
    UPDATE_FAMILY_SCHEMA['unflatten'] = True
273 316

  
274 317
    @endpoint(
......
417 460

  
418 461
        raise APIError('Child not found', err_code='not-found')
419 462

  
463
    def sanitize_update_family_data(self, name_id, post_data):
464
        family_data = None
465

  
466
        # transform ENFANT list to dict, where the key is the field IDPERSONNE
467
        # because children in post_date are maybe not in the same order than on Axel side
468
        children = {}
469
        children_by_index = {}
470
        for i, child in enumerate(post_data.get('ENFANT', [])):
471
            # check if IDPERSONNE is filled
472
            if child['IDPERSONNE']:
473
                children[child['IDPERSONNE']] = child
474
                children_by_index[str(i)] = child['IDPERSONNE']
475
        post_data['ENFANT'] = children
476

  
477
        # sanitize post_data
478
        flags = sorted(self.UPDATE_FAMILY_FLAGS.keys())
479
        for flag in flags:
480
            flag_value = post_data.pop(flag)
481
            flag_value = encode_bool(flag_value)
482

  
483
            # no update for the related block
484
            if flag_value != 'NON':
485
                continue
486

  
487
            # build the xml elements to cross
488
            key = self.UPDATE_FAMILY_FLAGS[flag]
489
            # special case for ENFANT flags
490
            if key.startswith('ENFANT/'):
491
                # replace the index by IDPERSONNE value
492
                index = key.split('/')[1]
493
                if index not in children_by_index:
494
                    # no child with IDPERSONNE found in post_data
495
                    continue
496
                key = key.replace('ENFANT/%s' % index, 'ENFANT/%s' % children_by_index[index])
497
            elements = key.split('/')
498

  
499
            schema = self.UPDATE_FAMILY_SCHEMA
500
            data = post_data
501
            # find the structure in schema and data containing the element to remove
502
            not_found = False
503
            for element in elements[:-1]:
504
                if schema.get('type') == 'array':
505
                    schema = schema['items']
506
                else:
507
                    schema = schema['properties'][element]
508
                try:
509
                    data = data[element]
510
                except (IndexError, KeyError):
511
                    not_found = True
512
                    break
513
            if not_found:
514
                continue
515

  
516
            element_to_remove = elements[-1]
517
            if element_to_remove == 'ADRESSE':
518
                # empty all subelements
519
                for k in data[element_to_remove].keys():
520
                    data[element_to_remove][k] = None
521
            elif element_to_remove == 'CONTACT':
522
                # get the correct child
523
                child_data = post_data['ENFANT'][elements[1]]
524
                child_id = child_data['IDPERSONNE']
525
                # and reset the contacts
526
                if family_data is None:
527
                    family_data = self.get_family_data(name_id)
528
                for child in family_data['ENFANT']:
529
                    if child['IDPERSONNE'] == child_id:
530
                        if child.get('CONTACT'):
531
                            child_data['CONTACT'] = child['CONTACT']
532
                            # XXX set LIENPARENTE because if empty the contact is deleted
533
                            for contact in child_data['CONTACT']:
534
                                if not contact['LIENPARENTE']:
535
                                    contact['LIENPARENTE'] = 'BABY'
536
                        elif 'CONTACT' in child_data:
537
                            child_data.pop('CONTACT')
538
                        break
539
            elif element_to_remove in data:
540
                # remove block
541
                data.pop(element_to_remove)
542

  
543
        # transform ENFANT dict to a list back
544
        post_data['ENFANT'] = post_data['ENFANT'].values()
545

  
546
        # if ENFANT block is empty, remove it
547
        if not post_data['ENFANT']:
548
            post_data.pop('ENFANT')
549

  
420 550
    @endpoint(
421 551
        description=_("Update information about user's family"),
422 552
        perm='can_access',
......
432 562
        })
433 563
    def update_family_info(self, request, NameID, post_data):
434 564
        link = self.get_link(NameID)
565

  
566
        # prepare data
435 567
        post_data['IDDUI'] = link.dui
436 568
        post_data['DATEDEMANDE'] = datetime.date.today().strftime('%Y-%m-%d')
437 569
        if 'RL2' in post_data and post_data['RL2'].get('IDPERSONNE') == link.person_id:
438 570
            post_data['QUIACTUALISEDUI'] = '2'
439 571
        else:
440 572
            post_data['QUIACTUALISEDUI'] = '1'
573

  
574
        self.sanitize_update_family_data(name_id=NameID, post_data=post_data)
575

  
441 576
        try:
442 577
            result = form_maj_famille_dui(self, {'PORTAIL': {'DUI': post_data}})
443 578
        except AxelError as e:
tests/data/toulouse_axel/flat_update_family_info.json
16 16
  "ENFANT/0/AUTORISATIONURGENCEMEDICALE": "OUI",
17 17
  "ENFANT/0/CONTACT/0/CHERCHERLENFANT": "OUI",
18 18
  "ENFANT/0/CONTACT/0/ENCASURGENCE": "OUI",
19
  "ENFANT/0/CONTACT/0/LIENPARENTE": "",
19
  "ENFANT/0/CONTACT/0/LIENPARENTE": "VOI",
20 20
  "ENFANT/0/CONTACT/0/NOM": "foo",
21 21
  "ENFANT/0/CONTACT/0/PRENOM": "foo",
22 22
  "ENFANT/0/CONTACT/0/TELFIXE": "0505050505",
23 23
  "ENFANT/0/CONTACT/0/TELPORTABLE": "0606060606",
24 24
  "ENFANT/0/CONTACT/1/CHERCHERLENFANT": "OUI",
25 25
  "ENFANT/0/CONTACT/1/ENCASURGENCE": "OUI",
26
  "ENFANT/0/CONTACT/1/LIENPARENTE": "",
26
  "ENFANT/0/CONTACT/1/LIENPARENTE": "VOI",
27 27
  "ENFANT/0/CONTACT/1/NOM": "foo",
28 28
  "ENFANT/0/CONTACT/1/PRENOM": "foo",
29 29
  "ENFANT/0/CONTACT/1/TELFIXE": "0505050505",
30 30
  "ENFANT/0/CONTACT/1/TELPORTABLE": "0606060606",
31 31
  "ENFANT/0/CONTACT/2/CHERCHERLENFANT": "OUI",
32 32
  "ENFANT/0/CONTACT/2/ENCASURGENCE": "OUI",
33
  "ENFANT/0/CONTACT/2/LIENPARENTE": "",
33
  "ENFANT/0/CONTACT/2/LIENPARENTE": "VOI",
34 34
  "ENFANT/0/CONTACT/2/NOM": "foo",
35 35
  "ENFANT/0/CONTACT/2/PRENOM": "foo",
36 36
  "ENFANT/0/CONTACT/2/TELFIXE": "0505050505",
......
152 152
  "RL2/PRENOM": "foo",
153 153
  "RL2/PROFESSION": "foo",
154 154
  "RL2/TELPORTABLE": "0606060606",
155
  "TELFIXE": ""
155
  "TELFIXE": "",
156
  "maj:adresse": "OUI",
157
  "maj:enfant_0": "OUI",
158
  "maj:enfant_0_assurance": "OUI",
159
  "maj:enfant_0_contact": "OUI",
160
  "maj:enfant_0_sanitaire": "OUI",
161
  "maj:enfant_0_sanitaire_allergie": "OUI",
162
  "maj:enfant_0_sanitaire_medecin": "OUI",
163
  "maj:enfant_0_sanitaire_vaccin": "OUI",
164
  "maj:enfant_1": "OUI",
165
  "maj:enfant_1_assurance": "OUI",
166
  "maj:enfant_1_contact": "OUI",
167
  "maj:enfant_1_sanitaire": "OUI",
168
  "maj:enfant_1_sanitaire_allergie": "OUI",
169
  "maj:enfant_1_sanitaire_medecin": "OUI",
170
  "maj:enfant_1_sanitaire_vaccin": "OUI",
171
  "maj:enfant_2": "OUI",
172
  "maj:enfant_2_assurance": "OUI",
173
  "maj:enfant_2_contact": "OUI",
174
  "maj:enfant_2_sanitaire": "OUI",
175
  "maj:enfant_2_sanitaire_allergie": "OUI",
176
  "maj:enfant_2_sanitaire_medecin": "OUI",
177
  "maj:enfant_2_sanitaire_vaccin": "OUI",
178
  "maj:enfant_3": "OUI",
179
  "maj:enfant_3_assurance": "OUI",
180
  "maj:enfant_3_contact": "OUI",
181
  "maj:enfant_3_sanitaire": "OUI",
182
  "maj:enfant_3_sanitaire_allergie": "OUI",
183
  "maj:enfant_3_sanitaire_medecin": "OUI",
184
  "maj:enfant_3_sanitaire_vaccin": "OUI",
185
  "maj:enfant_4": "OUI",
186
  "maj:enfant_4_assurance": "OUI",
187
  "maj:enfant_4_contact": "OUI",
188
  "maj:enfant_4_sanitaire": "OUI",
189
  "maj:enfant_4_sanitaire_allergie": "OUI",
190
  "maj:enfant_4_sanitaire_medecin": "OUI",
191
  "maj:enfant_4_sanitaire_vaccin": "OUI",
192
  "maj:enfant_5": "OUI",
193
  "maj:enfant_5_assurance": "OUI",
194
  "maj:enfant_5_contact": "OUI",
195
  "maj:enfant_5_sanitaire": "OUI",
196
  "maj:enfant_5_sanitaire_allergie": "OUI",
197
  "maj:enfant_5_sanitaire_medecin": "OUI",
198
  "maj:enfant_5_sanitaire_vaccin": "OUI",
199
  "maj:revenus": "OUI",
200
  "maj:rl1": "OUI",
201
  "maj:rl1_adresse_employeur": "OUI",
202
  "maj:rl2": "OUI",
203
  "maj:rl2_adresse_employeur": "OUI"
156 204
}
tests/data/toulouse_axel/update_family_info.json
24 24
                {
25 25
                    "CHERCHERLENFANT": "OUI",
26 26
                    "ENCASURGENCE": "OUI",
27
                    "LIENPARENTE": null,
27
                    "LIENPARENTE": "VOI",
28 28
                    "NOM": "foo",
29 29
                    "PRENOM": "foo",
30 30
                    "TELFIXE": "0505050505",
......
33 33
                {
34 34
                    "CHERCHERLENFANT": "OUI",
35 35
                    "ENCASURGENCE": "OUI",
36
                    "LIENPARENTE": null,
36
                    "LIENPARENTE": "VOI",
37 37
                    "NOM": "foo",
38 38
                    "PRENOM": "foo",
39 39
                    "TELFIXE": "0505050505",
......
42 42
                {
43 43
                    "CHERCHERLENFANT": "OUI",
44 44
                    "ENCASURGENCE": "OUI",
45
                    "LIENPARENTE": null,
45
                    "LIENPARENTE": "VOI",
46 46
                    "NOM": "foo",
47 47
                    "PRENOM": "foo",
48 48
                    "TELFIXE": "0505050505",
......
210 210
        "PROFESSION": "foo",
211 211
        "TELPORTABLE": "0606060606"
212 212
    },
213
    "TELFIXE": null
213
    "TELFIXE": null,
214
    "maj:adresse": "OUI",
215
    "maj:enfant_0": "OUI",
216
    "maj:enfant_0_assurance": "OUI",
217
    "maj:enfant_0_contact": "OUI",
218
    "maj:enfant_0_sanitaire": "OUI",
219
    "maj:enfant_0_sanitaire_allergie": "OUI",
220
    "maj:enfant_0_sanitaire_medecin": "OUI",
221
    "maj:enfant_0_sanitaire_vaccin": "OUI",
222
    "maj:enfant_1": "OUI",
223
    "maj:enfant_1_assurance": "OUI",
224
    "maj:enfant_1_contact": "OUI",
225
    "maj:enfant_1_sanitaire": "OUI",
226
    "maj:enfant_1_sanitaire_allergie": "OUI",
227
    "maj:enfant_1_sanitaire_medecin": "OUI",
228
    "maj:enfant_1_sanitaire_vaccin": "OUI",
229
    "maj:enfant_2": "OUI",
230
    "maj:enfant_2_assurance": "OUI",
231
    "maj:enfant_2_contact": "OUI",
232
    "maj:enfant_2_sanitaire": "OUI",
233
    "maj:enfant_2_sanitaire_allergie": "OUI",
234
    "maj:enfant_2_sanitaire_medecin": "OUI",
235
    "maj:enfant_2_sanitaire_vaccin": "OUI",
236
    "maj:enfant_3": "OUI",
237
    "maj:enfant_3_assurance": "OUI",
238
    "maj:enfant_3_contact": "OUI",
239
    "maj:enfant_3_sanitaire": "OUI",
240
    "maj:enfant_3_sanitaire_allergie": "OUI",
241
    "maj:enfant_3_sanitaire_medecin": "OUI",
242
    "maj:enfant_3_sanitaire_vaccin": "OUI",
243
    "maj:enfant_4": "OUI",
244
    "maj:enfant_4_assurance": "OUI",
245
    "maj:enfant_4_contact": "OUI",
246
    "maj:enfant_4_sanitaire": "OUI",
247
    "maj:enfant_4_sanitaire_allergie": "OUI",
248
    "maj:enfant_4_sanitaire_medecin": "OUI",
249
    "maj:enfant_4_sanitaire_vaccin": "OUI",
250
    "maj:enfant_5": "OUI",
251
    "maj:enfant_5_assurance": "OUI",
252
    "maj:enfant_5_contact": "OUI",
253
    "maj:enfant_5_sanitaire": "OUI",
254
    "maj:enfant_5_sanitaire_allergie": "OUI",
255
    "maj:enfant_5_sanitaire_medecin": "OUI",
256
    "maj:enfant_5_sanitaire_vaccin": "OUI",
257
    "maj:revenus": "OUI",
258
    "maj:rl1": "OUI",
259
    "maj:rl1_adresse_employeur": "OUI",
260
    "maj:rl2": "OUI",
261
    "maj:rl2_adresse_employeur": "OUI"
214 262
}
tests/test_toulouse_axel.py
15 15
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16

  
17 17
from contextlib import contextmanager
18
import copy
18 19
import datetime
19 20
import json
20 21
import mock
......
35 36
    ref_facture_pdf,
36 37
    ref_verif_dui,
37 38
)
39
from passerelle.utils.jsonresponse import APIError
38 40
import utils
39 41

  
40 42

  
......
620 622
    assert 'xml_response' in resp.json['data']
621 623

  
622 624

  
625
def test_sanitize_update_family_data_adresse(app, resource, update_params):
626
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
627

  
628
    # test maj:adresse
629
    partial_update_params = copy.deepcopy(update_params)
630
    partial_update_params['maj:adresse'] = False
631
    for key in partial_update_params['ADRESSE'].keys():
632
        partial_update_params['ADRESSE'][key] = None  # reset fields
633
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
634
    for value in partial_update_params['ADRESSE'].values():
635
        assert value is None
636

  
637

  
638
def test_sanitize_update_family_data_revenus(app, resource, update_params):
639
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
640

  
641
    # test maj:revenus
642
    partial_update_params = copy.deepcopy(update_params)
643
    partial_update_params['maj:revenus'] = False
644
    for key in partial_update_params['REVENUS'].keys():
645
        partial_update_params['REVENUS'][key] = None  # reset fields
646
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
647
    assert 'REVENUS' not in partial_update_params
648

  
649

  
650
def test_sanitize_update_family_data_rln(app, resource, update_params):
651
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
652

  
653
    # test maj:rln
654
    partial_update_params = copy.deepcopy(update_params)
655
    partial_update_params['maj:rl1'] = False
656
    for key in partial_update_params['RL1'].keys():
657
        partial_update_params['RL1'][key] = None  # reset fields
658
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
659
    assert 'RL1' not in partial_update_params
660
    partial_update_params = copy.deepcopy(update_params)
661
    partial_update_params['maj:rl2'] = False
662
    for key in partial_update_params['RL2'].keys():
663
        partial_update_params['RL2'][key] = None  # reset fields
664
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
665
    assert 'RL2' not in partial_update_params
666

  
667

  
668
def test_sanitize_update_family_data_rln_adresse_employeur(app, resource, update_params):
669
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
670

  
671
    # test maj:rln_adresse_employeur
672
    partial_update_params = copy.deepcopy(update_params)
673
    partial_update_params['maj:rl1_adresse_employeur'] = False
674
    for key in partial_update_params['RL1']['ADREMPLOYEUR'].keys():
675
        partial_update_params['RL1']['ADREMPLOYEUR'][key] = None  # reset fields
676
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
677
    assert 'ADREMPLOYEUR' not in partial_update_params['RL1']
678
    partial_update_params = copy.deepcopy(update_params)
679
    partial_update_params['maj:rl2_adresse_employeur'] = False
680
    for key in partial_update_params['RL2']['ADREMPLOYEUR'].keys():
681
        partial_update_params['RL2']['ADREMPLOYEUR'][key] = None  # reset fields
682
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
683
    assert 'ADREMPLOYEUR' not in partial_update_params['RL2']
684
    # combine with maj:rln
685
    partial_update_params = copy.deepcopy(update_params)
686
    partial_update_params['maj:rl1'] = False
687
    partial_update_params['maj:rl1_adresse_employeur'] = False
688
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
689
    assert 'RL1' not in partial_update_params
690
    partial_update_params = copy.deepcopy(update_params)
691
    partial_update_params['maj:rl2'] = False
692
    partial_update_params['maj:rl2_adresse_employeur'] = False
693
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
694
    assert 'RL2' not in partial_update_params
695

  
696
    # test maj:rln_adresse_employeur not set
697
    partial_update_params = copy.deepcopy(update_params)
698
    partial_update_params['maj:rl1_adresse_employeur'] = None
699
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
700
    assert 'ADREMPLOYEUR' in partial_update_params['RL1']
701
    partial_update_params = copy.deepcopy(update_params)
702
    partial_update_params['maj:rl2_adresse_employeur'] = None
703
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
704
    assert 'ADREMPLOYEUR' in partial_update_params['RL2']
705

  
706

  
707
def test_sanitize_update_family_data_enfant_n(app, resource, update_params):
708
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
709

  
710
    # test maj:enfant_n
711
    partial_update_params = copy.deepcopy(update_params)
712
    partial_update_params['maj:enfant_0'] = False
713
    for key in partial_update_params['ENFANT'][0].keys():
714
        if key == 'IDPERSONNE':
715
            continue
716
        partial_update_params['ENFANT'][0][key] = None  # reset fields
717
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
718
    assert len(partial_update_params['ENFANT']) == 1
719
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
720

  
721
    partial_update_params = copy.deepcopy(update_params)
722
    partial_update_params['maj:enfant_1'] = False
723
    for key in partial_update_params['ENFANT'][1].keys():
724
        if key == 'IDPERSONNE':
725
            continue
726
        partial_update_params['ENFANT'][1][key] = None  # reset fields
727
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
728
    assert len(partial_update_params['ENFANT']) == 1
729
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
730

  
731
    # do not fill IDPERSONNE for the removed child
732
    partial_update_params = copy.deepcopy(update_params)
733
    partial_update_params['maj:enfant_1'] = False
734
    for key in partial_update_params['ENFANT'][1].keys():
735
        partial_update_params['ENFANT'][1][key] = None  # reset fields
736
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
737
    assert len(partial_update_params['ENFANT']) == 1
738
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
739

  
740
    # remove all children
741
    partial_update_params = copy.deepcopy(update_params)
742
    partial_update_params['maj:enfant_0'] = False
743
    partial_update_params['maj:enfant_1'] = False
744
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
745
    assert 'ENFANT' not in partial_update_params
746

  
747
    # unknown child
748
    partial_update_params = copy.deepcopy(update_params)
749
    partial_update_params['maj:enfant_5'] = False
750
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
751
    assert len(partial_update_params['ENFANT']) == 2
752

  
753

  
754
def test_sanitize_update_family_data_enfant_n_assurance(app, resource, update_params):
755
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
756

  
757
    # test maj:enfant_n_assurance
758
    partial_update_params = copy.deepcopy(update_params)
759
    partial_update_params['maj:enfant_1_assurance'] = False
760
    for key in partial_update_params['ENFANT'][1]['ASSURANCE'].keys():
761
        partial_update_params['ENFANT'][1]['ASSURANCE'][key] = None  # reset fields
762
    partial_update_params['maj:enfant_0'] = False  # check that ordering is not a problem
763
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
764
    assert len(partial_update_params['ENFANT']) == 1
765
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
766
    assert 'ASSURANCE' not in partial_update_params['ENFANT'][0]
767
    # combine with maj:enfant_n
768
    partial_update_params = copy.deepcopy(update_params)
769
    partial_update_params['maj:enfant_1'] = False
770
    partial_update_params['maj:enfant_1_assurance'] = False
771
    partial_update_params['maj:enfant_0'] = False
772
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
773
    assert 'ENFANT' not in partial_update_params
774

  
775
    # test maj:enfant_n_assurance not set
776
    partial_update_params = copy.deepcopy(update_params)
777
    partial_update_params['maj:enfant_1_assurance'] = None
778
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
779
    assert 'ASSURANCE' in partial_update_params['ENFANT'][0]
780

  
781

  
782
def test_sanitize_update_family_data_enfant_n_contact(app, resource, update_params):
783
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
784

  
785
    # test maj:enfant_n_contact
786
    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
787
    with open(filepath) as xml:
788
        content = xml.read()
789
    partial_update_params = copy.deepcopy(update_params)
790
    partial_update_params['maj:enfant_0_contact'] = False
791
    for i, contact in enumerate(partial_update_params['ENFANT'][0]['CONTACT']):
792
        for key in contact.keys():
793
            partial_update_params['ENFANT'][0]['CONTACT'][i][key] = None  # reset fields
794
    partial_update_params['maj:enfant_1'] = False
795
    with mock_getdata(content, 'RefFamilleDui'):
796
        resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
797
        original_contacts = resource.get_family_data(name_id='yyy')['ENFANT'][0]['CONTACT']
798
    assert len(partial_update_params['ENFANT']) == 1
799
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
800
    # CONTACT was set with origin values found in Axel
801
    for i, contact in enumerate(partial_update_params['ENFANT'][0]['CONTACT']):
802
        for key, value in contact.items():
803
            if key == 'LIENPARENTE':
804
                assert original_contacts[i][key] is None
805
                assert 'BABY' == value  # XXX this is a hack
806
                continue
807
            assert original_contacts[i][key] == value
808
    # combine with maj:enfant_n
809
    partial_update_params = copy.deepcopy(update_params)
810
    partial_update_params['maj:enfant_1'] = False
811
    partial_update_params['maj:enfant_1_contact'] = False
812
    partial_update_params['maj:enfant_0'] = False
813
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
814
    assert 'ENFANT' not in partial_update_params
815

  
816
    # test maj:enfant_n_contact not set
817
    partial_update_params = copy.deepcopy(update_params)
818
    partial_update_params['maj:enfant_0_contact'] = None
819
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
820
        resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
821
    assert operation.call_args_list == []
822

  
823

  
824
def test_sanitize_update_family_data_enfant_n_sanitaire(app, resource, update_params):
825
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
826

  
827
    # test maj:enfant_n_sanitaire
828
    partial_update_params = copy.deepcopy(update_params)
829
    partial_update_params['maj:enfant_1_sanitaire'] = False
830
    for key in partial_update_params['ENFANT'][1]['SANITAIRE'].keys():
831
        partial_update_params['ENFANT'][1]['SANITAIRE'][key] = None  # reset fields
832
    partial_update_params['maj:enfant_0'] = False
833
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
834
    assert len(partial_update_params['ENFANT']) == 1
835
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
836
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
837
    # combine with maj:enfant_n
838
    partial_update_params = copy.deepcopy(update_params)
839
    partial_update_params['maj:enfant_1'] = False
840
    partial_update_params['maj:enfant_1_sanitaire'] = False
841
    partial_update_params['maj:enfant_0'] = False
842
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
843
    assert 'ENFANT' not in partial_update_params
844

  
845
    # test maj:enfant_n_sanitaire not set
846
    partial_update_params = copy.deepcopy(update_params)
847
    partial_update_params['maj:enfant_0_sanitaire'] = None
848
    partial_update_params['maj:enfant_1_sanitaire'] = None
849
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
850
    assert 'SANITAIRE' in partial_update_params['ENFANT'][0]
851
    assert 'SANITAIRE' in partial_update_params['ENFANT'][1]
852

  
853

  
854
def test_sanitize_update_family_data_enfant_n_sanitaire_allergie(app, resource, update_params):
855
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
856

  
857
    # test maj:enfant_n_sanitaire_allergie
858
    partial_update_params = copy.deepcopy(update_params)
859
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
860
    for i, allergie in enumerate(partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']):
861
        for key in allergie.keys():
862
            partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'][i][key] = None  # reset fields
863
    partial_update_params['maj:enfant_0'] = False
864
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
865
    assert len(partial_update_params['ENFANT']) == 1
866
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
867
    assert 'ALLERGIE' not in partial_update_params['ENFANT'][0]['SANITAIRE']
868
    # combine with maj:enfant_n_sanitaire
869
    partial_update_params = copy.deepcopy(update_params)
870
    partial_update_params['maj:enfant_1_sanitaire'] = False
871
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
872
    partial_update_params['maj:enfant_0'] = False
873
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
874
    assert len(partial_update_params['ENFANT']) == 1
875
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
876
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
877
    # combine with maj:enfant_n
878
    partial_update_params = copy.deepcopy(update_params)
879
    partial_update_params['maj:enfant_1'] = False
880
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
881
    partial_update_params['maj:enfant_0'] = False
882
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
883
    assert 'ENFANT' not in partial_update_params
884

  
885
    # test maj:enfant_n_sanitaire_allergie not set
886
    partial_update_params = copy.deepcopy(update_params)
887
    partial_update_params['maj:enfant_0_sanitaire_allergie'] = None
888
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = None
889
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
890
    assert 'ALLERGIE' in partial_update_params['ENFANT'][0]['SANITAIRE']
891
    assert 'ALLERGIE' in partial_update_params['ENFANT'][1]['SANITAIRE']
892

  
893

  
894
def test_sanitize_update_family_data_enfant_n_sanitaire_medecin(app, resource, update_params):
895
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
896

  
897
    # test maj:enfant_n_sanitaire_medecin
898
    partial_update_params = copy.deepcopy(update_params)
899
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
900
    for key in partial_update_params['ENFANT'][1]['SANITAIRE']['MEDECIN'].keys():
901
        partial_update_params['ENFANT'][1]['SANITAIRE']['MEDECIN'][key] = None  # reset fields
902
    partial_update_params['maj:enfant_0'] = False
903
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
904
    assert len(partial_update_params['ENFANT']) == 1
905
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
906
    assert 'MEDECIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
907
    # combine with maj:enfant_n_sanitaire
908
    partial_update_params = copy.deepcopy(update_params)
909
    partial_update_params['maj:enfant_1_sanitaire'] = False
910
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
911
    partial_update_params['maj:enfant_0'] = False
912
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
913
    assert len(partial_update_params['ENFANT']) == 1
914
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
915
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
916
    # combine with maj:enfant_n
917
    partial_update_params = copy.deepcopy(update_params)
918
    partial_update_params['maj:enfant_1'] = False
919
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
920
    partial_update_params['maj:enfant_0'] = False
921
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
922
    assert 'ENFANT' not in partial_update_params
923

  
924
    # test maj:enfant_n_sanitaire_medecin not set
925
    partial_update_params = copy.deepcopy(update_params)
926
    partial_update_params['maj:enfant_0_sanitaire_medecin'] = None
927
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = None
928
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
929
    assert 'MEDECIN' in partial_update_params['ENFANT'][0]['SANITAIRE']
930
    assert 'MEDECIN' in partial_update_params['ENFANT'][1]['SANITAIRE']
931

  
932

  
933
def test_sanitize_update_family_data_enfant_n_sanitaire_vaccin(app, resource, update_params):
934
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
935

  
936
    # test maj:enfant_n_sanitaire_vaccin
937
    partial_update_params = copy.deepcopy(update_params)
938
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
939
    for key in partial_update_params['ENFANT'][1]['SANITAIRE']['VACCIN'].keys():
940
        partial_update_params['ENFANT'][1]['SANITAIRE']['VACCIN'][key] = None  # reset fields
941
    partial_update_params['maj:enfant_0'] = False
942
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
943
    assert len(partial_update_params['ENFANT']) == 1
944
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
945
    assert 'VACCIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
946
    # combine with maj:enfant_n_sanitaire
947
    partial_update_params = copy.deepcopy(update_params)
948
    partial_update_params['maj:enfant_1_sanitaire'] = False
949
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
950
    partial_update_params['maj:enfant_0'] = False
951
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
952
    assert len(partial_update_params['ENFANT']) == 1
953
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
954
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
955
    # combine with maj:enfant_n
956
    partial_update_params = copy.deepcopy(update_params)
957
    partial_update_params['maj:enfant_1'] = False
958
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
959
    partial_update_params['maj:enfant_0'] = False
960
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
961
    assert 'ENFANT' not in partial_update_params
962

  
963
    # test maj:enfant_n_sanitaire_vaccin not set
964
    partial_update_params = copy.deepcopy(update_params)
965
    partial_update_params['maj:enfant_0_sanitaire_vaccin'] = None
966
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = None
967
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
968
    assert 'VACCIN' in partial_update_params['ENFANT'][0]['SANITAIRE']
969
    assert 'VACCIN' in partial_update_params['ENFANT'][1]['SANITAIRE']
970

  
971

  
972
def test_sanitize_update_family_data_axel_error(app, resource, update_params):
973
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
974
    partial_update_params = copy.deepcopy(update_params)
975
    partial_update_params['maj:enfant_0_contact'] = False
976
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
977
        operation.side_effect = AxelError('FooBar')
978
        with pytest.raises(APIError, match='Axel error: FooBar'):
979
            resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
980

  
981

  
982
def test_update_family_info_endpoint_sanitize_axel_error(app, resource, update_params):
983
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
984
    with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.sanitize_update_family_data') as sanitize:
985
        sanitize.side_effect = APIError('Axel error: FooBar')
986
        resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
987
        assert resp.json['err_desc'] == "Axel error: FooBar"
988

  
989

  
623 990
def test_invoices_endpoint_axel_error(app, resource):
624 991
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
625 992
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_facture_a_payer') as operation:
626
-