Projet

Général

Profil

0002-plone_restapi-adapt-list-content-sent-to-Plone-62943.patch

Nicolas Roche, 18 mars 2022 16:22

Télécharger (6,74 ko)

Voir les différences:

Subject: [PATCH 2/2] plone_restapi: adapt list content sent to Plone (#62943)

 passerelle/apps/plone_restapi/models.py | 29 ++++++++++++++++++++-
 tests/test_plone_restapi.py             | 34 +++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 1 deletion(-)
passerelle/apps/plone_restapi/models.py
106 106
    def convert_image_format(self, payload):
107 107
        for file_field in payload.values():
108 108
            if isinstance(file_field, dict) and file_field.get('filename'):
109 109
                file_field['encoding'] = 'base64'
110 110
                file_field['data'] = file_field['content']
111 111
                file_field['content-type'] = file_field['content_type']
112 112
                del file_field['content']
113 113

  
114
    def remove_unvaluated_dict_from_list(self, data):
115
        """Remove from lists, not empty dicts having all empty string values"""
116

  
117
        def is_not_empty_dict_having_all_empty_values(data):
118
            if not isinstance(data, dict):
119
                return False
120
            if len(data) == 0:
121
                return False
122
            for value in data.values():
123
                if value != '':
124
                    return False
125
            return True
126

  
127
        if isinstance(data, dict):
128
            res = {}
129
            for key, value in data.items():
130
                res[key] = self.remove_unvaluated_dict_from_list(value)
131
            return res
132
        if isinstance(data, list):
133
            res = []
134
            for value in data:
135
                tmp = self.remove_unvaluated_dict_from_list(value)
136
                if not is_not_empty_dict_having_all_empty_values(tmp):
137
                    res.append(tmp)
138
            return res
139
        return data
140

  
114 141
    def adapt_payload(self, payload):
115 142
        self.convert_image_format(payload)
116
        return payload
143
        return self.remove_unvaluated_dict_from_list(payload)
117 144

  
118 145
    def adapt_record(
119 146
        self,
120 147
        record,
121 148
        text_template='{{ id }}',
122 149
        id_key='UID',
123 150
    ):
124 151
        self.adapt_id_and_type_plone_attributes(record)
tests/test_plone_restapi.py
391 391
    payload = {
392 392
        '@type': 'imio.directory.Contact',
393 393
        'title': "Test Entr'ouvert",
394 394
        'type': 'organization',
395 395
        'schedule': {},
396 396
        'topics/0/title': 'Tourisme',
397 397
        'topics/0/token': 'tourism',
398 398
        'image': {'filename': 'foo.jpg', 'content_type': 'image/jpeg', 'content': '...'},
399
        'phones': [
400
            {'label': 'numéro principal', 'number': '0123456789', 'type': 'work'},
401
            {'label': '', 'number': '', 'type': ''},
402
        ],
399 403
    }
400 404
    with utils.mock_url(url=url, response=json_get_data('fetch'), status_code=201) as mocked:
401 405
        resp = app.post_json(endpoint + '?uri=braine-l-alleud&publish=false', params=payload)
402 406
        body = json.loads(mocked.handlers[0].call['requests'][1].body)
403 407
        assert body['topics'] == [{'title': 'Tourisme', 'token': 'tourism'}]
404 408
        assert body['image'] == {
405 409
            'filename': 'foo.jpg',
406 410
            'content_type': 'image/jpeg',
407 411
            'encoding': 'base64',
408 412
            'data': '...',
409 413
            'content-type': 'image/jpeg',
410 414
        }
415
        assert body['phones'] == [{'label': 'numéro principal', 'number': '0123456789', 'type': 'work'}]
411 416
    assert not resp.json['err']
412 417
    assert resp.json['data'] == {
413 418
        'uid': 'dccd85d12cf54b6899dff41e5a56ee7f',
414 419
        'created': True,
415 420
        'review_state': None,
416 421
    }
417 422

  
418 423

  
......
466 471
    endpoint = utils.generic_endpoint_url('plone-restapi', 'update', slug=connector.slug)
467 472
    assert endpoint == '/plone-restapi/my_connector/update'
468 473
    url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
469 474
    query_string = '?uri=braine-l-alleud&uid=dccd85d12cf54b6899dff41e5a56ee7f'
470 475
    payload = {
471 476
        'title': 'Test update',
472 477
        'topics/0/token': 'social',
473 478
        'image': {'filename': 'foo.jpg', 'content_type': 'image/jpeg', 'content': '...'},
479
        'phones': [
480
            {'label': '', 'number': '', 'type': ''},
481
            {'label': '', 'number': '', 'type': ''},
482
        ],
474 483
    }
475 484
    with utils.mock_url(url=url, response='', status_code=204) as mocked:
476 485
        resp = app.post_json(endpoint + query_string, params=payload)
477 486
        body = json.loads(mocked.handlers[0].call['requests'][1].body)
478 487
        assert body['topics'] == [{'token': 'social'}]
479 488
        assert body['image'] == {
480 489
            'filename': 'foo.jpg',
481 490
            'content_type': 'image/jpeg',
482 491
            'encoding': 'base64',
483 492
            'data': '...',
484 493
            'content-type': 'image/jpeg',
485 494
        }
495
        assert body['phones'] == []
496

  
486 497
    assert not resp.json['err']
487 498
    assert resp.json['data'] == {'uid': 'dccd85d12cf54b6899dff41e5a56ee7f', 'updated': True}
488 499

  
489 500

  
490 501
def test_update_wrong_payload(app, connector, token):
491 502
    endpoint = utils.generic_endpoint_url('plone-restapi', 'update', slug=connector.slug)
492 503
    assert endpoint == '/plone-restapi/my_connector/update'
493 504
    url = connector.service_url + '/braine-l-alleud/dccd85d12cf54b6899dff41e5a56ee7f'
......
657 668
        resp = app.get(endpoint, params=params)
658 669
    assert qs == {
659 670
        'UID': '9fbb2afd499e465983434f974fce8404',
660 671
        'fullobjects': 'y',
661 672
    }
662 673
    assert len(resp.json['data']) == 1
663 674
    assert resp.json['data'][0]['text'] == "Académie de Musique de Braine-l'Alleud (imio.directory.Contact)"
664 675
    assert resp.json['meta'] == {'label': 'demo query', 'description': "Annuaire de Braine-l'Alleud"}
676

  
677

  
678
@pytest.mark.parametrize(
679
    'in_data, out_data',
680
    [
681
        [{}, 'same'],
682
        [[], 'same'],
683
        [[''], 'same'],
684
        [[{}], 'same'],
685
        [{'k1': ''}, 'same'],
686
        [{'k1': []}, 'same'],
687
        [{'k1': '', 'k2': 'v2'}, 'same'],
688
        [[{'k1': ''}], []],
689
        [[{'k1': ''}, {}], [{}]],
690
        [[{'k1': []}], 'same'],
691
        [[{'k1': [{'k11': ''}]}], [{'k1': []}]],
692
        [[{'k1': [{'k11': ''}, {}]}], [{'k1': [{}]}]],
693
    ],
694
)
695
def test_remove_unvaluated_dict_from_list(connector, in_data, out_data):
696
    if out_data == 'same':
697
        out_data = in_data
698
    assert connector.remove_unvaluated_dict_from_list(in_data) == out_data
665
-