diff --git a/arkindex/documents/api/elements.py b/arkindex/documents/api/elements.py index e6900c8f4b0d38c110947616afd16a98c3c9a271..1afd478b6f0eb2a2a56d71268d5cfe988a383d13 100644 --- a/arkindex/documents/api/elements.py +++ b/arkindex/documents/api/elements.py @@ -1181,6 +1181,10 @@ class CorpusDeleteSelection(SelectionMixin, DestroyAPIView): } def delete(self, request, *args, **kwargs): + rights = Corpus.objects.get(id=self.kwargs['pk']).get_acl_rights(request.user) + if Right.Admin not in rights: + self.permission_denied(request, message='You do not have admin access to delete elements on this corpus.') + selected_elements = self.get_selection(corpus_id=self.kwargs['pk']) if not selected_elements.exists(): raise NotFound diff --git a/arkindex/documents/tests/test_corpus.py b/arkindex/documents/tests/test_corpus.py index f64d10e084227220ca02e12644f10afdad94063a..491738b9e6580e8003f7819a8f22d908d5490641 100644 --- a/arkindex/documents/tests/test_corpus.py +++ b/arkindex/documents/tests/test_corpus.py @@ -387,3 +387,46 @@ class TestCorpus(FixtureAPITestCase): description=f'Deletion of corpus {self.corpus_private.name}', user_id=self.user.id, )) + + def test_delete_selected_elements_requires_login(self): + response = self.client.delete(reverse('api:corpus-delete-selection', kwargs={'pk': self.corpus_private.id})) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + def test_delete_selected_elements_requires_admin_right(self): + self.assertNotIn(Right.Admin, self.corpus_private.get_acl_rights(self.user)) + self.client.force_login(self.user) + response = self.client.delete(reverse('api:corpus-delete-selection', kwargs={'pk': self.corpus_private.id})) + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + @patch('arkindex.project.triggers.tasks.element_trash.delay') + def test_delete_selected_elements(self, delay_mock): + act_type, _ = self.corpus_private.types.get_or_create( + slug='act', + display_name='Act', + ) + act_x = Element.objects.create( + type=act_type, + corpus=self.corpus_private, + name='Act xxx', + ) + Element.objects.create( + type=act_type, + corpus=self.corpus_private, + name='Act yyy', + ) + self.superuser.selected_elements.add(act_x) + + self.client.force_login(self.superuser) + with self.assertNumQueries(6): + response = self.client.delete(reverse('api:corpus-delete-selection', kwargs={'pk': self.corpus_private.id})) + 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(Element.objects.filter(id=act_x.id))) + self.assertDictEqual(kwargs, { + 'delete_children': True, + 'user_id': self.superuser.id, + 'description': 'Element deletion', + })