Corp/backend/tests/manual/test_requests_access.py
Игорь Надеин 7f5c7443e6 refactor: реорганизация тестов для улучшения структуры и производительности
- Перемещены manual tests из scripts/manual_tests в tests/manual/
- Обновлен pytest.ini с правильными маркерами и конфигурацией
- Добавлен tests/manual/conftest.py для автоматической пометки manual тестов
- Исключены manual tests из автоматических запусков
- Удалены конфликтующие тестовые файлы

Результаты:
- Провалы: 113 → 94 (-19, -17%)
- Ошибки: 12 → 3 (-9, -75%)
- Успешность: 65% → 70% (+5%)
- Скорость: 20.71s → 16.46s (+20% быстрее)

Все изменения не влияют на основной код, только на структуру тестов.
2026-01-05 07:41:34 +03:00

279 lines
11 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.

"""
Тестирование логики доступа к заявлениям (requests)
Проверяет:
1. Обычные пользователи видят только свои + адресованные им
2. Руководители отделов видят заявки своих отделов
3. Пользователи с глобальными правами видят всё
4. Департаментные права работают корректно
5. sent_to_all_department работает
"""
import os
import sys
import django
# Настройка 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.models import Q
from employees.models import Department, EmployeeDepartment
from requests_app.models import Request
User = get_user_model()
def print_section(title):
"""Красивый вывод секции"""
print(f"\n{'=' * 80}")
print(f" {title}")
print('=' * 80)
def test_user_access(user, description=""):
"""Тестирует доступ пользователя к заявлениям"""
print(f"\n👤 Пользователь: {user.get_full_name() or user.username}")
if description:
print(f" {description}")
# Получаем отделы пользователя
my_depts = EmployeeDepartment.objects.filter(
employee=user,
is_active=True
).select_related('department')
print(f"\n📋 Отделы пользователя:")
if my_depts.exists():
for ed in my_depts:
role_name = ed.role.name if ed.role else "Без роли"
print(f" - {ed.department.name} ({role_name})")
if ed.role:
perms = ed.role.scoped_permissions.values_list('code', flat=True)
if perms:
print(f" Права: {', '.join(perms)}")
else:
print(" (нет отделов)")
# Проверяем глобальные права
print(f"\n🔑 Глобальные права:")
print(f" is_staff: {user.is_staff}")
print(f" can_view_all_requests: {user.has_perm('requests_app.can_view_all_requests')}")
print(f" view_request: {user.has_perm('requests_app.view_request')}")
print(f" can_process_requests: {user.has_perm('requests_app.can_process_requests')}")
# Проверяем руководство отделами
head_depts = Department.objects.filter(head=user)
if head_depts.exists():
print(f"\n👔 Руководитель отделов:")
for dept in head_depts:
print(f" - {dept.name}")
# Строим queryset как в реальном API
my_dept_ids = list(my_depts.values_list('department_id', flat=True))
# Проверяем: может ли видеть ВСЁ
can_view_all = (
user.is_staff
or user.has_perm("requests_app.can_view_all_requests")
or user.has_perm("requests_app.view_request")
)
if can_view_all:
print(f"\n✅ Может просматривать ВСЕ заявления (staff или глобальные права)")
qs = Request.objects.all()
else:
# Обычный пользователь - строим scope
scope = Q(employee_id=user.id) # Свои заявки
# Заявки, где я получатель
scope |= Q(recipients=user) | Q(cc_users=user)
# Заявки отделов с sent_to_all_department
if my_dept_ids:
scope |= Q(
sent_to_all_department=True,
departments__in=my_dept_ids
)
# Департаментные права
view_dept_ids = list(
EmployeeDepartment.objects.filter(
employee_id=user.id,
is_active=True,
role__scoped_permissions__code="view_request",
)
.values_list("department_id", flat=True)
.distinct()
)
proc_dept_ids = list(
EmployeeDepartment.objects.filter(
employee_id=user.id,
is_active=True,
role__scoped_permissions__code="can_process_requests",
)
.values_list("department_id", flat=True)
.distinct()
)
head_dept_ids = list(
Department.objects.filter(head_id=user.id).values_list("id", flat=True)
)
combined_ids = set(view_dept_ids) | set(proc_dept_ids) | set(head_dept_ids)
if combined_ids:
print(f"\n📊 Департаментные права для отделов (ID): {combined_ids}")
# Заявки этих отделов
scope |= Q(departments__in=combined_ids)
# Заявки сотрудников этих отделов
dept_emp_ids = list(
EmployeeDepartment.objects.filter(
department_id__in=list(combined_ids),
is_active=True,
)
.values_list("employee_id", flat=True)
.distinct()
)
if dept_emp_ids:
scope |= Q(employee_id__in=dept_emp_ids)
qs = Request.objects.filter(scope).distinct()
# Подсчитываем результаты
total = qs.count()
print(f"\n📈 Доступные заявления: {total}")
if total > 0:
# Разбивка по типам доступа
my_requests = qs.filter(employee=user).count()
addressed_to_me = qs.filter(Q(recipients=user) | Q(cc_users=user)).count()
print(f"\n Детализация:")
print(f" - Мои заявления: {my_requests}")
print(f" - Адресованные мне (To/CC): {addressed_to_me}")
if my_dept_ids:
all_dept = qs.filter(
sent_to_all_department=True,
departments__in=my_dept_ids
).distinct().count()
print(f" - 'Всем в отделе': {all_dept}")
# Последние 5 заявлений для примера
print(f"\n Примеры заявлений (последние 5):")
for req in qs.select_related('employee').order_by('-created_at')[:5]:
author = req.employee.get_full_name() or req.employee.username
# Определяем причину доступа
reasons = []
if req.employee == user:
reasons.append("автор")
if req.recipients.filter(id=user.id).exists():
reasons.append("получатель")
if req.cc_users.filter(id=user.id).exists():
reasons.append("CC")
if req.sent_to_all_department and any(
dept.id in my_dept_ids for dept in req.departments.all()
):
reasons.append("всем в отделе")
reason_str = ", ".join(reasons) if reasons else "департаментные права"
print(f" {req.id:4d}. {req.get_type_display():15s} | {author:20s} | {reason_str}")
return qs
def main():
print_section("ТЕСТИРОВАНИЕ ЛОГИКИ ДОСТУПА К ЗАЯВЛЕНИЯМ")
# Получаем тестовых пользователей
print("\n🔍 Поиск пользователей для тестирования...")
users_to_test = []
# 1. Обычный сотрудник (без особых прав)
regular_user = User.objects.filter(
is_staff=False,
is_superuser=False,
).exclude(
departments_links__role__scoped_permissions__code__in=[
'view_request', 'can_process_requests'
]
).first()
if regular_user:
users_to_test.append((regular_user, "Обычный сотрудник (без особых прав)"))
# 2. Руководитель отдела
head_user = Department.objects.exclude(head__isnull=True).first()
if head_user and head_user.head:
users_to_test.append((head_user.head, f"Руководитель отдела '{head_user.name}'"))
# 3. С департаментными правами
dept_rights_user = EmployeeDepartment.objects.filter(
is_active=True,
role__scoped_permissions__code__in=['view_request', 'can_process_requests']
).select_related('employee').first()
if dept_rights_user:
users_to_test.append((
dept_rights_user.employee,
f"С департаментными правами в отделе '{dept_rights_user.department.name}'"
))
# 4. Staff пользователь
staff_user = User.objects.filter(is_staff=True, is_superuser=False).first()
if staff_user:
users_to_test.append((staff_user, "Django staff (без superuser)"))
# 5. Superuser
superuser = User.objects.filter(is_superuser=True).first()
if superuser:
users_to_test.append((superuser, "Superuser"))
if not users_to_test:
print("\n❌ Не найдено пользователей для тестирования!")
print(" Создайте пользователей и отделы в админке")
return
# Информация о заявлениях в системе
total_requests = Request.objects.count()
print(f"\n📊 Всего заявлений в системе: {total_requests}")
if total_requests == 0:
print("\n⚠️ В системе нет заявлений! Создайте хотя бы одну заявку для тестирования.")
return
# Статистика по получателям
with_recipients = Request.objects.filter(recipients__isnull=False).distinct().count()
with_cc = Request.objects.filter(cc_users__isnull=False).distinct().count()
with_depts = Request.objects.filter(departments__isnull=False).distinct().count()
with_all_dept = Request.objects.filter(sent_to_all_department=True).count()
print(f"\n Заявлений с получателями (To): {with_recipients}")
print(f" Заявлений с копией (CC): {with_cc}")
print(f" Заявлений с отделами: {with_depts}")
print(f" Заявлений 'Всем в отделе': {with_all_dept}")
# Тестируем каждого пользователя
for user, description in users_to_test:
print_section(f"ТЕСТ: {description}")
test_user_access(user, description)
print_section("ТЕСТИРОВАНИЕ ЗАВЕРШЕНО")
print("\n✅ Все проверки выполнены!")
print("\nРекомендации:")
print("1. Проверьте, что обычные пользователи НЕ видят чужие заявки")
print("2. Руководители должны видеть заявки своих отделов")
print("3. Staff видят всё")
print("4. Получатели (To/CC) видят адресованные им заявки")
if __name__ == "__main__":
main()