From 39cfdd1190049c009c0e44d361b77b720b4fdcc8 Mon Sep 17 00:00:00 2001 From: Mikko Nieminen Date: Mon, 20 Jan 2025 15:36:20 +0100 Subject: [PATCH] add timeline event creation (#1090) --- projectroles/tests/test_views.py | 22 ++++++++------- projectroles/views.py | 47 ++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/projectroles/tests/test_views.py b/projectroles/tests/test_views.py index 345d48d2..932f7878 100644 --- a/projectroles/tests/test_views.py +++ b/projectroles/tests/test_views.py @@ -2606,10 +2606,10 @@ class TestProjectDeleteView( """Tests for ProjectDeleteView""" @classmethod - def _get_tl(cls): + def _get_delete_tl(cls): return TimelineEvent.objects.filter(event_name='project_delete') - def _get_alerts(self): + def _get_delete_alerts(self): return self.app_alert_model.objects.filter(alert_name='project_delete') def setUp(self): @@ -2664,10 +2664,11 @@ def test_get_category(self): def test_post(self): """Test ProjectDeleteView POST""" self.assertEqual(Project.objects.count(), 2) - ''' - self.assertEqual(self._get_tl().count(), 0) - self.assertEqual(self._get_alerts().count(), 0) - ''' + self.assertEqual( + RoleAssignment.objects.filter(project=self.project).count(), 2 + ) + self.assertEqual(self._get_delete_tl().count(), 0) + self.assertEqual(self._get_delete_alerts().count(), 0) self.assertEqual(len(mail.outbox), 0) with self.login(self.user): @@ -2685,11 +2686,12 @@ def test_post(self): Project.objects.filter(sodar_uuid=self.project.sodar_uuid).first(), None, ) + self.assertEqual( + RoleAssignment.objects.filter(project=self.project).count(), 0 + ) + self.assertEqual(self._get_delete_tl().count(), 1) + # self.assertEqual(self._get_delete_alerts().count(), 1) ''' - self.assertEqual(self._get_tl().count(), 1) - # Only the contributor should receive an alert - self.assertEqual(self._get_alerts().count(), 1) - self.assertEqual(self._get_alerts().first().user, self.user_contributor) self.assertEqual(len(mail.outbox), 1) self.assertIn( SUBJECT_PROJECT_ARCHIVE.format( diff --git a/projectroles/views.py b/projectroles/views.py index 840d9505..79e3a55a 100644 --- a/projectroles/views.py +++ b/projectroles/views.py @@ -1669,7 +1669,42 @@ def handle_delete(self, project, request): :param project: Project object of project to be deleted :param request: HttpRequest object """ - # TODO: Add all necessary logic here + timeline = get_backend_api('timeline_backend') + if timeline: + local_users = { + a.user.username: a.role.name + for a in project.local_roles.order_by( + 'role__rank', 'user__username' + ) + } + extra_data = { + 'title': project.title, + 'type': project.type, + 'parent': ( + str(project.parent.sodar_uuid) if project.parent else None + ), + 'description': project.description, + 'readme': project.readme.raw, + 'public_guest_access': project.public_guest_access, + 'archive': project.archive, + 'full_title': project.full_title, + 'sodar_uuid': str(project.sodar_uuid), + 'local_roles': local_users, + } + timeline.add_event( + project=None, # No project as it has been deleted + app_name=APP_NAME, + user=request.user, + event_name='project_delete', + description=f'delete {project.type.lower()} "{project.title}"', + extra_data=extra_data, + classified=True, + status_type=timeline.TL_STATUS_OK, + ) + # TODO: Get project members, including inherited, omit request user + # TODO: Send alerts + # TODO: Send email + # Actually delete project project.delete() @@ -1697,7 +1732,8 @@ def get_context_data(self, *args, **kwargs): def post(self, *args, **kwargs): project = self.get_object() try: - self.handle_delete(project, self.request) + with transaction.atomic(): + self.handle_delete(project, self.request) p_type = get_display_name(project.type, title=True) messages.success(self.request, f'{p_type} deleted.') if project.parent: @@ -1708,11 +1744,12 @@ def post(self, *args, **kwargs): else: redirect_url = reverse('home') except Exception as ex: - p_type = get_display_name(self.object.type, title=False) + if settings.DEBUG: + raise ex + p_type = get_display_name(project.type, title=False) messages.error(self.request, f'Failed to delete {p_type}: {ex}') redirect_url = reverse( - 'projectroles:update', - kwargs={'project': self.object.sodar_uuid}, + 'projectroles:update', kwargs={'project': project.sodar_uuid} ) return redirect(redirect_url)