From 8ec167321e512b40f8aa372fefbd1069d6ba7ef3 Mon Sep 17 00:00:00 2001 From: mlbonhomme <bonhomme@teklia.com> Date: Thu, 9 Mar 2023 12:51:06 +0000 Subject: [PATCH] Add creator_email filter to element listing endpoints --- arkindex/documents/api/elements.py | 10 ++++ .../documents/tests/test_children_elements.py | 49 +++++++++++++++++++ .../documents/tests/test_corpus_elements.py | 47 +++++++++++++++++- .../documents/tests/test_parents_elements.py | 49 +++++++++++++++++++ 4 files changed, 154 insertions(+), 1 deletion(-) diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py index aa9215a3ce..fe62bc6b63 100644 --- a/arkindex/documents/api/elements.py +++ b/arkindex/documents/api/elements.py @@ -23,6 +23,7 @@ from django.db.models import ( from django.db.models.functions import Cast from django.shortcuts import get_object_or_404 from django.utils.functional import cached_property +from drf_spectacular.types import OpenApiTypes from drf_spectacular.utils import ( OpenApiParameter, PolymorphicProxySerializer, @@ -325,6 +326,12 @@ class ElementsListAutoSchema(AutoSchema): type=UUID, required=False, ), + OpenApiParameter( + 'creator_email', + description='Restrict to elements created by the user with the specified email address.', + type=OpenApiTypes.EMAIL, + required=False, + ), OpenApiParameter( 'classification_confidence', description='Restrict to elements having a classification with the given confidence. ' @@ -798,6 +805,9 @@ class ElementsListBase(CorpusACLMixin, DestroyModelMixin, ListAPIView): if 'name' in self.clean_params: filters &= Q(name__icontains=self.clean_params['name']) + if 'creator_email' in self.clean_params: + filters &= Q(creator__email=self.clean_params['creator_email']) + if 'rotation_angle' in self.clean_params: try: rotation_angle = int(self.clean_params['rotation_angle']) diff --git a/arkindex/documents/tests/test_children_elements.py b/arkindex/documents/tests/test_children_elements.py index 67ed18a55e..784450ed64 100644 --- a/arkindex/documents/tests/test_children_elements.py +++ b/arkindex/documents/tests/test_children_elements.py @@ -8,6 +8,7 @@ from arkindex.documents.models import Element, EntityType, MetaType, Transcripti from arkindex.process.models import WorkerRun, WorkerVersion from arkindex.project.aws import S3FileStatus from arkindex.project.tests import FixtureAPITestCase +from arkindex.users.models import User class TestChildrenElements(FixtureAPITestCase): @@ -688,6 +689,54 @@ class TestChildrenElements(FixtureAPITestCase): ] ) + def test_children_filter_creator_email(self): + element_type = self.corpus.types.first() + user2 = User.objects.get(email='user2@user.fr') + test_element = self.corpus.elements.create(type=element_type, name='Test Element', creator=user2) + test_element.add_parent(self.vol) + + with self.assertNumQueries(4): + response = self.client.get( + reverse('api:elements-children', kwargs={'pk': str(self.vol.id)}), + data={ + 'creator_email': 'user2@user.fr' + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.json()['results']), 1) + self.assertEqual(response.json()['results'][0]['name'], 'Test Element') + + def test_children_filter_creator_email_case_insensitive(self): + element_type = self.corpus.types.first() + user2 = User.objects.get(email='user2@user.fr') + test_element = self.corpus.elements.create(type=element_type, name='Test Element', creator=user2) + test_element.add_parent(self.vol) + + with self.assertNumQueries(4): + response = self.client.get( + reverse('api:elements-children', kwargs={'pk': str(self.vol.id)}), + data={ + 'creator_email': 'USEr2@user.fr' + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.json()['results']), 1) + self.assertEqual(response.json()['results'][0]['name'], 'Test Element') + + def test_children_filter_creator_email_does_not_exist(self): + """ + If there is no user with the given email, there is no error but no results are returned + """ + with self.assertNumQueries(2): + response = self.client.get( + reverse('api:elements-children', kwargs={'pk': str(self.vol.id)}), + data={ + 'creator_email': 'ohno@user.fr' + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.json()['results']), 0) + def test_children_filter_rotation_angle(self): element_type = self.corpus.types.first() not_rotated = self.corpus.elements.create(type=element_type, name='not rotated') diff --git a/arkindex/documents/tests/test_corpus_elements.py b/arkindex/documents/tests/test_corpus_elements.py index 0102b204f3..00b7b45401 100644 --- a/arkindex/documents/tests/test_corpus_elements.py +++ b/arkindex/documents/tests/test_corpus_elements.py @@ -5,9 +5,10 @@ import sqlparse from django.urls import reverse from rest_framework import status -from arkindex.documents.models import Corpus, Element, EntityType, MetaData, MetaType, Transcription +from arkindex.documents.models import Corpus, Element, ElementType, EntityType, MetaData, MetaType, Transcription from arkindex.process.models import WorkerVersion from arkindex.project.tests import FixtureAPITestCase +from arkindex.users.models import User class TestListElements(FixtureAPITestCase): @@ -136,6 +137,50 @@ class TestListElements(FixtureAPITestCase): for result in results: self.assertIn(nameSelected, result['name']) + def test_list_elements_filter_creator_email(self): + page_type = ElementType.objects.get(corpus=self.corpus, slug='page') + user2 = User.objects.get(email='user2@user.fr') + self.corpus.elements.create(type=page_type, name='Test Element', creator=user2) + mail = 'user2@user.fr' + with self.assertNumQueries(4): + response = self.client.get( + reverse('api:corpus-elements', kwargs={'corpus': self.corpus.id}), + data={'creator_email': mail} + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + results = response.json()['results'] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['name'], 'Test Element') + + def test_list_elements_filter_creator_email_case_insensitive(self): + page_type = ElementType.objects.get(corpus=self.corpus, slug='page') + user2 = User.objects.get(email='user2@user.fr') + self.corpus.elements.create(type=page_type, name='Test Element', creator=user2) + mail = 'UsER2@user.fr' + with self.assertNumQueries(4): + response = self.client.get( + reverse('api:corpus-elements', kwargs={'corpus': self.corpus.id}), + data={'creator_email': mail} + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + results = response.json()['results'] + self.assertEqual(len(results), 1) + self.assertEqual(results[0]['name'], 'Test Element') + + def test_list_elements_filter_creator_email_does_not_exist(self): + """ + If there is no user with the given email, there is no error but no results are returned + """ + mail = 'ohno@user.fr' + with self.assertNumQueries(2): + response = self.client.get( + reverse('api:corpus-elements', kwargs={'corpus': self.corpus.id}), + data={'creator_email': mail} + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + results = response.json()['results'] + self.assertEqual(len(results), 0) + def test_list_elements_corpus_uuid4(self): """ Ensure the corpus filter allows any UUID, not just version 4 UUIDs. diff --git a/arkindex/documents/tests/test_parents_elements.py b/arkindex/documents/tests/test_parents_elements.py index f07e4a0119..96d2e98a1c 100644 --- a/arkindex/documents/tests/test_parents_elements.py +++ b/arkindex/documents/tests/test_parents_elements.py @@ -7,6 +7,7 @@ from rest_framework import status from arkindex.documents.models import Corpus, Element, EntityType, MetaType from arkindex.process.models import WorkerVersion from arkindex.project.tests import FixtureAPITestCase +from arkindex.users.models import User class TestParentsElements(FixtureAPITestCase): @@ -397,6 +398,54 @@ class TestParentsElements(FixtureAPITestCase): expected_elements ) + def test_parents_filter_creator_email(self): + element_type = self.corpus.types.first() + user2 = User.objects.get(email='user2@user.fr') + parent_element = self.corpus.elements.create(type=element_type, name='Test Element', creator=user2) + self.page.add_parent(parent_element) + + with self.assertNumQueries(4): + response = self.client.get( + reverse('api:elements-parents', kwargs={'pk': str(self.page.id)}), + data={ + 'creator_email': 'user2@user.fr' + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.json()['results']), 1) + self.assertEqual(response.json()['results'][0]['name'], 'Test Element') + + def test_parents_filter_creator_email_case_insensitive(self): + element_type = self.corpus.types.first() + user2 = User.objects.get(email='user2@user.fr') + parent_element = self.corpus.elements.create(type=element_type, name='Test Element', creator=user2) + self.page.add_parent(parent_element) + + with self.assertNumQueries(4): + response = self.client.get( + reverse('api:elements-parents', kwargs={'pk': str(self.page.id)}), + data={ + 'creator_email': 'USEr2@user.fr' + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.json()['results']), 1) + self.assertEqual(response.json()['results'][0]['name'], 'Test Element') + + def test_parents_filter_creator_email_does_not_exist(self): + """ + If there is no user with the given email, there is no error but no results are returned + """ + with self.assertNumQueries(2): + response = self.client.get( + reverse('api:elements-parents', kwargs={'pk': str(self.page.id)}), + data={ + 'creator_email': 'ohno@user.fr' + } + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.json()['results']), 0) + def test_parents_invalid_order(self): cases = [ ({'order': 'blah', 'order_direction': 'asc'}, {'order': ['Unknown sorting field']}), -- GitLab