Skip to content

Commit

Permalink
Merge pull request #59 from Seasoning-Today/test/request-friendship-i…
Browse files Browse the repository at this point in the history
…ntegration-test

친구 신청 통합테스트 작성
  • Loading branch information
csct3434 authored Feb 6, 2024
2 parents 13293c2 + cff1fcb commit fa48eb3
Show file tree
Hide file tree
Showing 6 changed files with 241 additions and 13 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ dependencies {

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation 'io.rest-assured:rest-assured'
}

tasks.named('bootBuildImage') {
Expand Down
73 changes: 73 additions & 0 deletions src/test/java/today/seasoning/seasoning/BaseIntegrationTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package today.seasoning.seasoning;

import io.restassured.RestAssured;
import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension;
import org.json.JSONObject;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.util.FileCopyUtils;
import today.seasoning.seasoning.common.util.JwtUtil;

@ActiveProfiles("test")
@ExtendWith(SoftAssertionsExtension.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class BaseIntegrationTest {

static {
System.setProperty("com.amazonaws.sdk.disableEc2Metadata", "true");
}

@Autowired
JdbcTemplate jdbcTemplate;

@LocalServerPort
int port;

@BeforeEach
void setPort() {
// 실제 서블릿 컨테이너 실행을 위한 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));
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();

RequestSpecification request = RestAssured
.given().log().all()
.contentType("application/json")
.header("Authorization", "Bearer " + accessToken);

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

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

}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package today.seasoning.seasoning.friendship.integration;

import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import java.util.List;
import org.assertj.core.api.SoftAssertions;
import org.assertj.core.api.junit.jupiter.InjectSoftAssertions;
import org.json.JSONObject;
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.FriendRequest;
import today.seasoning.seasoning.friendship.domain.FriendRequestRepository;
import today.seasoning.seasoning.friendship.domain.Friendship;
import today.seasoning.seasoning.friendship.domain.FriendshipRepository;
import today.seasoning.seasoning.notification.domain.NotificationRepository;
import today.seasoning.seasoning.user.domain.User;
import today.seasoning.seasoning.user.domain.UserRepository;

@DisplayName("친구 신청 통합 테스트")
public class RequestFriendshipIntegrationTest extends BaseIntegrationTest {

@Autowired
UserRepository userRepository;

@Autowired
FriendshipRepository friendshipRepository;

@Autowired
FriendRequestRepository friendRequestRepository;

@Autowired
NotificationRepository notificationRepository;

@InjectSoftAssertions
SoftAssertions softAssertions;

// API 주소
static String uri = "/friend/add";

// Mock 유저 정보
User user;
User friend;
String friendId;

@BeforeEach
void initMocks() {
user = new User("userNickname", "https://test.org/user.jpg", "user@email.com", LoginType.KAKAO);
friend = new User("friendNickname", "https://test.org/friend.jpg", "friend@email.com", LoginType.KAKAO);
friendId = TsidUtil.toString(friend.getId());
userRepository.saveAll(List.of(user, friend));
}

@Test
@DisplayName("성공")
void success() throws Exception {
//given
JSONObject requestBody = new JSONObject()
.put("id", friendId);

//when
ExtractableResponse<Response> response = post(uri, user.getId(), requestBody);

//then
softAssertions.assertThat(response.statusCode()).isEqualTo(200);
softAssertions.assertThat(checkFriendRequestExists(user, friend)).isTrue();
softAssertions.assertThat(checkFriendRequestExists(friend, user)).isFalse();
softAssertions.assertThat(notificationRepository.count()).isEqualTo(1);
}

@Test
@DisplayName("실패 - 이미 친구인 경우, 409 응답을 한다")
void failedByAlreadyFriends() throws Exception {
//given
friendshipRepository.save(new Friendship(user, friend));
friendshipRepository.save(new Friendship(friend, user));

JSONObject requestBody = new JSONObject()
.put("id", friendId);

//when
ExtractableResponse<Response> response = post(uri, user.getId(), requestBody);

//then
softAssertions.assertThat(response.statusCode()).isEqualTo(409);
softAssertions.assertThat(checkFriendRequestExists(user, friend)).isFalse();
softAssertions.assertThat(notificationRepository.count()).isEqualTo(0);
}

@Test
@DisplayName("실패 - 이미 신청한 경우, 409 응답을 한다")
void failedByDuplicateRequest() throws Exception {
//given
friendRequestRepository.save(new FriendRequest(user, friend));

JSONObject requestBody = new JSONObject()
.put("id", friendId);

//when
ExtractableResponse<Response> response = post(uri, user.getId(), requestBody);

//then
softAssertions.assertThat(response.statusCode()).isEqualTo(409);
softAssertions.assertThat(notificationRepository.count()).isEqualTo(0);
}

@Test
@DisplayName("실패 - 자신에게 신청한 경우, 400 응답을 한다")
void failedBySelfRequest() throws Exception {
//given
JSONObject requestBody = new JSONObject()
.put("id", TsidUtil.toString(user.getId()));

//when
ExtractableResponse<Response> response = post(uri, user.getId(), requestBody);

//then
softAssertions.assertThat(response.statusCode()).isEqualTo(400);
softAssertions.assertThat(checkFriendRequestExists(user, user)).isFalse();
softAssertions.assertThat(notificationRepository.count()).isEqualTo(0);
}

private boolean checkFriendRequestExists(User fromUser, User toUser) {
return friendRequestRepository.existsByFromUserIdAndToUserId(fromUser.getId(), toUser.getId());
}

}
27 changes: 27 additions & 0 deletions src/test/resources/application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
spring:
config:
activate:
on-profile: test
import: secret/application-test-config.yml
datasource:
url: ${DATABASE_URL}
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}
driver-class-name: com.mysql.cj.jdbc.Driver
servlet:
multipart:
max-file-size: ${MAX_FILE_SIZE}
max-request-size: ${MAX_REQUEST_SIZE}
jpa:
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
open-in-view: false
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
logging:
level:
org:
hibernate:
SQL: debug
9 changes: 9 additions & 0 deletions src/test/resources/data/clear.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SET FOREIGN_KEY_CHECKS=0;
DELETE FROM user WHERE TRUE;
DELETE FROM article WHERE TRUE;
DELETE FROM article_image WHERE TRUE;
DELETE FROM article_like WHERE TRUE;
DELETE FROM friend_request WHERE TRUE;
DELETE FROM friendship WHERE TRUE;
DELETE FROM notification WHERE TRUE;
SET FOREIGN_KEY_CHECKS=1;

0 comments on commit fa48eb3

Please sign in to comment.