Skip to content

Commit

Permalink
refactor: MeetingController getCurrentUserId() 메소드로 통일 (#228)
Browse files Browse the repository at this point in the history
  • Loading branch information
choidongkuen committed Feb 16, 2024
1 parent 6e9ec47 commit 8b7fd66
Show file tree
Hide file tree
Showing 4 changed files with 224 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import net.teumteum.meeting.domain.Topic;
import net.teumteum.meeting.domain.request.CreateMeetingRequest;
import net.teumteum.meeting.domain.request.UpdateMeetingRequest;
import net.teumteum.meeting.domain.response.MeetingParticipantsResponse;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.domain.response.MeetingResponse;
import net.teumteum.meeting.domain.response.MeetingsResponse;
import net.teumteum.meeting.model.PageDto;
Expand Down Expand Up @@ -43,14 +43,14 @@ public class MeetingController {
public MeetingResponse createMeeting(
@RequestPart @Valid CreateMeetingRequest meetingRequest,
@RequestPart List<MultipartFile> images) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.createMeeting(images, meetingRequest, userId);
}

@GetMapping("/{meetingId}")
@ResponseStatus(HttpStatus.OK)
public MeetingResponse getMeetingById(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.getMeetingById(meetingId, userId);
}

Expand All @@ -64,7 +64,7 @@ public PageDto<MeetingsResponse> getMeetingsByCondition(
@RequestParam(value = "participantUserId", required = false) Long participantUserId,
@RequestParam(value = "isBookmarked", required = false) Boolean isBookmarked,
@RequestParam(value = "searchWord", required = false) String searchWord) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.getMeetingsBySpecification(pageable, topic, meetingAreaStreet, participantUserId,
searchWord, isBookmarked, isOpen, userId);
}
Expand All @@ -74,55 +74,56 @@ public PageDto<MeetingsResponse> getMeetingsByCondition(
public MeetingResponse updateMeeting(@PathVariable Long meetingId,
@RequestPart @Valid UpdateMeetingRequest request,
@RequestPart List<MultipartFile> images) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.updateMeeting(meetingId, images, request, userId);
}

@DeleteMapping("/{meetingId}")
@ResponseStatus(HttpStatus.OK)
public void deleteMeeting(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.deleteMeeting(meetingId, userId);
}

@PostMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.CREATED)
public MeetingResponse addParticipant(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
return meetingService.addParticipant(meetingId, userId);
}

@DeleteMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public void deleteParticipant(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.cancelParticipant(meetingId, userId);
}

@GetMapping("/{meetingId}/participants")
@ResponseStatus(HttpStatus.OK)
public List<MeetingParticipantsResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
return meetingService.getParticipants(meetingId);
public List<MeetingParticipantResponse> getParticipants(@PathVariable("meetingId") Long meetingId) {
Long userId = getCurrentUserId();
return meetingService.getParticipants(meetingId, userId);
}

@PostMapping("/{meetingId}/reports")
@ResponseStatus(HttpStatus.CREATED)
public void reportMeeting(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.reportMeeting(meetingId, userId);
}

@PostMapping("/{meetingId}/bookmarks")
@ResponseStatus(HttpStatus.CREATED)
public void addBookmark(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.addBookmark(meetingId, userId);
}

@DeleteMapping("/{meetingId}/bookmarks")
@ResponseStatus(HttpStatus.OK)
public void deleteBookmark(@PathVariable("meetingId") Long meetingId) {
Long userId = securityService.getCurrentUserId();
Long userId = getCurrentUserId();
meetingService.cancelBookmark(meetingId, userId);
}

Expand All @@ -132,4 +133,8 @@ public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ill
Sentry.captureException(illegalArgumentException);
return ErrorResponse.of(illegalArgumentException);
}

private Long getCurrentUserId() {
return securityService.getCurrentUserId();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

import net.teumteum.user.domain.User;

public record MeetingParticipantsResponse(
public record MeetingParticipantResponse(
Long id,
Long characterId,
String name,
String job
) {

public static MeetingParticipantsResponse of(
public static MeetingParticipantResponse of(
User user
) {
return new MeetingParticipantsResponse(
return new MeetingParticipantResponse(
user.getId(),
user.getCharacterId(),
user.getName(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package net.teumteum.unit.meeting.controller;

import static net.teumteum.unit.common.SecurityValue.VALID_ACCESS_TOKEN;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;
import static org.springframework.http.HttpHeaders.AUTHORIZATION;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
import net.teumteum.core.security.SecurityConfig;
import net.teumteum.core.security.filter.JwtAuthenticationFilter;
import net.teumteum.core.security.service.JwtService;
import net.teumteum.core.security.service.RedisService;
import net.teumteum.core.security.service.SecurityService;
import net.teumteum.meeting.controller.MeetingController;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.service.MeetingService;
import net.teumteum.user.domain.UserFixture;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
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.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(value = MeetingController.class,
excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = SecurityConfig.class),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = JwtAuthenticationFilter.class),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = RedisService.class),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = JwtService.class)}
)
@WithMockUser
@DisplayName("모임 컨트롤러 단위 테스트의")
public class MeetingControllerTest {

@Autowired
private ObjectMapper objectMapper;

@Autowired
private MockMvc mockMvc;

@MockBean
private MeetingService meetingService;

@MockBean
private SecurityService securityService;

@Nested
@DisplayName("모임 참여자 조회 API는")
class Get_meeting_participants_api_unit {

@Test
@DisplayName("API 호출 회원을 제외한, meetingId 해당하는 모임의 참여자 정보를 반환한다.")
void Return_meeting_participants_with_200_ok() throws Exception {
// given
var existUser1 = UserFixture.getUserWithId(1L);
var existUser2 = UserFixture.getUserWithId(2L);
var existUser3 = UserFixture.getUserWithId(3L);

List<MeetingParticipantResponse> response
= List.of(MeetingParticipantResponse.of(existUser2), MeetingParticipantResponse.of(existUser3));

given(securityService.getCurrentUserId())
.willReturn(existUser1.getId());

given(meetingService.getParticipants(anyLong(), anyLong()))
.willReturn(response);

// when && then
mockMvc.perform(get("/meetings/{meetingId}/participants", 2L)
.with(csrf())
.header(AUTHORIZATION, VALID_ACCESS_TOKEN))
.andDo(print())
.andExpect(status().isOk())
.andExpect(jsonPath("$").isNotEmpty())
.andExpect(jsonPath("$.length()").value(2))
.andExpect(jsonPath("$").isArray())
.andExpect(jsonPath("$[0].id").value(2))
.andExpect(jsonPath("$[0].characterId").value(1));
}

@Test
@DisplayName("모임에 API 호출 회원이 존재하지 않는 경우, 400 bad request를 응답한다.")
void Return_400_bad_request_if_meeting_not_contain_user() throws Exception {
// given
var existUser1 = UserFixture.getUserWithId(1L);

given(securityService.getCurrentUserId())
.willReturn(existUser1.getId());

given(meetingService.getParticipants(anyLong(), anyLong())).willThrow(
new IllegalArgumentException("모임에 참여하지 않은 회원입니다."));

// when & then
mockMvc.perform(get("/meetings/{meetingId}/participants", 2L)
.with(csrf())
.header(AUTHORIZATION, VALID_ACCESS_TOKEN))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value("모임에 참여하지 않은 회원입니다."));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package net.teumteum.unit.meeting.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.BDDMockito.given;

import java.util.List;
import java.util.Optional;
import net.teumteum.meeting.domain.ImageUpload;
import net.teumteum.meeting.domain.MeetingFixture;
import net.teumteum.meeting.domain.MeetingRepository;
import net.teumteum.meeting.domain.response.MeetingParticipantResponse;
import net.teumteum.meeting.service.MeetingService;
import net.teumteum.user.domain.UserConnector;
import net.teumteum.user.domain.UserFixture;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
@DisplayName("모임 서비스 단위 테스트의")
public class MeetingServiceTest {

@InjectMocks
MeetingService meetingService;

@Mock
MeetingRepository meetingRepository;

@Mock
UserConnector userConnector;

@Mock
ImageUpload imageUpload;

@Nested
@DisplayName("모임 참여자 조회 API는")
class Return_meeting_participants_api_unit {

@Test
@DisplayName("API 호출 회원을 제외한, meetingId 해당하는 모임의 참여자 정보를 반환한다.")
void Return_meeting_participants_with_200_ok() {
// given
var userId = 1L;
var meetingId = 1L;

var existMeeting
= MeetingFixture.getCloseMeetingWithParticipantUserIds(List.of(userId, 2L, 3L));

var existUser2 = UserFixture.getUserWithId(2L);
var existUser3 = UserFixture.getUserWithId(3L);

given(meetingRepository.findById(anyLong()))
.willReturn(Optional.of(existMeeting));

given(userConnector.findUserById(existUser2.getId())).willReturn(Optional.of(existUser2));
given(userConnector.findUserById(existUser3.getId())).willReturn(Optional.of(existUser3));

// when
List<MeetingParticipantResponse> participants = meetingService.getParticipants(meetingId, userId);
// then
assertThat(participants).hasSize(2);
}

@Test
@DisplayName("모임에 API 호출 회원이 존재하지 않는 경우, 400 bad request를 응답한다.")
void Return_400_bad_request_if_meeting_not_contain_user() {
// given
var userId = 1L;
var notContainedUserId = 4L;

var meetingId = 1L;

var existMeeting
= MeetingFixture.getCloseMeetingWithParticipantUserIds(List.of(userId, 2L, 3L));

given(meetingRepository.findById(anyLong()))
.willReturn(Optional.of(existMeeting));

// when
assertThatThrownBy(() -> meetingService.getParticipants(meetingId, notContainedUserId))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("모임에 참여하지 않은 회원입니다.");
}
}
}

0 comments on commit 8b7fd66

Please sign in to comment.