diff --git a/src/api/tests/messages.py b/src/api/tests/messages.py index 77b9649dce27d2a15509435bb31c341290696783..fdde3af340a281b68309a49f2c4e4ac42a1c5927 100644 --- a/src/api/tests/messages.py +++ b/src/api/tests/messages.py @@ -318,3 +318,54 @@ class MessagesTestCase(TestCase): self.assertEqual(DirectMessage.objects.all().count(), 3) dm3 = DirectMessage.objects.get(pk=resp.json()['id']) self.assertTrue(dm3.deleted_by_recipient) + + def test_DirectMessageDelete(self): + c = Client() + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(uuid.uuid4())})) + self.assertEqual(resp.status_code, 403) + c.force_login(self.human_user1) + + dm = DirectMessage( + conference=self.conference1, + sender=self.human_user1, + recipient=self.human_user2, + timestamp=datetime(2020, 5, 4, 3, 2, 1, tzinfo=UTC), + subject='Test Message', + body='Message Body', + ) + dm.save() + + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)})) + self.assertEqual(resp.status_code, 204) + dm.refresh_from_db() + self.assertTrue(dm.deleted_by_sender) + self.assertFalse(dm.deleted_by_recipient) + + dm = DirectMessage( + conference=self.conference1, + sender=self.human_user2, + recipient=self.human_user1, + timestamp=datetime(2020, 1, 2, 3, 4, 5, tzinfo=UTC), + subject='Test Message2', + body='Message Body2', + ) + dm.save() + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)})) + self.assertEqual(resp.status_code, 204) + dm.refresh_from_db() + self.assertFalse(dm.deleted_by_sender) + self.assertTrue(dm.deleted_by_recipient) + + dm = DirectMessage( + conference=self.conference1, + sender=self.human_user2, + recipient=self.human_user1, + timestamp=datetime(2020, 2, 2, 2, 2, 2, tzinfo=UTC), + deleted_by_sender=True, + subject='Test Message3', + body='Message Body3', + ) + dm.save() + resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)})) + self.assertEqual(resp.status_code, 204) + self.assertEqual(DirectMessage.objects.filter(pk=dm.pk).count(), 0) diff --git a/src/api/urls.py b/src/api/urls.py index b92ea88dca3a9781b96bf6d0306ee9fa74f345ef..8b618b9743729cffacb04f7193e364b5eb4cd352 100644 --- a/src/api/urls.py +++ b/src/api/urls.py @@ -20,6 +20,7 @@ urlpatterns = [ path('me/received-messages/<uuid:pk>', messages.DirectMessageReceived.as_view(), name='my-message-received'), path('me/sent-messages/<uuid:pk>', messages.DirectMessageSent.as_view(), name='my-message-sent'), path('me/send-message', messages.DirectMessageSend.as_view(), name='my-send-message'), + path('me/delete-message/<uuid:pk>', messages.DirectMessageDelete.as_view(), name='my-delete-message'), path('me/friends', users.friends, name='friends'), path('me/timeline', users.UserTimelineList.as_view(), name='timeline-list'), # conference-specific views diff --git a/src/api/views/messages.py b/src/api/views/messages.py index 1e9adb8176771bc3d75ee2fb19fb7a0949e25a40..01a3ecf3266d9f84dc9f302736355978944ee579 100644 --- a/src/api/views/messages.py +++ b/src/api/views/messages.py @@ -1,9 +1,16 @@ -from django.conf import settings from rest_framework import generics, permissions +from django.db.models import Q + from core.models.messages import DirectMessage -from ..serializers import DirectMessageSerializerReceived, DirectMessageSerializerReceivedShort, DirectMessageSerializerSent, DirectMessageSerializerSentShort, DirectMessageSendSerializer +from ..serializers import ( + DirectMessageSendSerializer, + DirectMessageSerializerReceived, + DirectMessageSerializerReceivedShort, + DirectMessageSerializerSent, + DirectMessageSerializerSentShort, +) from .mixins import ConferenceSlugMixin @@ -65,3 +72,30 @@ class DirectMessageSend(ConferenceSlugMixin, generics.CreateAPIView): sender=self.request.user, deleted_by_recipient=self.request.user != serializer.validated_data['recipient'] and self.request.user.shadow_banned, ) + + +class DirectMessageDelete(ConferenceSlugMixin, generics.DestroyAPIView): + permission_classes = [permissions.IsAuthenticated] + + def get_queryset(self): + return DirectMessage.objects.filter( + Q(conference=self.conference, recipient=self.request.user, deleted_by_recipient=False) + | Q(conference=self.conference, sender=self.request.user, deleted_by_sender=False) + ) + + def perform_destroy(self, instance: DirectMessage): + if instance.sender == self.request.user: + if instance.deleted_by_recipient: + instance.delete() + return + + instance.deleted_by_sender = True + instance.save(update_fields=['deleted_by_sender']) + + elif instance.recipient == self.request.user: + if instance.deleted_by_sender: + instance.delete() + return + + instance.deleted_by_recipient = True + instance.save(update_fields=['deleted_by_recipient'])