diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py index aa9215a3ce7140946cfeeaed6d880bf728810e9c..fe62bc6b63b110b112a051d06c5ec50714fba0f4 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 67ed18a55e40346cc83ebefd91cb8f6cffb907dc..784450ed643910da0fc8c15de4ae16f950f1a372 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 0102b204f340355fbbcd9ecafa21b1bf3026d96b..00b7b45401b57fdb3a2d400aacedd12cb921b140 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 f07e4a0119708d1dfe72aaffd83b0c0113341f3c..96d2e98a1cb5f74d9e6042d06afa99fab32a46f5 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']}),