From c6a73fc7628c97ffc7a0726bb12ad505e58816f9 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Nov 27 2017 10:03:52 +0000 Subject: [PATCH 1/3] When listing the user's PRs (filled or actionable) paginate the results To prevent a potential DOS vector via the API Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/api/user.py b/pagure/api/user.py index 43a1a5e..939ec72 100644 --- a/pagure/api/user.py +++ b/pagure/api/user.py @@ -655,6 +655,9 @@ def api_view_user_requests_filed(username): | | | | whose activity you are | | | | | interested in. | +---------------+----------+--------------+----------------------------+ + | ``page`` | integer | Mandatory | | The page requested. | + | | | | Defaults to 1. | + +---------------+----------+--------------+----------------------------+ | ``status`` | string | Optional | | Filter the status of | | | | | pull requests. Default: | | | | | ``Open`` (open pull | @@ -806,31 +809,47 @@ def api_view_user_requests_filed(username): """ status = flask.request.args.get('status', 'open') + 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 + + orig_status = status + if status.lower() == 'all': + status = None + else: + status = status.capitalize() pullrequests = pagure.lib.get_pull_request_of_user( SESSION, - username=username + username=username, + status=status, + offset=offset, + limit=limit, ) - pullrequestslist = [] - - for pr in pullrequests: - if pr.user.username == username: - if str(status).lower() == 'all': - pullrequestslist.append(pr.to_json(public=True, api=True)) - elif str(status).lower() == 'open' and pr.status == 'Open': - pullrequestslist.append(pr.to_json(public=True, api=True)) - elif str(status).lower() == 'closed' and pr.status == 'Closed': - pullrequestslist.append(pr.to_json(public=True, api=True)) - elif str(status).lower() == 'merged' and pr.status == 'Merged': - pullrequestslist.append(pr.to_json(public=True, api=True)) + pullrequestslist = [ + pr.to_json(public=True, api=True) + for pr in pullrequests + if pr.user.username == username + ] return flask.jsonify({ 'total_requests': len(pullrequestslist), 'requests': pullrequestslist, 'args': { 'username': username, - 'status': status, + 'status': orig_status, + 'page': page, } }) @@ -862,6 +881,9 @@ def api_view_user_requests_actionable(username): | | | | whose activity you are | | | | | interested in. | +---------------+----------+--------------+----------------------------+ + | ``page`` | integer | Mandatory | | The page requested. | + | | | | Defaults to 1. | + +---------------+----------+--------------+----------------------------+ | ``status`` | string | Optional | | Filter the status of | | | | | pull requests. Default: | | | | | ``Open`` (open pull | @@ -1012,30 +1034,46 @@ def api_view_user_requests_actionable(username): """ status = flask.request.args.get('status', 'open') + 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 + + orig_status = status + if status.lower() == 'all': + status = None + else: + status = status.capitalize() pullrequests = pagure.lib.get_pull_request_of_user( SESSION, - username=username + username=username, + status=status, + offset=offset, + limit=limit, ) - pullrequestslist = [] - - for pr in pullrequests: - if pr.user.username != username: - if str(status).lower() == 'all': - pullrequestslist.append(pr.to_json(public=True, api=True)) - elif str(status).lower() == 'open' and pr.status == 'Open': - pullrequestslist.append(pr.to_json(public=True, api=True)) - elif str(status).lower() == 'closed' and pr.status == 'Closed': - pullrequestslist.append(pr.to_json(public=True, api=True)) - elif str(status).lower() == 'merged' and pr.status == 'Merged': - pullrequestslist.append(pr.to_json(public=True, api=True)) + pullrequestslist = [ + pr.to_json(public=True, api=True) + for pr in pullrequests + if pr.user.username != username + ] return flask.jsonify({ 'total_requests': len(pullrequestslist), 'requests': pullrequestslist, 'args': { 'username': username, - 'status': status, + 'status': orig_status, + 'page': page, } }) diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index 308f2fb..17ccbed 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -3774,7 +3774,8 @@ def could_be_text(text): return False -def get_pull_request_of_user(session, username): +def get_pull_request_of_user( + session, username, status=None, offset=None, limit=None): '''List the opened pull-requests of an user. These pull-requests have either been opened by that user or against projects that user has commit on. @@ -3857,6 +3858,16 @@ def get_pull_request_of_user(session, username): model.PullRequest.date_created.desc() ) + if status: + query = query.filter( + model.PullRequest.status == status + ) + + if offset: + query = query.offset(offset) + if limit: + query = query.limit(limit) + return query.all() From 65d34adbcb0744f7240473e17968ac57face2a35 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Nov 27 2017 10:03:52 +0000 Subject: [PATCH 2/3] Fix the API documentation page Fix the layout of the documentation for the endpoints listing the user's PR (filled or actionable). Signed-off-by: Pierre-Yves Chibon --- diff --git a/pagure/api/user.py b/pagure/api/user.py index 939ec72..51cf937 100644 --- a/pagure/api/user.py +++ b/pagure/api/user.py @@ -632,10 +632,10 @@ def api_view_user_activity_date(username, date): @api_method def api_view_user_requests_filed(username): """ - Pull requests that were filed by a user over all projects - ------------------- - Use this endpoint to retrieve a list of open pull requests a user has filed - over the entire pagure instance. + List pull-requests filled by user + --------------------------------- + Use this endpoint to retrieve a list of open pull requests a user has + filed over the entire pagure instance. :: @@ -676,136 +676,138 @@ def api_view_user_requests_filed(username): ^^^^^^^^^^^^^^^ :: - { - "args": { - "status": "open", - "username": "dudemcpants" - }, - "requests": [ + { - "assignee": null, - "branch": "master", - "branch_from": "master", - "closed_at": null, - "closed_by": null, - "comments": [], - "commit_start": "3973fae98fc485783ca14f5c3612d85832185065", - "commit_stop": "3973fae98fc485783ca14f5c3612d85832185065", - "date_created": "1510227832", - "id": 2, - "initial_comment": null, - "last_updated": "1510227833", - "project": { - "access_groups": { - "admin": [], - "commit": [], - "ticket": [] - }, - "access_users": { - "admin": [], - "commit": [], - "owner": [ - "ryanlerch" - ], - "ticket": [] - }, - "close_status": [], - "custom_keys": [], - "date_created": "1510227638", - "date_modified": "1510227638", - "description": "this is a quick project", - "fullname": "aquickproject", - "id": 1, - "milestones": {}, - "name": "aquickproject", - "namespace": null, - "parent": null, - "priorities": {}, - "tags": [], - "url_path": "aquickproject", - "user": { - "fullname": "ryanlerch", - "name": "ryanlerch" - } - }, - "remote_git": null, - "repo_from": { - "access_groups": { - "admin": [], - "commit": [], - "ticket": [] - }, - "access_users": { - "admin": [], - "commit": [], - "owner": [ - "dudemcpants" - ], - "ticket": [] - }, - "close_status": [], - "custom_keys": [], - "date_created": "1510227729", - "date_modified": "1510227729", - "description": "this is a quick project", - "fullname": "forks/dudemcpants/aquickproject", - "id": 2, - "milestones": {}, - "name": "aquickproject", - "namespace": null, - "parent": { - "access_groups": { - "admin": [], - "commit": [], - "ticket": [] - }, - "access_users": { - "admin": [], - "commit": [], - "owner": [ - "ryanlerch" - ], - "ticket": [] - }, - "close_status": [], - "custom_keys": [], - "date_created": "1510227638", - "date_modified": "1510227638", - "description": "this is a quick project", - "fullname": "aquickproject", - "id": 1, - "milestones": {}, - "name": "aquickproject", - "namespace": null, - "parent": null, - "priorities": {}, - "tags": [], - "url_path": "aquickproject", - "user": { - "fullname": "ryanlerch", - "name": "ryanlerch" - } - }, - "priorities": {}, - "tags": [], - "url_path": "fork/dudemcpants/aquickproject", - "user": { - "fullname": "Dude McPants", - "name": "dudemcpants" + "args": { + "status": "open", + "username": "dudemcpants", + "page": 1, + }, + "requests": [ + { + "assignee": null, + "branch": "master", + "branch_from": "master", + "closed_at": null, + "closed_by": null, + "comments": [], + "commit_start": "3973fae98fc485783ca14f5c3612d85832185065", + "commit_stop": "3973fae98fc485783ca14f5c3612d85832185065", + "date_created": "1510227832", + "id": 2, + "initial_comment": null, + "last_updated": "1510227833", + "project": { + "access_groups": { + "admin": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "ryanlerch" + ], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1510227638", + "date_modified": "1510227638", + "description": "this is a quick project", + "fullname": "aquickproject", + "id": 1, + "milestones": {}, + "name": "aquickproject", + "namespace": null, + "parent": null, + "priorities": {}, + "tags": [], + "url_path": "aquickproject", + "user": { + "fullname": "ryanlerch", + "name": "ryanlerch" + } + }, + "remote_git": null, + "repo_from": { + "access_groups": { + "admin": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "dudemcpants" + ], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1510227729", + "date_modified": "1510227729", + "description": "this is a quick project", + "fullname": "forks/dudemcpants/aquickproject", + "id": 2, + "milestones": {}, + "name": "aquickproject", + "namespace": null, + "parent": { + "access_groups": { + "admin": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "ryanlerch" + ], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1510227638", + "date_modified": "1510227638", + "description": "this is a quick project", + "fullname": "aquickproject", + "id": 1, + "milestones": {}, + "name": "aquickproject", + "namespace": null, + "parent": null, + "priorities": {}, + "tags": [], + "url_path": "aquickproject", + "user": { + "fullname": "ryanlerch", + "name": "ryanlerch" + } + }, + "priorities": {}, + "tags": [], + "url_path": "fork/dudemcpants/aquickproject", + "user": { + "fullname": "Dude McPants", + "name": "dudemcpants" + } + }, + "status": "Open", + "title": "Update README.md", + "uid": "819e0b1c449e414fa291c914f28d73ec", + "updated_on": "1510227832", + "user": { + "fullname": "Dude McPants", + "name": "dudemcpants" + } } - }, - "status": "Open", - "title": "Update README.md", - "uid": "819e0b1c449e414fa291c914f28d73ec", - "updated_on": "1510227832", - "user": { - "fullname": "Dude McPants", - "name": "dudemcpants" - } + ], + "total_requests": 1 } - ], - "total_requests": 1 - } """ status = flask.request.args.get('status', 'open') @@ -858,10 +860,11 @@ def api_view_user_requests_filed(username): @api_method def api_view_user_requests_actionable(username): """ - Pull requests that are actionable by a user over all projects - ------------------- - Use this endpoint to retrieve a list of open pull requests a user is able - to action (e.g. merge) over the entire pagure instance. + List PRs actionable by user + --------------------------- + + Use this endpoint to retrieve a list of open pull requests a user is + able to action (e.g. merge) over the entire pagure instance. :: @@ -901,136 +904,138 @@ def api_view_user_requests_actionable(username): ^^^^^^^^^^^^^^^ :: - { - "args": { - "status": "open", - "username": "ryanlerch" - }, - "requests": [ + { - "assignee": null, - "branch": "master", - "branch_from": "master", - "closed_at": null, - "closed_by": null, - "comments": [], - "commit_start": "3973fae98fc485783ca14f5c3612d85832185065", - "commit_stop": "3973fae98fc485783ca14f5c3612d85832185065", - "date_created": "1510227832", - "id": 2, - "initial_comment": null, - "last_updated": "1510227833", - "project": { - "access_groups": { - "admin": [], - "commit": [], - "ticket": [] - }, - "access_users": { - "admin": [], - "commit": [], - "owner": [ - "ryanlerch" - ], - "ticket": [] - }, - "close_status": [], - "custom_keys": [], - "date_created": "1510227638", - "date_modified": "1510227638", - "description": "this is a quick project", - "fullname": "aquickproject", - "id": 1, - "milestones": {}, - "name": "aquickproject", - "namespace": null, - "parent": null, - "priorities": {}, - "tags": [], - "url_path": "aquickproject", - "user": { - "fullname": "ryanlerch", - "name": "ryanlerch" - } - }, - "remote_git": null, - "repo_from": { - "access_groups": { - "admin": [], - "commit": [], - "ticket": [] - }, - "access_users": { - "admin": [], - "commit": [], - "owner": [ - "dudemcpants" - ], - "ticket": [] - }, - "close_status": [], - "custom_keys": [], - "date_created": "1510227729", - "date_modified": "1510227729", - "description": "this is a quick project", - "fullname": "forks/dudemcpants/aquickproject", - "id": 2, - "milestones": {}, - "name": "aquickproject", - "namespace": null, - "parent": { - "access_groups": { - "admin": [], - "commit": [], - "ticket": [] - }, - "access_users": { - "admin": [], - "commit": [], - "owner": [ - "ryanlerch" - ], - "ticket": [] - }, - "close_status": [], - "custom_keys": [], - "date_created": "1510227638", - "date_modified": "1510227638", - "description": "this is a quick project", - "fullname": "aquickproject", - "id": 1, - "milestones": {}, - "name": "aquickproject", - "namespace": null, - "parent": null, - "priorities": {}, - "tags": [], - "url_path": "aquickproject", - "user": { - "fullname": "ryanlerch", - "name": "ryanlerch" - } - }, - "priorities": {}, - "tags": [], - "url_path": "fork/dudemcpants/aquickproject", - "user": { - "fullname": "Dude McPants", - "name": "dudemcpants" + "args": { + "status": "open", + "username": "ryanlerch", + "page": 1, + }, + "requests": [ + { + "assignee": null, + "branch": "master", + "branch_from": "master", + "closed_at": null, + "closed_by": null, + "comments": [], + "commit_start": "3973fae98fc485783ca14f5c3612d85832185065", + "commit_stop": "3973fae98fc485783ca14f5c3612d85832185065", + "date_created": "1510227832", + "id": 2, + "initial_comment": null, + "last_updated": "1510227833", + "project": { + "access_groups": { + "admin": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "ryanlerch" + ], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1510227638", + "date_modified": "1510227638", + "description": "this is a quick project", + "fullname": "aquickproject", + "id": 1, + "milestones": {}, + "name": "aquickproject", + "namespace": null, + "parent": null, + "priorities": {}, + "tags": [], + "url_path": "aquickproject", + "user": { + "fullname": "ryanlerch", + "name": "ryanlerch" + } + }, + "remote_git": null, + "repo_from": { + "access_groups": { + "admin": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "dudemcpants" + ], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1510227729", + "date_modified": "1510227729", + "description": "this is a quick project", + "fullname": "forks/dudemcpants/aquickproject", + "id": 2, + "milestones": {}, + "name": "aquickproject", + "namespace": null, + "parent": { + "access_groups": { + "admin": [], + "commit": [], + "ticket": [] + }, + "access_users": { + "admin": [], + "commit": [], + "owner": [ + "ryanlerch" + ], + "ticket": [] + }, + "close_status": [], + "custom_keys": [], + "date_created": "1510227638", + "date_modified": "1510227638", + "description": "this is a quick project", + "fullname": "aquickproject", + "id": 1, + "milestones": {}, + "name": "aquickproject", + "namespace": null, + "parent": null, + "priorities": {}, + "tags": [], + "url_path": "aquickproject", + "user": { + "fullname": "ryanlerch", + "name": "ryanlerch" + } + }, + "priorities": {}, + "tags": [], + "url_path": "fork/dudemcpants/aquickproject", + "user": { + "fullname": "Dude McPants", + "name": "dudemcpants" + } + }, + "status": "Open", + "title": "Update README.md", + "uid": "819e0b1c449e414fa291c914f28d73ec", + "updated_on": "1510227832", + "user": { + "fullname": "Dude McPants", + "name": "dudemcpants" + } } - }, - "status": "Open", - "title": "Update README.md", - "uid": "819e0b1c449e414fa291c914f28d73ec", - "updated_on": "1510227832", - "user": { - "fullname": "Dude McPants", - "name": "dudemcpants" - } + ], + "total_requests": 1 } - ], - "total_requests": 1 - } """ status = flask.request.args.get('status', 'open') diff --git a/tests/test_pagure_flask_api_user.py b/tests/test_pagure_flask_api_user.py index 75fd77b..c38416f 100644 --- a/tests/test_pagure_flask_api_user.py +++ b/tests/test_pagure_flask_api_user.py @@ -496,7 +496,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): user='foo', requestfolder=None, ) - + repo = pagure.get_authorized_project(self.session, 'test2') forked_repo = pagure.get_authorized_project(self.session, 'test2') pagure.lib.new_pull_request( @@ -524,7 +524,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): status='Closed', requestfolder=None, ) - + repo = pagure.get_authorized_project(self.session, 'test2') forked_repo = pagure.get_authorized_project(self.session, 'test2') pagure.lib.new_pull_request( @@ -553,7 +553,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): status='Merged', requestfolder=None, ) - + repo = pagure.get_authorized_project(self.session, 'test2') forked_repo = pagure.get_authorized_project(self.session, 'test2') pagure.lib.new_pull_request( @@ -676,6 +676,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "open pullrequest by user pingou on repo test2") self.assertEqual(data['requests'][1]['title'], "open pullrequest by user pingou on repo test") self.assertEqual(data['args']['status'], "open") + self.assertEqual(data['args']['page'], 1) # Next test with the status parameter set to `open`. output = self.app.get( @@ -691,6 +692,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "open pullrequest by user pingou on repo test2") self.assertEqual(data['requests'][1]['title'], "open pullrequest by user pingou on repo test") self.assertEqual(data['args']['status'], "open") + self.assertEqual(data['args']['page'], 1) # Next test with the status parameter set to `closed`. output = self.app.get( @@ -706,6 +708,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "closed pullrequest by user pingou on repo test2") self.assertEqual(data['requests'][1]['title'], "closed pullrequest by user pingou on repo test") self.assertEqual(data['args']['status'], "closed") + self.assertEqual(data['args']['page'], 1) # Next test with the status parameter set to `merged`. output = self.app.get( @@ -721,6 +724,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user pingou on repo test2") self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user pingou on repo test") self.assertEqual(data['args']['status'], "merged") + self.assertEqual(data['args']['page'], 1) # Finally, test with the status parameter set to `all`. output = self.app.get( @@ -742,12 +746,13 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][4]['status'], "Open") self.assertEqual(data['requests'][5]['status'], "Open") self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user pingou on repo test2") - self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user pingou on repo test") + self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user pingou on repo test") self.assertEqual(data['requests'][2]['title'], "closed pullrequest by user pingou on repo test2") self.assertEqual(data['requests'][3]['title'], "closed pullrequest by user pingou on repo test") self.assertEqual(data['requests'][4]['title'], "open pullrequest by user pingou on repo test2") self.assertEqual(data['requests'][5]['title'], "open pullrequest by user pingou on repo test") self.assertEqual(data['args']['status'], "all") + self.assertEqual(data['args']['page'], 1) @patch('pagure.lib.notify.send_email') def test_api_view_user_requests_actionable(self, mockemail): @@ -768,6 +773,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "open pullrequest by user foo on repo test2") self.assertEqual(data['requests'][1]['title'], "open pullrequest by user foo on repo test") self.assertEqual(data['args']['status'], "open") + self.assertEqual(data['args']['page'], 1) # Next test with the status parameter set to `open`. output = self.app.get( @@ -783,6 +789,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "open pullrequest by user foo on repo test2") self.assertEqual(data['requests'][1]['title'], "open pullrequest by user foo on repo test") self.assertEqual(data['args']['status'], "open") + self.assertEqual(data['args']['page'], 1) # Next test with the status parameter set to `closed`. output = self.app.get( @@ -798,6 +805,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "closed pullrequest by user foo on repo test2") self.assertEqual(data['requests'][1]['title'], "closed pullrequest by user foo on repo test") self.assertEqual(data['args']['status'], "closed") + self.assertEqual(data['args']['page'], 1) # Next test with the status parameter set to `merged`. output = self.app.get( @@ -813,6 +821,7 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user foo on repo test2") self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user foo on repo test") self.assertEqual(data['args']['status'], "merged") + self.assertEqual(data['args']['page'], 1) # Finally, test with the status parameter set to `all`. output = self.app.get( @@ -834,15 +843,14 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['requests'][4]['status'], "Open") self.assertEqual(data['requests'][5]['status'], "Open") self.assertEqual(data['requests'][0]['title'], "merged pullrequest by user foo on repo test2") - self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user foo on repo test") + self.assertEqual(data['requests'][1]['title'], "merged pullrequest by user foo on repo test") self.assertEqual(data['requests'][2]['title'], "closed pullrequest by user foo on repo test2") self.assertEqual(data['requests'][3]['title'], "closed pullrequest by user foo on repo test") self.assertEqual(data['requests'][4]['title'], "open pullrequest by user foo on repo test2") self.assertEqual(data['requests'][5]['title'], "open pullrequest by user foo on repo test") self.assertEqual(data['args']['status'], "all") + self.assertEqual(data['args']['page'], 1) - - if __name__ == '__main__': unittest.main(verbosity=2) From 254b062c190212ac6859bc2ad39745c7bd77a856 Mon Sep 17 00:00:00 2001 From: Pierre-Yves Chibon Date: Nov 27 2017 10:03:52 +0000 Subject: [PATCH 3/3] Add tests for the pagination Signed-off-by: Pierre-Yves Chibon --- diff --git a/tests/test_pagure_flask_api_user.py b/tests/test_pagure_flask_api_user.py index c38416f..20595ef 100644 --- a/tests/test_pagure_flask_api_user.py +++ b/tests/test_pagure_flask_api_user.py @@ -754,6 +754,15 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['args']['status'], "all") self.assertEqual(data['args']['page'], 1) + # Test page 2 with the status parameter set to `all`. + output = self.app.get( + '/api/0/user/pingou/requests/filed?status=all&page=2') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 0) + self.assertEqual(data['args']['page'], 2) + @patch('pagure.lib.notify.send_email') def test_api_view_user_requests_actionable(self, mockemail): """ Test the api_view_user_requests_actionable method of the flask user @@ -851,6 +860,15 @@ class PagureFlaskApiUsertestrequests(tests.Modeltests): self.assertEqual(data['args']['status'], "all") self.assertEqual(data['args']['page'], 1) + # Test page 2 with the status parameter set to `all`. + output = self.app.get( + '/api/0/user/pingou/requests/actionable?status=all&page=2') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 0) + self.assertEqual(data['args']['page'], 2) + if __name__ == '__main__': unittest.main(verbosity=2)