From 8322e91531bd1e7717d564b9abee5edae62a2e96 Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Tue, 15 Feb 2022 15:43:58 +0100 Subject: [PATCH] Add a delete_children query parameter on DestroyElement --- arkindex/documents/api/elements.py | 22 ++++++++++-- .../documents/tests/test_destroy_elements.py | 36 +++++++++++++++++-- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py index b93ab14ab7..ea5dd24839 100644 --- a/arkindex/documents/api/elements.py +++ b/arkindex/documents/api/elements.py @@ -873,8 +873,20 @@ class ElementChildren(ElementsListBase): get=extend_schema(description="Retrieve a single element's information and metadata"), patch=extend_schema(description='Rename an element'), put=extend_schema(description="Edit an element's attributes. Requires a write access on the corpus."), - delete=extend_schema(description='Delete an element. Requires either an admin access on the corpus, ' - 'or a write access and to be the creator of this element.'), + delete=extend_schema( + description='Delete an element. Requires either an admin access on the corpus, ' + 'or a write access and to be the creator of this element.', + parameters=[ + OpenApiParameter( + 'delete_children', + description='Delete all child elements of this element recursively. ' + 'By default, this only removes this element as a parent of the child elements, ' + 'without deleting any child element.', + type=bool, + required=False, + ), + ], + ), ) class ElementRetrieve(ACLMixin, RetrieveUpdateDestroyAPIView): serializer_class = ElementSerializer @@ -923,8 +935,12 @@ class ElementRetrieve(ACLMixin, RetrieveUpdateDestroyAPIView): def delete(self, request, *args, **kwargs): self.check_object_permissions(self.request, self.get_object()) + queryset = Element.objects.filter(id=self.kwargs['pk']) - element_trash(queryset, user_id=self.request.user.id) + delete_children = self.request.query_params.get('delete_children', 'false').lower() not in ('false', '0') + + element_trash(queryset, user_id=self.request.user.id, delete_children=delete_children) + return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/arkindex/documents/tests/test_destroy_elements.py b/arkindex/documents/tests/test_destroy_elements.py index 34be212608..06823b9c1a 100644 --- a/arkindex/documents/tests/test_destroy_elements.py +++ b/arkindex/documents/tests/test_destroy_elements.py @@ -58,11 +58,41 @@ class TestDestroyElements(FixtureAPITestCase): self.assertEqual(len(args), 0) self.assertCountEqual(list(kwargs.pop('queryset')), list(self.corpus.elements.filter(id=castle_story.id))) self.assertDictEqual(kwargs, { - 'delete_children': True, + 'delete_children': False, 'user_id': self.user.id, 'description': 'Element deletion', }) + @patch('arkindex.project.triggers.documents_tasks.element_trash.delay') + def test_element_destroy_delete_children(self, delay_mock): + self.client.force_login(self.user) + castle_story = self.corpus.elements.create( + type=self.volume_type, + name='Castle story' + ) + self.assertTrue(self.corpus.elements.filter(id=castle_story.id).exists()) + + for delete_children in [True, False]: + with self.subTest(delete_children=delete_children): + delay_mock.reset_mock() + + with self.assertNumQueries(7): + response = self.client.delete( + reverse('api:element-retrieve', kwargs={'pk': str(castle_story.id)}) + + f'?delete_children={delete_children}', + ) + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + self.assertEqual(delay_mock.call_count, 1) + args, kwargs = delay_mock.call_args + self.assertEqual(len(args), 0) + self.assertCountEqual(list(kwargs.pop('queryset')), list(self.corpus.elements.filter(id=castle_story.id))) + self.assertDictEqual(kwargs, { + 'delete_children': delete_children, + 'user_id': self.user.id, + 'description': 'Element deletion', + }) + @patch('arkindex.project.triggers.documents_tasks.element_trash.delay') def test_element_destroy_creator(self, delay_mock): """ @@ -84,7 +114,7 @@ class TestDestroyElements(FixtureAPITestCase): self.assertEqual(len(args), 0) self.assertCountEqual(list(kwargs.pop('queryset')), list(self.private_corpus.elements.filter(id=castle_story.id))) self.assertDictEqual(kwargs, { - 'delete_children': True, + 'delete_children': False, 'user_id': self.user.id, 'description': 'Element deletion', }) @@ -123,7 +153,7 @@ class TestDestroyElements(FixtureAPITestCase): self.assertEqual(len(args), 0) self.assertCountEqual(list(kwargs.pop('queryset')), list(self.corpus.elements.filter(id=self.vol.id))) self.assertDictEqual(kwargs, { - 'delete_children': True, + 'delete_children': False, 'user_id': self.user.id, 'description': 'Element deletion', }) -- GitLab