test: add PairingControllerTest unit test
This commit is contained in:
parent
45160f7f97
commit
efd8560324
@ -0,0 +1,263 @@
|
|||||||
|
package com.walkguide.controller;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.walkguide.dto.request.InviteUserRequest;
|
||||||
|
import com.walkguide.dto.request.PairingResponseRequest;
|
||||||
|
import com.walkguide.dto.response.PairingStatusResponse;
|
||||||
|
import com.walkguide.security.SecurityHelper;
|
||||||
|
import com.walkguide.service.PairingService;
|
||||||
|
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.http.MediaType;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.test.context.support.WithMockUser;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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(PairingController.class)
|
||||||
|
@DisplayName("PairingController Unit Tests")
|
||||||
|
class PairingControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private PairingService pairingService;
|
||||||
|
|
||||||
|
private PairingStatusResponse buildPairingStatus(String status) {
|
||||||
|
return PairingStatusResponse.builder()
|
||||||
|
.pairingId(1L)
|
||||||
|
.status(status)
|
||||||
|
.pairedWithName("Test Partner")
|
||||||
|
.pairedWithEmail("partner@test.com")
|
||||||
|
.uniqueUserId("ABC123")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== INVITE =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "2", roles = "GUARDIAN")
|
||||||
|
@DisplayName("POST /api/v1/shared/pairing/invite - Guardian undang User harus return 200")
|
||||||
|
void invite_asGuardian_shouldReturn200() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
|
||||||
|
|
||||||
|
InviteUserRequest req = new InviteUserRequest();
|
||||||
|
req.setUniqueUserId("ABC123DEF456");
|
||||||
|
|
||||||
|
PairingStatusResponse resp = buildPairingStatus("PENDING");
|
||||||
|
when(pairingService.inviteUser(2L, "ABC123DEF456")).thenReturn(resp);
|
||||||
|
|
||||||
|
mockMvc.perform(post("/api/v1/shared/pairing/invite")
|
||||||
|
.with(csrf())
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(req)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.message").value("Undangan dikirim ke user"))
|
||||||
|
.andExpect(jsonPath("$.data.status").value("PENDING"));
|
||||||
|
|
||||||
|
verify(pairingService).inviteUser(2L, "ABC123DEF456");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "2", roles = "GUARDIAN")
|
||||||
|
@DisplayName("POST /api/v1/shared/pairing/invite - uniqueUserId tidak ada harus return 500")
|
||||||
|
void invite_userNotFound_shouldReturn500() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
|
||||||
|
|
||||||
|
InviteUserRequest req = new InviteUserRequest();
|
||||||
|
req.setUniqueUserId("INVALID999");
|
||||||
|
|
||||||
|
when(pairingService.inviteUser(2L, "INVALID999"))
|
||||||
|
.thenThrow(new RuntimeException("User dengan ID tersebut tidak ditemukan"));
|
||||||
|
|
||||||
|
mockMvc.perform(post("/api/v1/shared/pairing/invite")
|
||||||
|
.with(csrf())
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(req)))
|
||||||
|
.andExpect(status().isInternalServerError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== RESPOND =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "1", roles = "USER")
|
||||||
|
@DisplayName("POST /api/v1/shared/pairing/respond - User terima pairing harus return 200")
|
||||||
|
void respond_accept_shouldReturn200WithAcceptMessage() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||||
|
|
||||||
|
PairingResponseRequest req = new PairingResponseRequest();
|
||||||
|
req.setPairingId(5L);
|
||||||
|
req.setAccept(true);
|
||||||
|
|
||||||
|
PairingStatusResponse resp = buildPairingStatus("ACTIVE");
|
||||||
|
when(pairingService.respondToPairing(1L, 5L, true)).thenReturn(resp);
|
||||||
|
|
||||||
|
mockMvc.perform(post("/api/v1/shared/pairing/respond")
|
||||||
|
.with(csrf())
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(req)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.message").value("Pairing diterima"))
|
||||||
|
.andExpect(jsonPath("$.data.status").value("ACTIVE"));
|
||||||
|
|
||||||
|
verify(pairingService).respondToPairing(1L, 5L, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "1", roles = "USER")
|
||||||
|
@DisplayName("POST /api/v1/shared/pairing/respond - User tolak pairing harus return 200 pesan ditolak")
|
||||||
|
void respond_reject_shouldReturn200WithRejectMessage() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||||
|
|
||||||
|
PairingResponseRequest req = new PairingResponseRequest();
|
||||||
|
req.setPairingId(5L);
|
||||||
|
req.setAccept(false);
|
||||||
|
|
||||||
|
PairingStatusResponse resp = buildPairingStatus("REJECTED");
|
||||||
|
when(pairingService.respondToPairing(1L, 5L, false)).thenReturn(resp);
|
||||||
|
|
||||||
|
mockMvc.perform(post("/api/v1/shared/pairing/respond")
|
||||||
|
.with(csrf())
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(req)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.message").value("Pairing ditolak"))
|
||||||
|
.andExpect(jsonPath("$.data.status").value("REJECTED"));
|
||||||
|
|
||||||
|
verify(pairingService).respondToPairing(1L, 5L, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== UNPAIR =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "1", roles = "USER")
|
||||||
|
@DisplayName("DELETE /api/v1/shared/pairing/unpair - harus akhiri pairing dan return 200")
|
||||||
|
void unpair_shouldReturn200() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||||
|
doNothing().when(pairingService).unpair(1L);
|
||||||
|
|
||||||
|
mockMvc.perform(delete("/api/v1/shared/pairing/unpair")
|
||||||
|
.with(csrf()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.message").value("Pairing diakhiri"));
|
||||||
|
|
||||||
|
verify(pairingService).unpair(1L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "2", roles = "GUARDIAN")
|
||||||
|
@DisplayName("DELETE /api/v1/shared/pairing/unpair - Guardian juga bisa unpair")
|
||||||
|
void unpair_asGuardian_shouldReturn200() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
|
||||||
|
doNothing().when(pairingService).unpair(2L);
|
||||||
|
|
||||||
|
mockMvc.perform(delete("/api/v1/shared/pairing/unpair")
|
||||||
|
.with(csrf()))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.message").value("Pairing diakhiri"));
|
||||||
|
|
||||||
|
verify(pairingService).unpair(2L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "1", roles = "USER")
|
||||||
|
@DisplayName("DELETE /api/v1/shared/pairing/unpair - service throw harus return 500")
|
||||||
|
void unpair_serviceThrows_shouldReturn500() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||||
|
doThrow(new RuntimeException("Tidak ada pairing aktif")).when(pairingService).unpair(1L);
|
||||||
|
|
||||||
|
mockMvc.perform(delete("/api/v1/shared/pairing/unpair")
|
||||||
|
.with(csrf()))
|
||||||
|
.andExpect(status().isInternalServerError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ===== STATUS =====
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "1", roles = "USER")
|
||||||
|
@DisplayName("GET /api/v1/shared/pairing/status - User harus return status pairing")
|
||||||
|
void status_asUser_shouldReturn200() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||||
|
|
||||||
|
PairingStatusResponse resp = buildPairingStatus("ACTIVE");
|
||||||
|
when(pairingService.getStatus(eq(1L), eq("ROLE_USER"))).thenReturn(resp);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/api/v1/shared/pairing/status"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.success").value(true))
|
||||||
|
.andExpect(jsonPath("$.message").value("Status pairing"))
|
||||||
|
.andExpect(jsonPath("$.data.status").value("ACTIVE"))
|
||||||
|
.andExpect(jsonPath("$.data.pairingId").value(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "2", roles = "GUARDIAN")
|
||||||
|
@DisplayName("GET /api/v1/shared/pairing/status - Guardian harus return status pairing dengan role GUARDIAN")
|
||||||
|
void status_asGuardian_shouldReturn200() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(2L);
|
||||||
|
|
||||||
|
PairingStatusResponse resp = buildPairingStatus("ACTIVE");
|
||||||
|
when(pairingService.getStatus(eq(2L), eq("ROLE_GUARDIAN"))).thenReturn(resp);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/api/v1/shared/pairing/status"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.message").value("Status pairing"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@WithMockUser(username = "1", roles = "USER")
|
||||||
|
@DisplayName("GET /api/v1/shared/pairing/status - belum ada pairing harus return status NONE")
|
||||||
|
void status_noPairing_shouldReturnNoneStatus() throws Exception {
|
||||||
|
try (MockedStatic<SecurityHelper> sh = mockStatic(SecurityHelper.class)) {
|
||||||
|
sh.when(SecurityHelper::getCurrentUserId).thenReturn(1L);
|
||||||
|
|
||||||
|
PairingStatusResponse resp = PairingStatusResponse.builder()
|
||||||
|
.status("NONE")
|
||||||
|
.build();
|
||||||
|
when(pairingService.getStatus(eq(1L), anyString())).thenReturn(resp);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/api/v1/shared/pairing/status"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data.status").value("NONE"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user