Corp/backend/tests/notifications/test_models.py
Игорь Надеин 64e033d72e fix: исправление модуля уведомлений и добавление тестов
- Исправлена маршрутизация API: обновлены JS файлы для использования /api/v1/notifications/
- Исправлена ошибка в api_views.py: last_error='' вместо None (TextField не может быть NULL)
- Исправлена ошибка в services.py: использование метода reset_errors()
- Добавлено 36 комплексных тестов (модели, API, сервисы) - все проходят
- Создана документация аудита модуля (NOTIFICATIONS_AUDIT.md)
- Создано руководство по тестированию (NOTIFICATIONS_TESTING.md)
- Добавлены management команды: cleanup_push_subscriptions, notification_stats
- Тесты перемещены в backend/tests/notifications/ для правильной организации

Вся функциональность уведомлений проверена и работает корректно.
2026-01-05 15:38:36 +03:00

225 lines
7.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Тесты для моделей уведомлений
"""
from django.test import TestCase
from django.contrib.auth import get_user_model
from notifications.models import (
NotificationCategory,
NotificationType,
Notification,
UserNotificationSettings,
WebPushSubscription,
)
User = get_user_model()
def create_test_user(email='test@example.com', phone='+79990000001'):
"""Helper для создания тестового пользователя с обязательным phone_number"""
return User.objects.create_user(
email=email,
phone_number=phone,
password='testpass123',
first_name='Test',
last_name='User',
is_active=True
)
class NotificationCategoryTest(TestCase):
"""Тесты категорий уведомлений"""
def setUp(self):
self.category = NotificationCategory.objects.create(
code='test_category',
name='Test Category',
icon='bi-test',
color='primary'
)
def test_category_creation(self):
"""Создание категории"""
self.assertEqual(self.category.code, 'test_category')
self.assertEqual(self.category.name, 'Test Category')
self.assertTrue(self.category.is_active)
def test_category_str(self):
"""Строковое представление"""
self.assertEqual(str(self.category), 'Test Category')
class NotificationTypeTest(TestCase):
"""Тесты типов уведомлений"""
def setUp(self):
self.category = NotificationCategory.objects.create(
code='test_category',
name='Test Category'
)
self.notification_type = NotificationType.objects.create(
category=self.category,
code='test_type',
name='Test Type',
default_enabled=True,
priority='normal'
)
def test_type_creation(self):
"""Создание типа уведомления"""
self.assertEqual(self.notification_type.code, 'test_type')
self.assertEqual(self.notification_type.category, self.category)
self.assertTrue(self.notification_type.default_enabled)
self.assertEqual(self.notification_type.priority, 'normal')
def test_type_str(self):
"""Строковое представление"""
self.assertEqual(str(self.notification_type), 'Test Category: Test Type')
class NotificationTest(TestCase):
"""Тесты уведомлений"""
def setUp(self):
self.user = create_test_user()
self.category = NotificationCategory.objects.create(
code='test_category',
name='Test Category'
)
self.notification_type = NotificationType.objects.create(
category=self.category,
code='test_type',
name='Test Type'
)
self.notification = Notification.objects.create(
recipient=self.user,
notification_type=self.notification_type,
title='Test Notification',
message='Test message',
short_message='Test'
)
def test_notification_creation(self):
"""Создание уведомления"""
self.assertEqual(self.notification.recipient, self.user)
self.assertEqual(self.notification.title, 'Test Notification')
self.assertFalse(self.notification.is_read)
self.assertFalse(self.notification.is_archived)
def test_mark_as_read(self):
"""Отметка как прочитанное"""
self.assertFalse(self.notification.is_read)
self.assertIsNone(self.notification.read_at)
self.notification.mark_as_read()
self.assertTrue(self.notification.is_read)
self.assertIsNotNone(self.notification.read_at)
def test_archive(self):
"""Архивирование"""
self.assertFalse(self.notification.is_archived)
self.assertIsNone(self.notification.archived_at)
self.notification.archive()
self.assertTrue(self.notification.is_archived)
self.assertIsNotNone(self.notification.archived_at)
class UserNotificationSettingsTest(TestCase):
"""Тесты настроек уведомлений пользователя"""
def setUp(self):
self.user = create_test_user()
self.category = NotificationCategory.objects.create(
code='test_category',
name='Test Category'
)
self.notification_type = NotificationType.objects.create(
category=self.category,
code='test_type',
name='Test Type'
)
self.settings = UserNotificationSettings.objects.create(
user=self.user,
notification_type=self.notification_type,
is_enabled=True,
send_web=True,
send_email=False
)
def test_settings_creation(self):
"""Создание настроек"""
self.assertEqual(self.settings.user, self.user)
self.assertTrue(self.settings.is_enabled)
self.assertTrue(self.settings.send_web)
self.assertFalse(self.settings.send_email)
class WebPushSubscriptionTest(TestCase):
"""Тесты Web Push подписок"""
def setUp(self):
self.user = create_test_user()
self.subscription = WebPushSubscription.objects.create(
user=self.user,
endpoint='https://fcm.googleapis.com/fcm/send/test123',
p256dh_key='test_p256dh_key',
auth_key='test_auth_key',
device_name='Test Device'
)
def test_subscription_creation(self):
"""Создание подписки"""
self.assertEqual(self.subscription.user, self.user)
self.assertEqual(self.subscription.device_name, 'Test Device')
self.assertTrue(self.subscription.is_active)
self.assertEqual(self.subscription.error_count, 0)
def test_mark_used(self):
"""Обновление времени использования"""
self.assertIsNone(self.subscription.last_used_at)
self.subscription.mark_used()
self.assertIsNotNone(self.subscription.last_used_at)
def test_increment_error(self):
"""Инкремент ошибок"""
self.assertEqual(self.subscription.error_count, 0)
self.subscription.increment_error('Test error')
self.assertEqual(self.subscription.error_count, 1)
self.assertEqual(self.subscription.last_error, 'Test error')
self.assertTrue(self.subscription.is_active)
def test_auto_deactivate_after_5_errors(self):
"""Автоматическая деактивация после 5 ошибок"""
for i in range(5):
self.subscription.increment_error(f'Error {i+1}')
self.subscription.refresh_from_db()
self.assertFalse(self.subscription.is_active)
self.assertEqual(self.subscription.error_count, 5)
def test_reset_errors(self):
"""Сброс ошибок"""
self.subscription.increment_error('Test error')
self.assertEqual(self.subscription.error_count, 1)
self.subscription.reset_errors()
self.assertEqual(self.subscription.error_count, 0)
self.assertEqual(self.subscription.last_error, '')
def test_unique_together(self):
"""Уникальность user + endpoint"""
with self.assertRaises(Exception):
WebPushSubscription.objects.create(
user=self.user,
endpoint='https://fcm.googleapis.com/fcm/send/test123',
p256dh_key='another_key',
auth_key='another_auth'
)