test: add ActivityLogServiceTest unit test
This commit is contained in:
parent
42543c27df
commit
2c5626c0f9
@ -0,0 +1,196 @@
|
|||||||
|
package com.walkguide.service;
|
||||||
|
|
||||||
|
import com.walkguide.dto.response.ActivityLogResponse;
|
||||||
|
import com.walkguide.entity.ActivityLog;
|
||||||
|
import com.walkguide.entity.PairingRelation;
|
||||||
|
import com.walkguide.entity.User;
|
||||||
|
import com.walkguide.enums.ActivityLogType;
|
||||||
|
import com.walkguide.enums.PairingStatus;
|
||||||
|
import com.walkguide.exception.ResourceNotFoundException;
|
||||||
|
import com.walkguide.repository.ActivityLogRepository;
|
||||||
|
import com.walkguide.repository.PairingRelationRepository;
|
||||||
|
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("ActivityLogService Unit Tests")
|
||||||
|
class ActivityLogServiceTest {
|
||||||
|
|
||||||
|
@Mock ActivityLogRepository activityLogRepository;
|
||||||
|
@Mock PairingRelationRepository pairingRelationRepository;
|
||||||
|
|
||||||
|
@InjectMocks ActivityLogService activityLogService;
|
||||||
|
|
||||||
|
private User sampleUser;
|
||||||
|
private User sampleGuardian;
|
||||||
|
private ActivityLog sampleLog;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
sampleUser = User.builder()
|
||||||
|
.id(1L).email("user@test.com").role("ROLE_USER")
|
||||||
|
.displayName("Test User").build();
|
||||||
|
|
||||||
|
sampleGuardian = User.builder()
|
||||||
|
.id(2L).email("guardian@test.com").role("ROLE_GUARDIAN")
|
||||||
|
.displayName("Test Guardian").build();
|
||||||
|
|
||||||
|
sampleLog = ActivityLog.builder()
|
||||||
|
.id(10L).user(sampleUser)
|
||||||
|
.logType(ActivityLogType.LOGIN)
|
||||||
|
.description("User login")
|
||||||
|
.metadata(null)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== CREATE LOG TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("createLog - harus simpan ActivityLog dengan data yang benar")
|
||||||
|
void createLog_shouldSaveWithCorrectData() {
|
||||||
|
activityLogService.createLog(sampleUser, ActivityLogType.LOGIN, "User login", null);
|
||||||
|
|
||||||
|
ArgumentCaptor<ActivityLog> captor = ArgumentCaptor.forClass(ActivityLog.class);
|
||||||
|
verify(activityLogRepository).save(captor.capture());
|
||||||
|
|
||||||
|
ActivityLog saved = captor.getValue();
|
||||||
|
assertThat(saved.getUser()).isEqualTo(sampleUser);
|
||||||
|
assertThat(saved.getLogType()).isEqualTo(ActivityLogType.LOGIN);
|
||||||
|
assertThat(saved.getDescription()).isEqualTo("User login");
|
||||||
|
assertThat(saved.getMetadata()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("createLog - harus simpan ActivityLog dengan metadata")
|
||||||
|
void createLog_withMetadata_shouldSaveMetadata() {
|
||||||
|
String meta = "{\"label\":\"person\",\"direction\":\"LEFT\"}";
|
||||||
|
activityLogService.createLog(sampleUser, ActivityLogType.OBSTACLE_DETECTED, "Obstacle terdeteksi", meta);
|
||||||
|
|
||||||
|
ArgumentCaptor<ActivityLog> captor = ArgumentCaptor.forClass(ActivityLog.class);
|
||||||
|
verify(activityLogRepository).save(captor.capture());
|
||||||
|
|
||||||
|
assertThat(captor.getValue().getMetadata()).isEqualTo(meta);
|
||||||
|
assertThat(captor.getValue().getLogType()).isEqualTo(ActivityLogType.OBSTACLE_DETECTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("createLog - berbagai tipe log harus disimpan dengan benar")
|
||||||
|
void createLog_variousLogTypes_shouldSaveCorrectly() {
|
||||||
|
ActivityLogType[] types = {
|
||||||
|
ActivityLogType.LOGOUT, ActivityLogType.SOS_TRIGGERED,
|
||||||
|
ActivityLogType.GEOFENCE_EXIT, ActivityLogType.PAIRING_ACCEPTED
|
||||||
|
};
|
||||||
|
|
||||||
|
for (ActivityLogType type : types) {
|
||||||
|
activityLogService.createLog(sampleUser, type, "Deskripsi", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(activityLogRepository, times(types.length)).save(any(ActivityLog.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== GET LOGS TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getLogs - harus return halaman log berdasarkan userId")
|
||||||
|
void getLogs_shouldReturnPagedLogs() {
|
||||||
|
sampleLog.setId(10L);
|
||||||
|
Page<ActivityLog> page = new PageImpl<>(List.of(sampleLog));
|
||||||
|
Pageable pageable = PageRequest.of(0, 10);
|
||||||
|
|
||||||
|
when(activityLogRepository.findByUser_IdOrderByCreatedAtDesc(1L, pageable))
|
||||||
|
.thenReturn(page);
|
||||||
|
|
||||||
|
Page<ActivityLogResponse> result = activityLogService.getLogs(1L, pageable);
|
||||||
|
|
||||||
|
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||||
|
assertThat(result.getContent().get(0).getId()).isEqualTo(10L);
|
||||||
|
assertThat(result.getContent().get(0).getLogType()).isEqualTo("LOGIN");
|
||||||
|
assertThat(result.getContent().get(0).getDescription()).isEqualTo("User login");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getLogs - tidak ada log harus return halaman kosong")
|
||||||
|
void getLogs_noLogs_shouldReturnEmptyPage() {
|
||||||
|
Pageable pageable = PageRequest.of(0, 10);
|
||||||
|
when(activityLogRepository.findByUser_IdOrderByCreatedAtDesc(1L, pageable))
|
||||||
|
.thenReturn(Page.empty());
|
||||||
|
|
||||||
|
Page<ActivityLogResponse> result = activityLogService.getLogs(1L, pageable);
|
||||||
|
|
||||||
|
assertThat(result.getTotalElements()).isZero();
|
||||||
|
assertThat(result.getContent()).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== GET LOGS FOR GUARDIAN TESTS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getLogsForGuardian - Guardian dengan pairing aktif harus return log user")
|
||||||
|
void getLogsForGuardian_activePairing_shouldReturnUserLogs() {
|
||||||
|
PairingRelation pairing = PairingRelation.builder()
|
||||||
|
.id(5L).guardian(sampleGuardian).user(sampleUser)
|
||||||
|
.status(PairingStatus.ACTIVE).build();
|
||||||
|
|
||||||
|
sampleLog.setId(10L);
|
||||||
|
Page<ActivityLog> page = new PageImpl<>(List.of(sampleLog));
|
||||||
|
Pageable pageable = PageRequest.of(0, 5);
|
||||||
|
|
||||||
|
when(pairingRelationRepository.findByGuardian_IdAndStatus(2L, PairingStatus.ACTIVE))
|
||||||
|
.thenReturn(Optional.of(pairing));
|
||||||
|
when(activityLogRepository.findByUser_IdOrderByCreatedAtDesc(1L, pageable))
|
||||||
|
.thenReturn(page);
|
||||||
|
|
||||||
|
Page<ActivityLogResponse> result = activityLogService.getLogsForGuardian(2L, pageable);
|
||||||
|
|
||||||
|
assertThat(result.getTotalElements()).isEqualTo(1);
|
||||||
|
assertThat(result.getContent().get(0).getLogType()).isEqualTo("LOGIN");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getLogsForGuardian - Guardian tanpa pairing aktif harus throw ResourceNotFoundException")
|
||||||
|
void getLogsForGuardian_noPairing_shouldThrow() {
|
||||||
|
when(pairingRelationRepository.findByGuardian_IdAndStatus(2L, PairingStatus.ACTIVE))
|
||||||
|
.thenReturn(Optional.empty());
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> activityLogService.getLogsForGuardian(2L, PageRequest.of(0, 10)))
|
||||||
|
.isInstanceOf(ResourceNotFoundException.class)
|
||||||
|
.hasMessageContaining("Belum ada user yang dipair");
|
||||||
|
|
||||||
|
verify(activityLogRepository, never()).findByUser_IdOrderByCreatedAtDesc(any(), any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("getLogsForGuardian - paginasi multi-halaman harus diteruskan ke repository")
|
||||||
|
void getLogsForGuardian_pagination_shouldPassPageableToRepository() {
|
||||||
|
PairingRelation pairing = PairingRelation.builder()
|
||||||
|
.id(5L).guardian(sampleGuardian).user(sampleUser)
|
||||||
|
.status(PairingStatus.ACTIVE).build();
|
||||||
|
|
||||||
|
Pageable page2 = PageRequest.of(1, 10);
|
||||||
|
when(pairingRelationRepository.findByGuardian_IdAndStatus(2L, PairingStatus.ACTIVE))
|
||||||
|
.thenReturn(Optional.of(pairing));
|
||||||
|
when(activityLogRepository.findByUser_IdOrderByCreatedAtDesc(1L, page2))
|
||||||
|
.thenReturn(Page.empty());
|
||||||
|
|
||||||
|
activityLogService.getLogsForGuardian(2L, page2);
|
||||||
|
|
||||||
|
verify(activityLogRepository).findByUser_IdOrderByCreatedAtDesc(1L, page2);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user