test: add NotificationServiceTest unit test
This commit is contained in:
parent
70487e6d0d
commit
42543c27df
@ -0,0 +1,197 @@
|
||||
package com.walkguide.service;
|
||||
|
||||
import com.walkguide.dto.request.SendNotificationRequest;
|
||||
import com.walkguide.dto.response.NotificationResponse;
|
||||
import com.walkguide.entity.GuardianNotification;
|
||||
import com.walkguide.entity.PairingRelation;
|
||||
import com.walkguide.entity.User;
|
||||
import com.walkguide.enums.NotificationType;
|
||||
import com.walkguide.enums.PairingStatus;
|
||||
import com.walkguide.exception.PairingException;
|
||||
import com.walkguide.repository.GuardianNotificationRepository;
|
||||
import com.walkguide.repository.PairingRelationRepository;
|
||||
import com.walkguide.websocket.LocationBroadcaster;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@DisplayName("NotificationService Unit Tests")
|
||||
class NotificationServiceTest {
|
||||
|
||||
@Mock GuardianNotificationRepository notifRepository;
|
||||
@Mock PairingRelationRepository pairingRelationRepository;
|
||||
@Mock FcmService fcmService;
|
||||
@Mock LocationBroadcaster locationBroadcaster;
|
||||
|
||||
@InjectMocks NotificationService notificationService;
|
||||
|
||||
private User guardian;
|
||||
private User user;
|
||||
private PairingRelation activePairing;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
guardian = User.builder()
|
||||
.id(1L).email("guardian@test.com").role("ROLE_GUARDIAN")
|
||||
.displayName("Guardian").fcmToken("guardian-fcm").build();
|
||||
|
||||
user = User.builder()
|
||||
.id(2L).email("user@test.com").role("ROLE_USER")
|
||||
.displayName("User").fcmToken("user-fcm").build();
|
||||
|
||||
activePairing = PairingRelation.builder()
|
||||
.id(10L).guardian(guardian).user(user).status(PairingStatus.ACTIVE).build();
|
||||
}
|
||||
|
||||
// ===== SEND NOTIFICATION TESTS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("sendNotification - TEXT type: harus simpan dan kirim FCM ke user")
|
||||
void sendNotification_textType_shouldSaveAndSendFcm() {
|
||||
SendNotificationRequest req = new SendNotificationRequest();
|
||||
req.setNotifType("TEXT");
|
||||
req.setContent("Hati-hati di pertigaan!");
|
||||
|
||||
when(pairingRelationRepository.findByGuardian_IdAndStatus(1L, PairingStatus.ACTIVE))
|
||||
.thenReturn(Optional.of(activePairing));
|
||||
when(notifRepository.save(any(GuardianNotification.class))).thenAnswer(inv -> {
|
||||
GuardianNotification n = inv.getArgument(0);
|
||||
n.setId(100L);
|
||||
return n;
|
||||
});
|
||||
|
||||
NotificationResponse result = notificationService.sendNotification(1L, req);
|
||||
|
||||
assertThat(result).isNotNull();
|
||||
assertThat(result.getContent()).isEqualTo("Hati-hati di pertigaan!");
|
||||
verify(notifRepository).save(any(GuardianNotification.class));
|
||||
verify(fcmService).sendToToken(eq("user-fcm"), anyString(), anyString(), anyMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendNotification - VOICE_NOTE type: harus simpan dengan tipe VOICE_NOTE")
|
||||
void sendNotification_voiceNoteType_shouldSaveAsVoiceNote() {
|
||||
SendNotificationRequest req = new SendNotificationRequest();
|
||||
req.setNotifType("VOICE_NOTE");
|
||||
req.setContent(null);
|
||||
req.setVoiceNoteUrl("https://storage/voice/001.m4a");
|
||||
req.setVoiceNoteDuration(12);
|
||||
|
||||
when(pairingRelationRepository.findByGuardian_IdAndStatus(1L, PairingStatus.ACTIVE))
|
||||
.thenReturn(Optional.of(activePairing));
|
||||
when(notifRepository.save(any(GuardianNotification.class))).thenAnswer(inv -> {
|
||||
GuardianNotification n = inv.getArgument(0);
|
||||
n.setId(101L);
|
||||
n.setNotifType(NotificationType.VOICE_NOTE);
|
||||
n.setVoiceNoteUrl("https://storage/voice/001.m4a");
|
||||
return n;
|
||||
});
|
||||
|
||||
NotificationResponse result = notificationService.sendNotification(1L, req);
|
||||
|
||||
assertThat(result.getVoiceNoteUrl()).isEqualTo("https://storage/voice/001.m4a");
|
||||
verify(fcmService).sendToToken(eq("user-fcm"), anyString(), anyString(), anyMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("sendNotification - Guardian tidak punya active pairing harus throw PairingException")
|
||||
void sendNotification_noPairing_shouldThrow() {
|
||||
SendNotificationRequest req = new SendNotificationRequest();
|
||||
req.setNotifType("TEXT");
|
||||
req.setContent("test");
|
||||
|
||||
when(pairingRelationRepository.findByGuardian_IdAndStatus(1L, PairingStatus.ACTIVE))
|
||||
.thenReturn(Optional.empty());
|
||||
|
||||
assertThatThrownBy(() -> notificationService.sendNotification(1L, req))
|
||||
.isInstanceOf(PairingException.class)
|
||||
.hasMessageContaining("Tidak ada user yang dipair");
|
||||
|
||||
verify(notifRepository, never()).save(any());
|
||||
verify(fcmService, never()).sendToToken(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
// ===== MARK AS READ TESTS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("markAsRead - harus set isRead=true dan simpan")
|
||||
void markAsRead_shouldSetReadTrue() {
|
||||
GuardianNotification notif = GuardianNotification.builder()
|
||||
.id(100L).userId(2L).guardianId(1L)
|
||||
.notifType(NotificationType.TEXT).content("Test").isRead(false).build();
|
||||
|
||||
when(notifRepository.findByIdAndUserId(100L, 2L)).thenReturn(Optional.of(notif));
|
||||
when(notifRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
|
||||
notificationService.markAsRead(2L, 100L);
|
||||
|
||||
assertThat(notif.isRead()).isTrue();
|
||||
verify(notifRepository).save(notif);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("markAsRead - notifikasi tidak ditemukan harus throw RuntimeException")
|
||||
void markAsRead_notFound_shouldThrow() {
|
||||
when(notifRepository.findByIdAndUserId(999L, 2L)).thenReturn(Optional.empty());
|
||||
|
||||
assertThatThrownBy(() -> notificationService.markAsRead(2L, 999L))
|
||||
.isInstanceOf(RuntimeException.class);
|
||||
}
|
||||
|
||||
// ===== UNREAD COUNT TESTS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("getUnreadCount - harus return jumlah notif yang belum dibaca")
|
||||
void getUnreadCount_shouldReturnCorrectCount() {
|
||||
when(notifRepository.countByUserIdAndIsReadFalse(2L)).thenReturn(5L);
|
||||
|
||||
long count = notificationService.getUnreadCount(2L);
|
||||
|
||||
assertThat(count).isEqualTo(5L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getUnreadCount - tidak ada notif belum dibaca harus return 0")
|
||||
void getUnreadCount_noUnread_shouldReturnZero() {
|
||||
when(notifRepository.countByUserIdAndIsReadFalse(2L)).thenReturn(0L);
|
||||
|
||||
long count = notificationService.getUnreadCount(2L);
|
||||
|
||||
assertThat(count).isZero();
|
||||
}
|
||||
|
||||
// ===== GET NOTIFICATIONS TESTS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("getNotifications - harus return page notif untuk user")
|
||||
void getNotifications_shouldReturnPagedResults() {
|
||||
GuardianNotification notif = GuardianNotification.builder()
|
||||
.id(1L).userId(2L).guardianId(1L)
|
||||
.notifType(NotificationType.TEXT).content("Hello").isRead(false).build();
|
||||
|
||||
Page<GuardianNotification> page = new PageImpl<>(List.of(notif));
|
||||
PageRequest pageable = PageRequest.of(0, 10);
|
||||
|
||||
when(notifRepository.findByUserIdOrderByCreatedAtDesc(2L, pageable)).thenReturn(page);
|
||||
|
||||
Page<NotificationResponse> result = notificationService.getNotifications(2L, pageable);
|
||||
|
||||
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||
assertThat(result.getContent().get(0).getContent()).isEqualTo("Hello");
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user