Corp/backend/documents/tests_v2.py
igor_nadein 49eff37671 feat(documents): Интеграция django-filer для управления файлами
Добавлена поддержка django-filer для профессионального управления файлами в приложении documents.

Что добавлено:
- models_v2.py: Новые модели DocumentV2 и DocumentAcknowledgementV2 с FilerFileField
- admin_v2.py: Django admin с drag & drop загрузкой и превью thumbnails
- rules_v2.py: Правила доступа django-rules для новых моделей
- tests_v2.py: Юнит-тесты для моделей и правил доступа
- management/commands/migrate_to_filer.py: Команда для миграции данных из старых моделей

Настройки:
- settings.py: Добавлены filer, easy_thumbnails, mptt, reversion в INSTALLED_APPS
- settings.py: Настроены THUMBNAIL_PROCESSORS и THUMBNAIL_ALIASES
- requirements.txt: Добавлены django-filer==3.4.4, easy-thumbnails==2.10.1, django-mptt==0.18.0, django-reversion==6.1.0

Документация:
- docs/reports/DOCUMENTS_REPLACEMENT_ANALYSIS.md: Анализ вариантов замены приложения documents

Преимущества:
- Поддержка папок и вложенной структуры файлов
- Автоматическая генерация thumbnails для изображений и PDF
- Полнотекстовый поиск по содержимому файлов
- Информация о размере, MIME-типе, метаданные
- История версий через django-reversion
- Сокращение кода с 1180 → ~580 строк (50%)

Миграция:
- Старые модели Document и DocumentAcknowledgement оставлены для совместимости
- Миграция данных: python manage.py migrate_to_filer
- После проверки старые модели можно удалить

Связанные issues: #N/A
Тип изменений: Feature
Область: documents, file management
2026-02-28 00:36:17 +03:00

298 lines
10 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.

# documents/tests_v2.py
"""
Тесты для моделей DocumentV2 и DocumentAcknowledgementV2
"""
from django.test import TestCase
from django.contrib.auth import get_user_model
from django.core.files.uploadedfile import SimpleUploadedFile
from filer.models import File as FilerFile
from documents.models_v2 import DocumentV2, DocumentAcknowledgementV2
from employees.models import Department
import rules
User = get_user_model()
class DocumentV2ModelTest(TestCase):
"""Тесты для модели DocumentV2"""
def setUp(self):
"""Создание тестовых данных"""
self.user = User.objects.create_user(
phone_number='+79999999999',
email='test1@example.com',
first_name='Тест',
last_name='Тестов',
is_active=True
)
# Создаем тестовый файл через filer
test_file = SimpleUploadedFile(
"test_document.txt",
b"Test content",
content_type="text/plain"
)
self.filer_file = FilerFile.objects.create(
file=test_file,
original_filename="test_document.txt",
name="Test Document",
owner=self.user
)
def test_create_document_v2(self):
"""Создание документа с filer файлом"""
document = DocumentV2.objects.create(
title="Тестовый документ",
file=self.filer_file,
description="Описание тестового документа",
uploaded_by=self.user,
sent_to_all=True
)
self.assertEqual(document.title, "Тестовый документ")
self.assertEqual(document.file, self.filer_file)
self.assertEqual(document.uploaded_by, self.user)
self.assertTrue(document.sent_to_all)
self.assertIsNotNone(document.uploaded_at)
def test_file_properties(self):
"""Проверка свойств файла (размер, расширение)"""
document = DocumentV2.objects.create(
title="Тестовый документ",
file=self.filer_file,
uploaded_by=self.user
)
self.assertGreater(document.file_size, 0)
self.assertEqual(document.file_extension, 'txt')
def test_sent_to_all(self):
"""Документ с sent_to_all=True"""
document = DocumentV2.objects.create(
title="Документ для всех",
file=self.filer_file,
uploaded_by=self.user,
sent_to_all=True
)
self.assertTrue(document.sent_to_all)
self.assertEqual(document.departments.count(), 0)
self.assertEqual(document.recipients.count(), 0)
def test_department_recipients(self):
"""Документ для конкретных отделов"""
department = Department.objects.create(
name="Тестовый отдел"
)
document = DocumentV2.objects.create(
title="Документ для отдела",
file=self.filer_file,
uploaded_by=self.user,
sent_to_all=False
)
document.departments.add(department)
self.assertFalse(document.sent_to_all)
self.assertEqual(document.departments.count(), 1)
self.assertIn(department, document.departments.all())
def test_individual_recipients(self):
"""Документ для конкретных получателей"""
recipient = User.objects.create_user(
phone_number='+79999999998',
email='recipient@example.com',
first_name='Получатель',
last_name='Тестовый',
is_active=True
)
document = DocumentV2.objects.create(
title="Документ для получателя",
file=self.filer_file,
uploaded_by=self.user,
sent_to_all=False
)
document.recipients.add(recipient)
self.assertFalse(document.sent_to_all)
self.assertEqual(document.recipients.count(), 1)
self.assertIn(recipient, document.recipients.all())
class DocumentAcknowledgementV2ModelTest(TestCase):
"""Тесты для модели DocumentAcknowledgementV2"""
def setUp(self):
"""Создание тестовых данных"""
self.user = User.objects.create_user(
phone_number='+79999999999',
email='test@example.com',
first_name='Тест',
last_name='Тестов',
is_active=True
)
test_file = SimpleUploadedFile(
"test_document.txt",
b"Test content",
content_type="text/plain"
)
filer_file = FilerFile.objects.create(
file=test_file,
original_filename="test_document.txt",
name="Test Document",
owner=self.user
)
self.document = DocumentV2.objects.create(
title="Тестовый документ",
file=filer_file,
uploaded_by=self.user,
sent_to_all=True
)
def test_create_acknowledgement(self):
"""Создание ознакомления с документом"""
ack = DocumentAcknowledgementV2.objects.create(
document=self.document,
user=self.user
)
self.assertEqual(ack.document, self.document)
self.assertEqual(ack.user, self.user)
self.assertIsNotNone(ack.acknowledged_at)
def test_unique_acknowledgement(self):
"""Один пользователь может ознакомиться только один раз"""
DocumentAcknowledgementV2.objects.create(
document=self.document,
user=self.user
)
# Попытка создать второе ознакомление должна вызвать ошибку
with self.assertRaises(Exception):
DocumentAcknowledgementV2.objects.create(
document=self.document,
user=self.user
)
def test_acknowledgement_count(self):
"""Подсчет ознакомлений"""
user2 = User.objects.create_user(
phone_number='+79999999998',
email='test2@example.com',
first_name='Тест2',
last_name='Тестов2',
is_active=True
)
DocumentAcknowledgementV2.objects.create(
document=self.document,
user=self.user
)
DocumentAcknowledgementV2.objects.create(
document=self.document,
user=user2
)
self.assertEqual(self.document.acknowledgements.count(), 2)
class DocumentV2RulesTest(TestCase):
"""Тесты для правил доступа django-rules"""
def setUp(self):
"""Создание тестовых данных"""
self.owner = User.objects.create_user(
phone_number='+79999999999',
email='owner@example.com',
first_name='Владелец',
last_name='Документа',
is_active=True
)
self.other_user = User.objects.create_user(
phone_number='+79999999998',
email='other@example.com',
first_name='Другой',
last_name='Пользователь',
is_active=True
)
test_file = SimpleUploadedFile(
"test_document.txt",
b"Test content",
content_type="text/plain"
)
filer_file = FilerFile.objects.create(
file=test_file,
original_filename="test_document.txt",
name="Test Document",
owner=self.owner
)
self.document = DocumentV2.objects.create(
title="Тестовый документ",
file=filer_file,
uploaded_by=self.owner,
sent_to_all=False # Не для всех
)
def test_owner_can_view(self):
"""Владелец может просматривать свой документ"""
self.assertTrue(
rules.test_rule('documents.view_documentv2', self.owner, self.document)
)
def test_other_user_cannot_view(self):
"""Другой пользователь не может просматривать чужой документ (если не в списке)"""
self.assertFalse(
rules.test_rule('documents.view_documentv2', self.other_user, self.document)
)
def test_sent_to_all_allows_view(self):
"""Документ с sent_to_all=True доступен всем активным пользователям"""
self.document.sent_to_all = True
self.document.save()
self.assertTrue(
rules.test_rule('documents.view_documentv2', self.other_user, self.document)
)
def test_recipient_can_view(self):
"""Получатель из списка может просматривать документ"""
self.document.recipients.add(self.other_user)
self.assertTrue(
rules.test_rule('documents.view_documentv2', self.other_user, self.document)
)
def test_owner_can_edit(self):
"""Владелец может редактировать свой документ"""
self.assertTrue(
rules.test_rule('documents.change_documentv2', self.owner, self.document)
)
def test_other_user_cannot_edit(self):
"""Другой пользователь не может редактировать чужой документ"""
self.assertFalse(
rules.test_rule('documents.change_documentv2', self.other_user, self.document)
)
def test_owner_can_delete(self):
"""Владелец может удалять свой документ"""
self.assertTrue(
rules.test_rule('documents.delete_documentv2', self.owner, self.document)
)
def test_other_user_cannot_delete(self):
"""Другой пользователь не может удалять чужой документ"""
self.assertFalse(
rules.test_rule('documents.delete_documentv2', self.other_user, self.document)
)