test: add GuardianControllerTest unit test

This commit is contained in:
5803024019 2026-05-16 08:12:26 +07:00
parent 785d883556
commit 45160f7f97

View File

@ -0,0 +1,363 @@
package com.walkguide.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.walkguide.dto.request.*;
import com.walkguide.dto.response.*;
import com.walkguide.security.SecurityHelper;
import com.walkguide.service.*;
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(GuardianController.class)
@WithMockUser(username = "2", roles = "GUARDIAN")
@DisplayName("GuardianController Unit Tests")
class GuardianControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@MockBean private GuardianDashboardService dashboardService;
@MockBean private LocationService locationService;
@MockBean private ActivityLogService activityLogService;
@MockBean private ObstacleLogService obstacleLogService;
@MockBean private NotificationService notificationService;
@MockBean private SosService sosService;
@MockBean private AiConfigService aiConfigService;
@MockBean private VoiceCommandService voiceCommandService;
@MockBean private HardwareShortcutService hardwareShortcutService;
@MockBean private GeofenceService geofenceService;
@MockBean private UserSettingsService userSettingsService;
// ===== DASHBOARD =====
@Test
@DisplayName("GET /api/v1/guardian/dashboard - harus return dashboard")
void dashboard_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(dashboardService.getDashboard(2L)).thenReturn(new DashboardResponse());
mockMvc.perform(get("/api/v1/guardian/dashboard"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.message").value("Dashboard Guardian"));
}
}
// ===== USER LOCATION =====
@Test
@DisplayName("GET /api/v1/guardian/user-location - harus return lokasi terakhir user")
void userLocation_locationExists_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(locationService.getLastLocationForGuardian(2L))
.thenReturn(Optional.of(new LocationResponse()));
mockMvc.perform(get("/api/v1/guardian/user-location"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.message").value("Lokasi terakhir user"));
}
}
@Test
@DisplayName("GET /api/v1/guardian/user-location - belum ada lokasi harus return data null")
void userLocation_noLocation_shouldReturnNullData() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(locationService.getLastLocationForGuardian(2L)).thenReturn(Optional.empty());
mockMvc.perform(get("/api/v1/guardian/user-location"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").isEmpty());
}
}
// ===== LOCATION HISTORY =====
@Test
@DisplayName("GET /api/v1/guardian/location-history - harus return paginated history")
void locationHistory_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
Page<LocationResponse> page = new PageImpl<>(List.of());
when(locationService.getLocationHistory(eq(2L), any())).thenReturn(page);
mockMvc.perform(get("/api/v1/guardian/location-history")
.param("page", "0").param("size", "20"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Riwayat lokasi"));
}
}
// ===== ACTIVITY LOGS =====
@Test
@DisplayName("GET /api/v1/guardian/activity-logs - harus return log aktivitas user")
void activityLogs_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
Page<ActivityLogResponse> page = new PageImpl<>(List.of());
when(activityLogService.getLogsForGuardian(eq(2L), any())).thenReturn(page);
mockMvc.perform(get("/api/v1/guardian/activity-logs"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Log aktivitas user"));
}
}
// ===== OBSTACLE LOGS =====
@Test
@DisplayName("GET /api/v1/guardian/obstacle-logs - harus return log obstacle user")
void obstacleLogs_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
Page<ObstacleLogResponse> page = new PageImpl<>(List.of());
when(obstacleLogService.getObstacleLogs(eq(2L), any())).thenReturn(page);
mockMvc.perform(get("/api/v1/guardian/obstacle-logs"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Log obstacle user"));
}
}
// ===== SEND NOTIFICATION =====
@Test
@DisplayName("POST /api/v1/guardian/notifications/send - harus kirim notifikasi dan return response")
void sendNotif_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
SendNotificationRequest req = new SendNotificationRequest();
NotificationResponse resp = new NotificationResponse();
when(notificationService.sendNotification(eq(2L), any())).thenReturn(resp);
mockMvc.perform(post("/api/v1/guardian/notifications/send")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(req)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Notifikasi terkirim"));
verify(notificationService).sendNotification(eq(2L), any(SendNotificationRequest.class));
}
}
// ===== SOS EVENTS =====
@Test
@DisplayName("GET /api/v1/guardian/sos-events - harus return paginated SOS events")
void sosEvents_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
Page<SosEventResponse> page = new PageImpl<>(List.of());
when(sosService.getSosEventsForGuardian(eq(2L), any())).thenReturn(page);
mockMvc.perform(get("/api/v1/guardian/sos-events"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("SOS events"));
}
}
@Test
@DisplayName("PUT /api/v1/guardian/sos/{id}/acknowledge - harus akui SOS")
void acknowledgeSos_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
SosEventResponse resp = new SosEventResponse();
when(sosService.acknowledgeSos(2L, 10L)).thenReturn(resp);
mockMvc.perform(put("/api/v1/guardian/sos/10/acknowledge")
.with(csrf()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("SOS diakui"));
verify(sosService).acknowledgeSos(2L, 10L);
}
}
// ===== AI CONFIG =====
@Test
@DisplayName("GET /api/v1/guardian/ai-config - harus return AI config user")
void getAiConfig_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(aiConfigService.getConfig(2L)).thenReturn(new AiConfigResponse());
mockMvc.perform(get("/api/v1/guardian/ai-config"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("AI config"));
}
}
@Test
@DisplayName("PUT /api/v1/guardian/ai-config - harus update AI config dan return response baru")
void updateAiConfig_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
AiConfigUpdateRequest req = new AiConfigUpdateRequest();
AiConfigResponse resp = new AiConfigResponse();
when(aiConfigService.updateConfigByGuardian(eq(2L), any())).thenReturn(resp);
mockMvc.perform(put("/api/v1/guardian/ai-config")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(req)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("AI config diperbarui"));
verify(aiConfigService).updateConfigByGuardian(eq(2L), any(AiConfigUpdateRequest.class));
}
}
// ===== VOICE COMMANDS =====
@Test
@DisplayName("GET /api/v1/guardian/voice-commands - harus return voice commands user")
void getVoiceCommands_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(voiceCommandService.getAll(2L)).thenReturn(List.of());
mockMvc.perform(get("/api/v1/guardian/voice-commands"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Voice commands"));
}
}
@Test
@DisplayName("PUT /api/v1/guardian/voice-commands - harus update voice command")
void updateVoiceCommand_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
VoiceCommandUpdateRequest req = new VoiceCommandUpdateRequest();
VoiceCommandResponse resp = new VoiceCommandResponse();
when(voiceCommandService.updateByGuardian(eq(2L), any())).thenReturn(resp);
mockMvc.perform(put("/api/v1/guardian/voice-commands")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(req)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Voice command diperbarui"));
}
}
// ===== SHORTCUTS =====
@Test
@DisplayName("GET /api/v1/guardian/shortcuts - harus return hardware shortcuts")
void getShortcuts_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(hardwareShortcutService.getAll(2L)).thenReturn(List.of());
mockMvc.perform(get("/api/v1/guardian/shortcuts"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Hardware shortcuts"));
}
}
// ===== GEOFENCE =====
@Test
@DisplayName("GET /api/v1/guardian/geofence - harus return konfigurasi geofence")
void getGeofence_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(geofenceService.getConfig(2L)).thenReturn(new GeofenceResponse());
mockMvc.perform(get("/api/v1/guardian/geofence"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Geofence config"));
}
}
@Test
@DisplayName("PUT /api/v1/guardian/geofence - harus update geofence config")
void updateGeofence_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
GeofenceConfigRequest req = new GeofenceConfigRequest();
GeofenceResponse resp = new GeofenceResponse();
when(geofenceService.updateConfig(eq(2L), any())).thenReturn(resp);
mockMvc.perform(put("/api/v1/guardian/geofence")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(req)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("Geofence diperbarui"));
verify(geofenceService).updateConfig(eq(2L), any(GeofenceConfigRequest.class));
}
}
// ===== USER SETTINGS (dikelola Guardian) =====
@Test
@DisplayName("GET /api/v1/guardian/user-settings - harus return settings user")
void getUserSettings_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
when(userSettingsService.getSettings(2L)).thenReturn(new UserSettingsResponse());
mockMvc.perform(get("/api/v1/guardian/user-settings"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("User settings"));
}
}
@Test
@DisplayName("PUT /api/v1/guardian/user-settings - harus update user settings")
void updateUserSettings_shouldReturn200() throws Exception {
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
UserSettingsUpdateRequest req = new UserSettingsUpdateRequest();
UserSettingsResponse resp = new UserSettingsResponse();
when(userSettingsService.updateSettings(eq(2L), any())).thenReturn(resp);
mockMvc.perform(put("/api/v1/guardian/user-settings")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(req)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("User settings diperbarui"));
}
}
}