239 lines
7.8 KiB
Java
239 lines
7.8 KiB
Java
package dev.lions.unionflow.server.service;
|
|
|
|
import static org.assertj.core.api.Assertions.*;
|
|
|
|
import dev.lions.unionflow.server.api.dto.suggestion.request.CreateSuggestionRequest;
|
|
import dev.lions.unionflow.server.api.dto.suggestion.response.SuggestionResponse;
|
|
import dev.lions.unionflow.server.entity.Suggestion;
|
|
import dev.lions.unionflow.server.entity.SuggestionVote;
|
|
import dev.lions.unionflow.server.repository.SuggestionRepository;
|
|
import dev.lions.unionflow.server.repository.SuggestionVoteRepository;
|
|
import io.quarkus.test.junit.QuarkusTest;
|
|
import jakarta.inject.Inject;
|
|
import jakarta.transaction.Transactional;
|
|
import jakarta.ws.rs.NotFoundException;
|
|
import java.time.LocalDateTime;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import org.junit.jupiter.api.*;
|
|
|
|
/**
|
|
* Tests unitaires pour SuggestionService
|
|
*
|
|
* @author UnionFlow Team
|
|
* @version 1.0
|
|
* @since 2025-12-18
|
|
*/
|
|
@QuarkusTest
|
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
|
class SuggestionServiceTest {
|
|
|
|
@Inject
|
|
SuggestionService suggestionService;
|
|
@Inject
|
|
SuggestionRepository suggestionRepository;
|
|
@Inject
|
|
SuggestionVoteRepository suggestionVoteRepository;
|
|
|
|
private Suggestion testSuggestion;
|
|
private UUID utilisateurId1;
|
|
private UUID utilisateurId2;
|
|
|
|
@BeforeEach
|
|
@Transactional
|
|
void setupTestData() {
|
|
utilisateurId1 = UUID.randomUUID();
|
|
utilisateurId2 = UUID.randomUUID();
|
|
|
|
// Créer une suggestion de test
|
|
testSuggestion = Suggestion.builder()
|
|
.utilisateurId(utilisateurId1)
|
|
.utilisateurNom("Test User")
|
|
.titre("Suggestion de Test")
|
|
.description("Description de test")
|
|
.statut("NOUVELLE")
|
|
.nbVotes(0)
|
|
.nbCommentaires(0)
|
|
.nbVues(0)
|
|
.build();
|
|
testSuggestion.setDateCreation(LocalDateTime.now());
|
|
testSuggestion.setDateSoumission(LocalDateTime.now());
|
|
testSuggestion.setActif(true);
|
|
suggestionRepository.persist(testSuggestion);
|
|
}
|
|
|
|
@AfterEach
|
|
@Transactional
|
|
void cleanupTestData() {
|
|
// Supprimer tous les votes
|
|
if (testSuggestion != null && testSuggestion.getId() != null) {
|
|
List<SuggestionVote> votes = suggestionVoteRepository.listerVotesParSuggestion(testSuggestion.getId());
|
|
votes.forEach(vote -> suggestionVoteRepository.delete(vote));
|
|
}
|
|
|
|
// Supprimer la suggestion
|
|
if (testSuggestion != null && testSuggestion.getId() != null) {
|
|
Suggestion suggestionToDelete = suggestionRepository.findById(testSuggestion.getId());
|
|
if (suggestionToDelete != null) {
|
|
suggestionRepository.delete(suggestionToDelete);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@Order(1)
|
|
@DisplayName("Devrait lister toutes les suggestions")
|
|
void testListerSuggestions() {
|
|
// When
|
|
List<SuggestionResponse> suggestions = suggestionService.listerSuggestions();
|
|
|
|
// Then
|
|
assertThat(suggestions).isNotNull();
|
|
assertThat(suggestions).isNotEmpty();
|
|
// Vérifier que notre suggestion de test est dans la liste
|
|
assertThat(suggestions)
|
|
.anyMatch(s -> s.getId().equals(testSuggestion.getId()));
|
|
}
|
|
|
|
@Test
|
|
@Order(2)
|
|
@DisplayName("Devrait créer une nouvelle suggestion")
|
|
void testCreerSuggestion() {
|
|
// Given
|
|
CreateSuggestionRequest request = CreateSuggestionRequest.builder()
|
|
.utilisateurId(utilisateurId2)
|
|
.utilisateurNom("Nouvel Utilisateur")
|
|
.titre("Nouvelle Suggestion")
|
|
.description("Description de la nouvelle suggestion")
|
|
.categorie("FEATURE")
|
|
.prioriteEstimee("HAUTE")
|
|
.build();
|
|
|
|
// When
|
|
SuggestionResponse created = suggestionService.creerSuggestion(request);
|
|
|
|
// Then
|
|
assertThat(created).isNotNull();
|
|
assertThat(created.getId()).isNotNull();
|
|
assertThat(created.getTitre()).isEqualTo("Nouvelle Suggestion");
|
|
assertThat(created.getStatut()).isEqualTo("NOUVELLE");
|
|
assertThat(created.getNbVotes()).isEqualTo(0);
|
|
assertThat(created.getNbCommentaires()).isEqualTo(0);
|
|
assertThat(created.getDateSoumission()).isNotNull();
|
|
|
|
// Cleanup
|
|
Suggestion createdEntity = suggestionRepository.findById(created.getId());
|
|
if (createdEntity != null) {
|
|
suggestionRepository.delete(createdEntity);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
@Order(3)
|
|
@DisplayName("Devrait permettre à un utilisateur de voter pour une suggestion")
|
|
void testVoterPourSuggestion() {
|
|
// Given
|
|
UUID suggestionId = testSuggestion.getId();
|
|
int nbVotesInitial = testSuggestion.getNbVotes() != null ? testSuggestion.getNbVotes() : 0;
|
|
|
|
// When
|
|
suggestionService.voterPourSuggestion(suggestionId, utilisateurId2);
|
|
|
|
// Then
|
|
// Vérifier que le vote a été créé
|
|
assertThat(suggestionVoteRepository.aDejaVote(suggestionId, utilisateurId2)).isTrue();
|
|
|
|
// Vérifier que le compteur de votes a été mis à jour
|
|
Suggestion updatedSuggestion = suggestionRepository.findById(suggestionId);
|
|
assertThat(updatedSuggestion.getNbVotes()).isEqualTo(nbVotesInitial + 1);
|
|
}
|
|
|
|
@Test
|
|
@Order(4)
|
|
@DisplayName("Ne devrait pas permettre à un utilisateur de voter deux fois")
|
|
void testNePasPermettreVoteMultiple() {
|
|
// Given
|
|
UUID suggestionId = testSuggestion.getId();
|
|
|
|
// Premier vote
|
|
suggestionService.voterPourSuggestion(suggestionId, utilisateurId2);
|
|
|
|
// When/Then - Tentative de vote multiple
|
|
assertThatThrownBy(
|
|
() -> suggestionService.voterPourSuggestion(suggestionId, utilisateurId2))
|
|
.isInstanceOf(IllegalStateException.class)
|
|
.hasMessageContaining("déjà voté");
|
|
}
|
|
|
|
@Test
|
|
@Order(5)
|
|
@DisplayName("Devrait lever une exception si la suggestion n'existe pas")
|
|
void testVoterPourSuggestionInexistante() {
|
|
// Given
|
|
UUID suggestionInexistante = UUID.randomUUID();
|
|
|
|
// When/Then
|
|
assertThatThrownBy(
|
|
() -> suggestionService.voterPourSuggestion(suggestionInexistante, utilisateurId2))
|
|
.isInstanceOf(NotFoundException.class)
|
|
.hasMessageContaining("non trouvée");
|
|
}
|
|
|
|
@Test
|
|
@Order(6)
|
|
@DisplayName("Devrait synchroniser le compteur de votes avec la base de données")
|
|
void testSynchronisationCompteurVotes() {
|
|
// Given
|
|
UUID suggestionId = testSuggestion.getId();
|
|
|
|
// Créer plusieurs votes directement dans la base
|
|
SuggestionVote vote1 = SuggestionVote.builder()
|
|
.suggestionId(suggestionId)
|
|
.utilisateurId(utilisateurId1)
|
|
.dateVote(LocalDateTime.now())
|
|
.build();
|
|
vote1.setActif(true);
|
|
suggestionVoteRepository.persist(vote1);
|
|
|
|
SuggestionVote vote2 = SuggestionVote.builder()
|
|
.suggestionId(suggestionId)
|
|
.utilisateurId(utilisateurId2)
|
|
.dateVote(LocalDateTime.now())
|
|
.build();
|
|
vote2.setActif(true);
|
|
suggestionVoteRepository.persist(vote2);
|
|
|
|
// Mettre à jour le compteur manuellement (simulation d'un état désynchronisé)
|
|
testSuggestion.setNbVotes(0);
|
|
suggestionRepository.update(testSuggestion);
|
|
|
|
// When - Voter via le service (qui doit synchroniser)
|
|
UUID utilisateurId3 = UUID.randomUUID();
|
|
suggestionService.voterPourSuggestion(suggestionId, utilisateurId3);
|
|
|
|
// Then - Le compteur doit être synchronisé avec la base (2 votes existants + 1
|
|
// nouveau = 3)
|
|
Suggestion updatedSuggestion = suggestionRepository.findById(suggestionId);
|
|
assertThat(updatedSuggestion.getNbVotes()).isEqualTo(3);
|
|
}
|
|
|
|
@Test
|
|
@Order(7)
|
|
@DisplayName("Devrait obtenir les statistiques des suggestions")
|
|
void testObtenirStatistiques() {
|
|
// When
|
|
Map<String, Object> stats = suggestionService.obtenirStatistiques();
|
|
|
|
// Then
|
|
assertThat(stats).isNotNull();
|
|
assertThat(stats).containsKey("totalSuggestions");
|
|
assertThat(stats).containsKey("suggestionsImplementees");
|
|
assertThat(stats).containsKey("totalVotes");
|
|
assertThat(stats).containsKey("contributeursActifs");
|
|
|
|
assertThat(stats.get("totalSuggestions")).isInstanceOf(Long.class);
|
|
assertThat((Long) stats.get("totalSuggestions")).isGreaterThanOrEqualTo(1);
|
|
}
|
|
}
|