Corp/backend/test_requests_access_detailed.py

290 lines
9.6 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.

"""
Детальное тестирование API логики доступа к заявлениям
Проверяет edge cases и специфические сценарии
"""
import os
import sys
import django
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'eusrr_backend.settings')
django.setup()
from django.contrib.auth import get_user_model
from django.db import models
from employees.models import Department, EmployeeDepartment
from requests_app.models import Request
from requests_app.enums import RequestStatus
User = get_user_model()
def test_scenario(title, test_func):
"""Обертка для тестов"""
print(f"\n{'=' * 80}")
print(f"🧪 ТЕСТ: {title}")
print('=' * 80)
try:
result = test_func()
if result:
print(f"✅ PASSED")
else:
print(f"❌ FAILED")
return result
except Exception as e:
print(f"💥 ERROR: {e}")
import traceback
traceback.print_exc()
return False
def test_recipient_can_see():
"""Тест: Получатель (To) видит заявку"""
print("\n1. Создаем пользователя и заявку...")
# Находим пользователя
user1 = User.objects.filter(is_staff=False, is_superuser=False).first()
user2 = User.objects.filter(is_staff=False, is_superuser=False).exclude(id=user1.id).first()
if not user1 or not user2:
print("⚠️ Недостаточно пользователей для теста")
return None
print(f" Автор: {user1.get_full_name() or user1.username}")
print(f" Получатель: {user2.get_full_name() or user2.username}")
# Создаем заявку
request = Request.objects.create(
employee=user1,
type='other',
title='Тест: получатель должен видеть',
status=RequestStatus.PENDING
)
request.recipients.add(user2)
print(f" Создана заявка ID={request.id}")
# Проверяем доступ
print("\n2. Проверяем доступ получателя...")
from django.db.models import Q
my_depts = EmployeeDepartment.objects.filter(
employee=user2, is_active=True
).values_list('department_id', flat=True)
scope = Q(employee_id=user2.id) | Q(recipients=user2) | Q(cc_users=user2)
if my_depts:
scope |= Q(sent_to_all_department=True, departments__in=my_depts)
accessible = Request.objects.filter(scope).filter(id=request.id).exists()
print(f" Получатель видит заявку: {accessible}")
# Cleanup
request.delete()
return accessible
def test_cc_user_can_see():
"""Тест: Пользователь в CC видит заявку"""
print("\n1. Создаем пользователей и заявку с CC...")
user1 = User.objects.filter(is_staff=False, is_superuser=False).first()
user2 = User.objects.filter(is_staff=False, is_superuser=False).exclude(id=user1.id).first()
if not user1 or not user2:
print("⚠️ Недостаточно пользователей для теста")
return None
print(f" Автор: {user1.get_full_name() or user1.username}")
print(f" CC: {user2.get_full_name() or user2.username}")
request = Request.objects.create(
employee=user1,
type='other',
title='Тест: CC должен видеть',
status=RequestStatus.PENDING
)
request.cc_users.add(user2)
print(f" Создана заявка ID={request.id}")
# Проверяем доступ
print("\n2. Проверяем доступ CC пользователя...")
from django.db.models import Q
scope = Q(employee_id=user2.id) | Q(recipients=user2) | Q(cc_users=user2)
accessible = Request.objects.filter(scope).filter(id=request.id).exists()
print(f" CC пользователь видит заявку: {accessible}")
# Cleanup
request.delete()
return accessible
def test_all_department_visibility():
"""Тест: sent_to_all_department работает"""
print("\n1. Создаем заявку 'Всем в отделе'...")
# Находим отдел с сотрудниками
dept = Department.objects.annotate(
emp_count=models.Count('employeedepartment')
).filter(emp_count__gte=2).first()
if not dept:
print("⚠️ Нет отдела с несколькими сотрудниками")
return None
# Берем двух сотрудников этого отдела
emp_dept = EmployeeDepartment.objects.filter(
department=dept,
is_active=True
).select_related('employee')[:2]
if len(emp_dept) < 2:
print("⚠️ Недостаточно сотрудников в отделе")
return None
author = emp_dept[0].employee
viewer = emp_dept[1].employee
print(f" Отдел: {dept.name}")
print(f" Автор: {author.get_full_name() or author.username}")
print(f" Сотрудник отдела: {viewer.get_full_name() or viewer.username}")
# Создаем заявку
request = Request.objects.create(
employee=author,
type='other',
title='Тест: Всем в отделе',
status=RequestStatus.PENDING,
sent_to_all_department=True
)
request.departments.add(dept)
print(f" Создана заявка ID={request.id}")
# Проверяем доступ
print("\n2. Проверяем, что другой сотрудник отдела видит заявку...")
from django.db.models import Q
my_depts = [dept.id]
scope = Q(employee_id=viewer.id) | Q(recipients=viewer) | Q(cc_users=viewer)
scope |= Q(sent_to_all_department=True, departments__in=my_depts)
accessible = Request.objects.filter(scope).filter(id=request.id).exists()
print(f" Сотрудник видит заявку: {accessible}")
# Cleanup
request.delete()
return accessible
def test_non_recipient_cannot_see():
"""Тест: Посторонний НЕ видит заявку"""
print("\n1. Создаем заявку без получателей...")
users = list(User.objects.filter(is_staff=False, is_superuser=False)[:3])
if len(users) < 3:
print("⚠️ Недостаточно пользователей")
return None
author = users[0]
recipient = users[1]
outsider = users[2]
print(f" Автор: {author.get_full_name() or author.username}")
print(f" Получатель: {recipient.get_full_name() or recipient.username}")
print(f" Посторонний: {outsider.get_full_name() or outsider.username}")
request = Request.objects.create(
employee=author,
type='other',
title='Тест: Посторонний не должен видеть',
status=RequestStatus.PENDING
)
request.recipients.add(recipient)
print(f" Создана заявка ID={request.id}")
# Проверяем, что посторонний НЕ видит
print("\n2. Проверяем, что посторонний НЕ видит заявку...")
from django.db.models import Q
my_depts = EmployeeDepartment.objects.filter(
employee=outsider, is_active=True
).values_list('department_id', flat=True)
scope = Q(employee_id=outsider.id) | Q(recipients=outsider) | Q(cc_users=outsider)
if my_depts:
scope |= Q(sent_to_all_department=True, departments__in=my_depts)
accessible = Request.objects.filter(scope).filter(id=request.id).exists()
print(f" Посторонний видит заявку: {accessible}")
print(f" Ожидается: False")
# Cleanup
request.delete()
return not accessible # Тест проходит, если НЕ видит
def main():
print("\n" + "=" * 80)
print(" ДЕТАЛЬНОЕ ТЕСТИРОВАНИЕ API ЛОГИКИ ДОСТУПА")
print("=" * 80)
from django.db import models
results = []
# Тесты
results.append(test_scenario(
"Получатель (To) видит заявку",
test_recipient_can_see
))
results.append(test_scenario(
"Пользователь в CC видит заявку",
test_cc_user_can_see
))
results.append(test_scenario(
"sent_to_all_department работает",
test_all_department_visibility
))
results.append(test_scenario(
"Посторонний НЕ видит чужую заявку",
test_non_recipient_cannot_see
))
# Итоги
print("\n" + "=" * 80)
print(" ИТОГИ ТЕСТИРОВАНИЯ")
print("=" * 80)
passed = sum(1 for r in results if r is True)
failed = sum(1 for r in results if r is False)
skipped = sum(1 for r in results if r is None)
print(f"\n✅ Пройдено: {passed}")
print(f"❌ Провалено: {failed}")
print(f"⏭️ Пропущено: {skipped}")
if failed == 0 and passed > 0:
print("\n🎉 Все тесты пройдены успешно!")
elif failed > 0:
print("\n⚠️ Есть проваленные тесты - требуется исправление!")
if __name__ == "__main__":
main()