From 4642abd642aa8dd6320126ee4a4032021e731036 Mon Sep 17 00:00:00 2001
From: GraceDB <gracedb@gracedb-dev1.ligo.uwm.edu>
Date: Wed, 7 Nov 2018 13:57:29 -0600
Subject: [PATCH] Update SupereventEventViewSet deletion handling

We now use ValidateDestroyMixin rather than SafeDeleteMixin for
handling removal of events from a superevent.  Some additional
logic in other places was no longer needed.
---
 gracedb/api/v1/superevents/views.py | 19 ++++++++++++++++---
 gracedb/superevents/models.py       |  4 ----
 gracedb/superevents/utils.py        |  6 ------
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/gracedb/api/v1/superevents/views.py b/gracedb/api/v1/superevents/views.py
index 94b2a17d8..36bee1efe 100644
--- a/gracedb/api/v1/superevents/views.py
+++ b/gracedb/api/v1/superevents/views.py
@@ -107,7 +107,7 @@ class SupereventViewSet(SafeCreateMixin, viewsets.ModelViewSet):
         return Response(serializer.data)
 
 
-class SupereventEventViewSet(SafeDestroyMixin,
+class SupereventEventViewSet(ValidateDestroyMixin,
                              SupereventNestedViewSet):
     """View for events attached to a superevent"""
     serializer_class = SupereventEventSerializer
@@ -115,8 +115,6 @@ class SupereventEventViewSet(SafeDestroyMixin,
     permission_classes = (permissions.IsAuthenticatedOrReadOnly,
         EventParentSupereventPermissions,)
     lookup_url_kwarg = 'graceid'
-    destroy_error_classes = (Superevent.PreferredEventRemovalError,)
-    destroy_error_response_status = status.HTTP_400_BAD_REQUEST
     list_view_order_by = ('pk',)
 
     def get_object(self):
@@ -130,6 +128,21 @@ class SupereventEventViewSet(SafeDestroyMixin,
 
         return event
 
+    def validate_destroy(self, request, instance):
+        # Don't allow removal of preferred events
+
+        # NOTE: instance should be an event attached to the superevent
+        # in question.  All other events are filtered out when we get
+        # and filter the queryset.  So if instance has the
+        # superevent_preferred_for attribute, it must be the preferred event.
+        if hasattr(instance, 'superevent_preferred_for'):
+            err_msg = ("Event {gid} can't be removed from superevent {sid} "
+                "because it is the preferred event").format(
+                gid=instance.graceid, sid=instance.superevent.graceid)
+            return False, err_msg
+        else:
+            return True, None
+
     def perform_destroy(self, instance):
         remove_event_from_superevent(instance.superevent, instance,
             self.request.user, add_superevent_log=True,
diff --git a/gracedb/superevents/models.py b/gracedb/superevents/models.py
index d4e298bbc..0c9037dfd 100644
--- a/gracedb/superevents/models.py
+++ b/gracedb/superevents/models.py
@@ -410,10 +410,6 @@ class Superevent(CleanSaveModel, AutoIncrementModel):
     def __unicode__(self):
         return self.superevent_id
 
-    class PreferredEventRemovalError(Exception):
-        # To be raised when an attempt is made to remove the preferred event.
-        pass
-
     class DateIdError(Exception):
         # To be raised when the superevent date ID is in a bad format; i.e.,
         # one that datetime can't parse or that the regex won't match
diff --git a/gracedb/superevents/utils.py b/gracedb/superevents/utils.py
index 77ccd9b22..7c76327ee 100644
--- a/gracedb/superevents/utils.py
+++ b/gracedb/superevents/utils.py
@@ -326,7 +326,6 @@ def remove_tag_from_log(log, tag, user, add_log_message=True,
         log_for_tag_removal = create_log(user, comment, event_or_superevent,
             issue_alert=False, autogenerated=True)
 
-
     return log_for_tag_removal
 
 
@@ -377,11 +376,6 @@ def remove_event_from_superevent(superevent, event, user, add_event_log=True,
     This function should be within a try-except block to catch exceptions and
     convert them to the appropriate response.
     """
-    # Throw error if this is the preferred event
-    if event == superevent.preferred_event:
-        raise Superevent.PreferredEventRemovalError("Can't remove a "
-            "superevent's preferred event without setting a new one.")
-
     # Remove event from superevent
     superevent.events.remove(event)
 
-- 
GitLab