""" Tests unitaires pour les paramètres d'unicité des documents. Ces tests vérifient que le système de versioning fonctionne correctement avec les paramètres d'unicité. """ from django.test import TestCase from django.contrib.auth import get_user_model from documents.models import DocumentFolder, DocumentTag, ManagedDocument from documents.services import DocumentManagementService from io import BytesIO from django.core.files.uploadedfile import SimpleUploadedFile User = get_user_model() class UniqueParamsTestCase(TestCase): """Tests pour les paramètres d'unicité des documents.""" def setUp(self): """Initialisation des données de test.""" self.user = User.objects.create_user( username='testuser', password='testpass123' ) # Créer un dossier de test self.folder = DocumentFolder.objects.create( name='Test Folder', slug='test-folder', ) # Créer un tag unique self.unique_tag = DocumentTag.objects.create( name_fr='As-Built', slug='asbuilt', is_unique=True, ) # Créer un tag non-unique self.regular_tag = DocumentTag.objects.create( name_fr='Photo', slug='photo', is_unique=False, ) def create_test_file(self, filename='test.pdf', content=b'test content'): """Crée un fichier de test.""" return SimpleUploadedFile(filename, content) def test_same_tag_different_params_creates_different_documents(self): """ Test: Deux documents avec le même tag mais des paramètres différents doivent créer deux documents distincts. """ # Premier document: as-built format PDF file1 = self.create_test_file('asbuilt_v1.pdf') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, title='As-Built PDF', unique_params={'format': 'pdf'} ) # Deuxième document: as-built format DXF file2 = self.create_test_file('asbuilt_v1.dxf') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, title='As-Built DXF', unique_params={'format': 'dxf'} ) # Vérifications self.assertFalse(result1['is_new_version']) self.assertFalse(result2['is_new_version']) self.assertNotEqual(result1['document'].id, result2['document'].id) self.assertEqual(result1['document'].unique_params, {'format': 'pdf'}) self.assertEqual(result2['document'].unique_params, {'format': 'dxf'}) def test_same_tag_same_params_creates_version(self): """ Test: Deux documents avec le même tag et les mêmes paramètres doivent créer une nouvelle version du même document. """ # Premier document file1 = self.create_test_file('asbuilt_v1.pdf') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, title='As-Built PDF v1', unique_params={'format': 'pdf'} ) # Deuxième document avec les mêmes paramètres file2 = self.create_test_file('asbuilt_v2.pdf') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, title='As-Built PDF v2', unique_params={'format': 'pdf'} ) # Vérifications self.assertFalse(result1['is_new_version']) self.assertTrue(result2['is_new_version']) self.assertEqual(result1['document'].id, result2['document'].id) self.assertEqual(result2['document'].versions.count(), 2) def test_empty_params_vs_no_params(self): """ Test: Un document sans paramètres ({}) et un document avec paramètres doivent être considérés comme différents. """ # Premier document: sans paramètres file1 = self.create_test_file('asbuilt1.pdf') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, title='As-Built sans format', unique_params={} ) # Deuxième document: avec paramètres file2 = self.create_test_file('asbuilt2.pdf') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, title='As-Built PDF', unique_params={'format': 'pdf'} ) # Vérifications self.assertFalse(result1['is_new_version']) self.assertFalse(result2['is_new_version']) self.assertNotEqual(result1['document'].id, result2['document'].id) self.assertEqual(result1['document'].unique_params, {}) self.assertEqual(result2['document'].unique_params, {'format': 'pdf'}) def test_multiple_params(self): """ Test: Documents avec plusieurs paramètres différents. """ # Document 1: câbles C1,C2 file1 = self.create_test_file('cross_plan_A.xlsx') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, title='Cross Plan A', unique_params={'cables': 'C1,C2', 'zone': 'A'} ) # Document 2: câbles C3,C4 (zone différente) file2 = self.create_test_file('cross_plan_B.xlsx') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, title='Cross Plan B', unique_params={'cables': 'C3,C4', 'zone': 'B'} ) # Document 3: mêmes paramètres que document 1 (nouvelle version) file3 = self.create_test_file('cross_plan_A_v2.xlsx') result3 = DocumentManagementService.add_document( file=file3, tag=self.unique_tag, folder=self.folder, user=self.user, title='Cross Plan A v2', unique_params={'cables': 'C1,C2', 'zone': 'A'} ) # Vérifications self.assertFalse(result1['is_new_version']) self.assertFalse(result2['is_new_version']) self.assertTrue(result3['is_new_version']) self.assertNotEqual(result1['document'].id, result2['document'].id) self.assertEqual(result1['document'].id, result3['document'].id) def test_get_all_documents_by_tag(self): """ Test: Récupération de tous les documents avec un tag donné. """ # Créer plusieurs documents avec le même tag mais des paramètres différents for i, fmt in enumerate(['pdf', 'dxf', 'dwg']): file = self.create_test_file(f'asbuilt_{i}.{fmt}') DocumentManagementService.add_document( file=file, tag=self.unique_tag, folder=self.folder, user=self.user, title=f'As-Built {fmt.upper()}', unique_params={'format': fmt} ) # Mock content_object avec get_default_folder class MockObject: pass mock_obj = MockObject() # On ne peut pas vraiment tester get_all_documents_by_tag sans un vrai content_object # mais on peut vérifier que les documents ont été créés correctement docs = ManagedDocument.objects.filter(tags=self.unique_tag) self.assertEqual(docs.count(), 3) formats = [doc.unique_params.get('format') for doc in docs] self.assertIn('pdf', formats) self.assertIn('dxf', formats) self.assertIn('dwg', formats) def test_params_order_doesnt_matter(self): """ Test: L'ordre des paramètres ne doit pas affecter l'unicité. """ # Premier document file1 = self.create_test_file('doc1.pdf') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, title='Doc 1', unique_params={'format': 'pdf', 'language': 'fr'} ) # Deuxième document avec les mêmes paramètres mais dans un ordre différent file2 = self.create_test_file('doc2.pdf') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, title='Doc 2', unique_params={'language': 'fr', 'format': 'pdf'} ) # Vérifications: doit créer une nouvelle version, pas un nouveau document self.assertFalse(result1['is_new_version']) self.assertTrue(result2['is_new_version']) self.assertEqual(result1['document'].id, result2['document'].id) def test_non_unique_tag_ignores_params(self): """ Test: Les tags non-uniques doivent toujours créer de nouveaux documents, même avec les mêmes paramètres. """ # Premier document file1 = self.create_test_file('photo1.jpg') result1 = DocumentManagementService.add_document( file=file1, tag=self.regular_tag, folder=self.folder, user=self.user, title='Photo 1', unique_params={'format': 'jpg'} ) # Deuxième document avec les mêmes paramètres file2 = self.create_test_file('photo2.jpg') result2 = DocumentManagementService.add_document( file=file2, tag=self.regular_tag, folder=self.folder, user=self.user, title='Photo 2', unique_params={'format': 'jpg'} ) # Vérifications: doit créer deux documents distincts self.assertFalse(result1['is_new_version']) self.assertFalse(result2['is_new_version']) self.assertNotEqual(result1['document'].id, result2['document'].id) class UniqueParamsEdgeCasesTestCase(TestCase): """Tests pour les cas limites et edge cases.""" def setUp(self): """Initialisation des données de test.""" self.user = User.objects.create_user( username='testuser', password='testpass123' ) self.folder = DocumentFolder.objects.create( name='Test Folder', slug='test-folder', ) self.unique_tag = DocumentTag.objects.create( name_fr='Document', slug='document', is_unique=True, ) def create_test_file(self, filename='test.pdf', content=b'test content'): """Crée un fichier de test.""" return SimpleUploadedFile(filename, content) def test_case_sensitive_params(self): """ Test: Les paramètres sont sensibles à la casse. """ file1 = self.create_test_file('doc1.pdf') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, unique_params={'format': 'pdf'} ) file2 = self.create_test_file('doc2.pdf') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, unique_params={'format': 'PDF'} # Majuscules ) # Doit créer deux documents différents car 'pdf' != 'PDF' self.assertNotEqual(result1['document'].id, result2['document'].id) def test_nested_params_not_recommended(self): """ Test: Les paramètres imbriqués fonctionnent mais ne sont pas recommandés. """ file1 = self.create_test_file('doc1.pdf') result1 = DocumentManagementService.add_document( file=file1, tag=self.unique_tag, folder=self.folder, user=self.user, unique_params={'metadata': {'format': 'pdf', 'size': 'A4'}} ) file2 = self.create_test_file('doc2.pdf') result2 = DocumentManagementService.add_document( file=file2, tag=self.unique_tag, folder=self.folder, user=self.user, unique_params={'metadata': {'format': 'pdf', 'size': 'A4'}} ) # Doit créer une nouvelle version self.assertTrue(result2['is_new_version']) self.assertEqual(result1['document'].id, result2['document'].id)