package local.epul4a.fotosharing.integration; import local.epul4a.fotosharing.model.Commentaire; import local.epul4a.fotosharing.model.Photo; import local.epul4a.fotosharing.model.Utilisateur; import local.epul4a.fotosharing.repository.CommentaireRepository; import local.epul4a.fotosharing.repository.PhotoRepository; import local.epul4a.fotosharing.repository.UtilisateurRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.test.context.ActiveProfiles; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.List; import static org.junit.jupiter.api.Assertions.*; /** * Tests d'intégration pour la suppression en cascade * Teste : Supprimer un user doit supprimer ses photos et commentaires */ @SpringBootTest @ActiveProfiles("test") class CascadeDeleteIntegrationTest { @Autowired private UtilisateurRepository utilisateurRepository; @Autowired private PhotoRepository photoRepository; @Autowired private CommentaireRepository commentaireRepository; @Autowired private PasswordEncoder passwordEncoder; private Utilisateur userA; private Utilisateur userB; @BeforeEach void setUp() { // Nettoyer la BDD commentaireRepository.deleteAll(); photoRepository.deleteAll(); utilisateurRepository.deleteAll(); // Créer User A userA = new Utilisateur(); userA.setEmail("userA@example.com"); userA.setNom("A"); userA.setPrenom("User"); userA.setMotDePasse(passwordEncoder.encode("password")); userA = utilisateurRepository.save(userA); // Créer User B userB = new Utilisateur(); userB.setEmail("userB@example.com"); userB.setNom("B"); userB.setPrenom("User"); userB.setMotDePasse(passwordEncoder.encode("password")); userB = utilisateurRepository.save(userB); } @Test void testDeleteUser_ShouldDeleteUserOwnPhotos() { // Given - User A possède 3 photos Photo photo1 = createPhoto("photo1.jpg", userA); Photo photo2 = createPhoto("photo2.jpg", userA); Photo photo3 = createPhoto("photo3.jpg", userA); photoRepository.save(photo1); photoRepository.save(photo2); photoRepository.save(photo3); // Given - User B possède 2 photos (ne doivent PAS être supprimées) Photo photoB1 = createPhoto("photoB1.jpg", userB); Photo photoB2 = createPhoto("photoB2.jpg", userB); photoRepository.save(photoB1); photoRepository.save(photoB2); // Vérifier la situation initiale assertEquals(5, photoRepository.count(), "5 photos au total"); assertEquals(3, photoRepository.findByProprietaire_Email(userA.getEmail()).size()); assertEquals(2, photoRepository.findByProprietaire_Email(userB.getEmail()).size()); // When - Supprimer User A utilisateurRepository.deleteById(userA.getId()); // Then - Les photos de User A doivent être supprimées assertEquals(2, photoRepository.count(), "Seules les 2 photos de User B doivent rester"); List remainingPhotos = photoRepository.findAll(); assertEquals(2, remainingPhotos.size()); assertTrue(remainingPhotos.stream().allMatch(p -> p.getProprietaire().getId().equals(userB.getId())), "Toutes les photos restantes doivent appartenir à User B"); } @Test void testDeleteUser_ShouldDeleteUserOwnComments() { // Given - Photo de User B Photo photoB = createPhoto("photoB.jpg", userB); photoB = photoRepository.save(photoB); // Given - User A commente la photo de User B Commentaire comment1 = createCommentaire("Super photo !", userA, photoB); Commentaire comment2 = createCommentaire("J'adore !", userA, photoB); Commentaire comment3 = createCommentaire("Merci !", userB, photoB); // Commentaire de User B commentaireRepository.save(comment1); commentaireRepository.save(comment2); commentaireRepository.save(comment3); // Vérifier la situation initiale assertEquals(3, commentaireRepository.count()); // When - Supprimer User A utilisateurRepository.deleteById(userA.getId()); // Then - Les commentaires de User A doivent être supprimés assertEquals(1, commentaireRepository.count(), "Seul le commentaire de User B doit rester"); List remainingComments = commentaireRepository.findAll(); assertEquals(1, remainingComments.size()); assertEquals(userB.getId(), remainingComments.get(0).getAuteur().getId(), "Le commentaire restant doit être celui de User B"); } @Test void testDeleteUser_ShouldDeletePhotosAndAllCommentsOnThosePhotos() { // Given - User A possède une photo Photo photoA = createPhoto("photoA.jpg", userA); photoA = photoRepository.save(photoA); // Given - Plusieurs utilisateurs commentent la photo de User A Commentaire commentByA = createCommentaire("Ma photo", userA, photoA); Commentaire commentByB = createCommentaire("Belle photo", userB, photoA); commentaireRepository.save(commentByA); commentaireRepository.save(commentByB); // Vérifier la situation initiale assertEquals(1, photoRepository.count()); assertEquals(2, commentaireRepository.count()); // When - Supprimer User A (et donc sa photo) utilisateurRepository.deleteById(userA.getId()); // Then - La photo ET tous ses commentaires doivent être supprimés assertEquals(0, photoRepository.count(), "La photo de User A doit être supprimée"); assertEquals(0, commentaireRepository.count(), "TOUS les commentaires sur la photo supprimée doivent disparaître (cascade)"); } @Test void testDeleteUser_ComplexScenario() { // Scénario complexe : // - User A a 2 photos // - User B a 1 photo // - User A commente sa propre photo ET la photo de User B // - User B commente sa propre photo ET une photo de User A // Given - Photos Photo photoA1 = photoRepository.save(createPhoto("photoA1.jpg", userA)); Photo photoA2 = photoRepository.save(createPhoto("photoA2.jpg", userA)); Photo photoB = photoRepository.save(createPhoto("photoB.jpg", userB)); // Given - Commentaires commentaireRepository.save(createCommentaire("A sur A1", userA, photoA1)); commentaireRepository.save(createCommentaire("A sur A2", userA, photoA2)); commentaireRepository.save(createCommentaire("A sur B", userA, photoB)); commentaireRepository.save(createCommentaire("B sur A1", userB, photoA1)); commentaireRepository.save(createCommentaire("B sur B", userB, photoB)); // Vérifier la situation initiale assertEquals(3, photoRepository.count()); assertEquals(5, commentaireRepository.count()); // When - Supprimer User A utilisateurRepository.deleteById(userA.getId()); // Then - Vérifier les suppressions assertEquals(1, photoRepository.count(), "Seule la photo de User B doit rester"); List remainingPhotos = photoRepository.findAll(); assertEquals(photoB.getId(), remainingPhotos.get(0).getId()); // Then - Vérifier les commentaires restants List remainingComments = commentaireRepository.findAll(); assertEquals(1, remainingComments.size(), "Seul le commentaire 'B sur B' doit rester"); Commentaire lastComment = remainingComments.get(0); assertEquals("B sur B", lastComment.getContenu()); assertEquals(userB.getId(), lastComment.getAuteur().getId()); assertEquals(photoB.getId(), lastComment.getPhoto().getId()); } @Test void testDeleteUser_ShouldNotAffectOtherUsers() { // Given - Créer User C Utilisateur userC = new Utilisateur(); userC.setEmail("userC@example.com"); userC.setNom("C"); userC.setPrenom("User"); userC.setMotDePasse(passwordEncoder.encode("password")); userC = utilisateurRepository.save(userC); // Given - Chaque utilisateur a des photos et commentaires Photo photoA = photoRepository.save(createPhoto("photoA.jpg", userA)); Photo photoB = photoRepository.save(createPhoto("photoB.jpg", userB)); Photo photoC = photoRepository.save(createPhoto("photoC.jpg", userC)); commentaireRepository.save(createCommentaire("Comment A", userA, photoA)); commentaireRepository.save(createCommentaire("Comment B", userB, photoB)); commentaireRepository.save(createCommentaire("Comment C", userC, photoC)); // Vérifier la situation initiale assertEquals(3, utilisateurRepository.count()); assertEquals(3, photoRepository.count()); assertEquals(3, commentaireRepository.count()); // When - Supprimer User A utilisateurRepository.deleteById(userA.getId()); // Then - User B et C ne doivent pas être affectés assertEquals(2, utilisateurRepository.count(), "Users B et C doivent rester"); assertEquals(2, photoRepository.count(), "Photos de B et C doivent rester"); assertEquals(2, commentaireRepository.count(), "Commentaires de B et C doivent rester"); // Then - Vérifier que les bonnes entités restent assertTrue(utilisateurRepository.findById(userB.getId()).isPresent()); assertTrue(utilisateurRepository.findById(userC.getId()).isPresent()); assertFalse(utilisateurRepository.findById(userA.getId()).isPresent()); } @Test void testDeleteMultipleUsers_ShouldDeleteRespectiveData() { // Given - Chaque user a des photos photoRepository.save(createPhoto("photoA.jpg", userA)); photoRepository.save(createPhoto("photoB.jpg", userB)); assertEquals(2, photoRepository.count()); // When - Supprimer les deux utilisateurs utilisateurRepository.deleteById(userA.getId()); utilisateurRepository.deleteById(userB.getId()); // Then - Tout doit être supprimé assertEquals(0, utilisateurRepository.count()); assertEquals(0, photoRepository.count()); } // ===================== Méthodes Utilitaires ===================== private Photo createPhoto(String filename, Utilisateur owner) { Photo photo = new Photo(); photo.setNomFichierOriginal(filename); photo.setUuidFichier("uuid-" + filename); photo.setUuidThumbnail("thumb-" + filename); photo.setVisibilite(Photo.Visibilite.PUBLIC); photo.setDateUpload(LocalDateTime.now()); photo.setProprietaire(owner); photo.setMimeType("image/jpeg"); photo.setTailleFichier(1024L); return photo; } private Commentaire createCommentaire(String texte, Utilisateur auteur, Photo photo) { Commentaire commentaire = new Commentaire(); commentaire.setContenu(texte); commentaire.setAuteur(auteur); commentaire.setPhoto(photo); commentaire.setDateCommentaire(LocalDateTime.now()); return commentaire; } }