test: add ObstacleLogServiceTest unit test
This commit is contained in:
parent
3eff1275f9
commit
def12a1bdb
@ -0,0 +1,212 @@
|
|||||||
|
package com.walkguide.service;
|
||||||
|
|
||||||
|
import com.walkguide.dto.request.ObstacleLogRequest;
|
||||||
|
import com.walkguide.dto.response.ObstacleLogResponse;
|
||||||
|
import com.walkguide.entity.ObstacleLog;
|
||||||
|
import com.walkguide.entity.User;
|
||||||
|
import com.walkguide.enums.ActivityLogType;
|
||||||
|
import com.walkguide.exception.ResourceNotFoundException;
|
||||||
|
import com.walkguide.repository.ObstacleLogRepository;
|
||||||
|
import com.walkguide.repository.UserRepository;
|
||||||
|
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.ArgumentCaptor;
|
||||||
|
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 org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
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("ObstacleLogService Unit Tests")
|
||||||
|
class ObstacleLogServiceTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ObstacleLogRepository obstacleLogRepository;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
UserRepository userRepository;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
ActivityLogService activityLogService;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
ObstacleLogService obstacleLogService;
|
||||||
|
|
||||||
|
private User sampleUser;
|
||||||
|
private ObstacleLogRequest sampleRequest;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
sampleUser = User.builder()
|
||||||
|
.id(5L)
|
||||||
|
.email("user@test.com")
|
||||||
|
.role("ROLE_USER")
|
||||||
|
.displayName("Test User")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
sampleRequest = new ObstacleLogRequest();
|
||||||
|
sampleRequest.setLabel("Sepeda motor");
|
||||||
|
sampleRequest.setConfidence(0.92);
|
||||||
|
sampleRequest.setDirection("kiri");
|
||||||
|
sampleRequest.setEstimatedDist("1.5 meter");
|
||||||
|
sampleRequest.setLat(-7.2575);
|
||||||
|
sampleRequest.setLng(112.7521);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== saveObstacle TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("saveObstacle - harus simpan log dan return ObstacleLogResponse yang benar")
|
||||||
|
void saveObstacle_validRequest_shouldSaveAndReturnResponse() {
|
||||||
|
ObstacleLog savedLog = ObstacleLog.builder()
|
||||||
|
.id(1L)
|
||||||
|
.userId(5L)
|
||||||
|
.label("Sepeda motor")
|
||||||
|
.confidence(0.92)
|
||||||
|
.direction("kiri")
|
||||||
|
.estimatedDist("1.5 meter")
|
||||||
|
.lat(-7.2575)
|
||||||
|
.lng(112.7521)
|
||||||
|
.createdAt(LocalDateTime.now())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
when(obstacleLogRepository.save(any(ObstacleLog.class))).thenReturn(savedLog);
|
||||||
|
when(userRepository.findById(5L)).thenReturn(Optional.of(sampleUser));
|
||||||
|
|
||||||
|
ObstacleLogResponse result = obstacleLogService.saveObstacle(5L, sampleRequest);
|
||||||
|
|
||||||
|
assertThat(result).isNotNull();
|
||||||
|
assertThat(result.getId()).isEqualTo(1L);
|
||||||
|
assertThat(result.getLabel()).isEqualTo("Sepeda motor");
|
||||||
|
assertThat(result.getConfidence()).isEqualTo(0.92);
|
||||||
|
assertThat(result.getDirection()).isEqualTo("kiri");
|
||||||
|
assertThat(result.getEstimatedDist()).isEqualTo("1.5 meter");
|
||||||
|
assertThat(result.getLat()).isEqualTo(-7.2575);
|
||||||
|
assertThat(result.getLng()).isEqualTo(112.7521);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("saveObstacle - harus simpan ObstacleLog dengan data dari request")
|
||||||
|
void saveObstacle_shouldPersistCorrectData() {
|
||||||
|
when(obstacleLogRepository.save(any(ObstacleLog.class)))
|
||||||
|
.thenAnswer(inv -> {
|
||||||
|
ObstacleLog log = inv.getArgument(0);
|
||||||
|
log = ObstacleLog.builder()
|
||||||
|
.id(10L).userId(log.getUserId()).label(log.getLabel())
|
||||||
|
.confidence(log.getConfidence()).direction(log.getDirection())
|
||||||
|
.estimatedDist(log.getEstimatedDist())
|
||||||
|
.lat(log.getLat()).lng(log.getLng()).build();
|
||||||
|
return log;
|
||||||
|
});
|
||||||
|
when(userRepository.findById(5L)).thenReturn(Optional.of(sampleUser));
|
||||||
|
|
||||||
|
obstacleLogService.saveObstacle(5L, sampleRequest);
|
||||||
|
|
||||||
|
ArgumentCaptor<ObstacleLog> captor = ArgumentCaptor.forClass(ObstacleLog.class);
|
||||||
|
verify(obstacleLogRepository).save(captor.capture());
|
||||||
|
|
||||||
|
ObstacleLog captured = captor.getValue();
|
||||||
|
assertThat(captured.getUserId()).isEqualTo(5L);
|
||||||
|
assertThat(captured.getLabel()).isEqualTo("Sepeda motor");
|
||||||
|
assertThat(captured.getConfidence()).isEqualTo(0.92);
|
||||||
|
assertThat(captured.getDirection()).isEqualTo("kiri");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("saveObstacle - harus mencatat OBSTACLE_DETECTED ke ActivityLog")
|
||||||
|
void saveObstacle_shouldCreateActivityLog() {
|
||||||
|
when(obstacleLogRepository.save(any(ObstacleLog.class)))
|
||||||
|
.thenReturn(ObstacleLog.builder().id(1L).label("Sepeda motor").direction("kiri").build());
|
||||||
|
when(userRepository.findById(5L)).thenReturn(Optional.of(sampleUser));
|
||||||
|
|
||||||
|
obstacleLogService.saveObstacle(5L, sampleRequest);
|
||||||
|
|
||||||
|
verify(activityLogService).createLog(
|
||||||
|
eq(sampleUser),
|
||||||
|
eq(ActivityLogType.OBSTACLE_DETECTED),
|
||||||
|
contains("Sepeda motor"),
|
||||||
|
anyString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("saveObstacle - metadata ActivityLog harus mengandung label, direction, dan confidence")
|
||||||
|
void saveObstacle_activityLogMeta_shouldContainObstacleDetails() {
|
||||||
|
when(obstacleLogRepository.save(any(ObstacleLog.class)))
|
||||||
|
.thenReturn(ObstacleLog.builder().id(1L).label("Lubang").direction("depan").build());
|
||||||
|
when(userRepository.findById(5L)).thenReturn(Optional.of(sampleUser));
|
||||||
|
|
||||||
|
sampleRequest.setLabel("Lubang");
|
||||||
|
sampleRequest.setDirection("depan");
|
||||||
|
sampleRequest.setConfidence(0.85);
|
||||||
|
obstacleLogService.saveObstacle(5L, sampleRequest);
|
||||||
|
|
||||||
|
ArgumentCaptor<String> metaCaptor = ArgumentCaptor.forClass(String.class);
|
||||||
|
verify(activityLogService).createLog(any(), any(), any(), metaCaptor.capture());
|
||||||
|
|
||||||
|
String meta = metaCaptor.getValue();
|
||||||
|
assertThat(meta).contains("Lubang");
|
||||||
|
assertThat(meta).contains("depan");
|
||||||
|
assertThat(meta).contains("0.85");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("saveObstacle - user tidak ditemukan harus throw ResourceNotFoundException")
|
||||||
|
void saveObstacle_userNotFound_shouldThrow() {
|
||||||
|
when(obstacleLogRepository.save(any(ObstacleLog.class)))
|
||||||
|
.thenReturn(ObstacleLog.builder().id(1L).build());
|
||||||
|
when(userRepository.findById(99L)).thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> obstacleLogService.saveObstacle(99L, sampleRequest))
|
||||||
|
.isInstanceOf(ResourceNotFoundException.class)
|
||||||
|
.hasMessageContaining("User tidak ditemukan");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== getObstacleLogs TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getObstacleLogs - harus return page dari ObstacleLogResponse")
|
||||||
|
void getObstacleLogs_shouldReturnPagedResponse() {
|
||||||
|
ObstacleLog log1 = ObstacleLog.builder().id(1L).userId(5L).label("Trotoar").confidence(0.80)
|
||||||
|
.direction("kanan").estimatedDist("2 meter").lat(-7.25).lng(112.75).build();
|
||||||
|
ObstacleLog log2 = ObstacleLog.builder().id(2L).userId(5L).label("Pohon").confidence(0.95)
|
||||||
|
.direction("depan").estimatedDist("1 meter").lat(-7.26).lng(112.76).build();
|
||||||
|
|
||||||
|
Page<ObstacleLog> page = new PageImpl<>(List.of(log1, log2));
|
||||||
|
Pageable pageable = PageRequest.of(0, 10);
|
||||||
|
|
||||||
|
when(obstacleLogRepository.findByUserIdOrderByCreatedAtDesc(5L, pageable)).thenReturn(page);
|
||||||
|
|
||||||
|
Page<ObstacleLogResponse> result = obstacleLogService.getObstacleLogs(5L, pageable);
|
||||||
|
|
||||||
|
assertThat(result.getContent()).hasSize(2);
|
||||||
|
assertThat(result.getContent().get(0).getLabel()).isEqualTo("Trotoar");
|
||||||
|
assertThat(result.getContent().get(1).getLabel()).isEqualTo("Pohon");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getObstacleLogs - halaman kosong harus return page kosong tanpa error")
|
||||||
|
void getObstacleLogs_emptyPage_shouldReturnEmptyPage() {
|
||||||
|
Pageable pageable = PageRequest.of(0, 10);
|
||||||
|
when(obstacleLogRepository.findByUserIdOrderByCreatedAtDesc(5L, pageable))
|
||||||
|
.thenReturn(Page.empty());
|
||||||
|
|
||||||
|
Page<ObstacleLogResponse> result = obstacleLogService.getObstacleLogs(5L, pageable);
|
||||||
|
|
||||||
|
assertThat(result.getContent()).isEmpty();
|
||||||
|
assertThat(result.getTotalElements()).isZero();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user