Browse Source

Tag filtering support on api pull requests endpoint

Julen Landa Alustiza 4 years ago
parent
commit
49aa66f53b

+ 20 - 2
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

+ 125 - 0
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,
@@ -513,6 +518,126 @@ class PagureFlaskApiForktests(tests.Modeltests):
             data2["pagination"][k] = "http://localhost..."
         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. """

+ 1 - 0
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,