From d654219208bcab13c26a7ed1eb9035b0da6c2620 Mon Sep 17 00:00:00 2001 From: Yoann Schneider <yschneider@teklia.com> Date: Tue, 26 Apr 2022 10:50:36 +0000 Subject: [PATCH] Allow filtering by worker types --- arkindex/dataimport/api.py | 21 ++++++-- arkindex/dataimport/tests/test_workers.py | 59 +++++++++++++++++++++++ 2 files changed, 77 insertions(+), 3 deletions(-) diff --git a/arkindex/dataimport/api.py b/arkindex/dataimport/api.py index 136c1b79ee..dad6d83f7d 100644 --- a/arkindex/dataimport/api.py +++ b/arkindex/dataimport/api.py @@ -797,19 +797,34 @@ class WorkerList(WorkerACLMixin, ListCreateAPIView): queryset = Worker.objects.none() def filter_queryset(self, qs): + filters = Q() + repo_id = self.request.query_params.get('repository_id') if repo_id: try: repo_id = UUID(repo_id) except (TypeError, ValueError): raise ValidationError({'repository_id': ['Invalid UUID']}) - qs = qs.filter(repository_id=repo_id) + filters &= Q(repository_id=repo_id) name_filter = self.request.query_params.get('name') if name_filter: - qs = qs.filter(name__icontains=name_filter) + filters &= Q(name__icontains=name_filter) - return super().filter_queryset(qs) + worker_type = self.request.query_params.get('type') + if worker_type: + try: + worker_type_id = UUID(worker_type) + filters &= Q(type_id=worker_type_id) + except ValueError: + # If the given type is not a worker_type id, it might be a worker_type__slug + try: + worker_type = WorkerType.objects.get(slug=worker_type) + except WorkerType.DoesNotExist: + raise ValidationError({'type': ['No registered worker type with that slug.']}) + filters &= Q(type_id=worker_type.id) + + return super().filter_queryset(qs.filter(filters)) def get_queryset(self): """ diff --git a/arkindex/dataimport/tests/test_workers.py b/arkindex/dataimport/tests/test_workers.py index c5e866dbf1..18f2c7e183 100644 --- a/arkindex/dataimport/tests/test_workers.py +++ b/arkindex/dataimport/tests/test_workers.py @@ -104,6 +104,65 @@ class TestWorkersWorkerVersions(FixtureAPITestCase): ] }) + def test_workers_list_filter_type_slug(self): + """ + User is able to filter workers on the repository by worker type slug + """ + self.client.force_login(self.user) + with self.assertNumQueries(8): + response = self.client.get(reverse('api:workers-list'), {'type': 'dla'}) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertDictEqual(response.json(), { + 'count': 1, + 'next': None, + 'number': 1, + 'previous': None, + 'results': [ + { + 'id': str(self.worker_2.id), + 'repository_id': str(self.repo.id), + 'name': 'Document layout analyser', + 'slug': 'dla', + 'type': 'dla', + } + ] + }) + + def test_workers_list_filter_invalid_type_slug(self): + """ + Raise when trying to filter workers with an invalid type slug + """ + self.client.force_login(self.user) + with self.assertNumQueries(3): + response = self.client.get(reverse('api:workers-list'), {'type': 'invalid-slug'}) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + self.assertDictEqual(response.json(), {"type": ['No registered worker type with that slug.']}) + + def test_workers_list_filter_type_id(self): + """ + User is able to filter workers on the repository by worker type id + """ + worker_type_dla = WorkerType.objects.get(slug="dla") + self.client.force_login(self.user) + with self.assertNumQueries(7): + response = self.client.get(reverse('api:workers-list'), {'type': worker_type_dla.id}) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertDictEqual(response.json(), { + 'count': 1, + 'next': None, + 'number': 1, + 'previous': None, + 'results': [ + { + 'id': str(self.worker_2.id), + 'repository_id': str(self.repo.id), + 'name': 'Document layout analyser', + 'slug': 'dla', + 'type': 'dla', + } + ] + }) + def test_workers_list_requires_contributor(self): """ User is not able to list workers with a guest access -- GitLab