Projet

Général

Profil

0001-toulouse_axel-partial-update-38543.patch

Lauréline Guérin, 19 décembre 2019 11:54

Télécharger (37,2 ko)

Voir les différences:

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

 functests/toulouse_axel/test_toulouse_axel.py |  20 +-
 passerelle/contrib/toulouse_axel/models.py    | 144 ++++++-
 .../flat_update_family_info.json              |  56 ++-
 .../toulouse_axel/update_family_info.json     |  56 ++-
 tests/test_toulouse_axel.py                   | 367 ++++++++++++++++++
 5 files changed, 629 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
40 40
BASE_XSD_PATH = os.path.join(os.path.dirname(__file__), 'xsd')
41 41

  
42 42

  
43
def encode_bool(obj):
44
    if obj is True or str(obj).lower() in ['true', 'oui', '1']:
45
        return 'OUI'
46
    if obj is False or str(obj).lower() in ['false', 'non', '0']:
47
        return 'NON'
48
    return obj
49

  
50

  
43 51
class AxelSchema(JSONSchemaFromXMLSchema):
44 52
    type_map = {
45 53
        '{urn:AllAxelTypes}DATEREQUIREDType': 'date',
......
88 96
        }
89 97

  
90 98
    def encode_bool(self, obj):
91
        if obj is True or str(obj).lower() in ['true', 'oui', '1']:
92
            return 'OUI'
93
        if obj is False or str(obj).lower() in ['false', 'non', '0']:
94
            return 'NON'
95
        return obj
99
        return encode_bool(obj)
96 100

  
97 101
    def decode_bool(self, data):
98 102
        value = False
......
195 199
    LINK_SCHEMA['properties'].pop('IDPERSONNE')
196 200
    LINK_SCHEMA['required'].remove('IDPERSONNE')
197 201

  
202
    UPDATE_FAMILY_FLAGS = {
203
        'maj:adresse': 'ADRESSE',
204
        'maj:rl1': 'RL1',
205
        'maj:rl1_adresse_employeur': 'RL1/ADREMPLOYEUR',
206
        'maj:rl2': 'RL2',
207
        'maj:rl2_adresse_employeur': 'RL2/ADREMPLOYEUR',
208
        'maj:revenus': 'REVENUS',
209
    }
210
    UPDATE_FAMILY_REQUIRED_FLAGS = [
211
        'maj:adresse',
212
        'maj:rl1',
213
        'maj:rl2',
214
        'maj:revenus',
215
    ]
216
    for i in range(0, 6):
217
        UPDATE_FAMILY_FLAGS.update({
218
            'maj:enfant_%s' % i: 'ENFANT/%s' % i,
219
            'maj:enfant_%s_sanitaire' % i: 'ENFANT/%s/SANITAIRE' % i,
220
            'maj:enfant_%s_sanitaire_medecin' % i: 'ENFANT/%s/SANITAIRE/MEDECIN' % i,
221
            'maj:enfant_%s_sanitaire_vaccin' % i: 'ENFANT/%s/SANITAIRE/VACCIN' % i,
222
            'maj:enfant_%s_sanitaire_allergie' % i: 'ENFANT/%s/SANITAIRE/ALLERGIE' % i,
223
            'maj:enfant_%s_assurance' % i: 'ENFANT/%s/ASSURANCE' % i,
224
            'maj:enfant_%s_contact' % i: 'ENFANT/%s/CONTACT' % i,
225
        })
226
        UPDATE_FAMILY_REQUIRED_FLAGS.append('maj:enfant_%s' % i)
198 227
    UPDATE_FAMILY_SCHEMA = copy.deepcopy(
199 228
        form_maj_famille_dui.request_schema['properties']['PORTAIL']['properties']['DUI'])
200 229
    UPDATE_FAMILY_SCHEMA['properties'].pop('IDDUI')
......
203 232
    UPDATE_FAMILY_SCHEMA['required'].remove('IDDUI')
204 233
    UPDATE_FAMILY_SCHEMA['required'].remove('DATEDEMANDE')
205 234
    UPDATE_FAMILY_SCHEMA['required'].remove('QUIACTUALISEDUI')
235
    for flag in sorted(UPDATE_FAMILY_FLAGS.keys()):
236
        flag_type = {
237
            'oneOf': [
238
                {'type': 'boolean'},
239
                {
240
                    'type': 'string',
241
                    'pattern': '[Oo][Uu][Ii]|[Nn][Oo][Nn]|[Tt][Rr][Uu][Ee]|[Ff][Aa][Ll][Ss][Ee]|1|0',
242
                }
243
            ]
244
        }
245
        if flag not in UPDATE_FAMILY_REQUIRED_FLAGS:
246
            flag_type['oneOf'].append({'type': 'null'})
247
        UPDATE_FAMILY_SCHEMA['properties'][flag] = flag_type
248
        UPDATE_FAMILY_SCHEMA['required'].append(flag)
206 249
    UPDATE_FAMILY_SCHEMA['unflatten'] = True
207 250

  
208 251
    @endpoint(
......
335 378

  
336 379
        raise APIError('Child not found', err='not-found')
337 380

  
381
    def sanitize_update_family_data(self, name_id, post_data):
382
        family_data = None
383

  
384
        # transform ENFANT list to dict, where the key is the field IDPERSONNE
385
        # because children in post_date are maybe not in the same order than on Axel side
386
        children = {}
387
        children_by_index = {}
388
        for i, child in enumerate(post_data.get('ENFANT', [])):
389
            # check if IDPERSONNE is filled
390
            if child['IDPERSONNE']:
391
                children[child['IDPERSONNE']] = child
392
                children_by_index[str(i)] = child['IDPERSONNE']
393
        post_data['ENFANT'] = children
394

  
395
        # sanitize post_data
396
        flags = sorted(self.UPDATE_FAMILY_FLAGS.keys())
397
        for flag in flags:
398
            flag_value = post_data.pop(flag)
399
            flag_value = encode_bool(flag_value)
400

  
401
            # no update for the related block
402
            if flag_value != 'NON':
403
                continue
404

  
405
            # build the xml elements to cross
406
            key = self.UPDATE_FAMILY_FLAGS[flag]
407
            # special case for ENFANT flags
408
            if key.startswith('ENFANT/'):
409
                # replace the index by IDPERSONNE value
410
                index = key.split('/')[1]
411
                if index not in children_by_index:
412
                    # no child with IDPERSONNE found in post_data
413
                    continue
414
                key = key.replace('ENFANT/%s' % index, 'ENFANT/%s' % children_by_index[index])
415
            elements = key.split('/')
416

  
417
            schema = self.UPDATE_FAMILY_SCHEMA
418
            data = post_data
419
            # find the structure in schema and data containing the element to remove
420
            not_found = False
421
            for element in elements[:-1]:
422
                if schema.get('type') == 'array':
423
                    schema = schema['items']
424
                else:
425
                    schema = schema['properties'][element]
426
                try:
427
                    data = data[element]
428
                except (IndexError, KeyError):
429
                    not_found = True
430
                    break
431
            if not_found:
432
                continue
433

  
434
            element_to_remove = elements[-1]
435
            if element_to_remove == 'ADRESSE':
436
                # empty all subelements
437
                for k in data[element_to_remove].keys():
438
                    data[element_to_remove][k] = None
439
            elif element_to_remove == 'CONTACT':
440
                # get the correct child
441
                child_data = post_data['ENFANT'][elements[1]]
442
                child_id = child_data['IDPERSONNE']
443
                # and reset the contacts
444
                if family_data is None:
445
                    family_data = self.get_family_data(name_id)
446
                for child in family_data['ENFANT']:
447
                    if child['IDPERSONNE'] == child_id:
448
                        if child.get('CONTACT'):
449
                            child_data['CONTACT'] = child['CONTACT']
450
                            # XXX set LIENPARENTE because if empty the contact is deleted
451
                            for contact in child_data['CONTACT']:
452
                                if not contact['LIENPARENTE']:
453
                                    contact['LIENPARENTE'] = 'BABY'
454
                        elif 'CONTACT' in child_data:
455
                            child_data.pop('CONTACT')
456
                        break
457
            elif element_to_remove in data:
458
                # remove block
459
                data.pop(element_to_remove)
460

  
461
        # transform ENFANT dict to a list back
462
        post_data['ENFANT'] = post_data['ENFANT'].values()
463

  
464
        # if ENFANT block is empty, remove it
465
        if not post_data['ENFANT']:
466
            post_data.pop('ENFANT')
467

  
338 468
    @endpoint(
339 469
        description=_("Update information about user's family"),
340 470
        perm='can_access',
......
354 484
        except Link.DoesNotExist:
355 485
            raise APIError('Person not found', err='not-found')
356 486

  
487
        # prepare data
357 488
        post_data['IDDUI'] = link.dui
358 489
        post_data['DATEDEMANDE'] = datetime.date.today().strftime('%Y-%m-%d')
359 490
        if 'RL2' in post_data and post_data['RL2'].get('IDPERSONNE') == link.person_id:
360 491
            post_data['QUIACTUALISEDUI'] = '2'
361 492
        else:
362 493
            post_data['QUIACTUALISEDUI'] = '1'
494

  
495
        self.sanitize_update_family_data(name_id=NameID, post_data=post_data)
496

  
363 497
        try:
364 498
            form_maj_famille_dui(self, {'PORTAIL': {'DUI': post_data}})
365 499
        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
......
33 34
    ref_facture_pdf,
34 35
    ref_verif_dui,
35 36
)
37
from passerelle.utils.jsonresponse import APIError
36 38
import utils
37 39

  
38 40

  
......
516 518
    assert 'post_data' in resp.json
517 519

  
518 520

  
521
def test_sanitize_update_family_data_adresse(app, resource, update_params):
522
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
523

  
524
    # test maj:adresse
525
    partial_update_params = copy.deepcopy(update_params)
526
    partial_update_params['maj:adresse'] = False
527
    for key in partial_update_params['ADRESSE'].keys():
528
        partial_update_params['ADRESSE'][key] = None  # reset fields
529
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
530
    for value in partial_update_params['ADRESSE'].values():
531
        assert value is None
532

  
533

  
534
def test_sanitize_update_family_data_revenus(app, resource, update_params):
535
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
536

  
537
    # test maj:revenus
538
    partial_update_params = copy.deepcopy(update_params)
539
    partial_update_params['maj:revenus'] = False
540
    for key in partial_update_params['REVENUS'].keys():
541
        partial_update_params['REVENUS'][key] = None  # reset fields
542
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
543
    assert 'REVENUS' not in partial_update_params
544

  
545

  
546
def test_sanitize_update_family_data_rln(app, resource, update_params):
547
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
548

  
549
    # test maj:rln
550
    partial_update_params = copy.deepcopy(update_params)
551
    partial_update_params['maj:rl1'] = False
552
    for key in partial_update_params['RL1'].keys():
553
        partial_update_params['RL1'][key] = None  # reset fields
554
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
555
    assert 'RL1' not in partial_update_params
556
    partial_update_params = copy.deepcopy(update_params)
557
    partial_update_params['maj:rl2'] = False
558
    for key in partial_update_params['RL2'].keys():
559
        partial_update_params['RL2'][key] = None  # reset fields
560
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
561
    assert 'RL2' not in partial_update_params
562

  
563

  
564
def test_sanitize_update_family_data_rln_adresse_employeur(app, resource, update_params):
565
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
566

  
567
    # test maj:rln_adresse_employeur
568
    partial_update_params = copy.deepcopy(update_params)
569
    partial_update_params['maj:rl1_adresse_employeur'] = False
570
    for key in partial_update_params['RL1']['ADREMPLOYEUR'].keys():
571
        partial_update_params['RL1']['ADREMPLOYEUR'][key] = None  # reset fields
572
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
573
    assert 'ADREMPLOYEUR' not in partial_update_params['RL1']
574
    partial_update_params = copy.deepcopy(update_params)
575
    partial_update_params['maj:rl2_adresse_employeur'] = False
576
    for key in partial_update_params['RL2']['ADREMPLOYEUR'].keys():
577
        partial_update_params['RL2']['ADREMPLOYEUR'][key] = None  # reset fields
578
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
579
    assert 'ADREMPLOYEUR' not in partial_update_params['RL2']
580
    # combine with maj:rln
581
    partial_update_params = copy.deepcopy(update_params)
582
    partial_update_params['maj:rl1'] = False
583
    partial_update_params['maj:rl1_adresse_employeur'] = False
584
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
585
    assert 'RL1' not in partial_update_params
586
    partial_update_params = copy.deepcopy(update_params)
587
    partial_update_params['maj:rl2'] = False
588
    partial_update_params['maj:rl2_adresse_employeur'] = False
589
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
590
    assert 'RL2' not in partial_update_params
591

  
592
    # test maj:rln_adresse_employeur not set
593
    partial_update_params = copy.deepcopy(update_params)
594
    partial_update_params['maj:rl1_adresse_employeur'] = None
595
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
596
    assert 'ADREMPLOYEUR' in partial_update_params['RL1']
597
    partial_update_params = copy.deepcopy(update_params)
598
    partial_update_params['maj:rl2_adresse_employeur'] = None
599
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
600
    assert 'ADREMPLOYEUR' in partial_update_params['RL2']
601

  
602

  
603
def test_sanitize_update_family_data_enfant_n(app, resource, update_params):
604
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
605

  
606
    # test maj:enfant_n
607
    partial_update_params = copy.deepcopy(update_params)
608
    partial_update_params['maj:enfant_0'] = False
609
    for key in partial_update_params['ENFANT'][0].keys():
610
        if key == 'IDPERSONNE':
611
            continue
612
        partial_update_params['ENFANT'][0][key] = None  # reset fields
613
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
614
    assert len(partial_update_params['ENFANT']) == 1
615
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
616

  
617
    partial_update_params = copy.deepcopy(update_params)
618
    partial_update_params['maj:enfant_1'] = False
619
    for key in partial_update_params['ENFANT'][1].keys():
620
        if key == 'IDPERSONNE':
621
            continue
622
        partial_update_params['ENFANT'][1][key] = None  # reset fields
623
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
624
    assert len(partial_update_params['ENFANT']) == 1
625
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
626

  
627
    # do not fill IDPERSONNE for the removed child
628
    partial_update_params = copy.deepcopy(update_params)
629
    partial_update_params['maj:enfant_1'] = False
630
    for key in partial_update_params['ENFANT'][1].keys():
631
        partial_update_params['ENFANT'][1][key] = None  # reset fields
632
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
633
    assert len(partial_update_params['ENFANT']) == 1
634
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
635

  
636
    # remove all children
637
    partial_update_params = copy.deepcopy(update_params)
638
    partial_update_params['maj:enfant_0'] = False
639
    partial_update_params['maj:enfant_1'] = False
640
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
641
    assert 'ENFANT' not in partial_update_params
642

  
643
    # unknown child
644
    partial_update_params = copy.deepcopy(update_params)
645
    partial_update_params['maj:enfant_5'] = False
646
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
647
    assert len(partial_update_params['ENFANT']) == 2
648

  
649

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

  
653
    # test maj:enfant_n_assurance
654
    partial_update_params = copy.deepcopy(update_params)
655
    partial_update_params['maj:enfant_1_assurance'] = False
656
    for key in partial_update_params['ENFANT'][1]['ASSURANCE'].keys():
657
        partial_update_params['ENFANT'][1]['ASSURANCE'][key] = None  # reset fields
658
    partial_update_params['maj:enfant_0'] = False  # check that ordering is not a problem
659
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
660
    assert len(partial_update_params['ENFANT']) == 1
661
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
662
    assert 'ASSURANCE' not in partial_update_params['ENFANT'][0]
663
    # combine with maj:enfant_n
664
    partial_update_params = copy.deepcopy(update_params)
665
    partial_update_params['maj:enfant_1'] = False
666
    partial_update_params['maj:enfant_1_assurance'] = False
667
    partial_update_params['maj:enfant_0'] = False
668
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
669
    assert 'ENFANT' not in partial_update_params
670

  
671
    # test maj:enfant_n_assurance not set
672
    partial_update_params = copy.deepcopy(update_params)
673
    partial_update_params['maj:enfant_1_assurance'] = None
674
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
675
    assert 'ASSURANCE' in partial_update_params['ENFANT'][0]
676

  
677

  
678
def test_sanitize_update_family_data_enfant_n_contact(app, resource, update_params):
679
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
680

  
681
    # test maj:enfant_n_contact
682
    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/family_info.xml')
683
    with open(filepath) as xml:
684
        content = xml.read()
685
    partial_update_params = copy.deepcopy(update_params)
686
    partial_update_params['maj:enfant_0_contact'] = False
687
    for i, contact in enumerate(partial_update_params['ENFANT'][0]['CONTACT']):
688
        for key in contact.keys():
689
            partial_update_params['ENFANT'][0]['CONTACT'][i][key] = None  # reset fields
690
    partial_update_params['maj:enfant_1'] = False
691
    with mock_getdata(content, 'RefFamilleDui'):
692
        resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
693
        original_contacts = resource.get_family_data(name_id='yyy')['ENFANT'][0]['CONTACT']
694
    assert len(partial_update_params['ENFANT']) == 1
695
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "4242"
696
    # CONTACT was set with origin values found in Axel
697
    for i, contact in enumerate(partial_update_params['ENFANT'][0]['CONTACT']):
698
        for key, value in contact.items():
699
            if key == 'LIENPARENTE':
700
                assert original_contacts[i][key] is None
701
                assert 'BABY' == value  # XXX this is a hack
702
                continue
703
            assert original_contacts[i][key] == value
704
    # combine with maj:enfant_n
705
    partial_update_params = copy.deepcopy(update_params)
706
    partial_update_params['maj:enfant_1'] = False
707
    partial_update_params['maj:enfant_1_contact'] = False
708
    partial_update_params['maj:enfant_0'] = False
709
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
710
    assert 'ENFANT' not in partial_update_params
711

  
712
    # test maj:enfant_n_contact not set
713
    partial_update_params = copy.deepcopy(update_params)
714
    partial_update_params['maj:enfant_0_contact'] = None
715
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
716
        resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
717
    assert operation.call_args_list == []
718

  
719

  
720
def test_sanitize_update_family_data_enfant_n_sanitaire(app, resource, update_params):
721
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
722

  
723
    # test maj:enfant_n_sanitaire
724
    partial_update_params = copy.deepcopy(update_params)
725
    partial_update_params['maj:enfant_1_sanitaire'] = False
726
    for key in partial_update_params['ENFANT'][1]['SANITAIRE'].keys():
727
        partial_update_params['ENFANT'][1]['SANITAIRE'][key] = None  # reset fields
728
    partial_update_params['maj:enfant_0'] = False
729
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
730
    assert len(partial_update_params['ENFANT']) == 1
731
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
732
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
733
    # combine with maj:enfant_n
734
    partial_update_params = copy.deepcopy(update_params)
735
    partial_update_params['maj:enfant_1'] = False
736
    partial_update_params['maj:enfant_1_sanitaire'] = False
737
    partial_update_params['maj:enfant_0'] = False
738
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
739
    assert 'ENFANT' not in partial_update_params
740

  
741
    # test maj:enfant_n_sanitaire not set
742
    partial_update_params = copy.deepcopy(update_params)
743
    partial_update_params['maj:enfant_1_sanitaire'] = None
744
    partial_update_params['maj:enfant_2_sanitaire'] = None
745
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
746
    assert 'SANITAIRE' in partial_update_params['ENFANT'][0]
747
    assert 'SANITAIRE' in partial_update_params['ENFANT'][1]
748

  
749

  
750
def test_sanitize_update_family_data_enfant_n_sanitaire_allergie(app, resource, update_params):
751
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
752

  
753
    # test maj:enfant_n_sanitaire_allergie
754
    partial_update_params = copy.deepcopy(update_params)
755
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
756
    for i, allergie in enumerate(partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE']):
757
        for key in allergie.keys():
758
            partial_update_params['ENFANT'][0]['SANITAIRE']['ALLERGIE'][i][key] = None  # reset fields
759
    partial_update_params['maj:enfant_0'] = False
760
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
761
    assert len(partial_update_params['ENFANT']) == 1
762
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
763
    assert 'ALLERGIE' not in partial_update_params['ENFANT'][0]['SANITAIRE']
764
    # combine with maj:enfant_n_sanitaire
765
    partial_update_params = copy.deepcopy(update_params)
766
    partial_update_params['maj:enfant_1_sanitaire'] = False
767
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
768
    partial_update_params['maj:enfant_0'] = False
769
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
770
    assert len(partial_update_params['ENFANT']) == 1
771
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
772
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
773
    # combine with maj:enfant_n
774
    partial_update_params = copy.deepcopy(update_params)
775
    partial_update_params['maj:enfant_1'] = False
776
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = False
777
    partial_update_params['maj:enfant_0'] = False
778
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
779
    assert 'ENFANT' not in partial_update_params
780

  
781
    # test maj:enfant_n_sanitaire_allergie not set
782
    partial_update_params = copy.deepcopy(update_params)
783
    partial_update_params['maj:enfant_1_sanitaire_allergie'] = None
784
    partial_update_params['maj:enfant_2_sanitaire_allergie'] = None
785
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
786
    assert 'ALLERGIE' in partial_update_params['ENFANT'][0]['SANITAIRE']
787
    assert 'ALLERGIE' in partial_update_params['ENFANT'][1]['SANITAIRE']
788

  
789

  
790
def test_sanitize_update_family_data_enfant_n_sanitaire_medecin(app, resource, update_params):
791
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
792

  
793
    # test maj:enfant_n_sanitaire_medecin
794
    partial_update_params = copy.deepcopy(update_params)
795
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
796
    for key in partial_update_params['ENFANT'][1]['SANITAIRE']['MEDECIN'].keys():
797
        partial_update_params['ENFANT'][1]['SANITAIRE']['MEDECIN'][key] = None  # reset fields
798
    partial_update_params['maj:enfant_0'] = False
799
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
800
    assert len(partial_update_params['ENFANT']) == 1
801
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
802
    assert 'MEDECIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
803
    # combine with maj:enfant_n_sanitaire
804
    partial_update_params = copy.deepcopy(update_params)
805
    partial_update_params['maj:enfant_1_sanitaire'] = False
806
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
807
    partial_update_params['maj:enfant_0'] = False
808
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
809
    assert len(partial_update_params['ENFANT']) == 1
810
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
811
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
812
    # combine with maj:enfant_n
813
    partial_update_params = copy.deepcopy(update_params)
814
    partial_update_params['maj:enfant_1'] = False
815
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = False
816
    partial_update_params['maj:enfant_0'] = False
817
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
818
    assert 'ENFANT' not in partial_update_params
819

  
820
    # test maj:enfant_n_sanitaire_medecin not set
821
    partial_update_params = copy.deepcopy(update_params)
822
    partial_update_params['maj:enfant_1_sanitaire_medecin'] = None
823
    partial_update_params['maj:enfant_2_sanitaire_medecin'] = None
824
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
825
    assert 'MEDECIN' in partial_update_params['ENFANT'][0]['SANITAIRE']
826
    assert 'MEDECIN' in partial_update_params['ENFANT'][1]['SANITAIRE']
827

  
828

  
829
def test_sanitize_update_family_data_enfant_n_sanitaire_vaccin(app, resource, update_params):
830
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
831

  
832
    # test maj:enfant_n_sanitaire_vaccin
833
    partial_update_params = copy.deepcopy(update_params)
834
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
835
    for key in partial_update_params['ENFANT'][1]['SANITAIRE']['VACCIN'].keys():
836
        partial_update_params['ENFANT'][1]['SANITAIRE']['VACCIN'][key] = None  # reset fields
837
    partial_update_params['maj:enfant_0'] = False
838
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
839
    assert len(partial_update_params['ENFANT']) == 1
840
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
841
    assert 'VACCIN' not in partial_update_params['ENFANT'][0]['SANITAIRE']
842
    # combine with maj:enfant_n_sanitaire
843
    partial_update_params = copy.deepcopy(update_params)
844
    partial_update_params['maj:enfant_1_sanitaire'] = False
845
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
846
    partial_update_params['maj:enfant_0'] = False
847
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
848
    assert len(partial_update_params['ENFANT']) == 1
849
    assert partial_update_params['ENFANT'][0]['IDPERSONNE'] == "3535"
850
    assert 'SANITAIRE' not in partial_update_params['ENFANT'][0]
851
    # combine with maj:enfant_n
852
    partial_update_params = copy.deepcopy(update_params)
853
    partial_update_params['maj:enfant_1'] = False
854
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = False
855
    partial_update_params['maj:enfant_0'] = False
856
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
857
    assert 'ENFANT' not in partial_update_params
858

  
859
    # test maj:enfant_n_sanitaire_vaccin not set
860
    partial_update_params = copy.deepcopy(update_params)
861
    partial_update_params['maj:enfant_1_sanitaire_vaccin'] = None
862
    partial_update_params['maj:enfant_2_sanitaire_vaccin'] = None
863
    resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
864
    assert 'VACCIN' in partial_update_params['ENFANT'][0]['SANITAIRE']
865
    assert 'VACCIN' in partial_update_params['ENFANT'][1]['SANITAIRE']
866

  
867

  
868
def test_sanitize_update_family_data_axel_error(app, resource, update_params):
869
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
870
    partial_update_params = copy.deepcopy(update_params)
871
    partial_update_params['maj:enfant_0_contact'] = False
872
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_famille_dui') as operation:
873
        operation.side_effect = AxelError('FooBar')
874
        with pytest.raises(APIError, match='Axel error: FooBar'):
875
            resource.sanitize_update_family_data(name_id='yyy', post_data=partial_update_params)
876

  
877

  
878
def test_update_family_info_endpoint_sanitize_axel_error(app, resource, update_params):
879
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
880
    with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.sanitize_update_family_data') as sanitize:
881
        sanitize.side_effect = APIError('Axel error: FooBar')
882
        resp = app.post_json('/toulouse-axel/test/update_family_info?NameID=yyy', params=update_params)
883
        assert resp.json['err_desc'] == "Axel error: FooBar"
884

  
885

  
519 886
def test_invoices_endpoint_axel_error(app, resource):
520 887
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
521 888
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_facture_a_payer') as operation:
522
-