366 lines
13 KiB
Python
366 lines
13 KiB
Python
"""
|
||
Unit тесты для уведомлений модуля Requests
|
||
|
||
Запуск:
|
||
pytest backend/requests_app/tests/test_notifications.py -v
|
||
или
|
||
python manage.py test requests_app.tests.test_notifications
|
||
"""
|
||
|
||
from unittest.mock import patch
|
||
|
||
import pytest
|
||
from django.contrib.auth import get_user_model
|
||
from django.test import TestCase
|
||
|
||
from communications.comments_helpers import create_comment
|
||
from employees.models import Department
|
||
from notifications.models import Notification
|
||
from requests_app.models import Request
|
||
from requests_app.notifications.handlers import notify_new_request
|
||
|
||
Employee = get_user_model()
|
||
|
||
|
||
@pytest.mark.django_db
|
||
class TestRequestNotifications(TestCase):
|
||
"""Тесты уведомлений при работе с заявлениями"""
|
||
|
||
def setUp(self):
|
||
"""Подготовка тестовых данных"""
|
||
# Создаем тестовых пользователей
|
||
self.author = Employee.objects.create_user(
|
||
username="test_author",
|
||
email="author@test.com",
|
||
phone_number="+79990000001",
|
||
first_name="Иван",
|
||
last_name="Автор",
|
||
email_verified=True,
|
||
send_activation_email=False,
|
||
)
|
||
|
||
self.recipient = Employee.objects.create_user(
|
||
username="test_recipient",
|
||
email="recipient@test.com",
|
||
phone_number="+79990000002",
|
||
first_name="Петр",
|
||
last_name="Получатель",
|
||
email_verified=True,
|
||
send_activation_email=False,
|
||
)
|
||
|
||
self.cc_user = Employee.objects.create_user(
|
||
username="test_cc",
|
||
email="cc@test.com",
|
||
phone_number="+79990000003",
|
||
first_name="Сидор",
|
||
last_name="Копия",
|
||
email_verified=True,
|
||
send_activation_email=False,
|
||
)
|
||
|
||
self.approver = Employee.objects.create_user(
|
||
username="test_approver",
|
||
email="approver@test.com",
|
||
phone_number="+79990000004",
|
||
first_name="Алексей",
|
||
last_name="Согласующий",
|
||
email_verified=True,
|
||
send_activation_email=False,
|
||
)
|
||
for employee in [
|
||
self.author,
|
||
self.recipient,
|
||
self.cc_user,
|
||
self.approver,
|
||
]:
|
||
employee.email_verified = True
|
||
employee.is_active = True
|
||
employee.save(update_fields=["email_verified", "is_active"])
|
||
|
||
# Создаем отдел
|
||
self.department = Department.objects.create(
|
||
name="Тестовый отдел", head=self.approver
|
||
)
|
||
|
||
def test_new_request_notification_to_recipient(self):
|
||
"""Тест: уведомление получателю при создании заявления"""
|
||
# Создаем заявление
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск с 1 по 10 июля",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
|
||
# Устанавливаем получателя (триггерит сигнал)
|
||
request.recipients.set([self.recipient])
|
||
|
||
# Проверяем что уведомление создано
|
||
notifications = Notification.objects.filter(
|
||
recipient=self.recipient, verb="request_new"
|
||
)
|
||
|
||
self.assertEqual(notifications.count(), 1)
|
||
notif = notifications.first()
|
||
|
||
# Проверяем содержимое
|
||
self.assertEqual(
|
||
notif.data["title"],
|
||
"Новое заявление",
|
||
)
|
||
self.assertIn(
|
||
"Иван Автор адресовал вам заявление",
|
||
notif.description,
|
||
)
|
||
self.assertEqual(notif.data["request_id"], request.id)
|
||
self.assertEqual(notif.data["is_primary_recipient"], True)
|
||
self.assertTrue(notif.unread)
|
||
|
||
def test_new_request_notification_to_cc(self):
|
||
"""Тест: уведомление пользователю в копии"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
|
||
request.recipients.set([self.recipient])
|
||
request.cc_users.set([self.cc_user])
|
||
Notification.objects.all().delete()
|
||
notify_new_request(request)
|
||
|
||
# Проверяем уведомление для CC
|
||
notifications = Notification.objects.filter(
|
||
recipient=self.cc_user, verb="request_new"
|
||
)
|
||
|
||
self.assertEqual(notifications.count(), 1)
|
||
notif = notifications.first()
|
||
|
||
self.assertEqual(notif.data["is_cc"], True)
|
||
self.assertEqual(
|
||
notif.data["title"],
|
||
"Новое заявление",
|
||
)
|
||
self.assertIn(
|
||
"Иван Автор поставил вас в копию заявления",
|
||
notif.description,
|
||
)
|
||
|
||
def test_new_request_notification_to_approver(self):
|
||
"""Тест: уведомление согласующему при создании заявления"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
request.approver = self.approver
|
||
|
||
Notification.objects.all().delete()
|
||
notify_new_request(request)
|
||
|
||
notif = Notification.objects.get(
|
||
recipient=self.approver,
|
||
verb="request_new",
|
||
)
|
||
|
||
self.assertEqual(
|
||
notif.data["title"],
|
||
"Новое заявление",
|
||
)
|
||
self.assertIn(
|
||
"Иван Автор отправил заявление вам на согласование",
|
||
notif.description,
|
||
)
|
||
self.assertEqual(notif.data["is_approver"], True)
|
||
|
||
def test_new_request_notification_to_department(self):
|
||
"""Тест: уведомление отделу при создании заявления"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
|
||
Notification.objects.all().delete()
|
||
notify_new_request(request)
|
||
|
||
notif = Notification.objects.get(
|
||
recipient=self.approver,
|
||
verb="request_new",
|
||
)
|
||
|
||
self.assertEqual(
|
||
notif.data["title"],
|
||
"Новое заявление",
|
||
)
|
||
self.assertIn(
|
||
"Иван Автор направил заявление в отдел",
|
||
notif.description,
|
||
)
|
||
self.assertEqual(notif.data["is_approver"], False)
|
||
|
||
def test_request_approval_notification(self):
|
||
"""Тест: уведомление об одобрении заявления"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
approver=self.approver,
|
||
)
|
||
request.recipients.set([self.recipient])
|
||
|
||
# Очищаем уведомления о создании
|
||
Notification.objects.all().delete()
|
||
|
||
# Одобряем заявление
|
||
request.approve(self.approver)
|
||
|
||
# Проверяем уведомление автору
|
||
notifications = Notification.objects.filter(
|
||
recipient=self.author, verb="request_approved"
|
||
)
|
||
|
||
self.assertEqual(notifications.count(), 1)
|
||
notif = notifications.first()
|
||
|
||
self.assertIn("одобрено", notif.data["title"])
|
||
self.assertEqual(notif.data["new_status"], "approved")
|
||
self.assertEqual(notif.data["approver_id"], self.approver.id)
|
||
|
||
def test_request_rejection_notification(self):
|
||
"""Тест: уведомление об отклонении заявления"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
approver=self.approver,
|
||
)
|
||
request.recipients.set([self.recipient])
|
||
|
||
Notification.objects.all().delete()
|
||
|
||
# Отклоняем заявление
|
||
request.reject(self.approver)
|
||
|
||
notifications = Notification.objects.filter(
|
||
recipient=self.author, verb="request_rejected"
|
||
)
|
||
|
||
self.assertEqual(notifications.count(), 1)
|
||
notif = notifications.first()
|
||
|
||
self.assertIn("отклонено", notif.data["title"])
|
||
self.assertEqual(notif.data["new_status"], "rejected")
|
||
|
||
def test_comment_notification(self):
|
||
"""Тест: уведомление о комментарии к заявлению"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
request.recipients.set([self.recipient])
|
||
|
||
Notification.objects.all().delete()
|
||
|
||
# Добавляем комментарий
|
||
comment = create_comment(
|
||
obj=request, author=self.recipient, content="Нужна справка"
|
||
)
|
||
|
||
# Проверяем уведомление автору
|
||
notifications = Notification.objects.filter(
|
||
recipient=self.author, verb="commented"
|
||
)
|
||
|
||
self.assertEqual(notifications.count(), 1)
|
||
notif = notifications.first()
|
||
|
||
self.assertIn("комментарий", notif.data["title"])
|
||
self.assertEqual(notif.data["message_id"], comment.id)
|
||
self.assertIn("Нужна справка", notif.description)
|
||
|
||
def test_no_notification_to_author_on_own_comment(self):
|
||
"""Тест: автор не получает уведомление о своем комментарии"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
request.recipients.set([self.recipient])
|
||
|
||
Notification.objects.all().delete()
|
||
|
||
# Автор комментирует свое заявление
|
||
create_comment(
|
||
obj=request, author=self.author, content="Дополнительная информация"
|
||
)
|
||
|
||
# Автор НЕ должен получить уведомление
|
||
notifications = Notification.objects.filter(
|
||
recipient=self.author, verb="commented"
|
||
)
|
||
|
||
self.assertEqual(notifications.count(), 0)
|
||
|
||
def test_multiple_recipients_notification(self):
|
||
"""Тест: уведомления всем получателям"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
|
||
# Множественные получатели
|
||
request.recipients.set([self.recipient, self.cc_user])
|
||
|
||
# Проверяем что оба получили уведомления
|
||
notifications = Notification.objects.filter(verb="request_new")
|
||
|
||
recipients = [n.recipient for n in notifications]
|
||
|
||
self.assertIn(self.recipient, recipients)
|
||
self.assertIn(self.cc_user, recipients)
|
||
|
||
@patch("notifications.channels.route_notification_to_channels")
|
||
def test_channels_called_on_notification(self, mock_channels):
|
||
"""Тест: channels.py вызывается при создании уведомления"""
|
||
request = Request.objects.create(
|
||
employee=self.author,
|
||
type="vacation",
|
||
comment="Отпуск",
|
||
status="pending",
|
||
department=self.department,
|
||
)
|
||
|
||
request.recipients.set([self.recipient])
|
||
|
||
# Проверяем что channels.py был вызван
|
||
# (он должен вызываться автоматически через post_save)
|
||
notification = Notification.objects.filter(
|
||
recipient=self.recipient, verb="request_new"
|
||
).first()
|
||
|
||
# Просто проверяем что уведомление создано
|
||
# (channels.py запустится автоматически через сигнал)
|
||
self.assertIsNotNone(notification)
|