diff --git a/engine/apps/public_api/tests/test_resolution_notes.py b/engine/apps/public_api/tests/test_resolution_notes.py index 2a44e622..c3a89a1d 100644 --- a/engine/apps/public_api/tests/test_resolution_notes.py +++ b/engine/apps/public_api/tests/test_resolution_notes.py @@ -106,8 +106,14 @@ def test_get_resolution_note( assert response.data == result +@patch("apps.alerts.tasks.send_update_resolution_note_signal.send_update_resolution_note_signal.apply_async") @pytest.mark.django_db -def test_create_resolution_note(make_organization_and_user_with_token, make_alert_receive_channel, make_alert_group): +def test_create_resolution_note( + mock_send_update_resolution_note_signal, + make_organization_and_user_with_token, + make_alert_receive_channel, + make_alert_group, +): organization, user, token = make_organization_and_user_with_token() client = APIClient() @@ -137,6 +143,8 @@ def test_create_resolution_note(make_organization_and_user_with_token, make_aler assert response.status_code == status.HTTP_201_CREATED assert response.data == result + mock_send_update_resolution_note_signal.assert_called_once() + @pytest.mark.django_db def test_create_resolution_note_invalid_text( @@ -163,8 +171,10 @@ def test_create_resolution_note_invalid_text( assert response.data["text"][0] == "This field may not be blank." +@patch("apps.alerts.tasks.send_update_resolution_note_signal.send_update_resolution_note_signal.apply_async") @pytest.mark.django_db def test_update_resolution_note( + mock_send_update_resolution_note_signal, make_organization_and_user_with_token, make_alert_receive_channel, make_alert_group, @@ -206,6 +216,39 @@ def test_update_resolution_note( assert resolution_note.text == result["text"] assert response.data == result + mock_send_update_resolution_note_signal.assert_called_once() + + +@patch("apps.alerts.tasks.send_update_resolution_note_signal.send_update_resolution_note_signal.apply_async") +@pytest.mark.django_db +def test_update_resolution_note_same_text( + mock_send_update_resolution_note_signal, + make_organization_and_user_with_token, + make_alert_receive_channel, + make_alert_group, + make_resolution_note, +): + organization, user, token = make_organization_and_user_with_token() + client = APIClient() + + alert_receive_channel = make_alert_receive_channel(organization) + alert_group = make_alert_group(alert_receive_channel) + + resolution_note = make_resolution_note( + alert_group=alert_group, + source=ResolutionNote.Source.WEB, + author=user, + ) + + url = reverse("api-public:resolution_notes-detail", kwargs={"pk": resolution_note.public_primary_key}) + response = client.put( + url, data={"text": resolution_note.message_text}, format="json", HTTP_AUTHORIZATION=f"{token}" + ) + assert response.status_code == status.HTTP_200_OK + + # update signal shouldn't be sent when text doesn't change + mock_send_update_resolution_note_signal.assert_not_called() + @pytest.mark.django_db def test_update_resolution_note_invalid_source( @@ -242,8 +285,10 @@ def test_update_resolution_note_invalid_source( assert response.data["detail"] == "Cannot update message with this source type" +@patch("apps.alerts.tasks.send_update_resolution_note_signal.send_update_resolution_note_signal.apply_async") @pytest.mark.django_db def test_delete_resolution_note( + mock_send_update_resolution_note_signal, make_organization_and_user_with_token, make_alert_receive_channel, make_alert_group, @@ -272,6 +317,7 @@ def test_delete_resolution_note( resolution_note.refresh_from_db() assert resolution_note.deleted_at is not None + mock_send_update_resolution_note_signal.assert_called_once() response = client.get(url, format="json", HTTP_AUTHORIZATION=f"{token}") diff --git a/engine/apps/public_api/views/resolution_notes.py b/engine/apps/public_api/views/resolution_notes.py index 06252aa7..586c5aca 100644 --- a/engine/apps/public_api/views/resolution_notes.py +++ b/engine/apps/public_api/views/resolution_notes.py @@ -56,20 +56,16 @@ class ResolutionNoteView(RateLimitHeadersMixin, UpdateSerializerMixin, ModelView except ResolutionNote.DoesNotExist: raise NotFound - def dispatch(self, request, *args, **kwargs): - result = super().dispatch(request, *args, **kwargs) + def perform_create(self, serializer): + super().perform_create(serializer) + send_update_resolution_note_signal.apply_async((serializer.instance.alert_group.pk, serializer.instance.pk)) - # send signal to update alert group and resolution_note - method = request.method.lower() - if method in ["post", "put", "patch", "delete"]: - instance_id = self.kwargs.get("pk") or result.data.get("id") - if instance_id: - instance = ResolutionNote.objects_with_deleted.filter(public_primary_key=instance_id).first() - if instance is not None: - send_update_resolution_note_signal.apply_async( - kwargs={ - "alert_group_pk": instance.alert_group.pk, - "resolution_note_pk": instance.pk, - } - ) - return result + def perform_update(self, serializer): + is_text_updated = serializer.instance.message_text != serializer.validated_data["message_text"] + super().perform_update(serializer) + if is_text_updated: + send_update_resolution_note_signal.apply_async((serializer.instance.alert_group.pk, serializer.instance.pk)) + + def perform_destroy(self, instance): + super().perform_destroy(instance) + send_update_resolution_note_signal.apply_async((instance.alert_group.pk, instance.pk))