From 5241ac49be0873601f262abf0e1aacd09844ede0 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Nov 23 2017 09:50:41 +0000 Subject: Paginate the api_view_user_issues endpoint Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/api/user.py b/pagure/api/user.py index d3fce1e..4f0bc75 100644 --- a/pagure/api/user.py +++ b/pagure/api/user.py @@ -10,6 +10,7 @@ import collections import datetime +from math import ceil import arrow import flask @@ -150,6 +151,9 @@ def api_view_user_issues(username): +---------------+---------+--------------+---------------------------+ | Key | Type | Optionality | Description | +===============+=========+==============+===========================+ + | ``page`` | integer | Mandatory | | The page requested. | + | | | | Defaults to 1. | + +---------------+---------+--------------+---------------------------+ | ``status`` | string | Optional | | Filters the status of | | | | | issues. Fetches all the | | | | | issues if status is | @@ -284,6 +288,20 @@ def api_view_user_issues(username): status = flask.request.args.get('status', None) tags = flask.request.args.getlist('tags') tags = [tag.strip() for tag in tags if tag.strip()] + page = flask.request.args.get('page', 1) + + try: + page = int(page) + if page <= 0: + raise ValueError() + except ValueError: + raise pagure.exceptions.APIError( + 400, error_code=APIERROR.ENOCODE, + error='Invalid page requested') + + offset = (page - 1) * 50 + limit = page * 50 + params = { 'session': SESSION, 'tags': tags, @@ -291,6 +309,8 @@ def api_view_user_issues(username): 'order': order, 'order_key': order_key, 'no_milestones': no_stones, + 'offset': offset, + 'limit': limit, } if status is not None: @@ -327,13 +347,21 @@ def api_view_user_issues(username): params_created = params.copy() params_created.update({"author": username}) issues_created = pagure.lib.search_issues(**params_created) + params_created.update({"offset": None, 'limit': None, 'count': True}) + issues_created_cnt = pagure.lib.search_issues(**params_created) + issues_created_pages = int(ceil(issues_created_cnt / float(50))) or 1 # Issues assigned to this user params_assigned = params.copy() params_assigned.update({"assignee": username}) issues_assigned = pagure.lib.search_issues(**params_assigned) + params_assigned.update({"offset": None, 'limit': None, 'count': True}) + issues_assigned_cnt = pagure.lib.search_issues(**params_assigned) + issues_assigned_pages = int(ceil(issues_assigned_cnt / float(50))) or 1 jsonout = flask.jsonify({ + 'total_issues_created_pages': issues_created_pages, + 'total_issues_assigned_pages': issues_assigned_pages, 'total_issues_created': len(issues_created), 'total_issues_assigned': len(issues_assigned), 'issues_created': [issue.to_json(public=True) @@ -348,6 +376,7 @@ def api_view_user_issues(username): 'since': since, 'status': status, 'tags': tags, + 'page': page, } }) return jsonout diff --git a/tests/test_pagure_flask_api_issue.py b/tests/test_pagure_flask_api_issue.py index 9142544..beb2177 100644 --- a/tests/test_pagure_flask_api_issue.py +++ b/tests/test_pagure_flask_api_issue.py @@ -3086,6 +3086,7 @@ class PagureFlaskApiIssuetests(tests.Modeltests): "no_stones": None, "order": None, "order_key": None, + "page": 1, "since": None, "status": None, "tags": [] @@ -3096,6 +3097,8 @@ class PagureFlaskApiIssuetests(tests.Modeltests): self.assertEqual(len(data['issues_created']), 8) self.assertEqual(data['total_issues_assigned'], 0) self.assertEqual(data['total_issues_created'], 8) + self.assertEqual(data['total_issues_assigned_pages'], 1) + self.assertEqual(data['total_issues_created_pages'], 1) # Restrict to a certain, fake milestone output = self.app.get('/api/0/user/pingou/issues?milestones=v1.0') @@ -3106,6 +3109,7 @@ class PagureFlaskApiIssuetests(tests.Modeltests): "no_stones": None, "order": None, "order_key": None, + "page": 1, "since": None, "status": None, "tags": [] @@ -3116,6 +3120,8 @@ class PagureFlaskApiIssuetests(tests.Modeltests): self.assertEqual(data['issues_created'], []) self.assertEqual(data['total_issues_assigned'], 0) self.assertEqual(data['total_issues_created'], 0) + self.assertEqual(data['total_issues_assigned_pages'], 1) + self.assertEqual(data['total_issues_created_pages'], 1) # Restrict to a certain status output = self.app.get('/api/0/user/pingou/issues?status=closed') @@ -3126,6 +3132,7 @@ class PagureFlaskApiIssuetests(tests.Modeltests): "no_stones": None, "order": None, "order_key": None, + "page": 1, "since": None, "status": 'closed', "tags": [] @@ -3136,6 +3143,8 @@ class PagureFlaskApiIssuetests(tests.Modeltests): self.assertEqual(len(data['issues_created']), 1) self.assertEqual(data['total_issues_assigned'], 0) self.assertEqual(data['total_issues_created'], 1) + self.assertEqual(data['total_issues_assigned_pages'], 1) + self.assertEqual(data['total_issues_created_pages'], 1) # Restrict to a certain status output = self.app.get('/api/0/user/pingou/issues?status=all') @@ -3146,6 +3155,7 @@ class PagureFlaskApiIssuetests(tests.Modeltests): "no_stones": None, "order": None, "order_key": None, + "page": 1, "since": None, "status": 'all', "tags": [] @@ -3156,6 +3166,8 @@ class PagureFlaskApiIssuetests(tests.Modeltests): self.assertEqual(len(data['issues_created']), 9) self.assertEqual(data['total_issues_assigned'], 0) self.assertEqual(data['total_issues_created'], 9) + self.assertEqual(data['total_issues_assigned_pages'], 1) + self.assertEqual(data['total_issues_created_pages'], 1) def test_api_view_user_issues_foo(self): """ Test the api_view_user_issues method of the flask api for foo. @@ -3185,9 +3197,10 @@ class PagureFlaskApiIssuetests(tests.Modeltests): "no_stones": None, "order": None, "order_key": None, + "page": 1, "since": None, "status": None, - "tags": [] + "tags": [], } self.assertEqual(data['args'], args) @@ -3195,6 +3208,37 @@ class PagureFlaskApiIssuetests(tests.Modeltests): self.assertEqual(data['issues_created'], []) self.assertEqual(data['total_issues_assigned'], 1) self.assertEqual(data['total_issues_created'], 0) + self.assertEqual(data['total_issues_assigned_pages'], 1) + self.assertEqual(data['total_issues_created_pages'], 1) + + def test_api_view_user_issues_foo_invalid_page(self): + """ Test the api_view_user_issues method of the flask api for foo. + """ + self.test_api_new_issue() + + output = self.app.get('/api/0/user/foo/issues?page=0') + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + + self.assertEqual( + data, + { + u'error': u'Invalid page requested', + u'error_code': u'ENOCODE' + } + ) + + output = self.app.get('/api/0/user/foo/issues?page=abc') + self.assertEqual(output.status_code, 400) + data = json.loads(output.data) + + self.assertEqual( + data, + { + u'error': u'Invalid page requested', + u'error_code': u'ENOCODE' + } + ) if __name__ == '__main__':