Files
guilan-ace-backend/apps/events/tests/unit/test_events.py
Amirhossein Khalili 3ec28638d1 feat: replace email flows with in-app notifications
Add recipient notification detail and filtering, a queued admin composer, and contextual automatic titles. Retire email delivery, obsolete auth routes, newsletter data, and related templates and settings.
2026-09-26 12:23:10 +03:30

94 lines
4.5 KiB
Python

from types import SimpleNamespace
from unittest import mock
from datetime import timedelta
from django.contrib import admin
from django.test import SimpleTestCase, TestCase
from django.utils import timezone
from apps.events.admin import EventAdmin, RegistrationAdmin
from apps.events.models import Event, Registration
from apps.events.tasks import (
send_registration_cancellation_notification,
send_registration_confirmation_notification,
)
from apps.users.models import User
class AutomaticRegistrationNotificationTests(SimpleTestCase):
@mock.patch("apps.events.tasks.notify_user")
@mock.patch("apps.events.tasks.Registration.objects")
def test_confirmation_delivers_in_app_with_event_link(self, registrations, notify_user):
registration = SimpleNamespace(
user_id=7,
event_id=12,
ticket_id="ticket",
event=SimpleNamespace(title="Workshop", slug="workshop"),
)
registrations.select_related.return_value.get.return_value = registration
result = send_registration_confirmation_notification.run("1")
self.assertEqual(result, {"sent": True})
self.assertEqual(notify_user.call_args.args[0], 7)
self.assertEqual(notify_user.call_args.args[1]["action_url"], "/events/workshop")
@mock.patch("apps.events.tasks.send_critical_sms.delay")
@mock.patch("apps.events.tasks.notify_user")
@mock.patch("apps.events.tasks.Registration.objects")
def test_cancellation_delivers_in_app_and_optional_sms(self, registrations, notify_user, send_sms):
registrations.select_related.return_value.get.return_value = SimpleNamespace(
user_id=7,
event_id=12,
user=SimpleNamespace(mobile="09191110002", is_mobile_verified=True),
event=SimpleNamespace(title="Workshop", slug="workshop"),
)
self.assertEqual(send_registration_cancellation_notification.run("1"), {"sent": True})
self.assertEqual(notify_user.call_args.args[1]["type"], "event_cancellation")
send_sms.assert_called_once_with("09191110002", "event_cancellation", "Workshop")
class ManualActionRemovalTests(SimpleTestCase):
def test_event_and_registration_admin_have_no_manual_send_actions(self):
self.assertFalse(EventAdmin.__dict__.get("actions_row"))
self.assertFalse(RegistrationAdmin.__dict__.get("actions_row"))
def test_bulk_status_actions_save_each_registration_for_automatic_notification(self):
model_admin = RegistrationAdmin(Registration, admin.site)
registration = mock.Mock()
with mock.patch.object(model_admin, "message_user"):
model_admin.confirm_registrations(SimpleNamespace(), [registration])
self.assertEqual(registration.status, Registration.StatusChoices.CONFIRMED)
registration.save.assert_called_with(update_fields=["status"])
registration.reset_mock()
model_admin.cancel_registrations(SimpleNamespace(), [registration])
self.assertEqual(registration.status, Registration.StatusChoices.CANCELLED)
registration.save.assert_called_with(update_fields=["status"])
class EventModelTests(TestCase):
def setUp(self):
now = timezone.now()
self.event = Event.objects.create(
title="Workshop", description="**Important** details", start_time=now + timedelta(days=1),
end_time=now + timedelta(days=1, hours=2), capacity=1,
registration_start_date=now - timedelta(days=1),
registration_end_date=now + timedelta(hours=1),
)
self.user = User.objects.create_user(username="attendee", mobile="09191110003", password="password")
def test_markdown_description_and_registration_window_remain_available(self):
self.assertIn("<strong>Important</strong>", self.event.description_html)
self.assertTrue(self.event.is_registration_open)
self.event.registration_end_date = timezone.now() - timedelta(minutes=1)
self.assertFalse(self.event.is_registration_open)
@mock.patch("apps.events.tasks.send_registration_confirmation_notification.delay")
def test_capacity_counts_confirmed_registration(self, delay):
Registration.objects.create(event=self.event, user=self.user, status=Registration.StatusChoices.CONFIRMED)
self.assertEqual(self.event.current_attendees_count, 1)
self.assertFalse(self.event.has_available_slots)
delay.assert_called_once()
def test_unlimited_capacity_allows_registration(self):
self.event.capacity = None
self.assertTrue(self.event.has_available_slots)