]> git.ipfire.org Git - thirdparty/patchwork.git/commitdiff
REST: Allow filtering of users by usernames
authorStephen Finucane <stephen@that.guru>
Sun, 10 Dec 2017 17:30:35 +0000 (17:30 +0000)
committerStephen Finucane <stephen@that.guru>
Tue, 9 Jan 2018 23:45:52 +0000 (23:45 +0000)
Signed-off-by: Stephen Finucane <stephen@that.guru>
patchwork/api/filters.py
patchwork/tests/test_rest_api.py
patchwork/tests/utils.py
releasenotes/notes/improved-rest-filtering-bf68399270a9b245.yaml

index fd33e017c369c5a67a0f816722e2f548b1b09b66..d207b2b6b3c750fefb18a6178aa78c4877c8350c 100644 (file)
@@ -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
@@ -148,8 +149,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')
@@ -164,6 +181,8 @@ class EventFilter(ProjectMixin, TimestampMixin, FilterSet):
 
 class BundleFilter(ProjectMixin, FilterSet):
 
+    owner = UserFilter(queryset=User.objects.all())
+
     class Meta:
         model = Bundle
         fields = ('project', 'owner', 'public')
index 7d10f909716fe593e0af0f1ff9d832ef778f94a8..3e264e154ee1cd260fc6ad948d441ee66d1bf5e9 100644 (file)
@@ -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)
index d4005c7729e847f641f06972760e8df958b13fd7..004c2ca0a541021aeee1b27041b57cd0fdbb30ea 100644 (file)
@@ -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
index fda68790e6fd95ce2b6a6672e384196fc4c1efbc..b1d12eb634841232ea24975039afd54fb21ee251 100644 (file)
@@ -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