diff --git a/pagure/api/user.py b/pagure/api/user.py index 8d522ba..0d1a982 100644 --- a/pagure/api/user.py +++ b/pagure/api/user.py @@ -353,3 +353,416 @@ def api_view_user_activity_date(username, date): ) ) return jsonout + + +@API.route('/user//requests/filed') +@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. + + :: + + GET /api/0/user//requests/filed + + :: + + GET /api/0/user/dudemcpants/requests/filed + + Parameters + ^^^^^^^^^^ + + +---------------+----------+--------------+----------------------------+ + | Key | Type | Optionality | Description | + +===============+==========+==============+============================+ + | ``username`` | string | Mandatory | | The username of the user | + | | | | whose activity you are | + | | | | interested in. | + +---------------+----------+--------------+----------------------------+ + | ``status`` | string | Optional | | Filter the status of | + | | | | pull requests. Default: | + | | | | ``Open`` (open pull | + | | | | requests), can be | + | | | | ``Closed`` for closed | + | | | | requests, ``Merged`` | + | | | | for merged requests, or | + | | | | ``Open`` for open | + | | | | requests. | + | | | | ``All`` returns closed, | + | | | | merged and open requests.| + +---------------+----------+--------------+----------------------------+ + + + Sample response + ^^^^^^^^^^^^^^^ + + :: + { + "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" + } + }, + "status": "Open", + "title": "Update README.md", + "uid": "819e0b1c449e414fa291c914f28d73ec", + "updated_on": "1510227832", + "user": { + "fullname": "Dude McPants", + "name": "dudemcpants" + } + } + ], + "total_requests": 1 + } + + """ + status = flask.request.args.get('status', 'open') + + pullrequests = pagure.lib.get_pull_request_of_user( + SESSION, + username=username + ) + + 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)) + + return flask.jsonify({ + 'total_requests': len(pullrequestslist), + 'requests': pullrequestslist, + 'args': { + 'username': username, + 'status': status, + } + }) + + +@API.route('/user//requests/actionable') +@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. + + :: + + GET /api/0/user//requests/actionable + + :: + + GET /api/0/user/dudemcpants/requests/actionable + + Parameters + ^^^^^^^^^^ + + +---------------+----------+--------------+----------------------------+ + | Key | Type | Optionality | Description | + +===============+==========+==============+============================+ + | ``username`` | string | Mandatory | | The username of the user | + | | | | whose activity you are | + | | | | interested in. | + +---------------+----------+--------------+----------------------------+ + | ``status`` | string | Optional | | Filter the status of | + | | | | pull requests. Default: | + | | | | ``Open`` (open pull | + | | | | requests), can be | + | | | | ``Closed`` for closed | + | | | | requests, ``Merged`` | + | | | | for merged requests, or | + | | | | ``Open`` for open | + | | | | requests. | + | | | | ``All`` returns closed, | + | | | | merged and open requests.| + +---------------+----------+--------------+----------------------------+ + + Sample response + ^^^^^^^^^^^^^^^ + + :: + { + "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" + } + }, + "status": "Open", + "title": "Update README.md", + "uid": "819e0b1c449e414fa291c914f28d73ec", + "updated_on": "1510227832", + "user": { + "fullname": "Dude McPants", + "name": "dudemcpants" + } + } + ], + "total_requests": 1 + } + + """ + status = flask.request.args.get('status', 'open') + + pullrequests = pagure.lib.get_pull_request_of_user( + SESSION, + username=username + ) + + 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)) + + return flask.jsonify({ + 'total_requests': len(pullrequestslist), + 'requests': pullrequestslist, + 'args': { + 'username': username, + 'status': status, + } + }) diff --git a/tests/test_pagure_flask_api_user.py b/tests/test_pagure_flask_api_user.py index a3c0f00..75fd77b 100644 --- a/tests/test_pagure_flask_api_user.py +++ b/tests/test_pagure_flask_api_user.py @@ -463,5 +463,386 @@ class PagureFlaskApiUSertests(tests.Modeltests): self.assertEqual(data, exp) +class PagureFlaskApiUsertestrequests(tests.Modeltests): + """ Tests for the user requests endpoints """ + + maxDiff = None + + def setUp(self): + """ Set up the environnment, ran before every tests. """ + super(PagureFlaskApiUsertestrequests, self).setUp() + + pagure.APP.config['TESTING'] = True + pagure.SESSION = self.session + pagure.api.SESSION = self.session + pagure.api.fork.SESSION = self.session + pagure.api.user.SESSION = self.session + pagure.lib.SESSION = self.session + + pagure.APP.config['REQUESTS_FOLDER'] = None + + tests.create_projects(self.session) + + # Create few pull-requests + repo = pagure.get_authorized_project(self.session, 'test') + forked_repo = pagure.get_authorized_project(self.session, 'test') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='open pullrequest by user foo on repo test', + 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( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='open pullrequest by user foo on repo test2', + user='foo', + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test') + forked_repo = pagure.get_authorized_project(self.session, 'test') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='closed pullrequest by user foo on repo test', + user='foo', + 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( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='closed pullrequest by user foo on repo test2', + user='foo', + status='Closed', + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test') + forked_repo = pagure.get_authorized_project(self.session, 'test') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='merged pullrequest by user foo on repo test', + user='foo', + 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( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='merged pullrequest by user foo on repo test2', + user='foo', + status='Merged', + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test') + forked_repo = pagure.get_authorized_project(self.session, 'test') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='open pullrequest by user pingou on repo test', + user='pingou', + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test2') + forked_repo = pagure.get_authorized_project(self.session, 'test2') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='open pullrequest by user pingou on repo test2', + user='pingou', + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test') + forked_repo = pagure.get_authorized_project(self.session, 'test') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='closed pullrequest by user pingou on repo test', + user='pingou', + status="Closed", + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test2') + forked_repo = pagure.get_authorized_project(self.session, 'test2') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='closed pullrequest by user pingou on repo test2', + user='pingou', + status="Closed", + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test') + forked_repo = pagure.get_authorized_project(self.session, 'test') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='merged pullrequest by user pingou on repo test', + user='pingou', + status="Merged", + requestfolder=None, + ) + self.session.commit() + + repo = pagure.get_authorized_project(self.session, 'test2') + forked_repo = pagure.get_authorized_project(self.session, 'test2') + pagure.lib.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from='master', + repo_to=repo, + branch_to='master', + title='merged pullrequest by user pingou on repo test2', + user='pingou', + status="Merged", + requestfolder=None, + ) + self.session.commit() + + @patch('pagure.lib.notify.send_email') + def test_api_view_user_requests_filed(self, mockemail): + """ Test the api_view_user_requests_filed method of the flask user + api """ + + # First we test without the status parameter. It should default to `open` + output = self.app.get( + '/api/0/user/pingou/requests/filed') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "pingou") + self.assertEqual(data['requests'][1]['user']['name'], "pingou") + self.assertEqual(data['requests'][0]['status'], "Open") + self.assertEqual(data['requests'][1]['status'], "Open") + 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") + + # Next test with the status parameter set to `open`. + output = self.app.get( + '/api/0/user/pingou/requests/filed?status=open') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "pingou") + self.assertEqual(data['requests'][1]['user']['name'], "pingou") + self.assertEqual(data['requests'][0]['status'], "Open") + self.assertEqual(data['requests'][1]['status'], "Open") + 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") + + # Next test with the status parameter set to `closed`. + output = self.app.get( + '/api/0/user/pingou/requests/filed?status=closed') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "pingou") + self.assertEqual(data['requests'][1]['user']['name'], "pingou") + self.assertEqual(data['requests'][0]['status'], "Closed") + self.assertEqual(data['requests'][1]['status'], "Closed") + 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") + + # Next test with the status parameter set to `merged`. + output = self.app.get( + '/api/0/user/pingou/requests/filed?status=merged') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "pingou") + self.assertEqual(data['requests'][1]['user']['name'], "pingou") + self.assertEqual(data['requests'][0]['status'], "Merged") + self.assertEqual(data['requests'][1]['status'], "Merged") + 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") + + # Finally, test with the status parameter set to `all`. + output = self.app.get( + '/api/0/user/pingou/requests/filed?status=all') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 6) + self.assertEqual(data['requests'][0]['user']['name'], "pingou") + self.assertEqual(data['requests'][1]['user']['name'], "pingou") + self.assertEqual(data['requests'][2]['user']['name'], "pingou") + self.assertEqual(data['requests'][3]['user']['name'], "pingou") + self.assertEqual(data['requests'][4]['user']['name'], "pingou") + self.assertEqual(data['requests'][5]['user']['name'], "pingou") + self.assertEqual(data['requests'][0]['status'], "Merged") + self.assertEqual(data['requests'][1]['status'], "Merged") + self.assertEqual(data['requests'][2]['status'], "Closed") + self.assertEqual(data['requests'][3]['status'], "Closed") + 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'][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") + + @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 + api """ + + # First we test without the status parameter. It should default to `open` + output = self.app.get( + '/api/0/user/pingou/requests/actionable') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "foo") + self.assertEqual(data['requests'][1]['user']['name'], "foo") + self.assertEqual(data['requests'][0]['status'], "Open") + self.assertEqual(data['requests'][1]['status'], "Open") + 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") + + # Next test with the status parameter set to `open`. + output = self.app.get( + '/api/0/user/pingou/requests/actionable?status=open') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "foo") + self.assertEqual(data['requests'][1]['user']['name'], "foo") + self.assertEqual(data['requests'][0]['status'], "Open") + self.assertEqual(data['requests'][1]['status'], "Open") + 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") + + # Next test with the status parameter set to `closed`. + output = self.app.get( + '/api/0/user/pingou/requests/actionable?status=closed') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "foo") + self.assertEqual(data['requests'][1]['user']['name'], "foo") + self.assertEqual(data['requests'][0]['status'], "Closed") + self.assertEqual(data['requests'][1]['status'], "Closed") + 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") + + # Next test with the status parameter set to `merged`. + output = self.app.get( + '/api/0/user/pingou/requests/actionable?status=merged') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 2) + self.assertEqual(data['requests'][0]['user']['name'], "foo") + self.assertEqual(data['requests'][1]['user']['name'], "foo") + self.assertEqual(data['requests'][0]['status'], "Merged") + self.assertEqual(data['requests'][1]['status'], "Merged") + 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") + + # Finally, test with the status parameter set to `all`. + output = self.app.get( + '/api/0/user/pingou/requests/actionable?status=all') + self.assertEqual(output.status_code, 200) + data = json.loads(output.data) + + self.assertEqual(len(data['requests']), 6) + self.assertEqual(data['requests'][0]['user']['name'], "foo") + self.assertEqual(data['requests'][1]['user']['name'], "foo") + self.assertEqual(data['requests'][2]['user']['name'], "foo") + self.assertEqual(data['requests'][3]['user']['name'], "foo") + self.assertEqual(data['requests'][4]['user']['name'], "foo") + self.assertEqual(data['requests'][5]['user']['name'], "foo") + self.assertEqual(data['requests'][0]['status'], "Merged") + self.assertEqual(data['requests'][1]['status'], "Merged") + self.assertEqual(data['requests'][2]['status'], "Closed") + self.assertEqual(data['requests'][3]['status'], "Closed") + 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'][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") + + + + if __name__ == '__main__': unittest.main(verbosity=2)