From d029a0098d18288fc0fc2241c65c6fbc8b5c3fa8 Mon Sep 17 00:00:00 2001 From: Eunjin3395 Date: Tue, 10 Dec 2024 14:39:50 +0900 Subject: [PATCH 1/3] =?UTF-8?q?:sparkles:=20[Feat]=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=20=EA=B1=B0=EC=A0=88=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/controller/FriendController.java | 8 ++++++ .../friend/service/FriendFacadeService.java | 15 +++++++++++ .../friend/service/FriendService.java | 25 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/src/main/java/com/gamegoo/gamegoo_v2/friend/controller/FriendController.java b/src/main/java/com/gamegoo/gamegoo_v2/friend/controller/FriendController.java index 90d310a5..4a186e83 100644 --- a/src/main/java/com/gamegoo/gamegoo_v2/friend/controller/FriendController.java +++ b/src/main/java/com/gamegoo/gamegoo_v2/friend/controller/FriendController.java @@ -39,4 +39,12 @@ public ApiResponse acceptFriendRequest(@PathVariable(name return ApiResponse.ok(friendFacadeService.acceptFriendRequest(member, targetMemberId)); } + @Operation(summary = "친구 요청 거절 API", description = "대상 회원이 보낸 친구 요청을 거절 처리하는 API 입니다.") + @Parameter(name = "memberId", description = "친구 요청을 거절할 대상 회원의 id 입니다.") + @PatchMapping("/request/{memberId}/reject") + public ApiResponse rejectFriendRequest(@PathVariable(name = "memberId") Long targetMemberId, + @AuthMember Member member) { + return ApiResponse.ok(friendFacadeService.rejectFriendRequest(member, targetMemberId)); + } + } diff --git a/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendFacadeService.java b/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendFacadeService.java index cc877091..a2be1f86 100644 --- a/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendFacadeService.java +++ b/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendFacadeService.java @@ -46,4 +46,19 @@ public FriendRequestResponse acceptFriendRequest(Member member, Long targetMembe return FriendRequestResponse.of(friendRequest.getFromMember().getId(), "친구 요청 수락 성공"); } + /** + * 친구 요청 거절 Facade 메소드 + * + * @param member + * @param targetMemberId + * @return + */ + @Transactional + public FriendRequestResponse rejectFriendRequest(Member member, Long targetMemberId) { + Member targetMember = memberService.findMember(targetMemberId); + FriendRequest friendRequest = friendService.rejectFriendRequest(member, targetMember); + + return FriendRequestResponse.of(friendRequest.getFromMember().getId(), "친구 요청 거절 성공"); + } + } diff --git a/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendService.java b/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendService.java index e24a0645..0ef8126a 100644 --- a/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendService.java +++ b/src/main/java/com/gamegoo/gamegoo_v2/friend/service/FriendService.java @@ -86,6 +86,31 @@ public FriendRequest acceptFriendRequest(Member member, Member targetMember) { return friendRequest; } + /** + * targetMember가 보낸 친구 요청 거절 처리 메소드 + * + * @param member + * @param targetMember + * @return + */ + @Transactional + public FriendRequest rejectFriendRequest(Member member, Member targetMember) { + // targetMember로 나 자신을 요청한 경우 검증 + validateNotSelf(member, targetMember); + + // 수락 대기 상태인 FriendRequest 엔티티 조회 및 검증 + FriendRequest friendRequest = friendRequestRepository.findByFromMemberAndToMemberAndStatus(targetMember, + member, FriendRequestStatus.PENDING) + .orElseThrow(() -> new FriendException(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST)); + + // FriendRequest 엔티티 상태 변경 + friendRequest.updateStatus(FriendRequestStatus.REJECTED); + + // targetMember에게 친구 요청 거절 알림 생성 + + return friendRequest; + } + private void validateNotSelf(Member member, Member targetMember) { if (member.equals(targetMember)) { throw new FriendException(ErrorCode.FRIEND_BAD_REQUEST); From 4b1b8ebbe37894208a196f355281e413e1692a31 Mon Sep 17 00:00:00 2001 From: Eunjin3395 Date: Tue, 10 Dec 2024 14:48:17 +0900 Subject: [PATCH 2/3] =?UTF-8?q?:white=5Fcheck=5Fmark:=20[Test]=20=EC=B9=9C?= =?UTF-8?q?=EA=B5=AC=20=EC=9A=94=EC=B2=AD=20=EA=B1=B0=EC=A0=88=20API=20?= =?UTF-8?q?=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/FriendFacadeServiceTest.java | 47 ++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/gamegoo/gamegoo_v2/integration/friend/FriendFacadeServiceTest.java b/src/test/java/com/gamegoo/gamegoo_v2/integration/friend/FriendFacadeServiceTest.java index 62ce0025..7c61bd70 100644 --- a/src/test/java/com/gamegoo/gamegoo_v2/integration/friend/FriendFacadeServiceTest.java +++ b/src/test/java/com/gamegoo/gamegoo_v2/integration/friend/FriendFacadeServiceTest.java @@ -24,6 +24,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; @ActiveProfiles("test") @@ -206,7 +207,7 @@ void acceptFriendRequest_shouldThrowWhenTargetIsSelf() { @DisplayName("친구 요청 수락 실패: PENDING 상태인 친구 요청이 없는 경우 예외가 발생한다") @Test - void accpetFriendRequest_shouldThrowWhenNoPendingRequest() { + void acceptFriendRequest_shouldThrowWhenNoPendingRequest() { // given Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME); Member targetMember = createMember("target@naver.com", "target"); @@ -217,6 +218,50 @@ void accpetFriendRequest_shouldThrowWhenNoPendingRequest() { .hasMessage(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST.getMessage()); } + + @DisplayName("친구 요청 거절 성공") + @Test + void rejectFriendRequestSucceeds() { + // given + Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME); + Member targetMember = createMember("target@naver.com", "target"); + + // 상대 -> 나 친구 요청 생성 + friendRequestRepository.save(FriendRequest.create(targetMember, member)); + + // when + FriendRequestResponse response = friendFacadeService.rejectFriendRequest(member, targetMember.getId()); + + // then + assertThat(response.getTargetMemberId()).isEqualTo(targetMember.getId()); + assertFalse(friendRepository.existsByFromMemberAndToMember(member, targetMember)); + } + + @DisplayName("친구 요청 거절 실패: 본인 id를 요청한 경우 예외가 발생한다.") + @Test + void rejectFriendRequest_shouldThrowWhenTargetIsSelf() { + // given + Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME); + + // when // then + assertThatThrownBy(() -> friendFacadeService.rejectFriendRequest(member, member.getId())) + .isInstanceOf(FriendException.class) + .hasMessage(ErrorCode.FRIEND_BAD_REQUEST.getMessage()); + } + + @DisplayName("친구 요청 거절 실패: PENDING 상태인 친구 요청이 없는 경우 예외가 발생한다") + @Test + void rejectFriendRequest_shouldThrowWhenNoPendingRequest() { + // given + Member member = createMember(MEMBER_EMAIL, MEMBER_GAMENAME); + Member targetMember = createMember("target@naver.com", "target"); + + // when // then + assertThatThrownBy(() -> friendFacadeService.rejectFriendRequest(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() .email(email) From cafd12298b6f9151a10e59b95a015ea74cee9b17 Mon Sep 17 00:00:00 2001 From: Eunjin3395 Date: Tue, 10 Dec 2024 14:54:07 +0900 Subject: [PATCH 3/3] =?UTF-8?q?:white=5Fcheck=5Fmark:=20[Test]=20=EC=B9=9C?= =?UTF-8?q?=EA=B5=AC=20=EC=9A=94=EC=B2=AD=20=EA=B1=B0=EC=A0=88=20API=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/FriendControllerTest.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/test/java/com/gamegoo/gamegoo_v2/controller/friend/FriendControllerTest.java b/src/test/java/com/gamegoo/gamegoo_v2/controller/friend/FriendControllerTest.java index ea00bd8e..ed98b566 100644 --- a/src/test/java/com/gamegoo/gamegoo_v2/controller/friend/FriendControllerTest.java +++ b/src/test/java/com/gamegoo/gamegoo_v2/controller/friend/FriendControllerTest.java @@ -198,4 +198,55 @@ void acceptFriendRequestFailedWhenNoPendingRequest() throws Exception { } + @Nested + @DisplayName("친구 요청 거절") + class rejectFriendRequestTest { + + @DisplayName("친구 요청 거절 성공") + @Test + void rejectFriendRequestSucceeds() throws Exception { + // given + FriendRequestResponse response = FriendRequestResponse.builder() + .targetMemberId(TARGET_MEMBER_ID) + .message("친구 요청 거절 성공") + .build(); + + given(friendFacadeService.rejectFriendRequest(any(), any())).willReturn(response); + + // when // then + mockMvc.perform(patch(API_URL_PREFIX + "/request/{memberId}/reject", 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 rejectFriendRequestFailedWhenTargetIsSelf() throws Exception { + // given + willThrow(new FriendException(ErrorCode.FRIEND_BAD_REQUEST)) + .given(friendFacadeService).rejectFriendRequest(any(), eq(TARGET_MEMBER_ID)); + + // when // then + mockMvc.perform(patch(API_URL_PREFIX + "/request/{memberId}/reject", TARGET_MEMBER_ID)) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.message").value(ErrorCode.FRIEND_BAD_REQUEST.getMessage())); + } + + @DisplayName("친구 요청 거절 실패: PENDING 상태인 친구 요청이 없는 경우 에러 응답을 반환한다.") + @Test + void rejectFriendRequestFailedWhenNoPendingRequest() throws Exception { + // given + willThrow(new FriendException(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST)) + .given(friendFacadeService).rejectFriendRequest(any(), eq(TARGET_MEMBER_ID)); + + // when // then + mockMvc.perform(patch(API_URL_PREFIX + "/request/{memberId}/reject", TARGET_MEMBER_ID)) + .andExpect(status().isNotFound()) + .andExpect(jsonPath("$.message").value(ErrorCode.PENDING_FRIEND_REQUEST_NOT_EXIST.getMessage())); + } + + } + }