diff --git a/src/main/java/com/server/domain/friend/controller/FriendController.java b/src/main/java/com/server/domain/friend/controller/FriendController.java index 7f2ef31..31db65c 100644 --- a/src/main/java/com/server/domain/friend/controller/FriendController.java +++ b/src/main/java/com/server/domain/friend/controller/FriendController.java @@ -16,7 +16,6 @@ import com.server.domain.friend.enums.FriendState; import com.server.domain.friend.service.FriendService; import com.server.global.dto.ApiResponseDto; -import com.server.global.jwt.JwtService; import io.swagger.v3.oas.annotations.Operation; import jakarta.servlet.http.HttpServletRequest; @@ -29,7 +28,6 @@ @RequestMapping("/api/friends") public class FriendController { - private final JwtService jwtService; private final FriendService friendService; @ResponseStatus(HttpStatus.CREATED) @@ -37,8 +35,7 @@ public class FriendController { @Operation(summary = "친구 신청 생성", description = "친구 신청할 사용자의 이름을 입력하여 친구 신청 생성") public ApiResponseDto createFriendRequest(HttpServletRequest request, @RequestParam String receiptUsername) { - String requestUsername = jwtService.extractUsernameFromToken(request).get(); - friendService.createFriendRequest(requestUsername, receiptUsername); + String requestUsername = friendService.createFriendRequest(request, receiptUsername); return ApiResponseDto.success(HttpStatus.CREATED.value(), String.format("A friend request from User '%s' to User '%s' has been created.", requestUsername, receiptUsername)); @@ -50,8 +47,7 @@ public ApiResponseDto createFriendRequest(HttpServletRequest request, public ApiResponseDto> getFriendRequest( @RequestParam(required = false) FriendState state, HttpServletRequest request) { - String username = jwtService.extractUsernameFromToken(request).get(); - List getUserOutDtos = friendService.getRequestUser(username, state); + List getUserOutDtos = friendService.getRequestUser(request, state); return ApiResponseDto.success(HttpStatus.OK.value(), getUserOutDtos); } @@ -60,8 +56,7 @@ public ApiResponseDto> getFriendRequest( @Operation(summary = "친구 신청 취소", description = "친구 신청할 사용자의 이름을 입력하여 친구 신청 삭제") public ApiResponseDto deleteFriendRequest(HttpServletRequest request, @RequestParam String receiptUsername) { - String requestUsername = jwtService.extractUsernameFromToken(request).get(); - friendService.deleteFriendRequest(requestUsername, receiptUsername); + String requestUsername = friendService.deleteFriendRequest(request, receiptUsername); return ApiResponseDto.success(HttpStatus.OK.value(), String .format("The friend request from '%s' to '%s' has been deleted.", requestUsername, receiptUsername)); } @@ -71,8 +66,7 @@ public ApiResponseDto deleteFriendRequest(HttpServletRequest request, @Operation(summary = "친구 내역 조회", description = "사용자 기준 신청 받은 내역") public ApiResponseDto> getFriendReceipt(HttpServletRequest request, @RequestParam(required = false) FriendState state) { - String username = jwtService.extractUsernameFromToken(request).get(); - List getUserOutDtos = friendService.getReceiptUser(username, state); + List getUserOutDtos = friendService.getReceiptUser(request, state); return ApiResponseDto.success(HttpStatus.OK.value(), getUserOutDtos); } @@ -81,8 +75,7 @@ public ApiResponseDto> getFriendReceipt(HttpServletRequest @Operation(summary = "친구 신청 승인", description = "친구 신청을 승인할 사용자의 이름을 입력하여 친구 신청 승인") public ApiResponseDto approveFriendRequest(HttpServletRequest request, @RequestParam String requestUsername) { - String receiptUsername = jwtService.extractUsernameFromToken(request).get(); - friendService.acceptFriendRequest(requestUsername, receiptUsername); + String receiptUsername = friendService.acceptFriendRequest(requestUsername, request); return ApiResponseDto.success(HttpStatus.CREATED.value(), String.format( "The friend request from User '%s' to User '%s' has been accepted.", requestUsername, receiptUsername)); } diff --git a/src/main/java/com/server/domain/friend/service/FriendService.java b/src/main/java/com/server/domain/friend/service/FriendService.java index dcb4b26..ee0a09f 100644 --- a/src/main/java/com/server/domain/friend/service/FriendService.java +++ b/src/main/java/com/server/domain/friend/service/FriendService.java @@ -17,7 +17,9 @@ import com.server.global.error.code.FriendErrorCode; import com.server.global.error.code.UserErrorCode; import com.server.global.error.exception.BusinessException; +import com.server.global.jwt.JwtService; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; @Service @@ -29,9 +31,11 @@ public class FriendService { private final UserRepository userRepository; private final FriendRepository friendRepository; private final FriendMapper friendMapper; + private final JwtService jwtService; - public List getRequestUser(String username, FriendState state) { + public List getRequestUser(HttpServletRequest request, FriendState state) { List friends; + String username = jwtService.extractUsernameFromToken(request).get(); User user = userRepository.findByUsername(username) .orElseThrow(() -> new BusinessException(UserErrorCode.NOT_FOUND)); if (state == null) { @@ -47,7 +51,8 @@ public List getRequestUser(String username, FriendState state) return getFriendOutDtos; } - public List getReceiptUser(String username, FriendState state) { + public List getReceiptUser(HttpServletRequest request, FriendState state) { + String username = jwtService.extractUsernameFromToken(request).get(); List friends; User user = userRepository.findByUsername(username) .orElseThrow(() -> new BusinessException(UserErrorCode.NOT_FOUND)); @@ -87,7 +92,8 @@ private void validateFriendRequest(User user1, User user2) { } @Transactional - public Friend createFriendRequest(String requestUsername, String receiptUsername) { + public String createFriendRequest(HttpServletRequest request, String receiptUsername) { + String requestUsername = jwtService.extractUsernameFromToken(request).get(); User requestUser = userRepository.findByUsername(requestUsername) .orElseThrow(() -> new BusinessException(UserErrorCode.NOT_FOUND)); User receiptUser = userRepository.findByUsername(receiptUsername) @@ -98,11 +104,13 @@ public Friend createFriendRequest(String requestUsername, String receiptUsername .receiptUser(receiptUser) .state(FriendState.SENDING) .build(); - return friendRepository.save(friend); + friendRepository.save(friend); + return requestUsername; } @Transactional - public void deleteFriendRequest(String requestUsername, String receiptUsername) { + public String deleteFriendRequest(HttpServletRequest request, String receiptUsername) { + String requestUsername = jwtService.extractUsernameFromToken(request).get(); User requestUser = userRepository.findByUsername(requestUsername) .orElseThrow(() -> new BusinessException(UserErrorCode.NOT_FOUND)); User receiptUser = userRepository.findByUsername(receiptUsername) @@ -116,10 +124,12 @@ public void deleteFriendRequest(String requestUsername, String receiptUsername) throw new BusinessException(FriendErrorCode.REQUEST_ALREADY_REMOVED); } friend.setState(FriendState.REMOVED); + return requestUsername; } @Transactional - public void acceptFriendRequest(String requestUsername, String receiptUsername) { + public String acceptFriendRequest(String requestUsername, HttpServletRequest request) { + String receiptUsername = jwtService.extractUsernameFromToken(request).get(); User requestUser = userRepository.findByUsername(requestUsername) .orElseThrow(() -> new BusinessException(UserErrorCode.NOT_FOUND)); User receiptUser = userRepository.findByUsername(receiptUsername) @@ -144,5 +154,6 @@ public void acceptFriendRequest(String requestUsername, String receiptUsername) .build(); friendRepository.save(friendApproved); } + return receiptUsername; } } diff --git a/src/test/java/com/server/domain/friend/service/FriendServiceTest.java b/src/test/java/com/server/domain/friend/service/FriendServiceTest.java new file mode 100644 index 0000000..de89c35 --- /dev/null +++ b/src/test/java/com/server/domain/friend/service/FriendServiceTest.java @@ -0,0 +1,207 @@ +package com.server.domain.friend.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.then; +import static org.mockito.Mockito.times; + +import java.util.List; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.mock.web.MockHttpServletRequest; + +import com.server.domain.friend.dto.GetFriendOutDto; +import com.server.domain.friend.entity.Friend; +import com.server.domain.friend.enums.FriendState; +import com.server.domain.friend.mapper.FriendMapper; +import com.server.domain.friend.repository.FriendRepository; +import com.server.domain.user.entity.User; +import com.server.domain.user.repository.UserRepository; +import com.server.global.jwt.JwtService; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@ExtendWith(MockitoExtension.class) +class FriendServiceTest { + + @InjectMocks + private FriendService friendService; + + @Mock + private JwtService jwtService; + + @Mock + private UserRepository userRepository; + + @Mock + private FriendRepository friendRepository; + + @Mock + private FriendMapper friendMapper; + + @Test + @DisplayName("본인이 다른 사용자에게 친구 신청") + void createFriendRequest_requestUser_returnsFriendRequest() { + /* given */ + String requestUsername = "request user"; + String receiptUsername = "receipt user"; + User requestUser = User.builder() + .username(requestUsername) + .email("user1@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho1234") + .build(); + User receiptUser = User.builder() + .username(receiptUsername) + .email("user2@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho4321") + .build(); + MockHttpServletRequest request = new MockHttpServletRequest(); + given(jwtService.extractUsernameFromToken(request)).willReturn(Optional.of(requestUsername)); + given(userRepository.findByUsername(requestUsername)).willReturn(Optional.of(requestUser)); + given(userRepository.findByUsername(receiptUsername)).willReturn(Optional.of(receiptUser)); + + /* when */ + ArgumentCaptor friendCaptor = ArgumentCaptor.forClass(Friend.class); + friendService.createFriendRequest(request, receiptUsername); + + /* then */ + then(friendRepository).should(times(1)).save(friendCaptor.capture()); + Friend savedFriend = friendCaptor.getValue(); + assertThat(savedFriend.getRequestUser()).isEqualTo(requestUser); + assertThat(savedFriend.getReceiptUser()).isEqualTo(receiptUser); + assertThat(savedFriend.getState()).isEqualTo(FriendState.SENDING); + } + + @Test + @DisplayName("다른 사용자가 보낸 친구 신청 수락") + void acceptFriendRequest_receiptUser_returnsFriendRequest() { + /* given */ + String requestUsername = "request user"; + String receiptUsername = "receipt user"; + User requestUser = User.builder() + .username(requestUsername) + .email("user1@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho1234") + .build(); + User receiptUser = User.builder() + .username(receiptUsername) + .email("user2@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho4321") + .build(); + Friend friendRequested = Friend.builder().requestUser(requestUser).receiptUser(receiptUser) + .state(FriendState.SENDING).build(); + MockHttpServletRequest request = new MockHttpServletRequest(); + given(jwtService.extractUsernameFromToken(request)).willReturn(Optional.of(receiptUsername)); + given(userRepository.findByUsername(requestUsername)).willReturn(Optional.of(requestUser)); + given(userRepository.findByUsername(receiptUsername)).willReturn(Optional.of(receiptUser)); + given(friendRepository.findByRequestUserAndReceiptUser(requestUser, receiptUser)) + .willReturn(Optional.of(friendRequested)); + given(friendRepository.findByRequestUserAndReceiptUser(receiptUser, requestUser)) + .willReturn(Optional.empty()); + + /* when */ + ArgumentCaptor friendCaptor = ArgumentCaptor.forClass(Friend.class); + friendService.acceptFriendRequest(requestUsername, request); + + /* then */ + assertThat(friendRequested.getState()).isEqualTo(FriendState.ACCEPTED); + then(friendRepository).should(times(1)).save(friendCaptor.capture()); + List capturedFriends = friendCaptor.getAllValues(); + assertThat(capturedFriends.get(0).getState()).isEqualTo(FriendState.ACCEPTED); + } + + @Test + @DisplayName("본인이 보낸 친구 신청 삭제") + void deleteFriendRequest_requestUser_returnsFriendRequest() { + /* given */ + String requestUsername = "request user"; + String receiptUsername = "receipt user"; + User requestUser = User.builder() + .username(requestUsername) + .email("user1@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho1234") + .build(); + User receiptUser = User.builder() + .username(receiptUsername) + .email("user2@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho4321") + .build(); + Friend friendRequested = Friend.builder().requestUser(requestUser).receiptUser(receiptUser) + .state(FriendState.SENDING).build(); + MockHttpServletRequest request = new MockHttpServletRequest(); + given(jwtService.extractUsernameFromToken(request)).willReturn(Optional.of(requestUsername)); + given(userRepository.findByUsername(requestUsername)).willReturn(Optional.of(requestUser)); + given(userRepository.findByUsername(receiptUsername)).willReturn(Optional.of(receiptUser)); + given(friendRepository.findByRequestUserAndReceiptUser(requestUser, receiptUser)) + .willReturn(Optional.of(friendRequested)); + + /* when */ + friendService.deleteFriendRequest(request, receiptUsername); + + /* then */ + assertThat(friendRequested.getState()).isEqualTo(FriendState.REMOVED); + } + + @Test + @DisplayName("타인이 친구 신청했을 때 본인이 친구 신청 목록 조회") + void getFriendRequest_receiptUser_returnsFriendRequest() { + /* given */ + String requestUsername = "request user"; + String receiptUsername = "receipt user"; + User requestUser = User.builder() + .username(requestUsername) + .email("user1@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho1234") + .build(); + User receiptUser = User.builder() + .username(receiptUsername) + .email("user2@example.com") + .thumbnail("https://avatars.githubusercontent.com/u/0?v=4") + .oauth("github") + .githubToken("gho4321") + .build(); + Friend friendRequested = Friend.builder().requestUser(requestUser).receiptUser(receiptUser) + .state(FriendState.SENDING).build(); + List friends = List.of(friendRequested); + MockHttpServletRequest request = new MockHttpServletRequest(); + GetFriendOutDto dto = new GetFriendOutDto(); + dto.setUsername(requestUser.getUsername()); + dto.setEmail(requestUser.getEmail()); + dto.setState(FriendState.SENDING); + given(jwtService.extractUsernameFromToken(request)).willReturn(Optional.of(receiptUsername)); + given(userRepository.findByUsername(receiptUsername)).willReturn(Optional.of(receiptUser)); + given(friendRepository.findByReceiptUser(receiptUser)).willReturn(Optional.of(friends)); + given(friendMapper.toGetFriendOutDto(requestUser, FriendState.SENDING)).willReturn(dto); + + /* when */ + List dtos = friendService.getReceiptUser(request, null); + + /* then */ + assertThat(dtos).hasSize(1); + GetFriendOutDto dto0 = dtos.get(0); + assertThat(dto0.getUsername()).isEqualTo(requestUser.getUsername()); + assertThat(dto0.getState()).isEqualTo(FriendState.SENDING); + } +}