From 3e819abcb6e8294bf77ade5a96e65ed2dd962dda Mon Sep 17 00:00:00 2001 From: mprahl Date: Mon, 26 Jun 2017 11:27:46 -0400 Subject: [PATCH] Include the query arguments in the pagination metadata --- module_build_service/utils.py | 37 ++++++++++++++++++++++++++-------- module_build_service/views.py | 2 +- tests/test_views/test_views.py | 12 ++++++++++- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/module_build_service/utils.py b/module_build_service/utils.py index 2a353d39..7994f09e 100644 --- a/module_build_service/utils.py +++ b/module_build_service/utils.py @@ -23,6 +23,7 @@ """ Utility functions for module_build_service. """ import re +import copy import functools import time import shutil @@ -311,28 +312,48 @@ def start_next_batch_build(config, module, session, builder, components=None): return continue_batch_build( config, module, session, builder, unbuilt_components) -def pagination_metadata(p_query): +def pagination_metadata(p_query, request_args): """ - Returns a dictionary containing metadata about the paginated query. This must be run as part of a Flask request. + Returns a dictionary containing metadata about the paginated query. + This must be run as part of a Flask request. :param p_query: flask_sqlalchemy.Pagination object + :param request_args: a dictionary of the arguments that were part of the + Flask request :return: a dictionary containing metadata about the paginated query """ + request_args_wo_page = dict(copy.deepcopy(request_args)) + # Remove pagination related args because those are handled elsewhere + # Also, remove any args that url_for accepts in case the user entered + # those in + for key in ['page', 'per_page', 'endpoint']: + if key in request_args_wo_page: + request_args_wo_page.pop(key) + for key in request_args: + if key.startswith('_'): + request_args_wo_page.pop(key) pagination_data = { 'page': p_query.page, - 'per_page': p_query.per_page, - 'total': p_query.total, 'pages': p_query.pages, - 'first': url_for(request.endpoint, page=1, per_page=p_query.per_page, _external=True), - 'last': url_for(request.endpoint, page=p_query.pages, per_page=p_query.per_page, _external=True) + 'per_page': p_query.per_page, + 'prev': None, + 'next': None, + 'total': p_query.total, + 'first': url_for(request.endpoint, page=1, per_page=p_query.per_page, + _external=True, **request_args_wo_page), + 'last': url_for(request.endpoint, page=p_query.pages, + per_page=p_query.per_page, _external=True, + **request_args_wo_page) } if p_query.has_prev: pagination_data['prev'] = url_for(request.endpoint, page=p_query.prev_num, - per_page=p_query.per_page, _external=True) + per_page=p_query.per_page, _external=True, + **request_args_wo_page) if p_query.has_next: pagination_data['next'] = url_for(request.endpoint, page=p_query.next_num, - per_page=p_query.per_page, _external=True) + per_page=p_query.per_page, _external=True, + **request_args_wo_page) return pagination_data diff --git a/module_build_service/views.py b/module_build_service/views.py index 1a7d6880..9ede4a50 100644 --- a/module_build_service/views.py +++ b/module_build_service/views.py @@ -72,7 +72,7 @@ class ModuleBuildAPI(MethodView): p_query = filter_module_builds(request) json_data = { - 'meta': pagination_metadata(p_query) + 'meta': pagination_metadata(p_query, request.args) } if verbose_flag.lower() == 'true' or verbose_flag == '1': diff --git a/tests/test_views/test_views.py b/tests/test_views/test_views.py index 0450be7a..bb540cac 100644 --- a/tests/test_views/test_views.py +++ b/tests/test_views/test_views.py @@ -193,7 +193,6 @@ class TestViews(unittest.TestCase): def test_pagination_metadata(self): rv = self.client.get('/module-build-service/1/module-builds/?per_page=8&page=2') meta_data = json.loads(rv.data)['meta'] - print meta_data self.assertIn( meta_data['prev'].split('?', 1)[1], ['per_page=8&page=1', 'page=1&per_page=8']) self.assertIn( @@ -207,6 +206,17 @@ class TestViews(unittest.TestCase): self.assertEquals(meta_data['pages'], 4) self.assertEquals(meta_data['page'], 2) + def test_pagination_metadata_with_args(self): + rv = self.client.get('/module-build-service/1/module-builds/?per_page=8&page=2&order_by=id') + meta_data = json.loads(rv.data)['meta'] + for link in [meta_data['prev'], meta_data['next'], meta_data['last'], meta_data['first']]: + self.assertIn('order_by=id', link) + self.assertIn('per_page=8', link) + self.assertEquals(meta_data['total'], 30) + self.assertEquals(meta_data['per_page'], 8) + self.assertEquals(meta_data['pages'], 4) + self.assertEquals(meta_data['page'], 2) + def test_query_builds(self): rv = self.client.get('/module-build-service/1/module-builds/?per_page=2') items = json.loads(rv.data)['items']