Fix procurement push notification delivery checks

This commit is contained in:
lizerk 2026-06-08 16:45:15 +03:00
parent 4555ee9bf7
commit 662dc873bb
3 changed files with 131 additions and 0 deletions

View File

@ -590,6 +590,13 @@ def subscribe_push(request):
}
)
prefs, _ = UserChannelPreferences.objects.get_or_create(
user=request.user,
)
if not prefs.push_enabled:
prefs.push_enabled = True
prefs.save(update_fields=["push_enabled"])
return Response({
'status': 'success',
'message': (
@ -628,6 +635,18 @@ def unsubscribe_push(request):
user=request.user
).delete()
has_active_devices = WebPushDevice.objects.filter(
user=request.user,
active=True,
).exists()
if not has_active_devices:
prefs, _ = UserChannelPreferences.objects.get_or_create(
user=request.user,
)
if prefs.push_enabled:
prefs.push_enabled = False
prefs.save(update_fields=["push_enabled"])
return Response({
'status': 'success',
'message': f'Deleted {deleted_count} push subscription(s)',

View File

@ -2,6 +2,7 @@ from unittest.mock import patch
import pytest
from push_notifications.models import WebPushDevice
from notifications.models import Notification
from notifications.models import UserChannelPreferences
@ -158,3 +159,54 @@ class TestNotificationPreferencesApi:
assert response.status_code == 200
prefs = UserChannelPreferences.objects.get(user=user)
assert prefs.email_frequency == "never"
def test_subscribe_push_enables_push_preferences(
self, api_client, user_factory
):
user = user_factory()
UserChannelPreferences.objects.create(user=user, push_enabled=False)
api_client.force_authenticate(user=user)
response = api_client.post(
"/api/v1/notifications/push/subscribe/",
{
"endpoint": "https://push.example.test/endpoint-1",
"keys": {"p256dh": "test-p256dh", "auth": "test-auth"},
"device_name": "Chrome",
},
format="json",
)
assert response.status_code == 200
prefs = UserChannelPreferences.objects.get(user=user)
assert prefs.push_enabled is True
assert WebPushDevice.objects.filter(
user=user,
registration_id="https://push.example.test/endpoint-1",
active=True,
).exists()
def test_unsubscribe_last_push_device_disables_push_preferences(
self, api_client, user_factory
):
user = user_factory()
UserChannelPreferences.objects.create(user=user, push_enabled=True)
WebPushDevice.objects.create(
user=user,
registration_id="https://push.example.test/endpoint-1",
p256dh="test-p256dh",
auth="test-auth",
browser="Chrome",
active=True,
)
api_client.force_authenticate(user=user)
response = api_client.delete(
"/api/v1/notifications/push/unsubscribe/",
{"endpoint": "https://push.example.test/endpoint-1"},
format="json",
)
assert response.status_code == 200
prefs = UserChannelPreferences.objects.get(user=user)
assert prefs.push_enabled is False

View File

@ -3,11 +3,13 @@
"""
from decimal import Decimal
from unittest.mock import patch
import pytest
from django.contrib.auth.models import Permission
from django.urls import reverse
from django.utils import timezone
from push_notifications.models import WebPushDevice
from rest_framework import status
from rest_framework.test import APIClient
@ -33,6 +35,7 @@ from procurement.models import (
ProcurementItem,
ProcurementRequest,
)
from notifications.models import Notification, UserChannelPreferences
pytestmark = pytest.mark.django_db
@ -1637,6 +1640,63 @@ class TestProcessingDepartmentWorkflow:
"ordered_quantity",
]
@pytest.mark.django_db(transaction=True)
def test_item_order_update_routes_push_to_requestor(
self, api_client, supply_user, processing_request,
procurement_item_factory
):
item = procurement_item_factory(
request=processing_request,
quantity=3,
)
processing_request.executor = supply_user
processing_request.status = ProcurementStatus.IN_PROGRESS
processing_request.save()
UserChannelPreferences.objects.update_or_create(
user=processing_request.requestor,
defaults={
"web_enabled": False,
"email_enabled": False,
"push_enabled": True,
"disabled_verbs": [],
},
)
WebPushDevice.objects.create(
user=processing_request.requestor,
registration_id="https://push.example.test/procurement-item",
p256dh="test-p256dh",
auth="test-auth",
browser="Chrome",
active=True,
)
api_client.force_authenticate(user=supply_user)
item_url = reverse(
'api:v1:procurement:procurementitem-detail',
kwargs={'pk': item.id},
)
with patch(
"notifications.tasks.send_push_notification.delay"
) as send_push:
response = api_client.patch(
item_url,
{"ordered_quantity": 2},
format="json",
)
assert response.status_code == status.HTTP_200_OK
notification = Notification.objects.get(
recipient=processing_request.requestor,
verb="procurement_item_updated",
data__item_id=item.id,
)
assert notification.data["changed_fields"] == [
"ordered_quantity",
"execution_status",
]
send_push.assert_called_once_with(notification.id)
def test_item_expected_delivery_dates_must_be_valid_dates(
self, api_client, supply_user, processing_request,
procurement_item_factory