From 58034245cbf5ef7288ae6a1ddccf6594b5b2170e Mon Sep 17 00:00:00 2001 From: lizerk Date: Wed, 26 Aug 2026 13:11:50 +0300 Subject: [PATCH] fix: read request notifications on decision --- .../api/v1/requests_app/viewsets/workflow.py | 9 ++++ .../api/v1/requests_app/test_requests_api.py | 49 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/backend/api/v1/requests_app/viewsets/workflow.py b/backend/api/v1/requests_app/viewsets/workflow.py index a75c4fb8..ced1f485 100644 --- a/backend/api/v1/requests_app/viewsets/workflow.py +++ b/backend/api/v1/requests_app/viewsets/workflow.py @@ -3,11 +3,18 @@ from rest_framework.exceptions import PermissionDenied, ValidationError from rest_framework.response import Response from requests_app.enums import RequestStatus +from requests_app.notifications.read_service import RequestNotificationReadService from ..serializers import RequestReadSerializer class RequestWorkflowMixin: + def _mark_decision_notifications_read(self, request, request_obj): + RequestNotificationReadService().mark_request_notifications_as_read( + user=request.user, + employee_request=request_obj, + ) + def _serialized_request(self, request_obj): return Response( RequestReadSerializer( @@ -31,6 +38,7 @@ class RequestWorkflowMixin: if request_obj.is_final: raise ValidationError("Заявка уже в финальном статусе.") request_obj.approve(by_user=request.user) + self._mark_decision_notifications_read(request, request_obj) return self._serialized_request(request_obj) @action(detail=True, methods=["post"]) @@ -48,6 +56,7 @@ class RequestWorkflowMixin: if request_obj.is_final: raise ValidationError("Заявка уже в финальном статусе.") request_obj.reject(by_user=request.user) + self._mark_decision_notifications_read(request, request_obj) return self._serialized_request(request_obj) @action(detail=True, methods=["post"]) diff --git a/backend/tests/api/v1/requests_app/test_requests_api.py b/backend/tests/api/v1/requests_app/test_requests_api.py index 460e7566..8b010516 100644 --- a/backend/tests/api/v1/requests_app/test_requests_api.py +++ b/backend/tests/api/v1/requests_app/test_requests_api.py @@ -108,6 +108,55 @@ def test_marks_only_opened_request_notifications_read( assert unrelated_notification.unread is True +@pytest.mark.parametrize("decision", ["approve", "reject"]) +def test_decision_marks_only_actors_request_notifications_read( + auth_client, + make_user, + make_request, + decision: str, +) -> None: + """Решение читает уведомления по заявлению только у принявшего его сотрудника.""" + owner = make_user(email=f"decision-{decision}-owner@example.com") + actor = make_user(email=f"decision-{decision}-actor@example.com") + other_recipient = make_user(email=f"decision-{decision}-other@example.com") + employee_request = make_request( + employee=owner, + status=RequestStatus.PENDING, + ) + employee_request.recipients.add(actor, other_recipient) + + actor_notification = Notification.objects.create( + recipient=actor, + verb="request_new", + data={"request_id": employee_request.id}, + ) + other_recipient_notification = Notification.objects.create( + recipient=other_recipient, + verb="request_new", + data={"request_id": employee_request.id}, + ) + unrelated_notification = Notification.objects.create( + recipient=actor, + verb="request_new", + data={"request_id": employee_request.id + 1}, + ) + + response = auth_client(actor).post( + f"{API_BASE}{employee_request.id}/{decision}/", + data={}, + format="json", + ) + + assert response.status_code == 200 + actor_notification.refresh_from_db() + other_recipient_notification.refresh_from_db() + unrelated_notification.refresh_from_db() + assert actor_notification.unread is False + assert actor_notification.timestamp_read is not None + assert other_recipient_notification.unread is True + assert unrelated_notification.unread is True + + def test_statistics_requires_privileged_access( auth_client, regular_user: models.Model, make_user ) -> None: