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: 친구 조회/삭제 기능 완성 (#74) (#101) #102

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
@@ -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);
}
}