diff --git a/module_build_service/utils.py b/module_build_service/utils.py index 810d24fa..8cc49502 100644 --- a/module_build_service/utils.py +++ b/module_build_service/utils.py @@ -380,6 +380,19 @@ def filter_module_builds(flask_request): elif context == 'before': query = query.filter(column <= item_datetime) + # Order the results by any column in the ModuleBuild table. + order_by = flask_request.args.get("order_by", None) + order_desc_by = flask_request.args.get("order_desc_by", None) + if order_by or order_desc_by: + column = getattr(models.ModuleBuild, order_desc_by or order_by, None) + if column: + if order_desc_by: + column = column.desc() + query = query.order_by(column) + else: + raise ValidationError('An invalid order_by or order_desc_by key ' + 'was supplied') + page = flask_request.args.get('page', 1, type=int) per_page = flask_request.args.get('per_page', 10, type=int) return query.paginate(page, per_page, False) diff --git a/tests/test_views/test_views.py b/tests/test_views/test_views.py index ee540eb8..7c664657 100644 --- a/tests/test_views/test_views.py +++ b/tests/test_views/test_views.py @@ -307,6 +307,44 @@ class TestViews(unittest.TestCase): ' was provided for the \"modified_after\" parameter') self.assertEquals(data['status'], 400) + def test_query_builds_order_by(self): + rv = self.client.get('/module-build-service/1/module-builds/?' + 'per_page=10&order_by=id') + items = json.loads(rv.data)['items'] + # Check that the id is 1, 2, 3, ..., 10 + for idx, item in enumerate(items): + self.assertEquals(item["id"], idx + 1) + + def test_query_builds_order_desc_by(self): + rv = self.client.get('/module-build-service/1/module-builds/?' + 'per_page=10&order_desc_by=id') + items = json.loads(rv.data)['items'] + # Check that the id is items[0]["id"], items[0]["id"] - 1, ... + for idx, item in enumerate(items): + self.assertEquals(item["id"], items[0]["id"] - idx) + + def test_query_builds_order_by_order_desc_by(self): + """ + Test that when both order_by and order_desc_by is set, + we prefer order_desc_by. + """ + rv = self.client.get('/module-build-service/1/module-builds/?' + 'per_page=10&order_desc_by=id&order_by=name') + items = json.loads(rv.data)['items'] + # Check that the id is items[0]["id"], items[0]["id"] - 1, ... + for idx, item in enumerate(items): + self.assertEquals(item["id"], items[0]["id"] - idx) + + def test_query_builds_order_by_wrong_key(self): + rv = self.client.get('/module-build-service/1/module-builds/?' + 'per_page=10&order_by=unknown') + data = json.loads(rv.data) + self.assertEquals(data['status'], 400) + self.assertEquals(data['error'], 'Bad Request') + self.assertEquals( + data['message'], 'An invalid order_by or order_desc_by key ' + 'was supplied') + @patch('module_build_service.auth.get_user', return_value=user) @patch('module_build_service.scm.SCM') def test_submit_build(self, mocked_scm, mocked_get_user):