2026-05-28 16:29:23 +07:00

133 lines
4.5 KiB
Java

package com.walkguide.service;
import com.walkguide.dto.request.CallNotifyRequest;
import com.walkguide.entity.User;
import com.walkguide.exception.ResourceNotFoundException;
import com.walkguide.repository.UserRepository;
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 java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.anyMap;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@DisplayName("CallNotificationService Unit Tests")
class CallNotificationServiceTest {
@Mock
private FcmService fcmService;
@Mock
private UserRepository userRepository;
@Mock
private LocationBroadcaster locationBroadcaster;
@InjectMocks
private CallNotificationService service;
private User caller;
private User receiver;
private CallNotifyRequest request;
@BeforeEach
void setUp() {
caller = User.builder()
.id(1L)
.email("caller@test.com")
.displayName("Caller User")
.build();
receiver = User.builder()
.id(2L)
.email("receiver@test.com")
.displayName("Receiver")
.fcmToken("receiver-token")
.build();
request = new CallNotifyRequest();
request.setReceiverId(2L);
request.setChannelName("call_1_2");
request.setAgoraToken("agora-token");
request.setReceiverUid(1002);
}
@Test
@DisplayName("notifyIncomingCall sends high priority FCM when receiver has token")
void notifyIncomingCall_receiverHasToken_shouldSendFcm() {
when(userRepository.findById(1L)).thenReturn(Optional.of(caller));
when(userRepository.findById(2L)).thenReturn(Optional.of(receiver));
String message = service.notifyIncomingCall(1L, request);
assertEquals("Notifikasi panggilan berhasil dikirim", message);
verify(fcmService).sendHighPriority(
eq("receiver-token"),
eq("Panggilan Masuk"),
contains("Caller User"),
anyMap()
);
}
@Test
@DisplayName("notifyIncomingCall skips FCM when receiver token is missing")
void notifyIncomingCall_receiverHasNoToken_shouldSkipFcm() {
receiver.setFcmToken(null);
when(userRepository.findById(1L)).thenReturn(Optional.of(caller));
when(userRepository.findById(2L)).thenReturn(Optional.of(receiver));
String message = service.notifyIncomingCall(1L, request);
assertEquals("Panggilan dikirim via realtime fallback.", message);
verify(fcmService, never()).sendHighPriority(anyString(), anyString(), anyString(), anyMap());
}
@Test
@DisplayName("notifyIncomingCall throws 404 when caller is missing")
void notifyIncomingCall_missingCaller_shouldThrow() {
when(userRepository.findById(1L)).thenReturn(Optional.empty());
assertThrows(ResourceNotFoundException.class, () -> service.notifyIncomingCall(1L, request));
verify(fcmService, never()).sendHighPriority(anyString(), anyString(), anyString(), anyMap());
}
@Test
@DisplayName("notifyCallEnded sends FCM when other user has token")
void notifyCallEnded_otherHasToken_shouldSendFcm() {
when(userRepository.findById(2L)).thenReturn(Optional.of(receiver));
service.notifyCallEnded(1L, 2L);
verify(fcmService).sendToToken(
eq("receiver-token"),
eq("Panggilan Berakhir"),
eq("Panggilan telah berakhir"),
anyMap()
);
}
@Test
@DisplayName("notifyCallEnded skips repository lookup when otherId is null")
void notifyCallEnded_nullOtherId_shouldReturn() {
service.notifyCallEnded(1L, null);
verify(userRepository, never()).findById(2L);
verify(fcmService, never()).sendToToken(anyString(), anyString(), anyString(), anyMap());
}
}