Corp/backend/test_notification_signals.py
Игорь Надеин ddf22c47da fix: автоматическое обновление JWT токенов
- ApiClient теперь обрабатывает 401 и 403 ошибки для обновления токена
- Добавлен JWTRefreshMiddleware для проактивного обновления токенов за 5 минут до истечения
- Добавлена настройка JWT_REFRESH_THRESHOLD_MINUTES (по умолчанию 5)
- Исправлена проблема с периодическими 403 ошибками после истечения access token
2025-11-20 18:52:29 +03:00

429 lines
15 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.

#!/usr/bin/env python
"""
Тестовый скрипт для проверки работы notification signals.
Тестирует все 5 модулей:
1. Communications - сообщения, упоминания, ответы
2. Requests - заявки, статусы, комментарии
3. Documents - документы, ознакомления
4. Calendar - события, изменения
5. Feed - публикации, комментарии
Запуск:
python test_notification_signals.py
"""
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
django.setup()
from django.contrib.auth import get_user_model
from communications.models import Chat, Message
from requests_app.models import Request, RequestComment
from documents.models import Document, DocumentAcknowledgement
from calendar_app.models import CalendarEvent
from feed.models import Post, Comment
from notifications.models import Notification
from employees.models import Department
Employee = get_user_model()
# ANSI цвета для красивого вывода
class Colors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKCYAN = '\033[96m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def print_header(text):
print(f"\n{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{text:^60}{Colors.ENDC}")
print(f"{Colors.HEADER}{Colors.BOLD}{'='*60}{Colors.ENDC}\n")
def print_success(text):
print(f"{Colors.OKGREEN}[OK] {text}{Colors.ENDC}")
def print_error(text):
print(f"{Colors.FAIL}[ERROR] {text}{Colors.ENDC}")
def print_info(text):
print(f"{Colors.OKCYAN}[INFO] {text}{Colors.ENDC}")
def get_or_create_test_users():
"""Создает или получает тестовых пользователей."""
print_info("Подготовка тестовых пользователей...")
user1, created = Employee.objects.get_or_create(
email='test_user1@test.com',
defaults={
'first_name': 'Иван',
'last_name': 'Иванов',
'is_active': True,
'phone_number': '+79001111111'
}
)
if created:
user1.set_password('testpass123')
user1.save()
user2, created = Employee.objects.get_or_create(
email='test_user2@test.com',
defaults={
'first_name': 'Петр',
'last_name': 'Петров',
'is_active': True,
'phone_number': '+79002222222'
}
)
if created:
user2.set_password('testpass123')
user2.save()
print_success(f"Пользователи готовы: {user1.email}, {user2.email}")
return user1, user2
def test_communications(user1, user2):
"""Тестирует signals модуля Communications."""
print_header("ТЕСТ 1: Communications")
# Очистка предыдущих уведомлений
Notification.objects.filter(recipient__in=[user1, user2]).delete()
# 1. Создаем приватный чат
chat = Chat.objects.create(type='private')
chat.participants.add(user1, user2)
print_success(f"Создан чат #{chat.id}")
# Проверяем уведомление о добавлении в чат
notif_count = Notification.objects.filter(
notification_type__code='chat_added_to_chat'
).count()
print_info(f"Уведомлений о добавлении в чат: {notif_count}")
# 2. Простое сообщение
msg1 = Message.objects.create(
chat=chat,
author=user1,
content='Привет! Как дела?'
)
print_success(f"Создано сообщение #{msg1.id}")
notif = Notification.objects.filter(
recipient=user2,
notification_type__code='chat_new_message'
).first()
if notif:
print_success(f"[+] Уведомление получено: {notif.title}")
else:
print_error("Уведомление о новом сообщении НЕ создано!")
# 3. Сообщение с упоминанием
msg2 = Message.objects.create(
chat=chat,
author=user1,
content=f'Привет @{user2.email}, нужна твоя помощь!'
)
print_success(f"Создано сообщение с упоминанием #{msg2.id}")
mention_notif = Notification.objects.filter(
recipient=user2,
notification_type__code='chat_mention'
).first()
if mention_notif:
print_success(f"[+] Уведомление об упоминании: {mention_notif.title}")
else:
print_error("Уведомление об упоминании НЕ создано!")
# 4. Ответ на сообщение
msg3 = Message.objects.create(
chat=chat,
author=user2,
content='Конечно, помогу!',
reply_to=msg1
)
print_success(f"Создан ответ на сообщение #{msg3.id}")
reply_notif = Notification.objects.filter(
recipient=user1,
notification_type__code='chat_reply'
).first()
if reply_notif:
print_success(f"[+] Уведомление об ответе: {reply_notif.title}")
else:
print_error("Уведомление об ответе НЕ создано!")
total = Notification.objects.filter(recipient__in=[user1, user2]).count()
print_info(f"Всего создано уведомлений: {total}")
def test_requests(user1, user2):
"""Тестирует signals модуля Requests."""
print_header("ТЕСТ 2: Requests")
Notification.objects.filter(recipient__in=[user1, user2]).delete()
# 1. Создаем заявку
request = Request.objects.create(
employee=user1,
type='vacation',
title='Отпуск',
comment='Прошу предоставить отпуск',
status='pending',
approver=user2
)
print_success(f"Создана заявка #{request.id}")
new_request_notif = Notification.objects.filter(
notification_type__code='request_new'
).first()
if new_request_notif:
print_success(f"✓ Уведомление о новой заявке: {new_request_notif.title}")
else:
print_error("Уведомление о новой заявке НЕ создано!")
# 2. Одобряем заявку
from django.utils import timezone
request.status = 'approved'
request.decided_at = timezone.now()
request.save()
print_success(f"Заявка #{request.id} одобрена")
approved_notif = Notification.objects.filter(
recipient=user1,
notification_type__code='request_approved'
).first()
if approved_notif:
print_success(f"✓ Уведомление об одобрении: {approved_notif.title}")
else:
print_error("Уведомление об одобрении НЕ создано!")
# 3. Добавляем комментарий
comment = RequestComment.objects.create(
request=request,
author=user2,
text='Одобрено, хорошего отдыха!'
)
print_success(f"Добавлен комментарий #{comment.id}")
comment_notif = Notification.objects.filter(
recipient=user1,
notification_type__code='request_comment'
).first()
if comment_notif:
print_success(f"✓ Уведомление о комментарии: {comment_notif.title}")
else:
print_error("Уведомление о комментарии НЕ создано!")
total = Notification.objects.filter(recipient__in=[user1, user2]).count()
print_info(f"Всего создано уведомлений: {total}")
def test_documents(user1, user2):
"""Тестирует signals модуля Documents."""
print_header("ТЕСТ 3: Documents")
Notification.objects.filter(recipient__in=[user1, user2]).delete()
# 1. Создаем документ для конкретных получателей
doc = Document.objects.create(
title='Важный документ',
description='Требует ознакомления',
uploaded_by=user1
)
doc.recipients.add(user2)
print_success(f"Создан документ #{doc.id}")
doc_notif = Notification.objects.filter(
recipient=user2,
notification_type__code='document_ready'
).first()
if doc_notif:
print_success(f"✓ Уведомление о документе: {doc_notif.title}")
else:
print_error("Уведомление о документе НЕ создано!")
# 2. Ознакомление с документом
ack = DocumentAcknowledgement.objects.create(
document=doc,
user=user2
)
print_success(f"Пользователь {user2.username} ознакомился")
# Проверяем уведомление о полном ознакомлении
all_ack_notif = Notification.objects.filter(
recipient=user1,
notification_type__code='document_signed_all'
).first()
if all_ack_notif:
print_success(f"✓ Уведомление о полном ознакомлении: {all_ack_notif.title}")
else:
print_error("Уведомление о полном ознакомлении НЕ создано!")
total = Notification.objects.filter(recipient__in=[user1, user2]).count()
print_info(f"Всего создано уведомлений: {total}")
def test_calendar(user1, user2):
"""Тестирует signals модуля Calendar."""
print_header("ТЕСТ 4: Calendar")
Notification.objects.filter(recipient__in=[user1, user2]).delete()
from datetime import date, timedelta
# 1. Создаем событие компании
event = CalendarEvent.objects.create(
title='Общее собрание',
description='Ежеквартальное собрание',
start_date=date.today() + timedelta(days=7),
created_by=user1
)
print_success(f"Создано событие #{event.id}")
event_notif = Notification.objects.filter(
notification_type__code='event_created'
).first()
if event_notif:
print_success(f"✓ Уведомление о событии: {event_notif.title}")
print_info(f" Получателей: {Notification.objects.filter(notification_type__code='event_created').count()}")
else:
print_error("Уведомление о событии НЕ создано!")
# 2. Изменяем событие
Notification.objects.all().delete() # Очищаем для чистоты теста
event.title = 'ВАЖНОЕ Общее собрание'
event.save()
print_success(f"Событие #{event.id} изменено")
changed_notif = Notification.objects.filter(
notification_type__code='event_changed'
).first()
if changed_notif:
print_success(f"✓ Уведомление об изменении: {changed_notif.title}")
else:
print_error("Уведомление об изменении НЕ создано!")
# 3. Удаляем событие
Notification.objects.all().delete()
event.delete()
print_success("Событие удалено")
cancelled_notif = Notification.objects.filter(
notification_type__code='event_cancelled'
).first()
if cancelled_notif:
print_success(f"✓ Уведомление об отмене: {cancelled_notif.title}")
else:
print_error("Уведомление об отмене НЕ создано!")
def test_feed(user1, user2):
"""Тестирует signals модуля Feed."""
print_header("ТЕСТ 5: Feed")
Notification.objects.filter(recipient__in=[user1, user2]).delete()
# 1. Создаем публикацию компании
post = Post.objects.create(
author=user1,
title='Важная новость',
body='Текст важной новости для всех сотрудников',
type='company'
)
print_success(f"Создана публикация #{post.id}")
post_notif = Notification.objects.filter(
notification_type__code='feed_new_post'
).first()
if post_notif:
print_success(f"✓ Уведомление о публикации: {post_notif.title}")
print_info(f" Получателей: {Notification.objects.filter(notification_type__code='feed_new_post').count()}")
else:
print_error("Уведомление о публикации НЕ создано!")
# 2. Добавляем комментарий
comment = Comment.objects.create(
post=post,
author=user2,
text='Отличная новость!'
)
print_success(f"Добавлен комментарий #{comment.id}")
comment_notif = Notification.objects.filter(
recipient=user1,
notification_type__code='feed_post_comment'
).first()
if comment_notif:
print_success(f"✓ Уведомление о комментарии: {comment_notif.title}")
else:
print_error("Уведомление о комментарии НЕ создано!")
# 3. Тестируем функцию реакции
from feed.notification_signals import notify_post_reaction
notify_post_reaction(post, user2)
print_success("Вызвана функция реакции")
reaction_notif = Notification.objects.filter(
recipient=user1,
notification_type__code='feed_post_reaction'
).first()
if reaction_notif:
print_success(f"✓ Уведомление о реакции: {reaction_notif.title}")
else:
print_error("Уведомление о реакции НЕ создано!")
def main():
"""Основная функция запуска всех тестов."""
print(f"{Colors.BOLD}{Colors.OKBLUE}")
print("="*60)
print(" ТЕСТИРОВАНИЕ СИСТЕМЫ УВЕДОМЛЕНИЙ - ЭТАП 3")
print(" Интеграция с модулями через signals")
print("="*60)
print(f"{Colors.ENDC}")
try:
# Подготовка
user1, user2 = get_or_create_test_users()
# Запуск тестов
test_communications(user1, user2)
test_requests(user1, user2)
test_documents(user1, user2)
test_calendar(user1, user2)
test_feed(user1, user2)
# Итоговая статистика
print_header("ИТОГИ")
total_notifications = Notification.objects.count()
total_types_used = Notification.objects.values(
'notification_type__code'
).distinct().count()
print_success(f"Всего уведомлений в БД: {total_notifications}")
print_success(f"Использовано типов: {total_types_used}")
print(f"\n{Colors.OKGREEN}{Colors.BOLD}✓ ВСЕ ТЕСТЫ ЗАВЕРШЕНЫ!{Colors.ENDC}\n")
except Exception as e:
print_error(f"ОШИБКА: {e}")
import traceback
traceback.print_exc()
if __name__ == '__main__':
main()