diff mbox series

[4/4] REST: Allow filtering of users by usernames

Message ID 20171210173035.24778-4-stephen@that.guru
State Accepted
Headers show
Series [1/4] Modify sections used in release notes | expand

Commit Message

Stephen Finucane Dec. 10, 2017, 5:30 p.m. UTC
Signed-off-by: Stephen Finucane <stephen@that.guru>
---
 patchwork/api/filters.py                             | 19 +++++++++++++++++++
 patchwork/tests/test_rest_api.py                     | 20 +++++++++++++++++++-
 patchwork/tests/utils.py                             |  4 +++-
 .../improved-rest-filtering-bf68399270a9b245.yaml    |  7 +++++++
 4 files changed, 48 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py
index c34f5496..85a74afc 100644
--- a/patchwork/api/filters.py
+++ b/patchwork/api/filters.py
@@ -17,6 +17,7 @@ 
 # along with Patchwork; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+from django.contrib.auth.models import User
 from django.core.exceptions import ValidationError
 from django_filters import FilterSet
 from django_filters import IsoDateTimeFilter
@@ -149,8 +150,24 @@  class PatchFilter(ProjectMixin, TimestampMixin, FilterSet):
                   'state', 'archived')
 
 
+class UserChoiceField(ModelMultiChoiceField):
+
+    def _get_filters(self, value):
+        try:
+            return {'pk': int(value)}
+        except ValueError:
+            return {'username__iexact': value}
+
+
+class UserFilter(ModelChoiceFilter):
+
+    field_class = UserChoiceField
+
+
 class CheckFilter(TimestampMixin, FilterSet):
 
+    user = UserFilter(queryset=User.objects.all())
+
     class Meta:
         model = Check
         fields = ('user', 'state', 'context')
@@ -165,6 +182,8 @@  class EventFilter(ProjectMixin, TimestampMixin, FilterSet):
 
 class BundleFilter(ProjectMixin, FilterSet):
 
+    owner = UserFilter(queryset=User.objects.all())
+
     class Meta:
         model = Bundle
         fields = ('project', 'owner', 'public')
diff --git a/patchwork/tests/test_rest_api.py b/patchwork/tests/test_rest_api.py
index 7d10f909..3e264e15 100644
--- a/patchwork/tests/test_rest_api.py
+++ b/patchwork/tests/test_rest_api.py
@@ -708,6 +708,14 @@  class TestCheckAPI(APITestCase):
         self.assertEqual(1, len(resp.data))
         self.assertSerialized(check_obj, resp.data[0])
 
+        # test filtering by owner, both ID and username
+        resp = self.client.get(self.api_url(), {'user': self.user.id})
+        self.assertEqual([check_obj.id], [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'user': self.user.username})
+        self.assertEqual([check_obj.id], [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'user': 'otheruser'})
+        self.assertEqual(0, len(resp.data))
+
     def test_detail(self):
         """Validate we can get a specific check."""
         check = self._create_check()
@@ -794,7 +802,7 @@  class TestBundleAPI(APITestCase):
         self.assertEqual(status.HTTP_200_OK, resp.status_code)
         self.assertEqual(0, len(resp.data))
 
-        user = create_user()
+        user = create_user(username='myuser')
         project = create_project(linkname='myproject')
         bundle_public = create_bundle(public=True, owner=user,
                                       project=project)
@@ -826,6 +834,16 @@  class TestBundleAPI(APITestCase):
         resp = self.client.get(self.api_url(), {'project': 'invalidproject'})
         self.assertEqual(0, len(resp.data))
 
+        # test filtering by owner, both ID and username
+        resp = self.client.get(self.api_url(), {'owner': user.id})
+        self.assertEqual([bundle_public.id, bundle_private.id],
+                         [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'owner': 'myuser'})
+        self.assertEqual([bundle_public.id, bundle_private.id],
+                         [x['id'] for x in resp.data])
+        resp = self.client.get(self.api_url(), {'owner': 'otheruser'})
+        self.assertEqual(0, len(resp.data))
+
     def test_detail(self):
         """Validate we can get a specific bundle."""
         bundle = create_bundle(public=True)
diff --git a/patchwork/tests/utils.py b/patchwork/tests/utils.py
index d4005c77..004c2ca0 100644
--- a/patchwork/tests/utils.py
+++ b/patchwork/tests/utils.py
@@ -101,15 +101,17 @@  def create_user(link_person=True, **kwargs):
     num = User.objects.count()
 
     values = {
+        'username': 'test_user_%d' % num,
         'name': 'test_user_%d' % num,
         'email': 'test_user_%d@example.com' % num,
     }
     values.update(kwargs)
 
-    user = User.objects.create_user(values['name'], values['email'],
+    user = User.objects.create_user(values['username'], values['email'],
                                     values['name'])
 
     if link_person:
+        values.pop('username')
         create_person(user=user, **values)
 
     return user
diff --git a/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml b/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml
index fda68790..b1d12eb6 100644
--- a/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml
+++ b/releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml
@@ -7,3 +7,10 @@  api:
     .. code-block:: shell
 
        $ curl /covers/?submitter=stephen@that.guru
+  - |
+    Bundles can be filtered by owner and checks by user using username. For
+    example:
+
+    .. code-block:: shell
+
+       $ curl /bundles/?owner=stephenfin