Projet

Général

Profil

0003-cvsdatasource-add-pagination-to-data-and-query-endpo.patch

Lauréline Guérin, 04 octobre 2019 08:27

Télécharger (4,49 ko)

Voir les différences:

Subject: [PATCH 3/3] cvsdatasource: add pagination to data and query endpoints
 (#32121)

 passerelle/apps/csvdatasource/models.py | 17 +++++++
 tests/test_csv_datasource.py            | 59 +++++++++++++++++++++++++
 2 files changed, 76 insertions(+)
passerelle/apps/csvdatasource/models.py
400 400
        # force rendition of iterator as list
401 401
        data = list(data)
402 402

  
403
        if 'limit' in request.GET:
404
            try:
405
                limit = int(request.GET['limit'])
406
            except ValueError:
407
                raise APIError('invalid limit parameter')
408
            if limit < 1:
409
                raise APIError('invalid limit parameter')
410
            try:
411
                offset = int(request.GET.get('offset') or 0)
412
            except ValueError:
413
                raise APIError('invalid offset parameter')
414
            if offset < 0:
415
                raise APIError('invalid offset parameter')
416

  
417
            # paginate data
418
            data = data[offset:offset+limit]
419

  
403 420
        if query.structure == 'array':
404 421
            return {'data': [[row[t] for t in titles] for row in data]}
405 422
        elif query.structure == 'dict':
tests/test_csv_datasource.py
28 28
from django.contrib.contenttypes.models import ContentType
29 29
from django.test import Client
30 30
from django.core.management import call_command
31
from django.utils.six.moves.urllib.parse import urlencode
31 32

  
32 33
from passerelle.base.models import ApiUser, AccessRight
33 34
from passerelle.apps.csvdatasource.models import CsvDataSource, Query, TableRow
......
764 765
    call_command('change-csv', 'test', os.path.join(TEST_BASE_DIR, 'data.ods'), sheet_name='Feuille2')
765 766
    csv.refresh_from_db()
766 767
    assert list(csv.get_rows()) != []
768

  
769

  
770
@pytest.mark.parametrize('payload,expected', [
771
    ({}, 20),
772
    ({'limit': 10}, 10),
773
    ({'limit': 10, 'offset': 0}, 10),
774
    ({'limit': 10, 'offset': 15}, 5),
775
    ({'limit': 10, 'offset': 42}, 0),
776
])
777
def test_pagination(app, setup, filetype, payload, expected):
778
    csvdata, url = setup('id,whatever,nom,prenom,sexe', filename=filetype,
779
                         data=get_file_content(filetype))
780

  
781
    # data endpoint
782
    response = app.get(url + '?' + urlencode(payload))
783
    assert len(response.json['data']) == expected
784

  
785
    # query endpoint
786
    url = reverse('generic-endpoint', kwargs={
787
        'connector': 'csvdatasource',
788
        'slug': csvdata.slug,
789
        'endpoint': 'query/query-1_/',
790
    })
791
    query = Query(slug='query-1_', resource=csvdata, structure='array')
792
    query.projections = '\n'.join(['id:int(id)', 'text:prenom'])
793
    query.save()
794
    response = app.get(url + '?' + urlencode(payload))
795
    assert len(response.json['data']) == expected
796

  
797

  
798
@pytest.mark.parametrize('payload,expected_error', [
799
    ({'limit': 'bla'}, 'invalid limit parameter'),
800
    ({'limit': 0}, 'invalid limit parameter'),
801
    ({'limit': -1}, 'invalid limit parameter'),
802
    ({'limit': 10, 'offset': 'bla'}, 'invalid offset parameter'),
803
    ({'limit': 10, 'offset': -1}, 'invalid offset parameter'),
804
])
805
def test_pagination_error(app, setup, filetype, payload, expected_error):
806
    csvdata, url = setup('id,whatever,nom,prenom,sexe', filename=filetype,
807
                         data=get_file_content(filetype))
808

  
809
    # data endpoint
810
    response = app.get(url + '?' + urlencode(payload))
811
    assert response.json['err'] == 1
812
    assert response.json['err_desc'] == expected_error
813

  
814
    # query endpoint
815
    url = reverse('generic-endpoint', kwargs={
816
        'connector': 'csvdatasource',
817
        'slug': csvdata.slug,
818
        'endpoint': 'query/query-1_/',
819
    })
820
    query = Query(slug='query-1_', resource=csvdata, structure='array')
821
    query.projections = '\n'.join(['id:int(id)', 'text:prenom'])
822
    query.save()
823
    response = app.get(url + '?' + urlencode(payload))
824
    assert response.json['err'] == 1
825
    assert response.json['err_desc'] == expected_error
767
-