Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat/30] 친구 요청 취소 API 구현 및 테스트 #32

Merged
merged 4 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
Expand Down Expand Up @@ -46,5 +47,13 @@ public ApiResponse<FriendRequestResponse> rejectFriendRequest(@PathVariable(name
@AuthMember Member member) {
return ApiResponse.ok(friendFacadeService.rejectFriendRequest(member, targetMemberId));
}

@Operation(summary = "친구 요청 취소 API", description = "대상 회원에게 보낸 친구 요청을 취소하는 API 입니다.")
@Parameter(name = "memberId", description = "친구 요청을 취소할 대상 회원의 id 입니다.")
@DeleteMapping("/request/{memberId}")
public ApiResponse<FriendRequestResponse> cancelFriendRequest(@PathVariable(name = "memberId") Long targetMemberId,
@AuthMember Member member) {
return ApiResponse.ok(friendFacadeService.cancelFriendRequest(member, targetMemberId));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,20 @@ public FriendRequestResponse rejectFriendRequest(Member member, Long targetMembe

return FriendRequestResponse.of(friendRequest.getFromMember().getId(), "친구 요청 거절 성공");
}

/**
* 친구 요청 취소 Facade 메소드
*
* @param member
* @param targetMemberId
* @return
*/
@Transactional
public FriendRequestResponse cancelFriendRequest(Member member, Long targetMemberId) {
Member targetMember = memberService.findMember(targetMemberId);
FriendRequest friendRequest = friendService.cancelFriendRequest(member, targetMember);

return FriendRequestResponse.of(friendRequest.getToMember().getId(), "친구 요청 취소 성공");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,28 @@ public FriendRequest rejectFriendRequest(Member member, Member targetMember) {

return friendRequest;
}

/**
* targetMember에게 보낸 친구 요청 취소 처리 메소드
*
* @param member
* @param targetMember
* @return
*/
@Transactional
public FriendRequest cancelFriendRequest(Member member, Member targetMember) {
// targetMember로 나 자신을 요청한 경우 검증
validateNotSelf(member, targetMember);

// 수락 대기 상태인 FriendRequest 엔티티 조회 및 검증
FriendRequest friendRequest = friendRequestRepository.findByFromMemberAndToMemberAndStatus(member,
targetMember, FriendRequestStatus.PENDING)
.orElseThrow(() -> new FriendException(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST));

// FriendRequest 엔티티 상태 변경
friendRequest.updateStatus(FriendRequestStatus.CANCELLED);
}


private void validateNotSelf(Member member, Member targetMember) {
if (member.equals(targetMember)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.willThrow;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
Expand Down Expand Up @@ -249,4 +250,54 @@ void rejectFriendRequestFailedWhenNoPendingRequest() throws Exception {

}

@Nested
@DisplayName("친구 요청 취소")
class CancelFriendRequestTest {

@DisplayName("친구 요청 취소 성공")
@Test
void cancelFriendRequestSucceeds() throws Exception {
// given
FriendRequestResponse response = FriendRequestResponse.builder()
.targetMemberId(TARGET_MEMBER_ID)
.message("친구 요청 취소 성공")
.build();

given(friendFacadeService.cancelFriendRequest(any(), any())).willReturn(response);

// when // then
mockMvc.perform(delete(API_URL_PREFIX + "/request/{memberId}", TARGET_MEMBER_ID))
.andExpect(status().isOk())
.andExpect(jsonPath("$.message").value("OK"))
.andExpect(jsonPath("$.data.message").value("친구 요청 취소 성공"))
.andExpect(jsonPath("$.data.targetMemberId").value(TARGET_MEMBER_ID));
}

@DisplayName("친구 요청 취소 실패: 본인 id를 요청한 경우 에러 응답을 반환한다.")
@Test
void cancelFriendRequestFailedWhenTargetIsSelf() throws Exception {
// given
willThrow(new FriendException(ErrorCode.FRIEND_BAD_REQUEST))
.given(friendFacadeService).cancelFriendRequest(any(), eq(TARGET_MEMBER_ID));

// when // then
mockMvc.perform(delete(API_URL_PREFIX + "/request/{memberId}", TARGET_MEMBER_ID))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.message").value(ErrorCode.FRIEND_BAD_REQUEST.getMessage()));
}

@DisplayName("친구 요청 취소 실패: PENDING 상태인 친구 요청이 없는 경우 에러 응답을 반환한다.")
@Test
void cancelFriendRequestFailedWhenNoPendingRequest() throws Exception {
// given
willThrow(new FriendException(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST))
.given(friendFacadeService).cancelFriendRequest(any(), eq(TARGET_MEMBER_ID));

// when // then
mockMvc.perform(delete(API_URL_PREFIX + "/request/{memberId}", TARGET_MEMBER_ID))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.message").value(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST.getMessage()));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.gamegoo.gamegoo_v2.exception.common.ErrorCode;
import com.gamegoo.gamegoo_v2.friend.domain.Friend;
import com.gamegoo.gamegoo_v2.friend.domain.FriendRequest;
import com.gamegoo.gamegoo_v2.friend.domain.FriendRequestStatus;
import com.gamegoo.gamegoo_v2.friend.dto.FriendRequestResponse;
import com.gamegoo.gamegoo_v2.friend.repository.FriendRepository;
import com.gamegoo.gamegoo_v2.friend.repository.FriendRequestRepository;
Expand Down Expand Up @@ -218,7 +219,6 @@ void acceptFriendRequest_shouldThrowWhenNoPendingRequest() {
.hasMessage(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST.getMessage());
}


@DisplayName("친구 요청 거절 성공")
@Test
void rejectFriendRequestSucceeds() {
Expand Down Expand Up @@ -261,6 +261,50 @@ void rejectFriendRequest_shouldThrowWhenNoPendingRequest() {
.isInstanceOf(FriendException.class)
.hasMessage(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST.getMessage());
}

@DisplayName("친구 요청 취소 성공")
@Test
void cancelFriendRequestSucceeds() {
// given
Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME);
Member targetMember = createMember("target@naver.com", "target");

// 나 -> 상대 친구 요청 생성
friendRequestRepository.save(FriendRequest.create(member, targetMember));

// when
FriendRequestResponse response = friendFacadeService.cancelFriendRequest(member, targetMember.getId());

// then
assertThat(response.getTargetMemberId()).isEqualTo(targetMember.getId());
assertThat(friendRequestRepository.findByFromMemberAndToMemberAndStatus(member, targetMember,
FriendRequestStatus.CANCELLED)).isNotEmpty();
}

@DisplayName("친구 요청 취소 실패: 본인 id를 요청한 경우 예외가 발생한다.")
@Test
void cancelFriendRequest_shouldThrowWhenTargetIsSelf() {
// given
Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME);

// when // then
assertThatThrownBy(() -> friendFacadeService.cancelFriendRequest(member, member.getId()))
.isInstanceOf(FriendException.class)
.hasMessage(ErrorCode.FRIEND_BAD_REQUEST.getMessage());
}

@DisplayName("친구 요청 취소 실패: PENDING 상태인 친구 요청이 없는 경우 예외가 발생한다")
@Test
void cancelFriendRequest_shouldThrowWhenNoPendingRequest() {
// given
Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME);
Member targetMember = createMember("target@naver.com", "target");

// when // then
assertThatThrownBy(() -> friendFacadeService.cancelFriendRequest(member, targetMember.getId()))
.isInstanceOf(FriendException.class)
.hasMessage(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST.getMessage());
}

private Member createMember(String email, String gameName) {
return memberRepository.save(Member.builder()
Expand Down
Loading