diff --git a/pagure/api/fork.py b/pagure/api/fork.py index b028771..e1330f4 100644 --- a/pagure/api/fork.py +++ b/pagure/api/fork.py @@ -87,6 +87,13 @@ def api_pull_request_views(repo, username=None, namespace=None): | ``author`` | string | Optional | | Filter the author of | | | | | pull requests | +---------------+----------+--------------+----------------------------+ + | ``tags`` | string | Optional | | A list of tags you | + | | | | wish to filter. If you | + | | | | want to filter for pull | + | | | | requests not having a | + | | | | tag, add an exclamation | + | | | | mark in front of it | + +---------------+----------+--------------+----------------------------+ Sample response ^^^^^^^^^^^^^^^ @@ -97,7 +104,8 @@ def api_pull_request_views(repo, username=None, namespace=None): "args": { "assignee": null, "author": null, - "status": true + "status": true, + "tags": null }, "total_requests": 1, "requests": [ @@ -154,6 +162,8 @@ def api_pull_request_views(repo, username=None, namespace=None): status = flask.request.args.get("status", True) assignee = flask.request.args.get("assignee", None) author = flask.request.args.get("author", None) + tags = flask.request.args.getlist("tags") + tags = [tag.strip() for tag in tags if tag.strip()] status_text = ("%s" % status).lower() requests = [] @@ -164,6 +174,7 @@ def api_pull_request_views(repo, username=None, namespace=None): status=False, assignee=assignee, author=author, + tags=tags, ) elif status_text == "all": @@ -173,6 +184,7 @@ def api_pull_request_views(repo, username=None, namespace=None): status=None, assignee=assignee, author=author, + tags=tags, ) else: @@ -182,6 +194,7 @@ def api_pull_request_views(repo, username=None, namespace=None): assignee=assignee, author=author, status=status, + tags=tags, ) page = get_page() @@ -201,7 +214,12 @@ def api_pull_request_views(repo, username=None, namespace=None): "requests": [ request.to_json(public=True, api=True) for request in requests_page ], - "args": {"status": status, "assignee": assignee, "author": author}, + "args": { + "status": status, + "assignee": assignee, + "author": author, + "tags": tags, + }, } if pagination_metadata: jsonout["args"]["page"] = page diff --git a/tests/test_pagure_flask_api_fork.py b/tests/test_pagure_flask_api_fork.py index 8f1c9f3..feb03fa 100644 --- a/tests/test_pagure_flask_api_fork.py +++ b/tests/test_pagure_flask_api_fork.py @@ -123,6 +123,7 @@ class PagureFlaskApiForktests(tests.Modeltests): "args": { "assignee": None, "author": None, + "tags": [], "page": 1, "per_page": 20, "status": "closed", @@ -158,6 +159,7 @@ class PagureFlaskApiForktests(tests.Modeltests): { "assignee": None, "author": None, + "tags": [], "page": 1, "per_page": 20, "status": "closed", @@ -301,6 +303,7 @@ class PagureFlaskApiForktests(tests.Modeltests): { "assignee": None, "author": None, + "tags": [], "page": 1, "per_page": 20, "status": "all", @@ -325,6 +328,7 @@ class PagureFlaskApiForktests(tests.Modeltests): { "assignee": None, "author": None, + "tags": [], "page": 1, "per_page": 20, "status": "all", @@ -386,6 +390,7 @@ class PagureFlaskApiForktests(tests.Modeltests): "args": { "assignee": None, "author": None, + "tags": [], "page": 1, "per_page": 20, "status": True, @@ -514,6 +519,126 @@ class PagureFlaskApiForktests(tests.Modeltests): self.assertDictEqual(data, data2) @patch("pagure.lib.notify.send_email") + def test_api_pull_request_view_tag_filtered(self, send_email): + """ Test the api_pull_request_view method of the flask api to list + tag filtered open PRs. """ + send_email.return_value = True + tests.create_projects(self.session) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + repo = pagure.lib.query.get_authorized_project(self.session, "test") + + # Add a tag + pagure.lib.query.new_tag( + self.session, "tag-1", "tag-1 description", "#ff0000", repo.id + ) + # Create a pull-request + forked_repo = pagure.lib.query.get_authorized_project( + self.session, "test" + ) + req = pagure.lib.query.new_pull_request( + session=self.session, + repo_from=forked_repo, + branch_from="master", + repo_to=repo, + branch_to="master", + title="test pull-request", + user="pingou", + ) + self.session.commit() + self.assertEqual(req.id, 1) + self.assertEqual(req.title, "test pull-request") + + output = self.app.get("/api/0/test/pull-requests?tags=tag-1") + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + for k in ["first", "last"]: + self.assertIsNotNone(data["pagination"][k]) + data["pagination"][k] = "http://localhost..." + self.assertDictEqual( + data, + { + "args": { + "assignee": None, + "author": None, + "tags": ["tag-1"], + "page": 1, + "per_page": 20, + "status": True, + }, + "pagination": { + "first": "http://localhost...", + "last": "http://localhost...", + "next": None, + "page": 1, + "pages": 0, + "per_page": 20, + "prev": None, + }, + "requests": [], + "total_requests": 0, + }, + ) + + # Tag the PR and try again + pagure.lib.query.update_tags( + self.session, obj=req, tags=["tag-1"], username="pingou" + ) + self.session.commit() + + output = self.app.get("/api/0/test/pull-requests?tags=tag-1") + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + self.assertEqual( + sorted(data.keys()), + ["args", "pagination", "requests", "total_requests"], + ) + self.assertDictEqual( + data["args"], + { + "assignee": None, + "author": None, + "tags": ["tag-1"], + "page": 1, + "per_page": 20, + "status": True, + }, + ) + self.assertEqual(data["total_requests"], 1) + + # Try negative filtering + output = self.app.get("/api/0/test/pull-requests?tags=!tag-1") + self.assertEqual(output.status_code, 200) + data = json.loads(output.get_data(as_text=True)) + for k in ["first", "last"]: + self.assertIsNotNone(data["pagination"][k]) + data["pagination"][k] = "http://localhost..." + self.assertDictEqual( + data, + { + "args": { + "assignee": None, + "author": None, + "tags": ["!tag-1"], + "page": 1, + "per_page": 20, + "status": True, + }, + "pagination": { + "first": "http://localhost...", + "last": "http://localhost...", + "next": None, + "page": 1, + "pages": 0, + "per_page": 20, + "prev": None, + }, + "requests": [], + "total_requests": 0, + }, + ) + + @patch("pagure.lib.notify.send_email") def test_api_pull_request_view_pr_disabled(self, send_email): """ Test the api_pull_request_view method of the flask api. """ send_email.return_value = True diff --git a/tests/test_pagure_flask_api_ui_private_repo.py b/tests/test_pagure_flask_api_ui_private_repo.py index b495f0b..6d6451b 100644 --- a/tests/test_pagure_flask_api_ui_private_repo.py +++ b/tests/test_pagure_flask_api_ui_private_repo.py @@ -1508,6 +1508,7 @@ class PagurePrivateRepotest(tests.Modeltests): "args": { "assignee": None, "author": None, + "tags": [], "page": 1, "per_page": 20, "status": True,