test: add UserControllerTest unit test
This commit is contained in:
parent
efd8560324
commit
f9a23dee58
@ -0,0 +1,391 @@
|
||||
package com.walkguide.controller;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.walkguide.dto.ApiResponse;
|
||||
import com.walkguide.dto.request.*;
|
||||
import com.walkguide.dto.response.*;
|
||||
import com.walkguide.entity.User;
|
||||
import com.walkguide.enums.ActivityLogType;
|
||||
import com.walkguide.repository.UserRepository;
|
||||
import com.walkguide.security.SecurityHelper;
|
||||
import com.walkguide.service.*;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.test.context.support.WithMockUser;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@WebMvcTest(UserController.class)
|
||||
@WithMockUser(username = "1", roles = "USER")
|
||||
@DisplayName("UserController Unit Tests")
|
||||
class UserControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Autowired
|
||||
private ObjectMapper objectMapper;
|
||||
|
||||
@MockBean private LocationService locationService;
|
||||
@MockBean private ObstacleLogService obstacleLogService;
|
||||
@MockBean private SosService sosService;
|
||||
@MockBean private ActivityLogService activityLogService;
|
||||
@MockBean private NotificationService notificationService;
|
||||
@MockBean private UserSettingsService userSettingsService;
|
||||
@MockBean private AiConfigService aiConfigService;
|
||||
@MockBean private VoiceCommandService voiceCommandService;
|
||||
@MockBean private HardwareShortcutService hardwareShortcutService;
|
||||
@MockBean private UserRepository userRepository;
|
||||
|
||||
private User sampleUser;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
sampleUser = User.builder()
|
||||
.id(1L)
|
||||
.email("user@test.com")
|
||||
.displayName("Test User")
|
||||
.role("ROLE_USER")
|
||||
.uniqueUserId("ABC123DEF456")
|
||||
.build();
|
||||
}
|
||||
|
||||
// ===== PROFILE =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/profile - harus return profil user")
|
||||
void getProfile_shouldReturn200WithProfile() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
when(userRepository.findById(1L)).thenReturn(Optional.of(sampleUser));
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/profile"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.data.email").value("user@test.com"))
|
||||
.andExpect(jsonPath("$.data.uniqueUserId").value("ABC123DEF456"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/profile - user tidak ditemukan harus return 500")
|
||||
void getProfile_userNotFound_shouldReturn500() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(99L);
|
||||
when(userRepository.findById(99L)).thenReturn(Optional.empty());
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/profile"))
|
||||
.andExpect(status().isInternalServerError());
|
||||
}
|
||||
}
|
||||
|
||||
// ===== SETTINGS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/settings - harus return settings user")
|
||||
void getSettings_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
UserSettingsResponse settings = new UserSettingsResponse();
|
||||
when(userSettingsService.getSettings(1L)).thenReturn(settings);
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/settings"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.message").value("Settings user"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("PUT /api/v1/user/settings - harus update dan return settings baru")
|
||||
void updateSettings_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
|
||||
UserSettingsResponse updated = new UserSettingsResponse();
|
||||
when(userSettingsService.updateSettings(eq(1L), any())).thenReturn(updated);
|
||||
|
||||
mockMvc.perform(put("/api/v1/user/settings")
|
||||
.with(csrf())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(req)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.message").value("Settings diperbarui"));
|
||||
|
||||
verify(userSettingsService).updateSettings(eq(1L), any(UserSettingsUpdateRequest.class));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== VOICE COMMANDS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/voice-commands - harus return list voice commands")
|
||||
void getVoiceCommands_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
VoiceCommandResponse cmd = new VoiceCommandResponse();
|
||||
when(voiceCommandService.getAll(1L)).thenReturn(List.of(cmd));
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/voice-commands"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.data").isArray());
|
||||
}
|
||||
}
|
||||
|
||||
// ===== SHORTCUTS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/shortcuts - harus return list shortcuts")
|
||||
void getShortcuts_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
when(hardwareShortcutService.getAll(1L)).thenReturn(List.of());
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/shortcuts"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("PUT /api/v1/user/shortcuts - harus update shortcut")
|
||||
void updateShortcut_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
HardwareShortcutUpdateRequest req = new HardwareShortcutUpdateRequest();
|
||||
HardwareShortcutResponse resp = new HardwareShortcutResponse();
|
||||
when(hardwareShortcutService.update(eq(1L), any())).thenReturn(resp);
|
||||
|
||||
mockMvc.perform(put("/api/v1/user/shortcuts")
|
||||
.with(csrf())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(req)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("Shortcut diperbarui"));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== AI CONFIG =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/ai-config - harus return AI config")
|
||||
void getAiConfig_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
when(aiConfigService.getConfig(1L)).thenReturn(new AiConfigResponse());
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/ai-config"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.message").value("AI config"));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== LOCATION =====
|
||||
|
||||
@Test
|
||||
@DisplayName("POST /api/v1/user/location - harus update lokasi dan return LocationResponse")
|
||||
void updateLocation_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
LocationUpdateRequest req = new LocationUpdateRequest();
|
||||
req.setLatitude(-7.2575);
|
||||
req.setLongitude(112.7521);
|
||||
|
||||
LocationResponse resp = new LocationResponse();
|
||||
when(locationService.updateLocation(eq(1L), any())).thenReturn(resp);
|
||||
|
||||
mockMvc.perform(post("/api/v1/user/location")
|
||||
.with(csrf())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(req)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.message").value("Lokasi diperbarui"));
|
||||
|
||||
verify(locationService).updateLocation(eq(1L), any(LocationUpdateRequest.class));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== OBSTACLE =====
|
||||
|
||||
@Test
|
||||
@DisplayName("POST /api/v1/user/obstacle - harus mencatat obstacle dan return response")
|
||||
void logObstacle_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
ObstacleLogRequest req = new ObstacleLogRequest();
|
||||
ObstacleLogResponse resp = new ObstacleLogResponse();
|
||||
when(obstacleLogService.saveObstacle(eq(1L), any())).thenReturn(resp);
|
||||
|
||||
mockMvc.perform(post("/api/v1/user/obstacle")
|
||||
.with(csrf())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(req)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("Obstacle dicatat"));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== SOS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("POST /api/v1/user/sos - harus trigger SOS dan return SosEventResponse")
|
||||
void triggerSos_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
SosRequest req = new SosRequest();
|
||||
SosEventResponse resp = new SosEventResponse();
|
||||
when(sosService.triggerSos(eq(1L), any())).thenReturn(resp);
|
||||
|
||||
mockMvc.perform(post("/api/v1/user/sos")
|
||||
.with(csrf())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content(objectMapper.writeValueAsString(req)))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.message").value("SOS dikirim! Guardian sudah diberitahu."));
|
||||
|
||||
verify(sosService).triggerSos(eq(1L), any(SosRequest.class));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== ACTIVITY LOGS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/activity-logs - harus return paginated activity logs")
|
||||
void getActivityLogs_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
Page<ActivityLogResponse> page = new PageImpl<>(List.of());
|
||||
when(activityLogService.getLogs(eq(1L), any(PageRequest.class))).thenReturn(page);
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/activity-logs")
|
||||
.param("page", "0")
|
||||
.param("size", "10"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("Log aktivitas"));
|
||||
}
|
||||
}
|
||||
|
||||
// ===== NOTIFICATIONS =====
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/notifications - harus return paginated notifikasi")
|
||||
void getNotifications_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
|
||||
Page<NotificationResponse> page = new PageImpl<>(List.of());
|
||||
when(notificationService.getNotifications(eq(1L), any())).thenReturn(page);
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/notifications"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("Notifikasi"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("GET /api/v1/user/notifications/unread-count - harus return jumlah belum dibaca")
|
||||
void getUnreadCount_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
when(notificationService.getUnreadCount(1L)).thenReturn(5L);
|
||||
|
||||
mockMvc.perform(get("/api/v1/user/notifications/unread-count"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.data").value(5))
|
||||
.andExpect(jsonPath("$.message").value("Jumlah notifikasi belum dibaca"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("PUT /api/v1/user/notifications/mark-all-read - harus mark semua sebagai dibaca")
|
||||
void markAllRead_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
doNothing().when(notificationService).markAllRead(1L);
|
||||
|
||||
mockMvc.perform(put("/api/v1/user/notifications/mark-all-read")
|
||||
.with(csrf()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("Semua notifikasi ditandai sudah dibaca"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("PUT /api/v1/user/notifications/{id}/read - harus mark satu notifikasi sebagai dibaca")
|
||||
void markOneRead_shouldReturn200() throws Exception {
|
||||
doNothing().when(notificationService).markOneRead(42L);
|
||||
|
||||
mockMvc.perform(put("/api/v1/user/notifications/42/read")
|
||||
.with(csrf()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("Notifikasi ditandai sudah dibaca"));
|
||||
|
||||
verify(notificationService).markOneRead(42L);
|
||||
}
|
||||
|
||||
// ===== WALKGUIDE START / STOP =====
|
||||
|
||||
@Test
|
||||
@DisplayName("POST /api/v1/user/walkguide/start - harus catat log WALKGUIDE_START")
|
||||
void walkGuideStart_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
when(userRepository.findById(1L)).thenReturn(Optional.of(sampleUser));
|
||||
doNothing().when(activityLogService).createLog(any(), eq(ActivityLogType.WALKGUIDE_START), anyString(), any());
|
||||
|
||||
mockMvc.perform(post("/api/v1/user/walkguide/start")
|
||||
.with(csrf()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("WalkGuide dimulai"));
|
||||
|
||||
verify(activityLogService).createLog(eq(sampleUser), eq(ActivityLogType.WALKGUIDE_START), anyString(), any());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("POST /api/v1/user/walkguide/stop - harus catat log WALKGUIDE_STOP")
|
||||
void walkGuideStop_shouldReturn200() throws Exception {
|
||||
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||
when(userRepository.findById(1L)).thenReturn(Optional.of(sampleUser));
|
||||
doNothing().when(activityLogService).createLog(any(), eq(ActivityLogType.WALKGUIDE_STOP), anyString(), any());
|
||||
|
||||
mockMvc.perform(post("/api/v1/user/walkguide/stop")
|
||||
.with(csrf()))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.message").value("WalkGuide dihentikan"));
|
||||
|
||||
verify(activityLogService).createLog(eq(sampleUser), eq(ActivityLogType.WALKGUIDE_STOP), anyString(), any());
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user