Refactoring
This commit is contained in:
103
src/test/java/com/lions/dev/config/ScheduledJobsTest.java
Normal file
103
src/test/java/com/lions/dev/config/ScheduledJobsTest.java
Normal file
@@ -0,0 +1,103 @@
|
||||
package com.lions.dev.config;
|
||||
|
||||
import com.lions.dev.repository.EstablishmentRepository;
|
||||
import com.lions.dev.repository.EstablishmentSubscriptionRepository;
|
||||
import com.lions.dev.repository.EventsRepository;
|
||||
import com.lions.dev.repository.PasswordResetTokenRepository;
|
||||
import com.lions.dev.repository.StoryRepository;
|
||||
import com.lions.dev.service.EmailService;
|
||||
import com.lions.dev.service.NotificationService;
|
||||
import io.quarkus.test.InjectMock;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* Tests des jobs planifiés (ScheduledJobs).
|
||||
* Les dépendances sont mockées pour éviter DB/Kafka ; on vérifie que les méthodes ne lèvent pas et appellent les repos.
|
||||
*/
|
||||
@QuarkusTest
|
||||
class ScheduledJobsTest {
|
||||
|
||||
@Inject
|
||||
ScheduledJobs scheduledJobs;
|
||||
|
||||
@InjectMock
|
||||
StoryRepository storyRepository;
|
||||
|
||||
@InjectMock
|
||||
PasswordResetTokenRepository passwordResetTokenRepository;
|
||||
|
||||
@InjectMock
|
||||
EstablishmentSubscriptionRepository subscriptionRepository;
|
||||
|
||||
@InjectMock
|
||||
EstablishmentRepository establishmentRepository;
|
||||
|
||||
@InjectMock
|
||||
EventsRepository eventsRepository;
|
||||
|
||||
@InjectMock
|
||||
NotificationService notificationService;
|
||||
|
||||
@InjectMock
|
||||
EmailService emailService;
|
||||
|
||||
@Test
|
||||
@DisplayName("deactivateExpiredStories appelle le repository et ne lance pas")
|
||||
void deactivateExpiredStories_callsRepository() {
|
||||
when(storyRepository.deactivateExpiredStories()).thenReturn(0);
|
||||
|
||||
scheduledJobs.deactivateExpiredStories();
|
||||
|
||||
verify(storyRepository).deactivateExpiredStories();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("deleteExpiredPasswordResetTokens appelle le repository et ne lance pas")
|
||||
void deleteExpiredPasswordResetTokens_callsRepository() {
|
||||
when(passwordResetTokenRepository.deleteExpiredTokens()).thenReturn(0L);
|
||||
|
||||
scheduledJobs.deleteExpiredPasswordResetTokens();
|
||||
|
||||
verify(passwordResetTokenRepository).deleteExpiredTokens();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("expireSubscriptionsAndDisableEstablishments sans abonnements expirés ne lance pas")
|
||||
void expireSubscriptionsAndDisableEstablishments_emptyList_doesNotThrow() {
|
||||
when(subscriptionRepository.findExpiredActiveSubscriptions()).thenReturn(Collections.emptyList());
|
||||
|
||||
scheduledJobs.expireSubscriptionsAndDisableEstablishments();
|
||||
|
||||
verify(subscriptionRepository).findExpiredActiveSubscriptions();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendEventReminders sans événements dans les fenêtres ne lance pas")
|
||||
void sendEventReminders_emptyWindows_doesNotThrow() {
|
||||
when(eventsRepository.findEventsStartingBetween(any(), any())).thenReturn(List.of());
|
||||
|
||||
scheduledJobs.sendEventReminders();
|
||||
|
||||
verify(eventsRepository, atLeast(1)).findEventsStartingBetween(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendSubscriptionExpirationWarningEmails sans abonnements J-3 ne lance pas")
|
||||
void sendSubscriptionExpirationWarningEmails_emptyList_doesNotThrow() {
|
||||
when(subscriptionRepository.findActiveSubscriptionsExpiringBetween(any(), any()))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
scheduledJobs.sendSubscriptionExpirationWarningEmails();
|
||||
|
||||
verify(subscriptionRepository).findActiveSubscriptionsExpiringBetween(any(), any());
|
||||
}
|
||||
}
|
||||
69
src/test/java/com/lions/dev/service/EmailServiceTest.java
Normal file
69
src/test/java/com/lions/dev/service/EmailServiceTest.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package com.lions.dev.service;
|
||||
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Tests du service email (mode mock : pas d'envoi réel).
|
||||
* Vérifie que les méthodes n'échouent pas et que le contenu est cohérent.
|
||||
*/
|
||||
@QuarkusTest
|
||||
class EmailServiceTest {
|
||||
|
||||
@Inject
|
||||
EmailService emailService;
|
||||
|
||||
@Test
|
||||
@DisplayName("sendPasswordResetEmail ne lance pas d'exception")
|
||||
void sendPasswordResetEmail_doesNotThrow() {
|
||||
emailService.sendPasswordResetEmail("test@example.com", "Jean", "token-123");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendWelcomeEmail ne lance pas d'exception")
|
||||
void sendWelcomeEmail_doesNotThrow() {
|
||||
emailService.sendWelcomeEmail("welcome@example.com", "Marie");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendPaymentConfirmationEmail ne lance pas d'exception")
|
||||
void sendPaymentConfirmationEmail_doesNotThrow() {
|
||||
emailService.sendPaymentConfirmationEmail(
|
||||
"manager@example.com", "Paul", "Le Bar du coin", 15_000, "MONTHLY");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendEventReminderEmail ne lance pas d'exception")
|
||||
void sendEventReminderEmail_doesNotThrow() {
|
||||
emailService.sendEventReminderEmail(
|
||||
"user@example.com", "Sophie", "Afterwork Jeudi",
|
||||
LocalDateTime.now().plusHours(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendSubscriptionExpirationWarningEmail ne lance pas d'exception")
|
||||
void sendSubscriptionExpirationWarningEmail_doesNotThrow() {
|
||||
emailService.sendSubscriptionExpirationWarningEmail(
|
||||
"manager@example.com", "Luc", "Mon Établissement",
|
||||
LocalDateTime.now().plusDays(3));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendBookingConfirmationEmail ne lance pas d'exception")
|
||||
void sendBookingConfirmationEmail_doesNotThrow() {
|
||||
emailService.sendBookingConfirmationEmail(
|
||||
"client@example.com", "Emma", "Le Restaurant",
|
||||
LocalDateTime.now().plusDays(1), 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendPaymentFailureEmail ne lance pas d'exception")
|
||||
void sendPaymentFailureEmail_doesNotThrow() {
|
||||
emailService.sendPaymentFailureEmail(
|
||||
"manager@example.com", "Marc", "Établissement XYZ");
|
||||
}
|
||||
}
|
||||
138
src/test/java/com/lions/dev/service/NotificationServiceTest.java
Normal file
138
src/test/java/com/lions/dev/service/NotificationServiceTest.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package com.lions.dev.service;
|
||||
|
||||
import com.lions.dev.entity.notification.Notification;
|
||||
import com.lions.dev.entity.users.Users;
|
||||
import com.lions.dev.exception.UserNotFoundException;
|
||||
import com.lions.dev.repository.EventsRepository;
|
||||
import com.lions.dev.repository.NotificationRepository;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import io.quarkus.test.InjectMock;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@QuarkusTest
|
||||
class NotificationServiceTest {
|
||||
|
||||
@Inject
|
||||
NotificationService notificationService;
|
||||
|
||||
@InjectMock
|
||||
NotificationRepository notificationRepository;
|
||||
|
||||
@InjectMock
|
||||
UsersRepository usersRepository;
|
||||
|
||||
@InjectMock
|
||||
EventsRepository eventsRepository;
|
||||
|
||||
@Test
|
||||
@DisplayName("getNotificationsByUserId avec utilisateur existant retourne la liste")
|
||||
void getNotificationsByUserId_userExists_returnsList() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
Users user = new Users();
|
||||
user.setId(userId);
|
||||
Notification notif = new Notification("Titre", "Message", "event", user);
|
||||
|
||||
when(usersRepository.findById(userId)).thenReturn(user);
|
||||
when(notificationRepository.findByUserId(userId)).thenReturn(List.of(notif));
|
||||
|
||||
List<Notification> result = notificationService.getNotificationsByUserId(userId);
|
||||
|
||||
assertNotNull(result);
|
||||
assertEquals(1, result.size());
|
||||
assertEquals("Titre", result.get(0).getTitle());
|
||||
verify(usersRepository).findById(userId);
|
||||
verify(notificationRepository).findByUserId(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getNotificationsByUserId avec utilisateur inconnu lance UserNotFoundException")
|
||||
void getNotificationsByUserId_userNotFound_throws() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
when(usersRepository.findById(userId)).thenReturn(null);
|
||||
|
||||
assertThrows(UserNotFoundException.class, () ->
|
||||
notificationService.getNotificationsByUserId(userId));
|
||||
verify(notificationRepository, never()).findByUserId(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("createNotification avec données valides persiste et retourne la notification")
|
||||
void createNotification_validData_persistsAndReturns() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
UUID eventId = UUID.randomUUID();
|
||||
Users user = new Users();
|
||||
user.setId(userId);
|
||||
|
||||
when(usersRepository.findById(userId)).thenReturn(user);
|
||||
|
||||
Notification created = notificationService.createNotification(
|
||||
"Rappel", "L'événement commence bientôt", "reminder", userId, eventId);
|
||||
|
||||
assertNotNull(created);
|
||||
assertEquals("Rappel", created.getTitle());
|
||||
assertEquals("reminder", created.getType());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("createNotification avec userId inconnu lance UserNotFoundException")
|
||||
void createNotification_unknownUser_throws() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
when(usersRepository.findById(userId)).thenReturn(null);
|
||||
|
||||
assertThrows(UserNotFoundException.class, () ->
|
||||
notificationService.createNotification("T", "M", "event", userId, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("countUnreadNotifications avec utilisateur existant retourne le compte")
|
||||
void countUnreadNotifications_userExists_returnsCount() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
Users user = new Users();
|
||||
user.setId(userId);
|
||||
when(usersRepository.findById(userId)).thenReturn(user);
|
||||
when(notificationRepository.countUnreadByUserId(userId)).thenReturn(3L);
|
||||
|
||||
long count = notificationService.countUnreadNotifications(userId);
|
||||
|
||||
assertEquals(3L, count);
|
||||
verify(notificationRepository).countUnreadByUserId(userId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("countUnreadNotifications avec utilisateur inconnu lance UserNotFoundException")
|
||||
void countUnreadNotifications_userNotFound_throws() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
when(usersRepository.findById(userId)).thenReturn(null);
|
||||
|
||||
assertThrows(UserNotFoundException.class, () ->
|
||||
notificationService.countUnreadNotifications(userId));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getNotificationsByUserIdWithPagination avec utilisateur existant retourne la page")
|
||||
void getNotificationsByUserIdWithPagination_userExists_returnsPage() {
|
||||
UUID userId = UUID.randomUUID();
|
||||
Users user = new Users();
|
||||
user.setId(userId);
|
||||
when(usersRepository.findById(userId)).thenReturn(user);
|
||||
when(notificationRepository.findByUserIdWithPagination(userId, 0, 10))
|
||||
.thenReturn(Collections.emptyList());
|
||||
|
||||
List<Notification> result = notificationService.getNotificationsByUserIdWithPagination(userId, 0, 10);
|
||||
|
||||
assertNotNull(result);
|
||||
assertTrue(result.isEmpty());
|
||||
verify(notificationRepository).findByUserIdWithPagination(userId, 0, 10);
|
||||
}
|
||||
}
|
||||
183
src/test/java/com/lions/dev/service/WavePaymentServiceTest.java
Normal file
183
src/test/java/com/lions/dev/service/WavePaymentServiceTest.java
Normal file
@@ -0,0 +1,183 @@
|
||||
package com.lions.dev.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.lions.dev.dto.response.establishment.InitiateSubscriptionResponseDTO;
|
||||
import com.lions.dev.entity.establishment.Establishment;
|
||||
import com.lions.dev.entity.establishment.EstablishmentSubscription;
|
||||
import com.lions.dev.entity.users.Users;
|
||||
import com.lions.dev.repository.EstablishmentPaymentRepository;
|
||||
import com.lions.dev.repository.EstablishmentRepository;
|
||||
import com.lions.dev.repository.EstablishmentSubscriptionRepository;
|
||||
import com.lions.dev.repository.UsersRepository;
|
||||
import io.quarkus.test.InjectMock;
|
||||
import io.quarkus.test.junit.QuarkusTest;
|
||||
import jakarta.inject.Inject;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@QuarkusTest
|
||||
class WavePaymentServiceTest {
|
||||
|
||||
@Inject
|
||||
WavePaymentService wavePaymentService;
|
||||
|
||||
@InjectMock
|
||||
EstablishmentRepository establishmentRepository;
|
||||
|
||||
@InjectMock
|
||||
EstablishmentSubscriptionRepository subscriptionRepository;
|
||||
|
||||
@InjectMock
|
||||
EstablishmentPaymentRepository paymentRepository;
|
||||
|
||||
@InjectMock
|
||||
UsersRepository usersRepository;
|
||||
|
||||
@InjectMock
|
||||
EmailService emailService;
|
||||
|
||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
@DisplayName("initiatePayment avec établissement inconnu lance IllegalArgumentException")
|
||||
void initiatePayment_unknownEstablishment_throws() {
|
||||
UUID establishmentId = UUID.randomUUID();
|
||||
when(establishmentRepository.findById(establishmentId)).thenReturn(null);
|
||||
|
||||
assertThrows(IllegalArgumentException.class, () ->
|
||||
wavePaymentService.initiatePayment(establishmentId, "MONTHLY", "+221771234567"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("initiatePayment avec établissement valide retourne un DTO avec paymentUrl")
|
||||
void initiatePayment_validEstablishment_returnsDto() {
|
||||
UUID establishmentId = UUID.randomUUID();
|
||||
Establishment establishment = new Establishment();
|
||||
establishment.setId(establishmentId);
|
||||
establishment.setName("Le Bar Test");
|
||||
|
||||
when(establishmentRepository.findById(establishmentId)).thenReturn(establishment);
|
||||
|
||||
InitiateSubscriptionResponseDTO result = wavePaymentService.initiatePayment(
|
||||
establishmentId, "MONTHLY", "+221771234567");
|
||||
|
||||
assertNotNull(result);
|
||||
assertNotNull(result.getPaymentUrl());
|
||||
assertTrue(result.getPaymentUrl().contains("checkout") || result.getPaymentUrl().contains("test"));
|
||||
assertEquals("MONTHLY", result.getPlan());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("hasActiveSubscription retourne false quand aucun abonnement actif")
|
||||
void hasActiveSubscription_noActive_returnsFalse() {
|
||||
UUID establishmentId = UUID.randomUUID();
|
||||
when(subscriptionRepository.findActiveByEstablishmentId(establishmentId)).thenReturn(Optional.empty());
|
||||
|
||||
boolean result = wavePaymentService.hasActiveSubscription(establishmentId);
|
||||
|
||||
assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("hasActiveSubscription retourne true quand abonnement actif existe")
|
||||
void hasActiveSubscription_hasActive_returnsTrue() {
|
||||
UUID establishmentId = UUID.randomUUID();
|
||||
EstablishmentSubscription sub = new EstablishmentSubscription();
|
||||
sub.setEstablishmentId(establishmentId);
|
||||
sub.setStatus(EstablishmentSubscription.STATUS_ACTIVE);
|
||||
when(subscriptionRepository.findActiveByEstablishmentId(establishmentId)).thenReturn(Optional.of(sub));
|
||||
|
||||
boolean result = wavePaymentService.hasActiveSubscription(establishmentId);
|
||||
|
||||
assertTrue(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("handleWebhook payment.completed active l'établissement et envoie l'email de confirmation")
|
||||
void handleWebhook_paymentCompleted_activatesAndSendsEmail() throws Exception {
|
||||
String sessionId = "wave-session-123";
|
||||
UUID establishmentId = UUID.randomUUID();
|
||||
Establishment establishment = new Establishment();
|
||||
establishment.setId(establishmentId);
|
||||
establishment.setName("Bar Test");
|
||||
establishment.setIsActive(false);
|
||||
Users manager = new Users();
|
||||
manager.setId(UUID.randomUUID());
|
||||
manager.setEmail("manager@test.com");
|
||||
manager.setFirstName("Jean");
|
||||
manager.setActive(false);
|
||||
establishment.setManager(manager);
|
||||
|
||||
EstablishmentSubscription sub = new EstablishmentSubscription();
|
||||
sub.setId(UUID.randomUUID());
|
||||
sub.setEstablishmentId(establishmentId);
|
||||
sub.setPlan(EstablishmentSubscription.PLAN_MONTHLY);
|
||||
sub.setStatus(EstablishmentSubscription.STATUS_PENDING);
|
||||
sub.setAmountXof(15_000);
|
||||
|
||||
when(subscriptionRepository.findByWaveSessionId(sessionId)).thenReturn(Optional.of(sub));
|
||||
when(establishmentRepository.findById(establishmentId)).thenReturn(establishment);
|
||||
when(usersRepository.findById(manager.getId())).thenReturn(manager);
|
||||
when(paymentRepository.findByWaveSessionId(sessionId)).thenReturn(Optional.of(new com.lions.dev.entity.establishment.EstablishmentPayment()));
|
||||
|
||||
String payload = """
|
||||
{"type":"payment.completed","data":{"id":"%s"}}
|
||||
""".formatted(sessionId);
|
||||
var node = objectMapper.readTree(payload);
|
||||
|
||||
wavePaymentService.handleWebhook(node);
|
||||
|
||||
verify(emailService).sendPaymentConfirmationEmail(
|
||||
eq("manager@test.com"),
|
||||
eq("Jean"),
|
||||
eq("Bar Test"),
|
||||
eq(15_000),
|
||||
eq("MONTHLY")
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("handleWebhook payment.failed envoie l'email d'échec")
|
||||
void handleWebhook_paymentFailed_sendsFailureEmail() throws Exception {
|
||||
String sessionId = "wave-session-fail";
|
||||
UUID establishmentId = UUID.randomUUID();
|
||||
Establishment establishment = new Establishment();
|
||||
establishment.setId(establishmentId);
|
||||
establishment.setName("Bar Fail");
|
||||
Users manager = new Users();
|
||||
manager.setId(UUID.randomUUID());
|
||||
manager.setEmail("manager@fail.com");
|
||||
manager.setFirstName("Paul");
|
||||
establishment.setManager(manager);
|
||||
|
||||
EstablishmentSubscription sub = new EstablishmentSubscription();
|
||||
sub.setId(UUID.randomUUID());
|
||||
sub.setEstablishmentId(establishmentId);
|
||||
sub.setStatus(EstablishmentSubscription.STATUS_PENDING);
|
||||
|
||||
when(subscriptionRepository.findByWaveSessionId(sessionId)).thenReturn(Optional.of(sub));
|
||||
when(establishmentRepository.findById(establishmentId)).thenReturn(establishment);
|
||||
when(usersRepository.findById(manager.getId())).thenReturn(manager);
|
||||
when(paymentRepository.findByWaveSessionId(sessionId)).thenReturn(Optional.of(new com.lions.dev.entity.establishment.EstablishmentPayment()));
|
||||
|
||||
String payload = """
|
||||
{"type":"payment.failed","data":{"id":"%s"}}
|
||||
""".formatted(sessionId);
|
||||
var node = objectMapper.readTree(payload);
|
||||
|
||||
wavePaymentService.handleWebhook(node);
|
||||
|
||||
verify(emailService).sendPaymentFailureEmail(
|
||||
eq("manager@fail.com"),
|
||||
eq("Paul"),
|
||||
eq("Bar Fail")
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user