Skip to content

Commit

Permalink
Merge pull request #61 from Seasoning-Today/test/find-all-friends-int…
Browse files Browse the repository at this point in the history
…egration-test

�친구 목록 조회 통합테스트 작성
  • Loading branch information
csct3434 authored Feb 6, 2024
2 parents 45edb95 + cbeaea9 commit 2c9c03a
Show file tree
Hide file tree
Showing 6 changed files with 189 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import today.seasoning.seasoning.common.UserPrincipal;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResult;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResponse;
import today.seasoning.seasoning.friendship.dto.SearchUserResult;
import today.seasoning.seasoning.friendship.dto.UserIdDto;
import today.seasoning.seasoning.friendship.service.AcceptFriendRequestService;
import today.seasoning.seasoning.friendship.service.CancelFriendRequestService;
import today.seasoning.seasoning.friendship.service.DeclineFriendRequestService;
import today.seasoning.seasoning.friendship.service.FindUserFriendsService;
import today.seasoning.seasoning.friendship.service.FindAllFriendsService;
import today.seasoning.seasoning.friendship.service.SearchUserService;
import today.seasoning.seasoning.friendship.service.SendFriendRequestService;
import today.seasoning.seasoning.friendship.service.UnfriendService;
Expand All @@ -32,7 +32,7 @@ public class FriendshipController {

private final UnfriendService unfriendService;
private final SearchUserService searchUserService;
private final FindUserFriendsService findUserFriendsService;
private final FindAllFriendsService findAllFriendsService;
private final SendFriendRequestService sendFriendRequestService;
private final AcceptFriendRequestService acceptFriendRequestService;
private final CancelFriendRequestService cancelFriendRequestService;
Expand All @@ -52,10 +52,10 @@ public ResponseEntity<String> requestFriendship(
}

@GetMapping("/list")
public ResponseEntity<List<FindUserFriendsResult>> findUserFriends(@AuthenticationPrincipal UserPrincipal principal) {
public ResponseEntity<List<FindUserFriendsResponse>> findUserFriends(@AuthenticationPrincipal UserPrincipal principal) {
Long userId = principal.getId();
List<FindUserFriendsResult> findUserFriendResults = findUserFriendsService.doFind(userId);
return ResponseEntity.ok().body(findUserFriendResults);
List<FindUserFriendsResponse> response = findAllFriendsService.doService(userId);
return ResponseEntity.ok().body(response);
}

@PutMapping("/add/accept")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

@Getter
@RequiredArgsConstructor
public class FindUserFriendsResult {
public class FindUserFriendsResponse {

private final String id;
private final String nickname;
private final String accountId;
private final String profileImageUrl;

public static FindUserFriendsResult build(User friend) {
return new FindUserFriendsResult(
public static FindUserFriendsResponse build(User friend) {
return new FindUserFriendsResponse(
TsidUtil.toString(friend.getId()),
friend.getNickname(),
friend.getAccountId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,20 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import today.seasoning.seasoning.friendship.domain.FriendshipRepository;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResult;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResponse;

@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class FindUserFriendsService {
public class FindAllFriendsService {

private final FriendshipRepository friendshipRepository;

public List<FindUserFriendsResult> doFind(Long userId) {
public List<FindUserFriendsResponse> doService(Long userId) {
return friendshipRepository.findFriendsByUserId(userId)
.stream()
.map(FindUserFriendsResult::build)
.map(FindUserFriendsResponse::build)
.collect(Collectors.toList());
}
}
36 changes: 27 additions & 9 deletions src/test/java/today/seasoning/seasoning/BaseIntegrationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
Expand All @@ -33,41 +35,57 @@ public class BaseIntegrationTest {
}

@Autowired
JdbcTemplate jdbcTemplate;
private JdbcTemplate jdbcTemplate;

@LocalServerPort
int port;
private int port;

@BeforeEach
void setPort() {
void init() {
// 실제 서블릿 컨테이너 실행을 위한 RANDOM PORT 설정
RestAssured.port = port;

// 모든 테이블 데이터 초기화 (정적 데이터 fortune, solar_term 제외)
Resource resource = new ClassPathResource("/data/clear.sql");
try {
String sql = FileCopyUtils.copyToString(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
String sql = FileCopyUtils.copyToString(
new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8));
Arrays.stream(sql.split("\n")).forEach(jdbcTemplate::execute);
} catch (IOException e) {
throw new RuntimeException("Error reading or executing SQL script: /data/clear.sql", e);
}
}

public ExtractableResponse<Response> post(String uri, Long userId, JSONObject jsonBody) {
String accessToken = JwtUtil.createToken(userId).getAccessToken();

protected ExtractableResponse<Response> post(String url, Long userId, JSONObject jsonBody) {
RequestSpecification request = RestAssured
.given().log().all()
.contentType("application/json")
.header("Authorization", "Bearer " + accessToken);
.header("Authorization", "Bearer " + createAccessToken(userId));

if (jsonBody != null) {
request.body(jsonBody.toString());
}

return request
.when().post(uri)
.when().post(url)
.then().log().all().extract();
}

protected ExtractableResponse<Response> get(String url, Long userId) {
return get(url, userId, new HashMap<>());
}


protected ExtractableResponse<Response> get(String url, Long userId, Map<String, Object> params) {
return RestAssured
.given().log().all()
.header("Authorization", "Bearer " + createAccessToken(userId))
.params(params)
.when().get(url)
.then().log().all().extract();
}

protected String createAccessToken(Long userId) {
return JwtUtil.createToken(userId).getAccessToken();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package today.seasoning.seasoning.friendship.integration;

import io.restassured.common.mapper.TypeRef;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import java.util.List;
import java.util.stream.Collectors;
import org.assertj.core.api.SoftAssertions;
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import today.seasoning.seasoning.BaseIntegrationTest;
import today.seasoning.seasoning.common.enums.LoginType;
import today.seasoning.seasoning.common.util.TsidUtil;
import today.seasoning.seasoning.friendship.domain.Friendship;
import today.seasoning.seasoning.friendship.domain.FriendshipRepository;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResponse;
import today.seasoning.seasoning.user.domain.User;
import today.seasoning.seasoning.user.domain.UserRepository;

@DisplayName("친구 목록 조회 통합 테스트")
public class FindAllFriendsIntegrationTest extends BaseIntegrationTest {

@Autowired
UserRepository userRepository;

@Autowired
FriendshipRepository friendshipRepository;

@InjectSoftAssertions
SoftAssertions softAssertions;

// API 주소
static String url = "/friend/list";

// Mock 유저 정보
List<User> users;

@BeforeEach
void initMockUsers() {
//given
users = List.of(
new User("userNickname0", "https://test.org/user0.jpg", "user0@email.com", LoginType.KAKAO),
new User("userNickname1", "https://test.org/user1.jpg", "user1@email.com", LoginType.KAKAO),
new User("userNickname2", "https://test.org/user2.jpg", "user2@email.com", LoginType.KAKAO),
new User("userNickname3", "https://test.org/user3.jpg", "user3@email.com", LoginType.KAKAO)
);
userRepository.saveAll(users);
}

@Test
@DisplayName("모든 친구가 조회되어야 한다")
void findAllFriends() {
//given : 회원이 user1, user2, user3와 친구일 때
User user = users.get(0);
List<User> friends = users.subList(1, 4);

setFriendships(user, friends);

//when : 친구 목록을 조회하면
ExtractableResponse<Response> response = get(url, user.getId());

List<FindUserFriendsResponse> responseFriendList = response.body().as(new TypeRef<>() {
});

//then : 응답은 다음과 같아야 한다
softAssertions.assertThat(response.statusCode())
.as("상태 코드는 200이어야 한다")
.isEqualTo(200);

softAssertions.assertThat(responseFriendList.size())
.as("조회된 친구의 수는 3명이다.")
.isEqualTo(3);

softAssertions.assertThat(responseFriendList)
.as("조회된 친구의 정보는 실제 회원의 정보와 일치해야 한다")
.usingRecursiveComparison()
.isEqualTo(createFindUserFriendsResponse(friends));
}

@Test
@DisplayName("친구가 아닌 회원은 조회되면 안된다")
void findAllFriendsExcludingNonFriends() {
//given : 회원이 user1과 user2와 친구이고, user3와는 친구가 아닐 때
User user = users.get(0);
List<User> friends = users.subList(1, 3);
User nonFriendUser = users.get(3);

setFriendships(user, friends);

//when : 친구 목록을 조회하면
ExtractableResponse<Response> response = get(url, user.getId());

List<FindUserFriendsResponse> responseFriendList = response.body().as(new TypeRef<>() {
});

//then : 응답은 다음과 같아야 한다
softAssertions.assertThat(response.statusCode())
.as("상태 코드는 200이어야 한다")
.isEqualTo(200);

softAssertions.assertThat(responseFriendList.size())
.as("조회된 친구의 수는 2명이다.")
.isEqualTo(2);

softAssertions.assertThat(responseFriendList)
.as("조회된 친구의 정보는 실제 회원의 정보와 일치해야 한다")
.usingRecursiveComparison()
.isEqualTo(createFindUserFriendsResponse(friends));

softAssertions.assertThat(responseFriendList)
.as("친구가 아닌 회원의 정보는 조회되면 안된다")
.usingRecursiveComparison()
.isNotEqualTo(createFindUserFriendsResponse(nonFriendUser));
}


private void setFriendships(User user, List<User> friends) {
friends.forEach(friend -> {
friendshipRepository.save(new Friendship(user, friend));
friendshipRepository.save(new Friendship(friend, user));
});
}

private List<FindUserFriendsResponse> createFindUserFriendsResponse(List<User> users) {
return users.stream()
.map(this::createFindUserFriendsResponse)
.collect(Collectors.toList());
}

private FindUserFriendsResponse createFindUserFriendsResponse(User user) {
return new FindUserFriendsResponse(
TsidUtil.toString(user.getId()),
user.getNickname(),
user.getAccountId(),
user.getProfileImageUrl());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@
import today.seasoning.seasoning.common.enums.LoginType;
import today.seasoning.seasoning.common.util.TsidUtil;
import today.seasoning.seasoning.friendship.domain.FriendshipRepository;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResult;
import today.seasoning.seasoning.friendship.dto.FindUserFriendsResponse;
import today.seasoning.seasoning.user.domain.User;

@DisplayName("친구 목록 조회 서비스")
@ExtendWith(MockitoExtension.class)
class FindUserFriendsServiceTest {
class FindAllFriendsServiceTest {

@Mock
FriendshipRepository friendshipRepository;
@InjectMocks
FindUserFriendsService findUserFriendsService;
FindAllFriendsService findAllFriendsService;

@Test
@DisplayName("성공")
Expand All @@ -33,17 +33,17 @@ void success() {
User friend2 = new User("friend2", "https://test/friend2.jpg", "friend2@email.com", LoginType.KAKAO);
User friend3 = new User("friend3", "https://test/friend3.jpg", "friend3@email.com", LoginType.KAKAO);

List<FindUserFriendsResult> expectedResult = List.of(
new FindUserFriendsResult(TsidUtil.toString(friend1.getId()), friend1.getNickname(), friend1.getAccountId(), friend1.getProfileImageUrl()),
new FindUserFriendsResult(TsidUtil.toString(friend2.getId()), friend2.getNickname(), friend2.getAccountId(), friend2.getProfileImageUrl()),
new FindUserFriendsResult(TsidUtil.toString(friend3.getId()), friend3.getNickname(), friend3.getAccountId(), friend3.getProfileImageUrl())
List<FindUserFriendsResponse> expectedResult = List.of(
new FindUserFriendsResponse(TsidUtil.toString(friend1.getId()), friend1.getNickname(), friend1.getAccountId(), friend1.getProfileImageUrl()),
new FindUserFriendsResponse(TsidUtil.toString(friend2.getId()), friend2.getNickname(), friend2.getAccountId(), friend2.getProfileImageUrl()),
new FindUserFriendsResponse(TsidUtil.toString(friend3.getId()), friend3.getNickname(), friend3.getAccountId(), friend3.getProfileImageUrl())
);

BDDMockito.given(friendshipRepository.findFriendsByUserId(user.getId()))
.willReturn(List.of(friend1, friend2, friend3));

//when
List<FindUserFriendsResult> actualResult = findUserFriendsService.doFind(user.getId());
List<FindUserFriendsResponse> actualResult = findAllFriendsService.doService(user.getId());

//then
Assertions.assertThat(actualResult)
Expand Down

0 comments on commit 2c9c03a

Please sign in to comment.