Skip to content

Commit

Permalink
feat: 친구 조회/삭제 기능 완성 (UMC-5th-Notation#74)
Browse files Browse the repository at this point in the history
  • Loading branch information
ryulkim committed Feb 18, 2024
1 parent e1e88cf commit c5d0a3e
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 72 deletions.
Original file line number Diff line number Diff line change
@@ -1,27 +1,54 @@
package UMC.campusNote.friend.controller;

import UMC.campusNote.auth.jwt.JwtProvider;
import UMC.campusNote.common.ApiResponse;

import UMC.campusNote.friend.dto.FriendRequestDTO;
import UMC.campusNote.friend.dto.FriendResponseDTO;
import UMC.campusNote.friend.service.FriendService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/friend")
@RequestMapping("/api/v1/friends")
public class FriendController {

private final FriendService friendService;

@PostMapping
@Operation(summary = "친구 추가 기능 API", description = "친구 관계를 추가하는 API입니다.")
private ApiResponse addFriend(@Valid @RequestBody FriendRequestDTO.AddFriendReqDTO addFriendReqDto){

friendService.addFriend(addFriendReqDto);

return ApiResponse.onSuccess(null);
}


@GetMapping("/{userId}")
@Operation(summary = "친구 조회 기능 API", description = "유저의 친구를 조회하는 API입니다.")
@Parameters({
@Parameter(name = "userId", description = "유저 id 입니다.")
})
private ApiResponse<List<FriendResponseDTO.friendListDTO>> friendList(@PathVariable("userId") Long userId){
List<FriendResponseDTO.friendListDTO> friendList = friendService.findFriendList(userId);

return ApiResponse.onSuccess(friendList);
}

@DeleteMapping("/{userId}/{friendId}")
@Operation(summary = "친구 삭제 기능 API", description = "")
private ApiResponse deleteFriend(@PathVariable("userId") Long userId, @PathVariable("friendId") Long friendId){
friendService.deleteFriend(userId, friendId);

return ApiResponse.onSuccess(null);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package UMC.campusNote.friend.converter;

import UMC.campusNote.friend.dto.FriendResponseDTO;
import UMC.campusNote.friend.entity.Friend;
import UMC.campusNote.user.entity.User;

Expand All @@ -10,4 +11,12 @@ public static Friend fromEntity(User user1, User user2){
.user2(user2)
.build();
}

public static FriendResponseDTO.friendListDTO toFriendListDTO(User user){
return FriendResponseDTO.friendListDTO.builder()
.friendId(user.getId())
.img(user.getImg())
.name(user.getName())
.build();
}
}
17 changes: 0 additions & 17 deletions src/main/java/UMC/campusNote/friend/dto/AddFriendReqDto.java

This file was deleted.

17 changes: 17 additions & 0 deletions src/main/java/UMC/campusNote/friend/dto/FriendResponseDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package UMC.campusNote.friend.dto;

import lombok.*;

public class FriendResponseDTO {
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@Builder
public static class friendListDTO{
private Long friendId;
private String name;
private String img;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import UMC.campusNote.user.entity.User;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

@Repository
Expand All @@ -15,4 +18,10 @@ public interface FriendRepository extends JpaRepository<Friend, Long> {
@Query("SELECT f FROM Friend f WHERE (f.user1=:user1 AND f.user2=:user2) OR (f.user1=:user2 AND f.user2=:user1)")
Optional<Friend> findByUser1AndUser2(@Param("user1") User user1, @Param("user2") User user2);

@Query("SELECT f FROM Friend f WHERE f.user1=:user OR f.user2=:user")
List<Friend> findAllByUser1(@Param("user1") User user);

@Modifying
@Query("DELETE FROM Friend f WHERE (f.user1=:user1 AND f.user2=:user2) OR (f.user1=:user2 AND f.user2=:user1)")
void deleteByUser1AndUser2(@Param("user1") User user1, @Param("user2") User user2);
}
39 changes: 35 additions & 4 deletions src/main/java/UMC/campusNote/friend/service/FriendService.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@
import UMC.campusNote.friend.converter.FriendConverter;
import UMC.campusNote.friend.dto.FriendRequestDTO;

import UMC.campusNote.friend.dto.FriendResponseDTO;
import UMC.campusNote.friend.entity.Friend;
import UMC.campusNote.friend.repository.FriendRepository;
import UMC.campusNote.user.entity.User;
import UMC.campusNote.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static UMC.campusNote.common.code.status.ErrorStatus.*;

Expand All @@ -27,10 +31,8 @@ public void addFriend(FriendRequestDTO.AddFriendReqDTO addFriendReqDto) {

if (invitedId.equals(inviterId)) throw new GeneralException(FRIEND_NOT_MYSELF);

User inviter = userRepository.findById(inviterId)
.orElseThrow(() -> new GeneralException(USER_NOT_FOUND));
User invited = userRepository.findById(invitedId)
.orElseThrow(() -> new GeneralException(USER_NOT_FOUND));
User inviter = findUser(inviterId);
User invited = findUser(invitedId);

friendRepository.findByUser1AndUser2(inviter, invited)
.ifPresent(friend1 -> {
Expand All @@ -41,4 +43,33 @@ public void addFriend(FriendRequestDTO.AddFriendReqDTO addFriendReqDto) {

friendRepository.save(friend);
}

public List<FriendResponseDTO.friendListDTO> findFriendList(Long userId){
User user = findUser(userId);

List<Friend> friends = friendRepository.findAllByUser1(user);

List<FriendResponseDTO.friendListDTO> friendList = friends.stream()
.map((friend) -> {
if (friend.getUser1().equals(user)) return FriendConverter.toFriendListDTO(friend.getUser2());
else return FriendConverter.toFriendListDTO(friend.getUser1());
})
.toList();

return friendList;
}

@Transactional
public void deleteFriend(Long userId, Long friendId){
User user = findUser(userId);
User friend = findUser(friendId);

friendRepository.deleteByUser1AndUser2(user, friend);
}

private User findUser(Long userId){
return userRepository.findById(userId)
.orElseThrow(() -> new GeneralException(USER_NOT_FOUND));
}

}

This file was deleted.

68 changes: 64 additions & 4 deletions src/test/java/UMC/campusNote/friend/service/FriendServiceTest.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package UMC.campusNote.friend.service;

import UMC.campusNote.common.exception.GeneralException;
import UMC.campusNote.friend.converter.FriendConverter;
import UMC.campusNote.friend.dto.FriendRequestDTO;
import UMC.campusNote.friend.dto.FriendResponseDTO;
import UMC.campusNote.friend.entity.Friend;
import UMC.campusNote.friend.repository.FriendRepository;
import UMC.campusNote.user.entity.User;
import UMC.campusNote.user.repository.UserRepository;
import org.junit.jupiter.api.Assertions;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
Expand All @@ -16,6 +19,8 @@

import org.mockito.junit.jupiter.MockitoExtension;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static org.mockito.Mockito.*;
Expand All @@ -30,10 +35,9 @@ public class FriendServiceTest {
@InjectMocks
FriendService friendService;

// @BeforeEach
// public void setUp(){
//
// }
//@BeforeEach
//public void setUp(){
//}

@Test
@DisplayName("[addFriend service 성공] Add friend test")
Expand Down Expand Up @@ -97,4 +101,60 @@ public void addFriendTest_FRIEND_ALREADY_EXIST(){
// friendRepository.save() 메서드가 호출되지 않았는지 검증
verify(friendRepository, never()).save(any(Friend.class));
}

@Test
@DisplayName("[findFriendList service 성공] find friendList test")
void findFriendListTest() {
// Mock 데이터 설정
Long userId=1L;
User user1 = User.builder()
.id(userId)
.build();
User user2 = User.builder()
.id(2L)
.build();
User user3 = User.builder()
.id(3L)
.build();

Friend friend1 = Friend.builder()
.user1(user1)
.user2(user2)
.build();
Friend friend2 = Friend.builder()
.user1(user3)
.user2(user1)
.build();

List<Friend> friends = new ArrayList<>();
friends.add(friend1);
friends.add(friend2);

List<FriendResponseDTO.friendListDTO> expectedFriendList = new ArrayList<>();
expectedFriendList.add(FriendConverter.toFriendListDTO(friend1.getUser2()));
expectedFriendList.add(FriendConverter.toFriendListDTO(friend2.getUser1()));

// userRepository의 findById 메소드 Mock 설정
when(userRepository.findById(userId)).thenReturn(Optional.of(user1));

// friendRepository의 findAllByUser1 메소드 Mock 설정
when(friendRepository.findAllByUser1(user1)).thenReturn(friends);

// 테스트 대상 메소드 호출
List<FriendResponseDTO.friendListDTO> actualFriendList = friendService.findFriendList(userId);

// 결과 검증
Assertions.assertEquals(expectedFriendList.size(), actualFriendList.size());
for (int i = 0; i < expectedFriendList.size(); i++) {
FriendResponseDTO.friendListDTO expectedFriend = expectedFriendList.get(i);
FriendResponseDTO.friendListDTO actualFriend = actualFriendList.get(i);
Assertions.assertEquals(expectedFriend.getFriendId(), actualFriend.getFriendId());
// 다른 필드에 대한 추가 검증 로직 작성
}

// userRepository의 findById 메소드가 정확히 1번 호출되었는지 검증
verify(userRepository, times(1)).findById(userId);
// friendRepository의 findAllByUser1 메소드가 정확히 1번 호출되었는지 검증
verify(friendRepository, times(1)).findAllByUser1(user1);
}
}

0 comments on commit c5d0a3e

Please sign in to comment.