From daea588b9d7b8c26495dbdc88b1e743bfe0bf4dd Mon Sep 17 00:00:00 2001
From: Wibaek Park <34394229+wibaek@users.noreply.github.com>
Date: Sun, 27 Apr 2025 11:31:28 +0900
Subject: [PATCH 01/90] =?UTF-8?q?chore:=20Alloy=EB=A5=BC=20=EC=9D=B4?=
=?UTF-8?q?=EC=9A=A9=ED=95=9C=20=EB=A1=9C=EA=B9=85=20=EC=B6=94=EA=B0=80=20?=
=?UTF-8?q?(#284)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* chore: logback으로 파일 로깅 설정
* chore: alloy 추가
* fix: EOF 개행
* chore: alloy 설정 적용, env 적용
---
.gitignore | 1 +
docker-compose.prod.yml | 13 ++++++++++
docker-compose.stage.yml | 13 ++++++++++
docs/config.alloy | 37 +++++++++++++++++++++++++++
src/main/resources/logback-spring.xml | 35 +++++++++++++++++++++++++
5 files changed, 99 insertions(+)
create mode 100644 docs/config.alloy
create mode 100644 src/main/resources/logback-spring.xml
diff --git a/.gitignore b/.gitignore
index 9f59fa8d9..d5df4047a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
+logs/
### STS ###
.apt_generated
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index 9517a07aa..30b0c9fc1 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -28,5 +28,18 @@ services:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATA_REDIS_HOST=redis
- SPRING_DATA_REDIS_PORT=6379
+ volumes:
+ - ./logs:/var/log/spring
depends_on:
- redis
+
+ alloy:
+ image: grafana/alloy:latest
+ container_name: alloy
+ ports:
+ - "12345:12345"
+ volumes:
+ - ./logs:/var/log/spring
+ - ./docs/config.alloy:/etc/alloy/config.alloy:ro
+ environment:
+ - ALLOY_ENV=production
diff --git a/docker-compose.stage.yml b/docker-compose.stage.yml
index 3a97a6411..c4ccd687f 100644
--- a/docker-compose.stage.yml
+++ b/docker-compose.stage.yml
@@ -28,6 +28,19 @@ services:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=stage
+ volumes:
+ - ./logs:/var/log/spring
depends_on:
- redis
network_mode: host
+
+ alloy:
+ image: grafana/alloy:latest
+ container_name: alloy
+ ports:
+ - "12345:12345"
+ volumes:
+ - ./logs:/var/log/spring
+ - ./docs/config.alloy:/etc/alloy/config.alloy:ro
+ environment:
+ - ALLOY_ENV=stage
diff --git a/docs/config.alloy b/docs/config.alloy
new file mode 100644
index 000000000..bd3aedf9a
--- /dev/null
+++ b/docs/config.alloy
@@ -0,0 +1,37 @@
+livedebugging {
+ enabled = true
+}
+
+logging {
+ level = "info"
+ format = "logfmt"
+}
+
+local.file_match "spring_logs" {
+ path_targets = [{ __path__ = "/var/log/spring/*.log" }] // 서비스 로그 파일 경로
+}
+
+loki.source.file "spring_source" {
+ targets = local.file_match.spring_logs.targets // 위에서 정의한 로그 파일 경로 사용
+ forward_to = [loki.process.spring_labels.receiver] // 읽은 로그를 처리 단계로 전달
+}
+
+loki.process "spring_labels" {
+ forward_to = [loki.write.grafana_loki.receiver] // 처리된 로그를 Loki로 전송
+
+ stage.static_labels {
+ values = {
+ service = "backend",
+ env = sys.env("ALLOY_ENV"),
+ }
+ }
+}
+
+loki.write "grafana_loki" {
+ endpoint {
+ url = "http://monitor.solid-connection.com:3100/loki/api/v1/push"
+ tenant_id = "fake" // Loki 테넌트 ID (싱글 테넌시이기에 fake로 설정)
+ batch_wait = "1s" // 로그 배치 전송 대기 시간
+ batch_size = "1MB" // 로그 배치 크기
+ }
+}
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
new file mode 100644
index 000000000..390c7c606
--- /dev/null
+++ b/src/main/resources/logback-spring.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+ /var/log/spring/solid-connection-server.log
+
+
+
+ /var/log/spring/solid-connection-server.%d{yyyy-MM-dd}.log
+ 30
+
+
+
+
+ timestamp=%d{yyyy-MM-dd'T'HH:mm:ss.SSS} level=%-5level thread=%thread logger=%logger{36}
+ message=%msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 2ec3edf0c13f313cbd8cd216f7cf2d0e6e2b58db Mon Sep 17 00:00:00 2001
From: Wibaek Park <34394229+wibaek@users.noreply.github.com>
Date: Wed, 30 Apr 2025 11:19:55 +0900
Subject: [PATCH 02/90] =?UTF-8?q?chore:=20dev->local,=20stage->dev=20?=
=?UTF-8?q?=ED=99=98=EA=B2=BD=EB=AA=85=20=EB=B3=80=EA=B2=BD,=20=EB=B0=B0?=
=?UTF-8?q?=ED=8F=AC=20=EB=B0=A9=EC=8B=9D=20=EB=B3=80=EA=B2=BD=20(#288)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* rename: 도커 파일명 변경
* rename: stage -> dev 환경명 변경
* chore: dev환경이 develop 브랜치를 추적하게 변경
---
.github/workflows/{stage-cd.yml => dev-cd.yml} | 6 +++---
docker-compose.stage.yml => docker-compose.dev.yml | 8 ++++----
src/main/resources/logback-spring.xml | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
rename .github/workflows/{stage-cd.yml => dev-cd.yml} (95%)
rename docker-compose.stage.yml => docker-compose.dev.yml (85%)
diff --git a/.github/workflows/stage-cd.yml b/.github/workflows/dev-cd.yml
similarity index 95%
rename from .github/workflows/stage-cd.yml
rename to .github/workflows/dev-cd.yml
index 41ff68b37..793f3dea3 100644
--- a/.github/workflows/stage-cd.yml
+++ b/.github/workflows/dev-cd.yml
@@ -1,8 +1,8 @@
-name: "[STAGE] Build Gradle and Deploy"
+name: "[DEV] Build Gradle and Deploy"
on:
push:
- branches: [ "release" ]
+ branches: [ "develop" ]
workflow_dispatch:
jobs:
@@ -59,7 +59,7 @@ jobs:
host: ${{ secrets.STAGE_HOST }}
username: ${{ secrets.STAGE_USERNAME }}
key: ${{ secrets.STAGE_PRIVATE_KEY }}
- source: "./docker-compose.stage.yml"
+ source: "./docker-compose.dev.yml"
target: "/home/${{ secrets.STAGE_USERNAME }}/solid-connect-stage/"
- name: Run docker compose
diff --git a/docker-compose.stage.yml b/docker-compose.dev.yml
similarity index 85%
rename from docker-compose.stage.yml
rename to docker-compose.dev.yml
index c4ccd687f..a37ef4c55 100644
--- a/docker-compose.stage.yml
+++ b/docker-compose.dev.yml
@@ -19,15 +19,15 @@ services:
- redis
network_mode: host
- solid-connection-stage:
+ solid-connection-dev:
build:
context: .
dockerfile: Dockerfile
- container_name: solid-connection-stage
+ container_name: solid-connection-dev
ports:
- "8080:8080"
environment:
- - SPRING_PROFILES_ACTIVE=stage
+ - SPRING_PROFILES_ACTIVE=dev
volumes:
- ./logs:/var/log/spring
depends_on:
@@ -43,4 +43,4 @@ services:
- ./logs:/var/log/spring
- ./docs/config.alloy:/etc/alloy/config.alloy:ro
environment:
- - ALLOY_ENV=stage
+ - ALLOY_ENV=dev
diff --git a/src/main/resources/logback-spring.xml b/src/main/resources/logback-spring.xml
index 390c7c606..e179be0fb 100644
--- a/src/main/resources/logback-spring.xml
+++ b/src/main/resources/logback-spring.xml
@@ -27,7 +27,7 @@
-
+
From ff0125d87f8fd2b82744549e94ef2034ac33b322 Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Sat, 3 May 2025 18:01:40 +0900
Subject: [PATCH 03/90] =?UTF-8?q?fix:=20=ED=86=A0=ED=81=B0=20=EC=9E=AC?=
=?UTF-8?q?=EB=B0=9C=EA=B8=89=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95=20?=
=?UTF-8?q?(#289)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 함수 분리
- subject의 기준이 SiteUser의 id가 아니게 바뀌더라도 변경 부분이 최소화되게 한다.
- SiteUser의 subject를 사용하는 곳은 accessToken과 refreshToken를 관리하는 AuthTokenProvider 의 영역이므로 이 위치에 함수를 생성한다.
* chore: 사용하지 않는 함수 삭제
* refactor: 가독성을 위해 함수 위치 변경
- parseSubject 가 parseSubjectIgnoringExpiration 보다 먼저 읽히도록
* refactor: 재발급 로직 수정
- subject가 아니라 엑세스 토큰으로 리프레시 토큰을 찾도록
* refactor: 리프레시 토큰 기간 연장
- 참고: discussion #292
* refactor: 액세스 토큰 재발급 로직 수정
* test: authServiceTest 작성
---
.../auth/controller/AuthController.java | 9 +-
.../auth/domain/TokenType.java | 10 +-
.../auth/dto/ReissueRequest.java | 8 ++
.../auth/service/AuthService.java | 19 ++-
.../auth/service/AuthTokenProvider.java | 10 +-
.../solidconnection/util/JwtUtils.java | 8 +-
.../auth/service/AuthServiceTest.java | 108 ++++++++++++++++++
7 files changed, 145 insertions(+), 27 deletions(-)
create mode 100644 src/main/java/com/example/solidconnection/auth/dto/ReissueRequest.java
create mode 100644 src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
index 9c84e8d22..7fe543bd7 100644
--- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
+++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
@@ -3,6 +3,7 @@
import com.example.solidconnection.auth.dto.EmailSignInRequest;
import com.example.solidconnection.auth.dto.EmailSignUpTokenRequest;
import com.example.solidconnection.auth.dto.EmailSignUpTokenResponse;
+import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
import com.example.solidconnection.auth.dto.SignInResponse;
import com.example.solidconnection.auth.dto.SignUpRequest;
@@ -114,13 +115,9 @@ public ResponseEntity quit(
@PostMapping("/reissue")
public ResponseEntity reissueToken(
- Authentication authentication
+ ReissueRequest reissueRequest
) {
- String token = authentication.getCredentials().toString();
- if (token == null) {
- throw new CustomException(ErrorCode.AUTHENTICATION_FAILED, "토큰이 없습니다.");
- }
- ReissueResponse reissueResponse = authService.reissue(token);
+ ReissueResponse reissueResponse = authService.reissue(reissueRequest);
return ResponseEntity.ok(reissueResponse);
}
}
diff --git a/src/main/java/com/example/solidconnection/auth/domain/TokenType.java b/src/main/java/com/example/solidconnection/auth/domain/TokenType.java
index caf1c7a9d..560b0e139 100644
--- a/src/main/java/com/example/solidconnection/auth/domain/TokenType.java
+++ b/src/main/java/com/example/solidconnection/auth/domain/TokenType.java
@@ -5,16 +5,16 @@
@Getter
public enum TokenType {
- ACCESS("ACCESS:", 1000 * 60 * 60), // 1hour
- REFRESH("REFRESH:", 1000 * 60 * 60 * 24 * 7), // 7days
+ ACCESS("ACCESS:", 1000L * 60 * 60), // 1hour
+ REFRESH("REFRESH:", 1000L * 60 * 60 * 24 * 90), // 90days
BLACKLIST("BLACKLIST:", ACCESS.expireTime),
- SIGN_UP("SIGN_UP:", 1000 * 60 * 10), // 10min
+ SIGN_UP("SIGN_UP:", 1000L * 60 * 10), // 10min
;
private final String prefix;
- private final int expireTime;
+ private final long expireTime;
- TokenType(String prefix, int expireTime) {
+ TokenType(String prefix, long expireTime) {
this.prefix = prefix;
this.expireTime = expireTime;
}
diff --git a/src/main/java/com/example/solidconnection/auth/dto/ReissueRequest.java b/src/main/java/com/example/solidconnection/auth/dto/ReissueRequest.java
new file mode 100644
index 000000000..00443255d
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/dto/ReissueRequest.java
@@ -0,0 +1,8 @@
+package com.example.solidconnection.auth.dto;
+
+import jakarta.validation.constraints.NotBlank;
+
+public record ReissueRequest(
+ @NotBlank(message = "리프레시 토큰과 함께 요청해주세요.")
+ String refreshToken) {
+}
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthService.java b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
index 04bcadde7..289893dbf 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
@@ -1,7 +1,9 @@
package com.example.solidconnection.auth.service;
+import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
+import com.example.solidconnection.config.security.JwtProperties;
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.RequiredArgsConstructor;
@@ -9,15 +11,18 @@
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
+import java.util.Objects;
import java.util.Optional;
import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
+import static com.example.solidconnection.util.JwtUtils.parseSubject;
@RequiredArgsConstructor
@Service
public class AuthService {
private final AuthTokenProvider authTokenProvider;
+ private final JwtProperties jwtProperties;
/*
* 로그아웃 한다.
@@ -40,13 +45,15 @@ public void quit(SiteUser siteUser) {
/*
* 액세스 토큰을 재발급한다.
- * - 리프레시 토큰이 만료되었거나, 존재하지 않는다면 예외 응답을 반환한다.
- * - 리프레시 토큰이 존재한다면, 액세스 토큰을 재발급한다.
+ * - 요청된 리프레시 토큰과 동일한 subject 의 토큰이 저장되어 있으며 값이 일치할 경우, 액세스 토큰을 재발급한다.
+ * - 그렇지 않으면 예외를 반환한다.
* */
- public ReissueResponse reissue(String subject) {
- // 리프레시 토큰 만료 확인
- Optional optionalRefreshToken = authTokenProvider.findRefreshToken(subject);
- if (optionalRefreshToken.isEmpty()) {
+ public ReissueResponse reissue(ReissueRequest reissueRequest) {
+ // 리프레시 토큰 확인
+ String requestedRefreshToken = reissueRequest.refreshToken();
+ String subject = parseSubject(requestedRefreshToken, jwtProperties.secret());
+ Optional savedRefreshToken = authTokenProvider.findRefreshToken(subject);
+ if (!Objects.equals(requestedRefreshToken, savedRefreshToken.orElse(null))) {
throw new CustomException(REFRESH_TOKEN_EXPIRED);
}
// 액세스 토큰 재발급
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
index da040a8d5..b682a4b39 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
@@ -8,8 +8,6 @@
import java.util.Optional;
-import static com.example.solidconnection.util.JwtUtils.parseSubjectIgnoringExpiration;
-
@Component
public class AuthTokenProvider extends TokenProvider {
@@ -18,7 +16,7 @@ public AuthTokenProvider(JwtProperties jwtProperties, RedisTemplate findBlackListToken(String subject) {
return Optional.ofNullable(redisTemplate.opsForValue().get(blackListTokenKey));
}
- public String getEmail(String token) {
- return parseSubjectIgnoringExpiration(token, jwtProperties.secret());
+ private String getSubject(SiteUser siteUser) {
+ return siteUser.getId().toString();
}
}
diff --git a/src/main/java/com/example/solidconnection/util/JwtUtils.java b/src/main/java/com/example/solidconnection/util/JwtUtils.java
index d3ea8fed9..d295f2a3e 100644
--- a/src/main/java/com/example/solidconnection/util/JwtUtils.java
+++ b/src/main/java/com/example/solidconnection/util/JwtUtils.java
@@ -28,19 +28,19 @@ public static String parseTokenFromRequest(HttpServletRequest request) {
return token.substring(TOKEN_PREFIX.length());
}
- public static String parseSubjectIgnoringExpiration(String token, String secretKey) {
+ public static String parseSubject(String token, String secretKey) {
try {
return parseClaims(token, secretKey).getSubject();
- } catch (ExpiredJwtException e) {
- return e.getClaims().getSubject();
} catch (Exception e) {
throw new CustomException(INVALID_TOKEN);
}
}
- public static String parseSubject(String token, String secretKey) {
+ public static String parseSubjectIgnoringExpiration(String token, String secretKey) {
try {
return parseClaims(token, secretKey).getSubject();
+ } catch (ExpiredJwtException e) {
+ return e.getClaims().getSubject();
} catch (Exception e) {
throw new CustomException(INVALID_TOKEN);
}
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
new file mode 100644
index 000000000..0030e45e2
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
@@ -0,0 +1,108 @@
+package com.example.solidconnection.auth.service;
+
+import com.example.solidconnection.auth.domain.TokenType;
+import com.example.solidconnection.auth.dto.ReissueRequest;
+import com.example.solidconnection.auth.dto.ReissueResponse;
+import com.example.solidconnection.config.security.JwtProperties;
+import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
+import com.example.solidconnection.type.PreparationStatus;
+import com.example.solidconnection.type.Role;
+import com.example.solidconnection.util.JwtUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.time.LocalDate;
+
+import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+
+@DisplayName("인증 서비스 테스트")
+@TestContainerSpringBootTest
+class AuthServiceTest {
+
+ @Autowired
+ private AuthService authService;
+
+ @Autowired
+ private AuthTokenProvider authTokenProvider;
+
+ @Autowired
+ private SiteUserRepository siteUserRepository;
+
+ @Autowired
+ private JwtProperties jwtProperties;
+
+ @Test
+ void 로그아웃한다() {
+ // given
+ String accessToken = "accessToken";
+
+ // when
+ authService.signOut(accessToken);
+
+ // then
+ assertThat(authTokenProvider.findBlackListToken(accessToken)).isNotNull();
+ }
+
+ @Test
+ void 탈퇴한다() {
+ // given
+ SiteUser siteUser = createSiteUser();
+
+ // when
+ authService.quit(siteUser);
+
+ // then
+ LocalDate tomorrow = LocalDate.now().plusDays(1);
+ assertThat(siteUser.getQuitedAt()).isEqualTo(tomorrow);
+ }
+
+ @Nested
+ class 토큰을_재발급한다 {
+
+ @Test
+ void 요청의_리프레시_토큰이_저장되어_있고_값이_일치면_액세스_토큰을_재발급한다() {
+ // given
+ SiteUser siteUser = createSiteUser();
+ String refreshToken = authTokenProvider.generateAndSaveRefreshToken(siteUser);
+ ReissueRequest reissueRequest = new ReissueRequest(refreshToken);
+
+ // when
+ ReissueResponse reissuedAccessToken = authService.reissue(reissueRequest);
+
+ // then
+ String actualSubject = JwtUtils.parseSubject(reissuedAccessToken.accessToken(), jwtProperties.secret());
+ String expectedSubject = JwtUtils.parseSubject(refreshToken, jwtProperties.secret());
+ assertThat(actualSubject).isEqualTo(expectedSubject);
+ }
+
+ @Test
+ void 요청의_리프레시_토큰이_저장되어있지_않다면_예외_응답을_반환한다() {
+ // given
+ String refreshToken = authTokenProvider.generateToken("subject", TokenType.REFRESH);
+ ReissueRequest reissueRequest = new ReissueRequest(refreshToken);
+
+ // when, then
+ assertThatCode(() -> authService.reissue(reissueRequest))
+ .isInstanceOf(CustomException.class)
+ .hasMessage(REFRESH_TOKEN_EXPIRED.getMessage());
+ }
+ }
+
+ private SiteUser createSiteUser() {
+ SiteUser siteUser = new SiteUser(
+ "test@example.com",
+ "nickname",
+ "profileImageUrl",
+ PreparationStatus.CONSIDERING,
+ Role.MENTEE
+ );
+ return siteUserRepository.save(siteUser);
+ }
+}
From 8a3885b6e15152ca2dd526168f5c5d2ef9849097 Mon Sep 17 00:00:00 2001
From: Wibaek Park <34394229+wibaek@users.noreply.github.com>
Date: Mon, 5 May 2025 09:04:54 +0900
Subject: [PATCH 04/90] =?UTF-8?q?chore:=20=EC=9B=8C=ED=81=AC=ED=94=8C?=
=?UTF-8?q?=EB=A1=9C=EC=9A=B0=20=EA=B2=BD=EB=A1=9C,=20=ED=99=98=EA=B2=BD?=
=?UTF-8?q?=EB=B3=80=EC=88=98=20=EB=B3=80=EA=B2=BD=20(#291)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* chore: 워크플로우 경로, 환경변수 변경
* chore: 환경변수 최신화
stage -> dev 변경
---
.github/workflows/dev-cd.yml | 34 +++++++++++++++++-----------------
src/main/resources/secret | 2 +-
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml
index 793f3dea3..1efa6d266 100644
--- a/.github/workflows/dev-cd.yml
+++ b/.github/workflows/dev-cd.yml
@@ -38,38 +38,38 @@ jobs:
- name: Copy jar file to remote
uses: appleboy/scp-action@master
with:
- host: ${{ secrets.STAGE_HOST }}
- username: ${{ secrets.STAGE_USERNAME }}
- key: ${{ secrets.STAGE_PRIVATE_KEY }}
+ host: ${{ secrets.DEV_HOST }}
+ username: ${{ secrets.DEV_USERNAME }}
+ key: ${{ secrets.DEV_PRIVATE_KEY }}
source: "./build/libs/*.jar"
- target: "/home/${{ secrets.STAGE_USERNAME }}/solid-connect-stage/"
+ target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/"
- name: Copy docker file to remote
uses: appleboy/scp-action@master
with:
- host: ${{ secrets.STAGE_HOST }}
- username: ${{ secrets.STAGE_USERNAME }}
- key: ${{ secrets.STAGE_PRIVATE_KEY }}
+ host: ${{ secrets.DEV_HOST }}
+ username: ${{ secrets.DEV_USERNAME }}
+ key: ${{ secrets.DEV_PRIVATE_KEY }}
source: "./Dockerfile"
- target: "/home/${{ secrets.STAGE_USERNAME }}/solid-connect-stage/"
+ target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/"
- name: Copy docker compose file to remote
uses: appleboy/scp-action@master
with:
- host: ${{ secrets.STAGE_HOST }}
- username: ${{ secrets.STAGE_USERNAME }}
- key: ${{ secrets.STAGE_PRIVATE_KEY }}
+ host: ${{ secrets.DEV_HOST }}
+ username: ${{ secrets.DEV_USERNAME }}
+ key: ${{ secrets.DEV_PRIVATE_KEY }}
source: "./docker-compose.dev.yml"
- target: "/home/${{ secrets.STAGE_USERNAME }}/solid-connect-stage/"
+ target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/"
- name: Run docker compose
uses: appleboy/ssh-action@master
with:
- host: ${{ secrets.STAGE_HOST }}
- username: ${{ secrets.STAGE_USERNAME }}
- key: ${{ secrets.STAGE_PRIVATE_KEY }}
+ host: ${{ secrets.DEV_HOST }}
+ username: ${{ secrets.DEV_USERNAME }}
+ key: ${{ secrets.DEV_PRIVATE_KEY }}
script_stop: true
script: |
- cd /home/${{ secrets.STAGE_USERNAME }}/solid-connect-stage
+ cd /home/${{ secrets.DEV_USERNAME }}/solid-connection-dev
docker compose down
- docker compose -f docker-compose.stage.yml up -d --build
+ docker compose -f docker-compose.dev.yml up -d --build
diff --git a/src/main/resources/secret b/src/main/resources/secret
index 661dc50f2..cbb94e8df 160000
--- a/src/main/resources/secret
+++ b/src/main/resources/secret
@@ -1 +1 @@
-Subproject commit 661dc50f2915b20525a2a00b2b7f6473775f3dc1
+Subproject commit cbb94e8dfd95b773decd4193c2821284bdde8adc
From fe0c2c05968c21420de73b18dfdba6dda05f7426 Mon Sep 17 00:00:00 2001
From: Wibaek Park <34394229+wibaek@users.noreply.github.com>
Date: Tue, 6 May 2025 11:39:08 +0900
Subject: [PATCH 05/90] =?UTF-8?q?fix:=20Alloy=20=EC=84=A4=EC=A0=95?=
=?UTF-8?q?=ED=8C=8C=EC=9D=BC=EC=9D=B4=20=EB=B0=B0=ED=8F=AC=EC=8B=9C?=
=?UTF-8?q?=EC=97=90=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=90=98=EC=A7=80=20?=
=?UTF-8?q?=EC=95=8A=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20?=
=?UTF-8?q?(#295)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* chore: alloy config 파일을 배포시에 전송하게 변경
* chore: alloy container 실행시 config 파일 위치 변경
---
.github/workflows/dev-cd.yml | 9 +++++++++
.github/workflows/prod-cd.yml | 11 ++++++++++-
docker-compose.dev.yml | 2 +-
docker-compose.prod.yml | 2 +-
4 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/dev-cd.yml b/.github/workflows/dev-cd.yml
index 1efa6d266..b86b541e1 100644
--- a/.github/workflows/dev-cd.yml
+++ b/.github/workflows/dev-cd.yml
@@ -62,6 +62,15 @@ jobs:
source: "./docker-compose.dev.yml"
target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/"
+ - name: Copy alloy config file to remote
+ uses: appleboy/scp-action@master
+ with:
+ host: ${{ secrets.DEV_HOST }}
+ username: ${{ secrets.DEV_USERNAME }}
+ key: ${{ secrets.DEV_PRIVATE_KEY }}
+ source: "./docs/config.alloy"
+ target: "/home/${{ secrets.DEV_USERNAME }}/solid-connection-dev/"
+
- name: Run docker compose
uses: appleboy/ssh-action@master
with:
diff --git a/.github/workflows/prod-cd.yml b/.github/workflows/prod-cd.yml
index 9030c80f5..354128b77 100644
--- a/.github/workflows/prod-cd.yml
+++ b/.github/workflows/prod-cd.yml
@@ -61,7 +61,16 @@ jobs:
key: ${{ secrets.PRIVATE_KEY }}
source: "./docker-compose.prod.yml"
target: "/home/${{ secrets.USERNAME }}/solid-connect-server/"
-
+
+ - name: Copy alloy config file to remote
+ uses: appleboy/scp-action@master
+ with:
+ host: ${{ secrets.HOST }}
+ username: ${{ secrets.USERNAME }}
+ key: ${{ secrets.PRIVATE_KEY }}
+ source: "./docs/config.alloy"
+ target: "/home/${{ secrets.USERNAME }}/solid-connect-server/"
+
- name: Run docker compose
uses: appleboy/ssh-action@master
with:
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index a37ef4c55..e66e3a201 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -41,6 +41,6 @@ services:
- "12345:12345"
volumes:
- ./logs:/var/log/spring
- - ./docs/config.alloy:/etc/alloy/config.alloy:ro
+ - ./config.alloy:/etc/alloy/config.alloy:ro
environment:
- ALLOY_ENV=dev
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index 30b0c9fc1..a6952f72c 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -40,6 +40,6 @@ services:
- "12345:12345"
volumes:
- ./logs:/var/log/spring
- - ./docs/config.alloy:/etc/alloy/config.alloy:ro
+ - ./config.alloy:/etc/alloy/config.alloy:ro
environment:
- ALLOY_ENV=production
From 9713f5179075e3827bfb4075d5f1a690d10165f6 Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Sat, 10 May 2025 00:29:27 +0900
Subject: [PATCH 06/90] =?UTF-8?q?refactor:=20=EB=AC=B8=EC=9E=90=EC=97=B4?=
=?UTF-8?q?=20=ED=86=A0=ED=81=B0=EC=9D=84=20Token=20=ED=81=B4=EB=9E=98?=
=?UTF-8?q?=EC=8A=A4=EB=A1=9C=20(#297)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 토큰 객체 생성
* refactor: authTokenProvider에 토큰 객체 적용
* refactor: authService에 토큰 객체 적용
* refactor: signInService에 토큰 객체 적용
* test: AuthTokenProvider 테스트 보충
* test: AuthService 테스트 보충
* refactor: 인터페이스로 DIP 구현
* test: 리프레시토큰 조회 함수 변경에 따른 테스트 수정
* test: 블랙리스트 저장 방법 변경에 따른 테스트 수정
* test: 깨진 테스트 수정
* refactor: 엑세스 토큰 자체를 블랙리스트로 저장하도록
* refactor: AuthController에서 인증 정보를 String으로 받도록
---
.../auth/controller/AuthController.java | 6 +-
.../auth/dto/ReissueResponse.java | 9 +-
.../auth/dto/SignInResponse.java | 7 +
.../auth/service/AccessToken.java | 11 ++
.../auth/service/AuthService.java | 24 +--
.../auth/service/AuthTokenProvider.java | 63 ++++---
.../auth/service/BlacklistChecker.java | 6 +
.../auth/service/RefreshToken.java | 11 ++
.../auth/service/SignInService.java | 7 +-
.../solidconnection/auth/service/Subject.java | 6 +
.../security/filter/SignOutCheckFilter.java | 6 +-
.../auth/service/AuthServiceTest.java | 29 ++-
.../auth/service/AuthTokenProviderTest.java | 167 ++++++------------
.../auth/service/SignInServiceTest.java | 10 +-
.../filter/SignOutCheckFilterTest.java | 4 +-
15 files changed, 182 insertions(+), 184 deletions(-)
create mode 100644 src/main/java/com/example/solidconnection/auth/service/AccessToken.java
create mode 100644 src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java
create mode 100644 src/main/java/com/example/solidconnection/auth/service/RefreshToken.java
create mode 100644 src/main/java/com/example/solidconnection/auth/service/Subject.java
diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
index 7fe543bd7..c4b9127d5 100644
--- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
+++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
@@ -97,11 +97,11 @@ public ResponseEntity signUp(
public ResponseEntity signOut(
Authentication authentication
) {
- String token = authentication.getCredentials().toString();
- if (token == null) {
+ String accessToken = (String) authentication.getCredentials();
+ if (accessToken == null || accessToken.isBlank()) {
throw new CustomException(ErrorCode.AUTHENTICATION_FAILED, "토큰이 없습니다.");
}
- authService.signOut(token);
+ authService.signOut(accessToken);
return ResponseEntity.ok().build();
}
diff --git a/src/main/java/com/example/solidconnection/auth/dto/ReissueResponse.java b/src/main/java/com/example/solidconnection/auth/dto/ReissueResponse.java
index 48b55e6cb..972470cca 100644
--- a/src/main/java/com/example/solidconnection/auth/dto/ReissueResponse.java
+++ b/src/main/java/com/example/solidconnection/auth/dto/ReissueResponse.java
@@ -1,5 +1,12 @@
package com.example.solidconnection.auth.dto;
+import com.example.solidconnection.auth.service.AccessToken;
+
public record ReissueResponse(
- String accessToken) {
+ String accessToken
+) {
+
+ public static ReissueResponse from(AccessToken accessToken) {
+ return new ReissueResponse(accessToken.token());
+ }
}
diff --git a/src/main/java/com/example/solidconnection/auth/dto/SignInResponse.java b/src/main/java/com/example/solidconnection/auth/dto/SignInResponse.java
index a4ae442e2..b01fdd369 100644
--- a/src/main/java/com/example/solidconnection/auth/dto/SignInResponse.java
+++ b/src/main/java/com/example/solidconnection/auth/dto/SignInResponse.java
@@ -1,7 +1,14 @@
package com.example.solidconnection.auth.dto;
+import com.example.solidconnection.auth.service.AccessToken;
+import com.example.solidconnection.auth.service.RefreshToken;
+
public record SignInResponse(
String accessToken,
String refreshToken
) {
+
+ public static SignInResponse of(AccessToken accessToken, RefreshToken refreshToken) {
+ return new SignInResponse(accessToken.token(), refreshToken.token());
+ }
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/AccessToken.java b/src/main/java/com/example/solidconnection/auth/service/AccessToken.java
new file mode 100644
index 000000000..c94e891aa
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/service/AccessToken.java
@@ -0,0 +1,11 @@
+package com.example.solidconnection.auth.service;
+
+public record AccessToken(
+ Subject subject,
+ String token
+) {
+
+ public AccessToken(String subject, String token) {
+ this(new Subject(subject), token);
+ }
+}
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthService.java b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
index 289893dbf..86220d863 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
@@ -1,9 +1,7 @@
package com.example.solidconnection.auth.service;
-
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
-import com.example.solidconnection.config.security.JwtProperties;
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.RequiredArgsConstructor;
@@ -11,25 +9,22 @@
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
-import java.util.Objects;
-import java.util.Optional;
import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
-import static com.example.solidconnection.util.JwtUtils.parseSubject;
@RequiredArgsConstructor
@Service
public class AuthService {
private final AuthTokenProvider authTokenProvider;
- private final JwtProperties jwtProperties;
/*
* 로그아웃 한다.
* - 엑세스 토큰을 블랙리스트에 추가한다.
* */
- public void signOut(String accessToken) {
- authTokenProvider.generateAndSaveBlackListToken(accessToken);
+ public void signOut(String token) {
+ AccessToken accessToken = authTokenProvider.toAccessToken(token);
+ authTokenProvider.addToBlacklist(accessToken);
}
/*
@@ -45,19 +40,18 @@ public void quit(SiteUser siteUser) {
/*
* 액세스 토큰을 재발급한다.
- * - 요청된 리프레시 토큰과 동일한 subject 의 토큰이 저장되어 있으며 값이 일치할 경우, 액세스 토큰을 재발급한다.
- * - 그렇지 않으면 예외를 반환한다.
+ * - 유효한 리프레시토큰이면, 액세스 토큰을 재발급한다.
+ * - 그렇지 않으면 예외를 발생시킨다.
* */
public ReissueResponse reissue(ReissueRequest reissueRequest) {
// 리프레시 토큰 확인
String requestedRefreshToken = reissueRequest.refreshToken();
- String subject = parseSubject(requestedRefreshToken, jwtProperties.secret());
- Optional savedRefreshToken = authTokenProvider.findRefreshToken(subject);
- if (!Objects.equals(requestedRefreshToken, savedRefreshToken.orElse(null))) {
+ if (!authTokenProvider.isValidRefreshToken(requestedRefreshToken)) {
throw new CustomException(REFRESH_TOKEN_EXPIRED);
}
// 액세스 토큰 재발급
- String newAccessToken = authTokenProvider.generateAccessToken(subject);
- return new ReissueResponse(newAccessToken);
+ Subject subject = authTokenProvider.parseSubject(requestedRefreshToken);
+ AccessToken newAccessToken = authTokenProvider.generateAccessToken(subject);
+ return ReissueResponse.from(newAccessToken);
}
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
index b682a4b39..d44f3bc8f 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
@@ -3,49 +3,68 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.config.security.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.util.JwtUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
-import java.util.Optional;
+import java.util.Objects;
@Component
-public class AuthTokenProvider extends TokenProvider {
+public class AuthTokenProvider extends TokenProvider implements BlacklistChecker {
public AuthTokenProvider(JwtProperties jwtProperties, RedisTemplate redisTemplate) {
super(jwtProperties, redisTemplate);
}
- public String generateAccessToken(SiteUser siteUser) {
- String subject = getSubject(siteUser);
- return generateToken(subject, TokenType.ACCESS);
+ public AccessToken generateAccessToken(Subject subject) {
+ String token = generateToken(subject.value(), TokenType.ACCESS);
+ return new AccessToken(subject, token);
}
- public String generateAccessToken(String subject) {
- return generateToken(subject, TokenType.ACCESS);
+ public RefreshToken generateAndSaveRefreshToken(Subject subject) {
+ String token = generateToken(subject.value(), TokenType.REFRESH);
+ saveToken(token, TokenType.REFRESH);
+ return new RefreshToken(subject, token);
}
- public String generateAndSaveRefreshToken(SiteUser siteUser) {
- String subject = getSubject(siteUser);
- String refreshToken = generateToken(subject, TokenType.REFRESH);
- return saveToken(refreshToken, TokenType.REFRESH);
+ /*
+ * 액세스 토큰을 블랙리스트에 저장한다.
+ * - key = BLACKLIST:{accessToken}
+ * - value = "signOut" -> key 의 존재만 확인하므로, value 에는 무슨 값이 들어가도 상관없다.
+ * */
+ public void addToBlacklist(AccessToken accessToken) {
+ String blackListKey = TokenType.BLACKLIST.addPrefix(accessToken.token());
+ redisTemplate.opsForValue().set(blackListKey, "signOut");
}
- public String generateAndSaveBlackListToken(String accessToken) {
- String blackListToken = generateToken(accessToken, TokenType.BLACKLIST);
- return saveToken(blackListToken, TokenType.BLACKLIST);
+ /*
+ * 유효한 리프레시 토큰인지 확인한다.
+ * - 요청된 토큰과 같은 subject 의 리프레시 토큰을 조회한다.
+ * - 조회된 리프레시 토큰과 요청된 토큰이 같은지 비교한다.
+ * */
+ public boolean isValidRefreshToken(String requestedRefreshToken) {
+ String subject = JwtUtils.parseSubject(requestedRefreshToken, jwtProperties.secret());
+ String refreshTokenKey = TokenType.REFRESH.addPrefix(subject);
+ String foundRefreshToken = redisTemplate.opsForValue().get(refreshTokenKey);
+ return Objects.equals(requestedRefreshToken, foundRefreshToken);
}
- public Optional findRefreshToken(String subject) {
- String refreshTokenKey = TokenType.REFRESH.addPrefix(subject);
- return Optional.ofNullable(redisTemplate.opsForValue().get(refreshTokenKey));
+ @Override
+ public boolean isTokenBlacklisted(String accessToken) {
+ String blackListTokenKey = TokenType.BLACKLIST.addPrefix(accessToken);
+ return redisTemplate.hasKey(blackListTokenKey);
+ }
+
+ public Subject parseSubject(String token) {
+ String subject = JwtUtils.parseSubject(token, jwtProperties.secret());
+ return new Subject(subject);
}
- public Optional findBlackListToken(String subject) {
- String blackListTokenKey = TokenType.BLACKLIST.addPrefix(subject);
- return Optional.ofNullable(redisTemplate.opsForValue().get(blackListTokenKey));
+ public Subject toSubject(SiteUser siteUser) {
+ return new Subject(siteUser.getId().toString());
}
- private String getSubject(SiteUser siteUser) {
- return siteUser.getId().toString();
+ public AccessToken toAccessToken(String token) {
+ return new AccessToken(parseSubject(token), token);
}
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java b/src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java
new file mode 100644
index 000000000..b4e174906
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java
@@ -0,0 +1,6 @@
+package com.example.solidconnection.auth.service;
+
+public interface BlacklistChecker {
+
+ boolean isTokenBlacklisted(String token);
+}
diff --git a/src/main/java/com/example/solidconnection/auth/service/RefreshToken.java b/src/main/java/com/example/solidconnection/auth/service/RefreshToken.java
new file mode 100644
index 000000000..2aac3ad8c
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/service/RefreshToken.java
@@ -0,0 +1,11 @@
+package com.example.solidconnection.auth.service;
+
+public record RefreshToken(
+ Subject subject,
+ String token
+) {
+
+ RefreshToken(String subject, String token) {
+ this(new Subject(subject), token);
+ }
+}
diff --git a/src/main/java/com/example/solidconnection/auth/service/SignInService.java b/src/main/java/com/example/solidconnection/auth/service/SignInService.java
index 820d2e573..c2b129214 100644
--- a/src/main/java/com/example/solidconnection/auth/service/SignInService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/SignInService.java
@@ -15,9 +15,10 @@ public class SignInService {
@Transactional
public SignInResponse signIn(SiteUser siteUser) {
resetQuitedAt(siteUser);
- String accessToken = authTokenProvider.generateAccessToken(siteUser);
- String refreshToken = authTokenProvider.generateAndSaveRefreshToken(siteUser);
- return new SignInResponse(accessToken, refreshToken);
+ Subject subject = authTokenProvider.toSubject(siteUser);
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
+ RefreshToken refreshToken = authTokenProvider.generateAndSaveRefreshToken(subject);
+ return SignInResponse.of(accessToken, refreshToken);
}
private void resetQuitedAt(SiteUser siteUser) {
diff --git a/src/main/java/com/example/solidconnection/auth/service/Subject.java b/src/main/java/com/example/solidconnection/auth/service/Subject.java
new file mode 100644
index 000000000..2c03eb013
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/service/Subject.java
@@ -0,0 +1,6 @@
+package com.example.solidconnection.auth.service;
+
+public record Subject(
+ String value
+) {
+}
diff --git a/src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java b/src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java
index 2cef8d1ac..a111a7292 100644
--- a/src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java
+++ b/src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.custom.security.filter;
-import com.example.solidconnection.auth.service.AuthTokenProvider;
+import com.example.solidconnection.auth.service.BlacklistChecker;
import com.example.solidconnection.custom.exception.CustomException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
@@ -20,7 +20,7 @@
@RequiredArgsConstructor
public class SignOutCheckFilter extends OncePerRequestFilter {
- private final AuthTokenProvider authTokenProvider;
+ private final BlacklistChecker tokenBlacklistChecker;
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request,
@@ -34,6 +34,6 @@ protected void doFilterInternal(@NonNull HttpServletRequest request,
}
private boolean hasSignedOut(String accessToken) {
- return authTokenProvider.findBlackListToken(accessToken).isPresent();
+ return tokenBlacklistChecker.isTokenBlacklisted(accessToken);
}
}
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
index 0030e45e2..759c90d88 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
@@ -1,16 +1,13 @@
package com.example.solidconnection.auth.service;
-import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
-import com.example.solidconnection.config.security.JwtProperties;
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.type.PreparationStatus;
import com.example.solidconnection.type.Role;
-import com.example.solidconnection.util.JwtUtils;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -35,19 +32,16 @@ class AuthServiceTest {
@Autowired
private SiteUserRepository siteUserRepository;
- @Autowired
- private JwtProperties jwtProperties;
-
@Test
void 로그아웃한다() {
// given
- String accessToken = "accessToken";
+ AccessToken accessToken = authTokenProvider.generateAccessToken(new Subject("subject")); // todo: #296
// when
- authService.signOut(accessToken);
+ authService.signOut(accessToken.token());
// then
- assertThat(authTokenProvider.findBlackListToken(accessToken)).isNotNull();
+ assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue();
}
@Test
@@ -67,26 +61,25 @@ class AuthServiceTest {
class 토큰을_재발급한다 {
@Test
- void 요청의_리프레시_토큰이_저장되어_있고_값이_일치면_액세스_토큰을_재발급한다() {
+ void 요청의_리프레시_토큰이_저장되어_있으면_액세스_토큰을_재발급한다() {
// given
- SiteUser siteUser = createSiteUser();
- String refreshToken = authTokenProvider.generateAndSaveRefreshToken(siteUser);
- ReissueRequest reissueRequest = new ReissueRequest(refreshToken);
+ RefreshToken refreshToken = authTokenProvider.generateAndSaveRefreshToken(new Subject("subject"));
+ ReissueRequest reissueRequest = new ReissueRequest(refreshToken.token());
// when
ReissueResponse reissuedAccessToken = authService.reissue(reissueRequest);
- // then
- String actualSubject = JwtUtils.parseSubject(reissuedAccessToken.accessToken(), jwtProperties.secret());
- String expectedSubject = JwtUtils.parseSubject(refreshToken, jwtProperties.secret());
+ // then - 요청의 리프레시 토큰과 재발급한 액세스 토큰의 subject 가 동일해야 한다.
+ Subject expectedSubject = authTokenProvider.parseSubject(refreshToken.token());
+ Subject actualSubject = authTokenProvider.parseSubject(reissuedAccessToken.accessToken());
assertThat(actualSubject).isEqualTo(expectedSubject);
}
@Test
void 요청의_리프레시_토큰이_저장되어있지_않다면_예외_응답을_반환한다() {
// given
- String refreshToken = authTokenProvider.generateToken("subject", TokenType.REFRESH);
- ReissueRequest reissueRequest = new ReissueRequest(refreshToken);
+ String invalidRefreshToken = authTokenProvider.generateAccessToken(new Subject("subject")).token();
+ ReissueRequest reissueRequest = new ReissueRequest(invalidRefreshToken);
// when, then
assertThatCode(() -> authService.reissue(reissueRequest))
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
index 57a9ea789..2a0bd9b73 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
@@ -1,14 +1,7 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.auth.domain.TokenType;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
-import com.example.solidconnection.util.JwtUtils;
-import io.jsonwebtoken.Jwts;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -16,8 +9,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
-import java.util.Optional;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
@@ -28,157 +19,105 @@ class AuthTokenProviderTest {
@Autowired
private AuthTokenProvider authTokenProvider;
- @Autowired
- private SiteUserRepository siteUserRepository;
-
@Autowired
private RedisTemplate redisTemplate;
- @Autowired
- private JwtProperties jwtProperties;
-
- private SiteUser siteUser;
- private String subject;
+ private Subject subject;
@BeforeEach
void setUp() {
- siteUser = createSiteUser();
- siteUserRepository.save(siteUser);
- subject = siteUser.getId().toString();
+ subject = new Subject("subject123");
}
- @Nested
- class 액세스_토큰을_제공한다 {
-
- @Test
- void SiteUser_로_액세스_토큰을_생성한다() {
- // when
- String token = authTokenProvider.generateAccessToken(siteUser);
-
- // then
- String actualSubject = JwtUtils.parseSubject(token, jwtProperties.secret());
- assertThat(actualSubject).isEqualTo(subject);
- }
-
- @Test
- void subject_로_액세스_토큰을_생성한다() {
- // given
- String subject = "subject123";
-
- // when
- String token = authTokenProvider.generateAccessToken(subject);
+ @Test
+ void 액세스_토큰을_생성한다() {
+ // when
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
- // then
- String actualSubject = JwtUtils.parseSubject(token, jwtProperties.secret());
- assertThat(actualSubject).isEqualTo(subject);
- }
+ // then
+ String actualSubject = authTokenProvider.parseSubject(accessToken.token()).value();
+ assertThat(actualSubject).isEqualTo(subject.value());
}
@Nested
class 리프레시_토큰을_제공한다 {
@Test
- void SiteUser_로_리프레시_토큰을_생성하고_저장한다() {
+ void 리프레시_토큰을_생성하고_저장한다() {
// when
- String refreshToken = authTokenProvider.generateAndSaveRefreshToken(siteUser);
+ RefreshToken actualRefreshToken = authTokenProvider.generateAndSaveRefreshToken(subject);
// then
- String actualSubject = JwtUtils.parseSubject(refreshToken, jwtProperties.secret());
- String refreshTokenKey = TokenType.REFRESH.addPrefix(subject);
+ String actualSubject = authTokenProvider.parseSubject(actualRefreshToken.token()).value();
+ String refreshTokenKey = TokenType.REFRESH.addPrefix(subject.value());
+ String expectedRefreshToken = redisTemplate.opsForValue().get(refreshTokenKey);
assertAll(
- () -> assertThat(actualSubject).isEqualTo(subject),
- () -> assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isEqualTo(refreshToken)
+ () -> assertThat(actualSubject).isEqualTo(subject.value()),
+ () -> assertThat(actualRefreshToken.token()).isEqualTo(expectedRefreshToken)
);
}
@Test
- void 저장된_리프레시_토큰을_조회한다() {
+ void 유효한_리프레시_토큰인지_확인한다() {
// given
- String refreshToken = "refreshToken";
- redisTemplate.opsForValue().set(TokenType.REFRESH.addPrefix(subject), refreshToken);
+ RefreshToken refreshToken = authTokenProvider.generateAndSaveRefreshToken(subject);
+ AccessToken fakeRefreshToken = authTokenProvider.generateAccessToken(subject); // todo: issue#296
- // when
- Optional optionalRefreshToken = authTokenProvider.findRefreshToken(subject);
-
- // then
- assertThat(optionalRefreshToken.get()).isEqualTo(refreshToken);
- }
-
- @Test
- void 저장되지_않은_리프레시_토큰을_조회한다() {
- // when
- Optional optionalRefreshToken = authTokenProvider.findRefreshToken(subject);
-
- // then
- assertThat(optionalRefreshToken).isEmpty();
+ // when, then
+ assertAll(
+ () -> assertThat(authTokenProvider.isValidRefreshToken(refreshToken.token())).isTrue(),
+ () -> assertThat(authTokenProvider.isValidRefreshToken(fakeRefreshToken.token())).isFalse()
+ );
}
}
@Nested
- class 블랙리스트_토큰을_제공한다 {
-
- @Test
- void 엑세스_토큰으로_블랙리스트_토큰을_생성하고_저장한다() {
- // when
- String accessToken = "accessToken";
- String blackListToken = authTokenProvider.generateAndSaveBlackListToken(accessToken);
-
- // then
- String actualSubject = JwtUtils.parseSubject(blackListToken, jwtProperties.secret());
- String blackListTokenKey = TokenType.BLACKLIST.addPrefix(accessToken);
- assertAll(
- () -> assertThat(actualSubject).isEqualTo(accessToken),
- () -> assertThat(redisTemplate.opsForValue().get(blackListTokenKey)).isEqualTo(blackListToken)
- );
- }
+ class 블랙리스트를_관리한다 {
@Test
- void 저장된_블랙리스트_토큰을_조회한다() {
+ void 액세스_토큰을_블랙리스트에_추가한다() {
// given
- String accessToken = "accessToken";
- String blackListToken = "token";
- redisTemplate.opsForValue().set(TokenType.BLACKLIST.addPrefix(accessToken), blackListToken);
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: issue#296
// when
- Optional optionalBlackListToken = authTokenProvider.findBlackListToken(accessToken);
+ authTokenProvider.addToBlacklist(accessToken);
// then
- assertThat(optionalBlackListToken).hasValue(blackListToken);
+ String blackListTokenKey = TokenType.BLACKLIST.addPrefix(accessToken.token());
+ String foundBlackListToken = redisTemplate.opsForValue().get(blackListTokenKey);
+ assertThat(foundBlackListToken).isNotNull();
}
+ /*
+ * todo: JwtUtils 나 TokenProvider 를 스프링 빈으로 주입받도록 변경한다. (issue#296)
+ * - 아래 테스트 코드에서는, 내부적으로 JwtUtils.parseSubject() 메서드가 호출될 때 발생하는 예외를 피하기 위해 jwt토큰을 생성한다.
+ * - 테스트 작성자는 예외 발생을 피하기 위해 "제대로된 jwt 토큰 생성이 필요하다"는 것을 몰라야한다.
+ * - 따라서, JwtUtils 나 TokenProvider 를 스프링 빈으로 주입받도록 변경하고, 테스트에서 mock 을 사용하여 의존성을 끊을 필요가 있다.
+ */
@Test
- void 저장되지_않은_블랙리스트_토큰을_조회한다() {
- // when
- Optional optionalBlackListToken = authTokenProvider.findBlackListToken("accessToken");
+ void 블랙리스트에_있는_토큰인지_확인한다() {
+ // given
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
+ authTokenProvider.addToBlacklist(accessToken);
+ AccessToken notRegisteredAccessToken = authTokenProvider.generateAccessToken(new Subject("!"));
- // then
- assertThat(optionalBlackListToken).isEmpty();
+ // when, then
+ assertAll(
+ () -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue(),
+ () -> assertThat(authTokenProvider.isTokenBlacklisted(notRegisteredAccessToken.token())).isFalse()
+ );
}
}
@Test
- void 토큰을_생성한다() {
+ void 토큰으로부터_Subject_를_추출한다() {
+ // given
+ String accessToken = authTokenProvider.generateAccessToken(subject).token();
+
// when
- String subject = "subject123";
- String token = authTokenProvider.generateToken(subject, TokenType.ACCESS);
+ Subject actualSubject = authTokenProvider.parseSubject(accessToken);
// then
- String extractedSubject = Jwts.parser()
- .setSigningKey(jwtProperties.secret())
- .parseClaimsJws(token)
- .getBody()
- .getSubject();
- assertThat(subject).isEqualTo(extractedSubject);
- }
-
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
+ assertThat(actualSubject.value()).isEqualTo(subject.value());
}
}
diff --git a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
index 6136bbee2..e40f20b7a 100644
--- a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
@@ -1,5 +1,6 @@
package com.example.solidconnection.auth.service;
+import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.SignInResponse;
import com.example.solidconnection.config.security.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
@@ -12,9 +13,9 @@
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
import java.time.LocalDate;
-import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
@@ -35,6 +36,9 @@ class SignInServiceTest {
@Autowired
private SiteUserRepository siteUserRepository;
+ @Autowired
+ private RedisTemplate redisTemplate;
+
private SiteUser siteUser;
private String subject;
@@ -53,11 +57,11 @@ void setUp() {
// then
String accessTokenSubject = JwtUtils.parseSubject(signInResponse.accessToken(), jwtProperties.secret());
String refreshTokenSubject = JwtUtils.parseSubject(signInResponse.refreshToken(), jwtProperties.secret());
- Optional savedRefreshToken = authTokenProvider.findRefreshToken(subject);
+ String savedRefreshToken = redisTemplate.opsForValue().get(TokenType.REFRESH.addPrefix(refreshTokenSubject));
assertAll(
() -> assertThat(accessTokenSubject).isEqualTo(subject),
() -> assertThat(refreshTokenSubject).isEqualTo(subject),
- () -> assertThat(savedRefreshToken).hasValue(signInResponse.refreshToken()));
+ () -> assertThat(savedRefreshToken).isEqualTo(signInResponse.refreshToken()));
}
@Test
diff --git a/src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java b/src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java
index a11d8d28a..e76a01c75 100644
--- a/src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java
+++ b/src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java
@@ -55,12 +55,12 @@ void setUp() {
}
@Test
- void 로그아웃한_토큰이면_예외를_응답한다() throws Exception {
+ void 로그아웃한_토큰이면_예외를_응답한다() {
// given
String token = createToken(subject);
request = createRequest(token);
String refreshTokenKey = BLACKLIST.addPrefix(token);
- redisTemplate.opsForValue().set(refreshTokenKey, "signOut");
+ redisTemplate.opsForValue().set(refreshTokenKey, token);
// when & then
assertThatCode(() -> signOutCheckFilter.doFilterInternal(request, response, filterChain))
From 3b16bda82a54b7cae6a8dc6c7c8f18a3677b1a60 Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Sun, 11 May 2025 01:44:38 +0900
Subject: [PATCH 07/90] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=95=84?=
=?UTF-8?q?=EC=9B=83,=20=ED=83=88=ED=87=B4=20=EC=8B=9C=20refresh=20?=
=?UTF-8?q?=ED=86=A0=ED=81=B0=EC=9D=84=20=EC=82=AD=EC=A0=9C=ED=95=98?=
=?UTF-8?q?=EB=8F=84=EB=A1=9D=20(#303)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: 액세스 토큰에 해당하는 리프레시 토큰 삭제 함수 구현
* refactor: 로그아웃 시, 리프레시 토큰 삭제하도록
* refactor: 탈퇴 시, 로그아웃하도록
* refactor: 엑세스 토큰 가져오는 함수 분리
- Authentication 자체가 null 인 경우도 예외처리
---
.../auth/controller/AuthController.java | 18 ++++++++-----
.../auth/service/AuthService.java | 8 ++++--
.../auth/service/AuthTokenProvider.java | 6 +++++
.../auth/service/AuthServiceTest.java | 26 ++++++++++++++++---
.../auth/service/AuthTokenProviderTest.java | 14 ++++++++++
5 files changed, 60 insertions(+), 12 deletions(-)
diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
index c4b9127d5..0df89426e 100644
--- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
+++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
@@ -97,19 +97,18 @@ public ResponseEntity signUp(
public ResponseEntity signOut(
Authentication authentication
) {
- String accessToken = (String) authentication.getCredentials();
- if (accessToken == null || accessToken.isBlank()) {
- throw new CustomException(ErrorCode.AUTHENTICATION_FAILED, "토큰이 없습니다.");
- }
+ String accessToken = getAccessToken(authentication);
authService.signOut(accessToken);
return ResponseEntity.ok().build();
}
@PatchMapping("/quit")
public ResponseEntity quit(
- @AuthorizedUser SiteUser siteUser
+ @AuthorizedUser SiteUser siteUser,
+ Authentication authentication // todo: #299를 작업하며 인자를 (Authentication authentication)만 받도록 수정해야 함
) {
- authService.quit(siteUser);
+ String accessToken = getAccessToken(authentication);
+ authService.quit(siteUser, accessToken);
return ResponseEntity.ok().build();
}
@@ -120,4 +119,11 @@ public ResponseEntity reissueToken(
ReissueResponse reissueResponse = authService.reissue(reissueRequest);
return ResponseEntity.ok(reissueResponse);
}
+
+ private String getAccessToken(Authentication authentication) {
+ if (authentication == null || !(authentication.getCredentials() instanceof String accessToken)) {
+ throw new CustomException(ErrorCode.AUTHENTICATION_FAILED, "엑세스 토큰이 없습니다.");
+ }
+ return accessToken;
+ }
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthService.java b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
index 86220d863..50926ca93 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
@@ -19,11 +19,13 @@ public class AuthService {
private final AuthTokenProvider authTokenProvider;
/*
- * 로그아웃 한다.
+ * 로그아웃한다.
* - 엑세스 토큰을 블랙리스트에 추가한다.
+ * - 리프레시 토큰을 삭제한다.
* */
public void signOut(String token) {
AccessToken accessToken = authTokenProvider.toAccessToken(token);
+ authTokenProvider.deleteRefreshTokenByAccessToken(accessToken);
authTokenProvider.addToBlacklist(accessToken);
}
@@ -31,11 +33,13 @@ public void signOut(String token) {
* 탈퇴한다.
* - 탈퇴한 시점의 다음날을 탈퇴일로 잡는다.
* - e.g. 2024-01-01 18:00 탈퇴 시, 2024-01-02 00:00 가 탈퇴일이 된다.
+ * - 로그아웃한다.
* */
@Transactional
- public void quit(SiteUser siteUser) {
+ public void quit(SiteUser siteUser, String token) { // todo: #299를 작업하며 인자를 (String token)만 받도록 수정해야 함
LocalDate tomorrow = LocalDate.now().plusDays(1);
siteUser.setQuitedAt(tomorrow);
+ signOut(token);
}
/*
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
index d44f3bc8f..2e43e8be9 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
@@ -49,6 +49,12 @@ public boolean isValidRefreshToken(String requestedRefreshToken) {
return Objects.equals(requestedRefreshToken, foundRefreshToken);
}
+ public void deleteRefreshTokenByAccessToken(AccessToken accessToken) {
+ String subject = accessToken.subject().value();
+ String refreshTokenKey = TokenType.REFRESH.addPrefix(subject);
+ redisTemplate.delete(refreshTokenKey);
+ }
+
@Override
public boolean isTokenBlacklisted(String accessToken) {
String blackListTokenKey = TokenType.BLACKLIST.addPrefix(accessToken);
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
index 759c90d88..18c7c4ef0 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
@@ -1,5 +1,6 @@
package com.example.solidconnection.auth.service;
+import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
import com.example.solidconnection.custom.exception.CustomException;
@@ -12,12 +13,14 @@
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
import java.time.LocalDate;
import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.jupiter.api.Assertions.assertAll;
@DisplayName("인증 서비스 테스트")
@TestContainerSpringBootTest
@@ -32,29 +35,44 @@ class AuthServiceTest {
@Autowired
private SiteUserRepository siteUserRepository;
+ @Autowired
+ private RedisTemplate redisTemplate;
+
@Test
void 로그아웃한다() {
// given
- AccessToken accessToken = authTokenProvider.generateAccessToken(new Subject("subject")); // todo: #296
+ Subject subject = new Subject("subject");
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: #296
// when
authService.signOut(accessToken.token());
// then
- assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue();
+ String refreshTokenKey = TokenType.REFRESH.addPrefix(subject.value());
+ assertAll(
+ () -> assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isNull(),
+ () -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue()
+ );
}
@Test
void 탈퇴한다() {
// given
SiteUser siteUser = createSiteUser();
+ Subject subject = authTokenProvider.toSubject(siteUser);
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: #296
// when
- authService.quit(siteUser);
+ authService.quit(siteUser, accessToken.token());
// then
LocalDate tomorrow = LocalDate.now().plusDays(1);
- assertThat(siteUser.getQuitedAt()).isEqualTo(tomorrow);
+ String refreshTokenKey = TokenType.REFRESH.addPrefix(subject.value());
+ assertAll(
+ () -> assertThat(siteUser.getQuitedAt()).isEqualTo(tomorrow),
+ () -> assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isNull(),
+ () -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue()
+ );
}
@Nested
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
index 2a0bd9b73..dc35ab3a7 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
@@ -69,6 +69,20 @@ class 리프레시_토큰을_제공한다 {
() -> assertThat(authTokenProvider.isValidRefreshToken(fakeRefreshToken.token())).isFalse()
);
}
+
+ @Test
+ void 액세서_토큰에_해당하는_리프레시_토큰을_삭제한다() {
+ // given
+ authTokenProvider.generateAndSaveRefreshToken(subject);
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
+
+ // when
+ authTokenProvider.deleteRefreshTokenByAccessToken(accessToken);
+
+ // then
+ String refreshTokenKey = TokenType.REFRESH.addPrefix(subject.value());
+ assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isNull();
+ }
}
@Nested
From 75d5d24a357b1f94d8b86a5d16ec3ff3ba839d2d Mon Sep 17 00:00:00 2001
From: Wibaek Park <34394229+wibaek@users.noreply.github.com>
Date: Sun, 11 May 2025 12:59:29 +0900
Subject: [PATCH 08/90] =?UTF-8?q?fix:=20Alloy=20=EC=98=A4=EB=A5=98=20?=
=?UTF-8?q?=EC=88=98=EC=A0=95=20(#305)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docker-compose.dev.yml | 2 +-
docker-compose.prod.yml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml
index e66e3a201..a37ef4c55 100644
--- a/docker-compose.dev.yml
+++ b/docker-compose.dev.yml
@@ -41,6 +41,6 @@ services:
- "12345:12345"
volumes:
- ./logs:/var/log/spring
- - ./config.alloy:/etc/alloy/config.alloy:ro
+ - ./docs/config.alloy:/etc/alloy/config.alloy:ro
environment:
- ALLOY_ENV=dev
diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml
index a6952f72c..30b0c9fc1 100644
--- a/docker-compose.prod.yml
+++ b/docker-compose.prod.yml
@@ -40,6 +40,6 @@ services:
- "12345:12345"
volumes:
- ./logs:/var/log/spring
- - ./config.alloy:/etc/alloy/config.alloy:ro
+ - ./docs/config.alloy:/etc/alloy/config.alloy:ro
environment:
- ALLOY_ENV=production
From bf97db45e44475dd1df8f48f9171be21d358c08c Mon Sep 17 00:00:00 2001
From: Wibaek Park <34394229+wibaek@users.noreply.github.com>
Date: Sun, 11 May 2025 13:01:49 +0900
Subject: [PATCH 09/90] =?UTF-8?q?feat:=20News=20=EC=86=8C=EC=8B=9D?=
=?UTF-8?q?=EC=A7=80=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=B6=94=EA=B0=80=20?=
=?UTF-8?q?(#302)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: News 소식지 도메인 추가
BaseEntity를 상속한 이유는 이후에 유저도 소식지를 쓸 수 있게 되면 필요할 것이라 추정되기에
* chore: import 수정
* feat: 뉴스 테이블 생성 Flyway 스키마 추가
* chore: Flyway 파일 포매팅
---
README.md | Bin 1154 -> 1114 bytes
.../solidconnection/news/domain/News.java | 32 ++++++++++++++++++
.../db/migration/V12__create_news.sql | 10 ++++++
3 files changed, 42 insertions(+)
create mode 100644 src/main/java/com/example/solidconnection/news/domain/News.java
create mode 100644 src/main/resources/db/migration/V12__create_news.sql
diff --git a/README.md b/README.md
index a07f6d77b95a903a0b2ef7d7e620278d8a540a83..5f4bcca59e9278564cbc50a3068a7f104325fce2 100644
GIT binary patch
delta 73
zcmZqTyu~rWXQD@lsRDxngDwy!Fz7MpGvqMjGbA%40_k`lozIZVPyi&08B&4#QXpFo
T$j)F;*v!Zn$+S6)S%(n-MHUYX
delta 93
zcmcb`(Zo5yXJSAAt1g2AL&C&Tc}HD_G$1pDA)g_cA)6tUp@=~j$jWEPWhelW#Xu1~
jh8(bLB9PW&s07O70CkiC
Date: Sun, 11 May 2025 20:47:34 +0900
Subject: [PATCH 10/90] =?UTF-8?q?fix:=20=EB=88=84=EB=9D=BD=ED=95=9C=20?=
=?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80=20(#309)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../example/solidconnection/auth/controller/AuthController.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
index 0df89426e..553ef4063 100644
--- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
+++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
@@ -114,7 +114,7 @@ public ResponseEntity quit(
@PostMapping("/reissue")
public ResponseEntity reissueToken(
- ReissueRequest reissueRequest
+ @Valid @RequestBody ReissueRequest reissueRequest
) {
ReissueResponse reissueResponse = authService.reissue(reissueRequest);
return ResponseEntity.ok(reissueResponse);
From c0f79cc4a4d12db4cfe9121650ec0040d0408ed6 Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Sun, 11 May 2025 22:38:45 +0900
Subject: [PATCH 11/90] =?UTF-8?q?refactor:=20=EB=A7=8C=EB=A3=8C=EB=90=9C?=
=?UTF-8?q?=20=ED=86=A0=ED=81=B0=20=ED=97=88=EC=9A=A9=ED=95=98=EB=8A=94=20?=
=?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20(#308)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 만료된 토큰도 허용하는 코드 삭제
* test: 만료된 토큰과 관련된 테스트 코드 삭제
* test: 삭제된 테스트와의 연관성 제거
- 삭제된 테스트 코드와 연관된 테스트 함수명, 구조 수정
---
.../security/AuthenticationManagerConfig.java | 5 +-
.../config/web/WebMvcConfig.java | 3 -
.../exception/JwtExpiredTokenException.java | 10 ---
.../custom/resolver/ExpiredToken.java | 12 ---
.../custom/resolver/ExpiredTokenResolver.java | 35 --------
.../ExpiredTokenAuthentication.java | 19 -----
.../filter/JwtAuthenticationFilter.java | 7 --
.../ExpiredTokenAuthenticationProvider.java | 35 --------
.../solidconnection/util/JwtUtils.java | 26 ------
.../resolver/ExpiredTokenResolverTest.java | 43 ----------
.../ExpiredTokenAuthenticationTest.java | 64 ---------------
.../filter/JwtAuthenticationFilterTest.java | 52 ++++--------
...xpiredTokenAuthenticationProviderTest.java | 80 ------------------
.../solidconnection/util/JwtUtilsTest.java | 81 +------------------
14 files changed, 17 insertions(+), 455 deletions(-)
delete mode 100644 src/main/java/com/example/solidconnection/custom/exception/JwtExpiredTokenException.java
delete mode 100644 src/main/java/com/example/solidconnection/custom/resolver/ExpiredToken.java
delete mode 100644 src/main/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolver.java
delete mode 100644 src/main/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthentication.java
delete mode 100644 src/main/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProvider.java
delete mode 100644 src/test/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolverTest.java
delete mode 100644 src/test/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthenticationTest.java
delete mode 100644 src/test/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProviderTest.java
diff --git a/src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java b/src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java
index 785283d7d..e4af023b7 100644
--- a/src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java
+++ b/src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java
@@ -1,6 +1,5 @@
package com.example.solidconnection.config.security;
-import com.example.solidconnection.custom.security.provider.ExpiredTokenAuthenticationProvider;
import com.example.solidconnection.custom.security.provider.SiteUserAuthenticationProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
@@ -13,13 +12,11 @@
public class AuthenticationManagerConfig {
private final SiteUserAuthenticationProvider siteUserAuthenticationProvider;
- private final ExpiredTokenAuthenticationProvider expiredTokenAuthenticationProvider;
@Bean
public AuthenticationManager authenticationManager() {
return new ProviderManager(
- siteUserAuthenticationProvider,
- expiredTokenAuthenticationProvider
+ siteUserAuthenticationProvider
);
}
}
diff --git a/src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java b/src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java
index 6d16694cc..7f56e320f 100644
--- a/src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java
+++ b/src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java
@@ -2,7 +2,6 @@
import com.example.solidconnection.custom.resolver.AuthorizedUserResolver;
import com.example.solidconnection.custom.resolver.CustomPageableHandlerMethodArgumentResolver;
-import com.example.solidconnection.custom.resolver.ExpiredTokenResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@@ -15,14 +14,12 @@
public class WebMvcConfig implements WebMvcConfigurer {
private final AuthorizedUserResolver authorizedUserResolver;
- private final ExpiredTokenResolver expiredTokenResolver;
private final CustomPageableHandlerMethodArgumentResolver customPageableHandlerMethodArgumentResolver;
@Override
public void addArgumentResolvers(List resolvers) {
resolvers.addAll(List.of(
authorizedUserResolver,
- expiredTokenResolver,
customPageableHandlerMethodArgumentResolver
));
}
diff --git a/src/main/java/com/example/solidconnection/custom/exception/JwtExpiredTokenException.java b/src/main/java/com/example/solidconnection/custom/exception/JwtExpiredTokenException.java
deleted file mode 100644
index b0a52e9fa..000000000
--- a/src/main/java/com/example/solidconnection/custom/exception/JwtExpiredTokenException.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package com.example.solidconnection.custom.exception;
-
-import org.springframework.security.core.AuthenticationException;
-
-public class JwtExpiredTokenException extends AuthenticationException {
-
- public JwtExpiredTokenException(String msg) {
- super(msg);
- }
-}
diff --git a/src/main/java/com/example/solidconnection/custom/resolver/ExpiredToken.java b/src/main/java/com/example/solidconnection/custom/resolver/ExpiredToken.java
deleted file mode 100644
index 5de4ad95a..000000000
--- a/src/main/java/com/example/solidconnection/custom/resolver/ExpiredToken.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.example.solidconnection.custom.resolver;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-// todo: 사용되지 않음, 다른 PR에서 삭제하고 더 효율적인 구조를 고민해봐야 함
-@Target({ElementType.PARAMETER})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface ExpiredToken {
-}
diff --git a/src/main/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolver.java b/src/main/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolver.java
deleted file mode 100644
index 7547a1d61..000000000
--- a/src/main/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolver.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.example.solidconnection.custom.resolver;
-
-import com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication;
-import lombok.RequiredArgsConstructor;
-import org.springframework.core.MethodParameter;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.stereotype.Component;
-import org.springframework.web.bind.support.WebDataBinderFactory;
-import org.springframework.web.context.request.NativeWebRequest;
-import org.springframework.web.method.support.HandlerMethodArgumentResolver;
-import org.springframework.web.method.support.ModelAndViewContainer;
-
-// todo: 사용되지 않음, 다른 PR에서 삭제하고 더 효율적인 구조를 고민해봐야 함
-@Component
-@RequiredArgsConstructor
-public class ExpiredTokenResolver implements HandlerMethodArgumentResolver {
-
- @Override
- public boolean supportsParameter(MethodParameter parameter) {
- return parameter.hasParameterAnnotation(ExpiredToken.class)
- && parameter.getParameterType().equals(ExpiredTokenAuthentication.class);
- }
-
- @Override
- public Object resolveArgument(MethodParameter parameter,
- ModelAndViewContainer mavContainer,
- NativeWebRequest webRequest,
- WebDataBinderFactory binderFactory) throws Exception {
- try {
- return SecurityContextHolder.getContext().getAuthentication();
- } catch (Exception e) {
- return null;
- }
- }
-}
diff --git a/src/main/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthentication.java b/src/main/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthentication.java
deleted file mode 100644
index 061484674..000000000
--- a/src/main/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthentication.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.example.solidconnection.custom.security.authentication;
-
-// todo: 사용되지 않음, 다른 PR에서 삭제하고 더 효율적인 구조를 고민해봐야 함
-public class ExpiredTokenAuthentication extends JwtAuthentication {
-
- public ExpiredTokenAuthentication(String token) {
- super(token, null);
- setAuthenticated(false);
- }
-
- public ExpiredTokenAuthentication(String token, String subject) {
- super(token, subject);
- setAuthenticated(false);
- }
-
- public String getSubject() {
- return (String) getPrincipal();
- }
-}
diff --git a/src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java
index 3f5bce556..d9d8efd65 100644
--- a/src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java
+++ b/src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java
@@ -1,7 +1,5 @@
package com.example.solidconnection.custom.security.filter;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication;
import com.example.solidconnection.custom.security.authentication.JwtAuthentication;
import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
import jakarta.servlet.FilterChain;
@@ -18,7 +16,6 @@
import java.io.IOException;
-import static com.example.solidconnection.util.JwtUtils.isExpired;
import static com.example.solidconnection.util.JwtUtils.parseTokenFromRequest;
@@ -26,7 +23,6 @@
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
- private final JwtProperties jwtProperties;
private final AuthenticationManager authenticationManager;
@Override
@@ -47,9 +43,6 @@ public void doFilterInternal(@NonNull HttpServletRequest request,
}
private JwtAuthentication createAuthentication(String token) {
- if (isExpired(token, jwtProperties.secret())) {
- return new ExpiredTokenAuthentication(token);
- }
return new SiteUserAuthentication(token);
}
}
diff --git a/src/main/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProvider.java b/src/main/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProvider.java
deleted file mode 100644
index 01b065a19..000000000
--- a/src/main/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProvider.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.example.solidconnection.custom.security.provider;
-
-
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication;
-import com.example.solidconnection.custom.security.authentication.JwtAuthentication;
-import lombok.RequiredArgsConstructor;
-import org.springframework.security.authentication.AuthenticationProvider;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.stereotype.Component;
-
-import static com.example.solidconnection.util.JwtUtils.parseSubjectIgnoringExpiration;
-
-// todo: 사용되지 않음, 다른 PR에서 삭제하고 더 효율적인 구조를 고민해봐야 함
-@Component
-@RequiredArgsConstructor
-public class ExpiredTokenAuthenticationProvider implements AuthenticationProvider {
-
- private final JwtProperties jwtProperties;
-
- @Override
- public Authentication authenticate(Authentication auth) throws AuthenticationException {
- JwtAuthentication jwtAuth = (JwtAuthentication) auth;
- String token = jwtAuth.getToken();
- String subject = parseSubjectIgnoringExpiration(token, jwtProperties.secret());
-
- return new ExpiredTokenAuthentication(token, subject);
- }
-
- @Override
- public boolean supports(Class> authentication) {
- return ExpiredTokenAuthentication.class.isAssignableFrom(authentication);
- }
-}
diff --git a/src/main/java/com/example/solidconnection/util/JwtUtils.java b/src/main/java/com/example/solidconnection/util/JwtUtils.java
index d295f2a3e..a5c96d092 100644
--- a/src/main/java/com/example/solidconnection/util/JwtUtils.java
+++ b/src/main/java/com/example/solidconnection/util/JwtUtils.java
@@ -7,8 +7,6 @@
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
-import java.util.Date;
-
import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_TOKEN;
@Component
@@ -35,30 +33,6 @@ public static String parseSubject(String token, String secretKey) {
throw new CustomException(INVALID_TOKEN);
}
}
-
- public static String parseSubjectIgnoringExpiration(String token, String secretKey) {
- try {
- return parseClaims(token, secretKey).getSubject();
- } catch (ExpiredJwtException e) {
- return e.getClaims().getSubject();
- } catch (Exception e) {
- throw new CustomException(INVALID_TOKEN);
- }
- }
-
- public static boolean isExpired(String token, String secretKey) {
- try {
- Date expiration = Jwts.parser()
- .setSigningKey(secretKey)
- .parseClaimsJws(token)
- .getBody()
- .getExpiration();
- return expiration.before(new Date());
- } catch (Exception e) {
- return true;
- }
- }
-
public static Claims parseClaims(String token, String secretKey) throws ExpiredJwtException {
return Jwts.parser()
.setSigningKey(secretKey)
diff --git a/src/test/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolverTest.java b/src/test/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolverTest.java
deleted file mode 100644
index a0393dbc7..000000000
--- a/src/test/java/com/example/solidconnection/custom/resolver/ExpiredTokenResolverTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package com.example.solidconnection.custom.resolver;
-
-import com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication;
-import com.example.solidconnection.support.TestContainerSpringBootTest;
-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 org.springframework.security.core.context.SecurityContextHolder;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-@TestContainerSpringBootTest
-@DisplayName("만료된 토큰 argument resolver 테스트")
-class ExpiredTokenResolverTest {
-
- @BeforeEach
- void setUp() {
- SecurityContextHolder.clearContext();
- }
-
- @Autowired
- private ExpiredTokenResolver expiredTokenResolver;
-
- @Test
- void security_context_에_저장된_만료시간을_검증하지_않는_토큰을_반환한다() throws Exception {
- // given
- ExpiredTokenAuthentication authentication = new ExpiredTokenAuthentication("token");
- SecurityContextHolder.getContext().setAuthentication(authentication);
-
- // when
- ExpiredTokenAuthentication expiredTokenAuthentication = (ExpiredTokenAuthentication) expiredTokenResolver.resolveArgument(null, null, null, null);
-
- // then
- assertThat(expiredTokenAuthentication.getToken()).isEqualTo("token");
- }
-
- @Test
- void security_context_에_저장된_만료시간을_검증하지_않는_토큰이_없으면_null_을_반환한다() throws Exception {
- // when, then
- assertThat(expiredTokenResolver.resolveArgument(null, null, null, null)).isNull();
- }
-}
diff --git a/src/test/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthenticationTest.java b/src/test/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthenticationTest.java
deleted file mode 100644
index 9ef78d0c7..000000000
--- a/src/test/java/com/example/solidconnection/custom/security/authentication/ExpiredTokenAuthenticationTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-package com.example.solidconnection.custom.security.authentication;
-
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-
-import java.util.Date;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
-
-@DisplayName("만료된 토큰 인증 정보 테스트")
-class ExpiredTokenAuthenticationTest {
-
- @Test
- void 인증_정보에_저장된_토큰을_반환한다() {
- // given
- String token = "token123";
- ExpiredTokenAuthentication auth = new ExpiredTokenAuthentication(token);
-
- // when
- String result = auth.getToken();
-
- // then
- assertThat(result).isEqualTo(token);
- }
-
- @Test
- void 인증_정보에_저장된_토큰의_subject_를_반환한다() {
- // given
- String subject = "subject321";
- String token = createToken(subject);
- ExpiredTokenAuthentication auth = new ExpiredTokenAuthentication(token, subject);
-
- // when
- String result = auth.getSubject();
-
- // then
- assertThat(result).isEqualTo(subject);
- }
-
- @Test
- void 항상_isAuthenticated_는_false_를_반환한다() {
- // given
- ExpiredTokenAuthentication auth1 = new ExpiredTokenAuthentication("token");
- ExpiredTokenAuthentication auth2 = new ExpiredTokenAuthentication("token", "subject");
-
- // when & then
- assertAll(
- () -> assertThat(auth1.isAuthenticated()).isFalse(),
- () -> assertThat(auth2.isAuthenticated()).isFalse()
- );
- }
-
- private String createToken(String subject) {
- return Jwts.builder()
- .setSubject(subject)
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() + 1000))
- .signWith(SignatureAlgorithm.HS256, "secret")
- .compact();
- }
-}
diff --git a/src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java b/src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java
index cbca9c5f2..61e4c9170 100644
--- a/src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java
+++ b/src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java
@@ -1,7 +1,6 @@
package com.example.solidconnection.custom.security.filter;
import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication;
import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
import com.example.solidconnection.custom.security.userdetails.SiteUserDetailsService;
import com.example.solidconnection.support.TestContainerSpringBootTest;
@@ -12,7 +11,6 @@
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.mock.mockito.MockBean;
@@ -36,7 +34,7 @@ class JwtAuthenticationFilterTest {
@Autowired
private JwtProperties jwtProperties;
- @MockBean
+ @MockBean // 이 테스트코드에서 사용자를 조회할 필요는 없으므로 MockBean 으로 대체
private SiteUserDetailsService siteUserDetailsService;
private HttpServletRequest request;
@@ -63,40 +61,20 @@ void setUp() {
then(filterChain).should().doFilter(request, response);
}
- @Nested
- class 토큰이_있으면_컨텍스트에_저장한다 {
-
- @Test
- void 유효한_토큰을_컨텍스트에_저장한다() throws Exception {
- // given
- Date validExpiration = new Date(System.currentTimeMillis() + 1000);
- String token = createTokenWithExpiration(validExpiration);
- request = createRequestWithToken(token);
-
- // when
- jwtAuthenticationFilter.doFilterInternal(request, response, filterChain);
-
- // then
- assertThat(SecurityContextHolder.getContext().getAuthentication())
- .isExactlyInstanceOf(SiteUserAuthentication.class);
- then(filterChain).should().doFilter(request, response);
- }
-
- @Test
- void 만료된_토큰을_컨텍스트에_저장한다() throws Exception {
- // given
- Date invalidExpiration = new Date(System.currentTimeMillis() - 1000);
- String token = createTokenWithExpiration(invalidExpiration);
- request = createRequestWithToken(token);
-
- // when
- jwtAuthenticationFilter.doFilterInternal(request, response, filterChain);
-
- // then
- assertThat(SecurityContextHolder.getContext().getAuthentication())
- .isExactlyInstanceOf(ExpiredTokenAuthentication.class);
- then(filterChain).should().doFilter(request, response);
- }
+ @Test
+ void 토큰이_있으면_컨텍스트에_저장한다() throws Exception {
+ // given
+ Date validExpiration = new Date(System.currentTimeMillis() + 1000);
+ String token = createTokenWithExpiration(validExpiration);
+ request = createRequestWithToken(token);
+
+ // when
+ jwtAuthenticationFilter.doFilterInternal(request, response, filterChain);
+
+ // then
+ assertThat(SecurityContextHolder.getContext().getAuthentication())
+ .isExactlyInstanceOf(SiteUserAuthentication.class);
+ then(filterChain).should().doFilter(request, response);
}
private String createTokenWithExpiration(Date expiration) {
diff --git a/src/test/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProviderTest.java b/src/test/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProviderTest.java
deleted file mode 100644
index ad6053359..000000000
--- a/src/test/java/com/example/solidconnection/custom/security/provider/ExpiredTokenAuthenticationProviderTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.example.solidconnection.custom.security.provider;
-
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.security.authentication.ExpiredTokenAuthentication;
-import com.example.solidconnection.support.TestContainerSpringBootTest;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.core.Authentication;
-
-import java.net.PasswordAuthentication;
-import java.util.Date;
-
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_TOKEN;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.junit.jupiter.api.Assertions.*;
-
-@TestContainerSpringBootTest
-@DisplayName("만료된 토큰 provider 테스트")
-class ExpiredTokenAuthenticationProviderTest {
-
- @Autowired
- private ExpiredTokenAuthenticationProvider expiredTokenAuthenticationProvider;
-
- @Autowired
- private JwtProperties jwtProperties;
-
- @Test
- void 처리할_수_있는_타입인지를_반환한다() {
- // given
- Class> supportedType = ExpiredTokenAuthentication.class;
- Class> notSupportedType = PasswordAuthentication.class;
-
- // when & then
- assertAll(
- () -> assertTrue(expiredTokenAuthenticationProvider.supports(supportedType)),
- () -> assertFalse(expiredTokenAuthenticationProvider.supports(notSupportedType))
- );
- }
-
- @Test
- void 만료된_토큰의_인증_정보를_반환한다() {
- // given
- String expiredToken = createExpiredToken();
- ExpiredTokenAuthentication ExpiredTokenAuthentication = new ExpiredTokenAuthentication(expiredToken);
-
- // when
- Authentication result = expiredTokenAuthenticationProvider.authenticate(ExpiredTokenAuthentication);
-
- // then
- assertAll(
- () -> assertThat(result).isInstanceOf(ExpiredTokenAuthentication.class),
- () -> assertThat(result.isAuthenticated()).isFalse()
- );
- }
-
- @Test
- void 유효하지_않은_토큰이면_예외_응답을_반환한다() {
- // given
- ExpiredTokenAuthentication ExpiredTokenAuthentication = new ExpiredTokenAuthentication("invalid token");
-
- // when & then
- assertThatCode(() -> expiredTokenAuthenticationProvider.authenticate(ExpiredTokenAuthentication))
- .isInstanceOf(CustomException.class)
- .hasMessageContaining(INVALID_TOKEN.getMessage());
- }
-
- private String createExpiredToken() {
- return Jwts.builder()
- .setSubject("1")
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() - 1000))
- .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
- .compact();
- }
-}
diff --git a/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java b/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
index 95bdd5a52..0c16de671 100644
--- a/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
+++ b/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
@@ -12,7 +12,6 @@
import java.util.Date;
import static com.example.solidconnection.util.JwtUtils.parseSubject;
-import static com.example.solidconnection.util.JwtUtils.parseSubjectIgnoringExpiration;
import static com.example.solidconnection.util.JwtUtils.parseTokenFromRequest;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
@@ -59,7 +58,7 @@ class 요청으로부터_토큰을_추출한다 {
}
@Nested
- class 유효한_토큰으로부터_subject_를_추출한다 {
+ class 토큰으로부터_subject_를_추출한다 {
@Test
void 유효한_토큰의_subject_를_추출한다() {
@@ -87,75 +86,6 @@ class 유효한_토큰으로부터_subject_를_추출한다 {
}
}
- @Nested
- class 만료된_토큰으로부터_subject_를_추출한다 {
-
- @Test
- void 만료된_토큰의_subject_를_예외를_발생시키지_않고_추출한다() {
- // given
- String subject = "subject999";
- String token = createExpiredToken(subject);
-
- // when
- String extractedSubject = parseSubjectIgnoringExpiration(token, jwtSecretKey);
-
- // then
- assertThat(extractedSubject).isEqualTo(subject);
- }
-
- @Test
- void 유효하지_않은_토큰의_subject_를_추출하면_예외_응답을_반환한다() {
- // given
- String token = createExpiredUnsignedToken("hackers secret key");
-
- // when & then
- assertThatCode(() -> parseSubjectIgnoringExpiration(token, jwtSecretKey))
- .isInstanceOf(CustomException.class)
- .hasMessage(ErrorCode.INVALID_TOKEN.getMessage());
- }
- }
-
-
- @Nested
- class 토큰이_만료되었는지_확인한다 {
-
- @Test
- void 서명된_토큰의_만료_여부를_반환한다() {
- // given
- String subject = "subject123";
- String validToken = createValidToken(subject);
- String expiredToken = createExpiredToken(subject);
-
- // when
- boolean isExpired1 = JwtUtils.isExpired(validToken, jwtSecretKey);
- boolean isExpired2 = JwtUtils.isExpired(expiredToken, jwtSecretKey);
-
- // then
- assertAll(
- () -> assertThat(isExpired1).isFalse(),
- () -> assertThat(isExpired2).isTrue()
- );
- }
-
- @Test
- void 서명되지_않은_토큰의_만료_여부를_반환한다() {
- // given
- String subject = "subject123";
- String validToken = createValidToken(subject);
- String expiredToken = createExpiredToken(subject);
-
- // when
- boolean isExpired1 = JwtUtils.isExpired(validToken, "wrong-secret-key");
- boolean isExpired2 = JwtUtils.isExpired(expiredToken, "wrong-secret-key");
-
- // then
- assertAll(
- () -> assertThat(isExpired1).isTrue(),
- () -> assertThat(isExpired2).isTrue()
- );
- }
- }
-
private String createValidToken(String subject) {
return Jwts.builder()
.setSubject(subject)
@@ -173,13 +103,4 @@ private String createExpiredToken(String subject) {
.signWith(SignatureAlgorithm.HS256, jwtSecretKey)
.compact();
}
-
- private String createExpiredUnsignedToken(String jwtSecretKey) {
- return Jwts.builder()
- .setSubject("subject")
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() - 1000))
- .signWith(SignatureAlgorithm.HS256, jwtSecretKey)
- .compact();
- }
}
From f9e05b0a383db28c67cfefb6e2e3592be1aaf7cc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Sun, 11 May 2025 23:55:28 +0900
Subject: [PATCH 12/90] =?UTF-8?q?refactor:=20=EB=8C=80=ED=95=99=20?=
=?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?=
=?UTF-8?q?=ED=8A=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=95=EC=9D=98=20?=
=?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0=20(#286)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 메서드 체이닝으로 대학 test fixture 생성
* refactor: UniversityQueryServiceTest에 임시 반영
* chore: 테스트 환경에서 lombok 사용을 위한 의존성 추가
* test: 메서드 체이닝을 활용하여 대학 관련 Fixture 클래스 추가
* test: 대학 생성을 위한 Fixture Helper 클래스 추가
* test: Fixture Helper 클래스 실제 대학 테스트에 적용
* chore: 사용하지 않는 BuilderSupporter 클래스 제거
* refactor: 내가 생각한 방향 구현
* refactor: 테스트 코드 컴포넌트 @TestComponent로 변경
* refactor: 패키지 구조를 도메인 중심으로 개선
* feat: RegionFixture에 지역 생성 메서드 추가
* feat: CountryFixture에 국가 생성 메서드 추가
* feat: UniversityFixture에 대학 생성 메서드 추가
* feat: UniversityInfoForApplyFixture에 대학 지원 생성 메서드 추가
* feat: LanguageRequirementFixture에 언어 요구사항 생성 메서드 추가
* test: 추가한 Fixture 함수 테스트에 반영
* chore: 대학 정보 이름 실제 데이터와 일치하게 반영
* refactor: 언어 요구사항 데이터 세팅 방식 변경
---------
Co-authored-by: nayonsoso
---
build.gradle | 2 +
.../country/fixture/CountryFixture.java | 54 ++++++++
.../fixture/CountryFixtureBuilder.java | 42 ++++++
.../repository/CountryRepositoryForTest.java | 11 ++
.../region/fixture/RegionFixture.java | 33 +++++
.../region/fixture/RegionFixtureBuilder.java | 35 +++++
.../repository/RegionRepositoryForTest.java | 11 ++
.../support/TestContainerSpringBootTest.java | 2 +
.../fixture/LanguageRequirementFixture.java | 54 ++++++++
.../LanguageRequirementFixtureBuilder.java | 45 +++++++
.../university/fixture/UniversityFixture.java | 97 ++++++++++++++
.../fixture/UniversityFixtureBuilder.java | 58 ++++++++
.../UniversityInfoForApplyFixture.java | 97 ++++++++++++++
.../UniversityInfoForApplyFixtureBuilder.java | 53 ++++++++
.../service/UniversityQueryServiceTest.java | 124 +++++++++---------
15 files changed, 656 insertions(+), 62 deletions(-)
create mode 100644 src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java
create mode 100644 src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java
create mode 100644 src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java
create mode 100644 src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java
create mode 100644 src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java
create mode 100644 src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java
create mode 100644 src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixture.java
create mode 100644 src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java
diff --git a/build.gradle b/build.gradle
index b4267f41e..6f6a01f61 100644
--- a/build.gradle
+++ b/build.gradle
@@ -58,6 +58,8 @@ dependencies {
testImplementation 'org.testcontainers:testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mysql'
+ testImplementation 'org.projectlombok:lombok'
+ testAnnotationProcessor 'org.projectlombok:lombok'
// Etc
implementation 'org.hibernate.validator:hibernate-validator'
diff --git a/src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java b/src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java
new file mode 100644
index 000000000..53f394eae
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java
@@ -0,0 +1,54 @@
+package com.example.solidconnection.country.fixture;
+
+import com.example.solidconnection.entity.Country;
+import com.example.solidconnection.region.fixture.RegionFixture;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class CountryFixture {
+
+ private final RegionFixture regionFixture;
+ private final CountryFixtureBuilder countryFixtureBuilder;
+
+ public Country 미국() {
+ return countryFixtureBuilder.country()
+ .code("US")
+ .koreanName("미국")
+ .region(regionFixture.영미권())
+ .findOrCreate();
+ }
+
+ public Country 캐나다() {
+ return countryFixtureBuilder.country()
+ .code("CA")
+ .koreanName("캐나다")
+ .region(regionFixture.영미권())
+ .findOrCreate();
+ }
+
+ public Country 덴마크() {
+ return countryFixtureBuilder.country()
+ .code("DK")
+ .koreanName("덴마크")
+ .region(regionFixture.유럽())
+ .findOrCreate();
+ }
+
+ public Country 오스트리아() {
+ return countryFixtureBuilder.country()
+ .code("AT")
+ .koreanName("오스트리아")
+ .region(regionFixture.유럽())
+ .findOrCreate();
+ }
+
+ public Country 일본() {
+ return countryFixtureBuilder.country()
+ .code("JP")
+ .koreanName("일본")
+ .region(regionFixture.아시아())
+ .findOrCreate();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java b/src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java
new file mode 100644
index 000000000..e3ea004c5
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java
@@ -0,0 +1,42 @@
+package com.example.solidconnection.country.fixture;
+
+import com.example.solidconnection.entity.Country;
+import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.country.repository.CountryRepositoryForTest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class CountryFixtureBuilder {
+
+ private final CountryRepositoryForTest countryRepositoryForTest;
+
+ private String code;
+ private String koreanName;
+ private Region region;
+
+ public CountryFixtureBuilder country() {
+ return new CountryFixtureBuilder(countryRepositoryForTest);
+ }
+
+ public CountryFixtureBuilder code(String code) {
+ this.code = code;
+ return this;
+ }
+
+ public CountryFixtureBuilder koreanName(String koreanName) {
+ this.koreanName = koreanName;
+ return this;
+ }
+
+ public CountryFixtureBuilder region(Region region) {
+ this.region = region;
+ return this;
+ }
+
+ public Country findOrCreate() {
+ return countryRepositoryForTest.findByCode(code)
+ .orElseGet(() -> countryRepositoryForTest.save(new Country(code, koreanName, region)));
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java b/src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java
new file mode 100644
index 000000000..fc5dab0f9
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java
@@ -0,0 +1,11 @@
+package com.example.solidconnection.country.repository;
+
+import com.example.solidconnection.entity.Country;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface CountryRepositoryForTest extends JpaRepository {
+
+ Optional findByCode(String code);
+}
diff --git a/src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java b/src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java
new file mode 100644
index 000000000..a1cd97e56
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java
@@ -0,0 +1,33 @@
+package com.example.solidconnection.region.fixture;
+
+import com.example.solidconnection.entity.Region;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class RegionFixture {
+
+ private final RegionFixtureBuilder regionFixtureBuilder;
+
+ public Region 영미권() {
+ return regionFixtureBuilder.region()
+ .code("AMERICAS")
+ .koreanName("영미권")
+ .findOrCreate();
+ }
+
+ public Region 유럽() {
+ return regionFixtureBuilder.region()
+ .code("EUROPE")
+ .koreanName("유럽")
+ .findOrCreate();
+ }
+
+ public Region 아시아() {
+ return regionFixtureBuilder.region()
+ .code("ASIA")
+ .koreanName("아시아")
+ .findOrCreate();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java b/src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java
new file mode 100644
index 000000000..a385a53f8
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java
@@ -0,0 +1,35 @@
+package com.example.solidconnection.region.fixture;
+
+import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.region.repository.RegionRepositoryForTest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class RegionFixtureBuilder {
+
+ private final RegionRepositoryForTest regionRepositoryForTest;
+
+ private String code;
+ private String koreanName;
+
+ public RegionFixtureBuilder region() {
+ return new RegionFixtureBuilder(regionRepositoryForTest);
+ }
+
+ public RegionFixtureBuilder code(String code) {
+ this.code = code;
+ return this;
+ }
+
+ public RegionFixtureBuilder koreanName(String koreanName) {
+ this.koreanName = koreanName;
+ return this;
+ }
+
+ public Region findOrCreate() {
+ return regionRepositoryForTest.findByCode(code)
+ .orElseGet(() -> regionRepositoryForTest.save(new Region(code, koreanName)));
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java b/src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java
new file mode 100644
index 000000000..00c35c02d
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java
@@ -0,0 +1,11 @@
+package com.example.solidconnection.region.repository;
+
+import com.example.solidconnection.entity.Region;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.Optional;
+
+public interface RegionRepositoryForTest extends JpaRepository {
+
+ Optional findByCode(String code);
+}
diff --git a/src/test/java/com/example/solidconnection/support/TestContainerSpringBootTest.java b/src/test/java/com/example/solidconnection/support/TestContainerSpringBootTest.java
index 5c5c93742..462400400 100644
--- a/src/test/java/com/example/solidconnection/support/TestContainerSpringBootTest.java
+++ b/src/test/java/com/example/solidconnection/support/TestContainerSpringBootTest.java
@@ -3,6 +3,7 @@
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.ContextConfiguration;
import org.testcontainers.junit.jupiter.Testcontainers;
@@ -11,6 +12,7 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+@ComponentScan(basePackages = "com.example.solidconnection")
@ExtendWith({DatabaseClearExtension.class})
@ContextConfiguration(initializers = {RedisTestContainer.class, MySQLTestContainer.class})
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
diff --git a/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java
new file mode 100644
index 000000000..ba32c1b27
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java
@@ -0,0 +1,54 @@
+package com.example.solidconnection.university.fixture;
+
+import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class LanguageRequirementFixture {
+
+ private final LanguageRequirementFixtureBuilder languageRequirementFixtureBuilder;
+
+ public LanguageRequirement 토플_80(UniversityInfoForApply universityInfo) {
+ return languageRequirementFixtureBuilder
+ .languageTestType(LanguageTestType.TOEFL_IBT)
+ .minScore("80")
+ .universityInfoForApply(universityInfo)
+ .create();
+ }
+
+ public LanguageRequirement 토플_70(UniversityInfoForApply universityInfo) {
+ return languageRequirementFixtureBuilder
+ .languageTestType(LanguageTestType.TOEFL_IBT)
+ .minScore("70")
+ .universityInfoForApply(universityInfo)
+ .create();
+ }
+
+ public LanguageRequirement 토익_800(UniversityInfoForApply universityInfo) {
+ return languageRequirementFixtureBuilder
+ .languageTestType(LanguageTestType.TOEIC)
+ .minScore("800")
+ .universityInfoForApply(universityInfo)
+ .create();
+ }
+
+ public LanguageRequirement 토익_900(UniversityInfoForApply universityInfo) {
+ return languageRequirementFixtureBuilder
+ .languageTestType(LanguageTestType.TOEIC)
+ .minScore("900")
+ .universityInfoForApply(universityInfo)
+ .create();
+ }
+
+ public LanguageRequirement JLPT_N2(UniversityInfoForApply universityInfo) {
+ return languageRequirementFixtureBuilder
+ .languageTestType(LanguageTestType.JLPT)
+ .minScore("N2")
+ .universityInfoForApply(universityInfo)
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java
new file mode 100644
index 000000000..e6f3fd4d5
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java
@@ -0,0 +1,45 @@
+package com.example.solidconnection.university.fixture;
+
+import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import com.example.solidconnection.university.repository.LanguageRequirementRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class LanguageRequirementFixtureBuilder {
+
+ private final LanguageRequirementRepository languageRequirementRepository;
+
+ private LanguageTestType languageTestType;
+ private String minScore;
+ private UniversityInfoForApply universityInfoForApply;
+
+ public LanguageRequirementFixtureBuilder languageTestType(LanguageTestType languageTestType) {
+ this.languageTestType = languageTestType;
+ return this;
+ }
+
+ public LanguageRequirementFixtureBuilder minScore(String minScore) {
+ this.minScore = minScore;
+ return this;
+ }
+
+ public LanguageRequirementFixtureBuilder universityInfoForApply(UniversityInfoForApply universityInfoForApply) {
+ this.universityInfoForApply = universityInfoForApply;
+ return this;
+ }
+
+ public LanguageRequirement create() {
+ LanguageRequirement languageRequirement = new LanguageRequirement(
+ null,
+ languageTestType,
+ minScore,
+ universityInfoForApply
+ );
+ universityInfoForApply.addLanguageRequirements(languageRequirement);
+ return languageRequirementRepository.save(languageRequirement);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java
new file mode 100644
index 000000000..f3a41515f
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java
@@ -0,0 +1,97 @@
+package com.example.solidconnection.university.fixture;
+
+import com.example.solidconnection.country.fixture.CountryFixture;
+import com.example.solidconnection.region.fixture.RegionFixture;
+import com.example.solidconnection.university.domain.University;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public final class UniversityFixture {
+
+ private final RegionFixture regionFixture;
+ private final CountryFixture countryFixture;
+ private final UniversityFixtureBuilder universityFixtureBuilder;
+
+ public University 괌_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("괌 대학")
+ .englishName("University of Guam")
+ .country(countryFixture.미국())
+ .region(regionFixture.영미권())
+ .create();
+ }
+
+ public University 네바다주립_대학_라스베이거스() {
+ return universityFixtureBuilder.university()
+ .koreanName("네바다주립 대학 라스베이거스")
+ .englishName("University of Nevada, Las Vegas")
+ .country(countryFixture.미국())
+ .region(regionFixture.영미권())
+ .create();
+ }
+
+ public University 메모리얼_대학_세인트존스() {
+ return universityFixtureBuilder.university()
+ .koreanName("메모리얼 대학 세인트존스")
+ .englishName("Memorial University of Newfoundland St. John's")
+ .country(countryFixture.캐나다())
+ .region(regionFixture.영미권())
+ .create();
+ }
+
+ public University 서던덴마크_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("서던덴마크 대학")
+ .englishName("University of Southern Denmark")
+ .country(countryFixture.덴마크())
+ .region(regionFixture.유럽())
+ .create();
+ }
+
+ public University 코펜하겐IT_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("코펜하겐IT 대학")
+ .englishName("IT University of Copenhagen")
+ .country(countryFixture.덴마크())
+ .region(regionFixture.유럽())
+ .create();
+ }
+
+ public University 그라츠_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("그라츠 대학")
+ .englishName("University of Graz")
+ .country(countryFixture.오스트리아())
+ .region(regionFixture.유럽())
+ .create();
+ }
+
+ public University 그라츠공과_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("그라츠공과 대학")
+ .englishName("Graz University of Technology")
+ .country(countryFixture.오스트리아())
+ .region(regionFixture.유럽())
+ .create();
+ }
+
+ public University 린츠_카톨릭_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("린츠 카톨릭 대학")
+ .englishName("Catholic Private University Linz")
+ .country(countryFixture.오스트리아())
+ .region(regionFixture.유럽())
+ .create();
+ }
+
+ public University 메이지_대학() {
+ return universityFixtureBuilder.university()
+ .koreanName("메이지 대학")
+ .englishName("Meiji University")
+ .country(countryFixture.일본())
+ .region(regionFixture.아시아())
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java
new file mode 100644
index 000000000..f51ea9677
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java
@@ -0,0 +1,58 @@
+package com.example.solidconnection.university.fixture;
+
+import com.example.solidconnection.entity.Country;
+import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.university.domain.University;
+import com.example.solidconnection.university.repository.UniversityRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class UniversityFixtureBuilder {
+
+ private final UniversityRepository universityRepository;
+
+ private String koreanName;
+ private String englishName;
+ private Country country;
+ private Region region;
+
+ public UniversityFixtureBuilder university() {
+ return new UniversityFixtureBuilder(universityRepository);
+ }
+
+ public UniversityFixtureBuilder koreanName(String koreanName) {
+ this.koreanName = koreanName;
+ return this;
+ }
+
+ public UniversityFixtureBuilder englishName(String englishName) {
+ this.englishName = englishName;
+ return this;
+ }
+
+ public UniversityFixtureBuilder country(Country country) {
+ this.country = country;
+ return this;
+ }
+
+ public UniversityFixtureBuilder region(Region region) {
+ this.region = region;
+ return this;
+ }
+
+ public University create() {
+ University university = new University(
+ null, koreanName, englishName,
+ "formatName",
+ "https://homepage-url",
+ "https://english-course-url",
+ "https://accommodation-url",
+ "https://logo-image-url",
+ "https://background-image-url",
+ null, country, region
+ );
+ return universityRepository.save(university);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixture.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixture.java
new file mode 100644
index 000000000..32a32cf6d
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixture.java
@@ -0,0 +1,97 @@
+package com.example.solidconnection.university.fixture;
+
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class UniversityInfoForApplyFixture {
+
+ private final UniversityInfoForApplyFixtureBuilder universityInfoForApplyFixtureBuilder;
+ private final UniversityFixture universityFixture;
+
+ @Value("${university.term}")
+ public String term;
+
+ public UniversityInfoForApply 괌대학_A_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("괌대학(A형)")
+ .university(universityFixture.괌_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 괌대학_B_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("괌대학(B형)")
+ .university(universityFixture.괌_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 네바다주립대학_라스베이거스_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("네바다주립대학 라스베이거스(B형)")
+ .university(universityFixture.네바다주립_대학_라스베이거스())
+ .create();
+ }
+
+ public UniversityInfoForApply 메모리얼대학_세인트존스_A_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("메모리얼 대학 세인트존스(A형)")
+ .university(universityFixture.메모리얼_대학_세인트존스())
+ .create();
+ }
+
+ public UniversityInfoForApply 서던덴마크대학교_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("서던덴마크대학교")
+ .university(universityFixture.서던덴마크_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 코펜하겐IT대학_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("코펜하겐 IT대학")
+ .university(universityFixture.코펜하겐IT_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 그라츠대학_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("그라츠 대학")
+ .university(universityFixture.그라츠_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 그라츠공과대학_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("그라츠공과대학")
+ .university(universityFixture.그라츠공과_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 린츠_카톨릭대학_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("린츠 카톨릭 대학교")
+ .university(universityFixture.린츠_카톨릭_대학())
+ .create();
+ }
+
+ public UniversityInfoForApply 메이지대학_지원_정보() {
+ return universityInfoForApplyFixtureBuilder.universityInfoForApply()
+ .term(term)
+ .koreanName("메이지대학")
+ .university(universityFixture.메이지_대학())
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java
new file mode 100644
index 000000000..8041bda1e
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java
@@ -0,0 +1,53 @@
+package com.example.solidconnection.university.fixture;
+
+import com.example.solidconnection.university.domain.University;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+import java.util.HashSet;
+
+import static com.example.solidconnection.type.SemesterAvailableForDispatch.ONE_SEMESTER;
+import static com.example.solidconnection.type.TuitionFeeType.HOME_UNIVERSITY_PAYMENT;
+
+@TestComponent
+@RequiredArgsConstructor
+public class UniversityInfoForApplyFixtureBuilder {
+
+ private final UniversityInfoForApplyRepository universityInfoForApplyRepository;
+
+ private String term;
+ private String koreanName;
+ private University university;
+
+ public UniversityInfoForApplyFixtureBuilder universityInfoForApply() {
+ return new UniversityInfoForApplyFixtureBuilder(universityInfoForApplyRepository);
+ }
+
+ public UniversityInfoForApplyFixtureBuilder term(String term) {
+ this.term = term;
+ return this;
+ }
+
+ public UniversityInfoForApplyFixtureBuilder koreanName(String koreanName) {
+ this.koreanName = koreanName;
+ return this;
+ }
+
+ public UniversityInfoForApplyFixtureBuilder university(University university) {
+ this.university = university;
+ return this;
+ }
+
+ public UniversityInfoForApply create() {
+ UniversityInfoForApply universityInfoForApply = new UniversityInfoForApply(
+ null, term, koreanName, 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
+ "1", "detailsForLanguage", "gpaRequirement",
+ "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
+ "detailsForAccommodation", "detailsForEnglishCourse", "details",
+ new HashSet<>(), university
+ );
+ return universityInfoForApplyRepository.save(universityInfoForApply);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java
index 1cd0d755f..731ccec5b 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java
@@ -1,15 +1,16 @@
package com.example.solidconnection.university.service;
import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
+import com.example.solidconnection.university.fixture.LanguageRequirementFixture;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.UniversityDetailResponse;
-import com.example.solidconnection.university.dto.LanguageRequirementResponse;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponses;
import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
import com.example.solidconnection.university.repository.custom.UniversityFilterRepository;
-import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -17,14 +18,15 @@
import java.util.List;
-import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.times;
+@TestContainerSpringBootTest
@DisplayName("대학교 조회 서비스 테스트")
-class UniversityQueryServiceTest extends BaseIntegrationTest {
+class UniversityQueryServiceTest {
@Autowired
private UniversityQueryService universityQueryService;
@@ -35,60 +37,36 @@ class UniversityQueryServiceTest extends BaseIntegrationTest {
@SpyBean
private UniversityInfoForApplyRepository universityInfoForApplyRepository;
+ @Autowired
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
+ @Autowired
+ private LanguageRequirementFixture languageRequirementFixture;
+
@Test
- void 대학_상세정보를_정상_조회한다() {
+ void 대학_상세정보를_정상_조회한다() {
// given
- Long universityId = 괌대학_A_지원_정보.getId();
+ UniversityInfoForApply 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
// when
- UniversityDetailResponse response = universityQueryService.getUniversityDetail(universityId);
+ UniversityDetailResponse response = universityQueryService.getUniversityDetail(괌대학_A_지원_정보.getId());
// then
- Assertions.assertAll(
- () -> assertThat(response.id()).isEqualTo(괌대학_A_지원_정보.getId()),
- () -> assertThat(response.term()).isEqualTo(괌대학_A_지원_정보.getTerm()),
- () -> assertThat(response.koreanName()).isEqualTo(괌대학_A_지원_정보.getKoreanName()),
- () -> assertThat(response.englishName()).isEqualTo(영미권_미국_괌대학.getEnglishName()),
- () -> assertThat(response.formatName()).isEqualTo(영미권_미국_괌대학.getFormatName()),
- () -> assertThat(response.region()).isEqualTo(영미권.getKoreanName()),
- () -> assertThat(response.country()).isEqualTo(미국.getKoreanName()),
- () -> assertThat(response.homepageUrl()).isEqualTo(영미권_미국_괌대학.getHomepageUrl()),
- () -> assertThat(response.logoImageUrl()).isEqualTo(영미권_미국_괌대학.getLogoImageUrl()),
- () -> assertThat(response.backgroundImageUrl()).isEqualTo(영미권_미국_괌대학.getBackgroundImageUrl()),
- () -> assertThat(response.detailsForLocal()).isEqualTo(영미권_미국_괌대학.getDetailsForLocal()),
- () -> assertThat(response.studentCapacity()).isEqualTo(괌대학_A_지원_정보.getStudentCapacity()),
- () -> assertThat(response.tuitionFeeType()).isEqualTo(괌대학_A_지원_정보.getTuitionFeeType().getKoreanName()),
- () -> assertThat(response.semesterAvailableForDispatch()).isEqualTo(괌대학_A_지원_정보.getSemesterAvailableForDispatch().getKoreanName()),
- () -> assertThat(response.languageRequirements()).containsOnlyOnceElementsOf(
- 괌대학_A_지원_정보.getLanguageRequirements().stream()
- .map(LanguageRequirementResponse::from)
- .toList()),
- () -> assertThat(response.detailsForLanguage()).isEqualTo(괌대학_A_지원_정보.getDetailsForLanguage()),
- () -> assertThat(response.gpaRequirement()).isEqualTo(괌대학_A_지원_정보.getGpaRequirement()),
- () -> assertThat(response.gpaRequirementCriteria()).isEqualTo(괌대학_A_지원_정보.getGpaRequirementCriteria()),
- () -> assertThat(response.semesterRequirement()).isEqualTo(괌대학_A_지원_정보.getSemesterRequirement()),
- () -> assertThat(response.detailsForApply()).isEqualTo(괌대학_A_지원_정보.getDetailsForApply()),
- () -> assertThat(response.detailsForMajor()).isEqualTo(괌대학_A_지원_정보.getDetailsForMajor()),
- () -> assertThat(response.detailsForAccommodation()).isEqualTo(괌대학_A_지원_정보.getDetailsForAccommodation()),
- () -> assertThat(response.detailsForEnglishCourse()).isEqualTo(괌대학_A_지원_정보.getDetailsForEnglishCourse()),
- () -> assertThat(response.details()).isEqualTo(괌대학_A_지원_정보.getDetails()),
- () -> assertThat(response.accommodationUrl()).isEqualTo(괌대학_A_지원_정보.getUniversity().getAccommodationUrl()),
- () -> assertThat(response.englishCourseUrl()).isEqualTo(괌대학_A_지원_정보.getUniversity().getEnglishCourseUrl())
- );
+ assertThat(response.id()).isEqualTo(괌대학_A_지원_정보.getId());
}
@Test
void 대학_상세정보_조회시_캐시가_적용된다() {
// given
- Long universityId = 괌대학_A_지원_정보.getId();
+ UniversityInfoForApply 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
// when
- UniversityDetailResponse firstResponse = universityQueryService.getUniversityDetail(universityId);
- UniversityDetailResponse secondResponse = universityQueryService.getUniversityDetail(universityId);
+ UniversityDetailResponse firstResponse = universityQueryService.getUniversityDetail(괌대학_A_지원_정보.getId());
+ UniversityDetailResponse secondResponse = universityQueryService.getUniversityDetail(괌대학_A_지원_정보.getId());
// then
assertThat(firstResponse).isEqualTo(secondResponse);
- then(universityInfoForApplyRepository).should(times(1)).getUniversityInfoForApplyById(universityId);
+ then(universityInfoForApplyRepository).should(times(1)).getUniversityInfoForApplyById(괌대학_A_지원_정보.getId());
}
@Test
@@ -106,6 +84,14 @@ class UniversityQueryServiceTest extends BaseIntegrationTest {
@Test
void 전체_대학을_조회한다() {
+ // given
+ UniversityInfoForApply 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ UniversityInfoForApply 괌대학_B_지원_정보 = universityInfoForApplyFixture.괌대학_B_지원_정보();
+ UniversityInfoForApply 네바다주립대학_라스베이거스_지원_정보 = universityInfoForApplyFixture.네바다주립대학_라스베이거스_지원_정보();
+ UniversityInfoForApply 서던덴마크대학교_지원_정보 = universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
+ UniversityInfoForApply 그라츠대학_지원_정보 = universityInfoForApplyFixture.그라츠대학_지원_정보();
+ UniversityInfoForApply 메이지대학_지원_정보 = universityInfoForApplyFixture.메이지대학_지원_정보();
+
// when
UniversityInfoForApplyPreviewResponses response = universityQueryService.searchUniversity(
null, List.of(), null, null);
@@ -116,12 +102,8 @@ class UniversityQueryServiceTest extends BaseIntegrationTest {
UniversityInfoForApplyPreviewResponse.from(괌대학_A_지원_정보),
UniversityInfoForApplyPreviewResponse.from(괌대학_B_지원_정보),
UniversityInfoForApplyPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보),
UniversityInfoForApplyPreviewResponse.from(서던덴마크대학교_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(코펜하겐IT대학_지원_정보),
UniversityInfoForApplyPreviewResponse.from(그라츠대학_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(그라츠공과대학_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(린츠_카톨릭대학_지원_정보),
UniversityInfoForApplyPreviewResponse.from(메이지대학_지원_정보)
);
}
@@ -129,7 +111,8 @@ class UniversityQueryServiceTest extends BaseIntegrationTest {
@Test
void 대학_조회시_캐시가_적용된다() {
// given
- String regionCode = 영미권.getCode();
+ universityInfoForApplyFixture.괌대학_A_지원_정보();
+ String regionCode = "AMERICAS";
List keywords = List.of("괌");
LanguageTestType testType = LanguageTestType.TOEFL_IBT;
String testScore = "70";
@@ -150,22 +133,28 @@ class UniversityQueryServiceTest extends BaseIntegrationTest {
@Test
void 지역으로_대학을_필터링한다() {
+ // given
+ UniversityInfoForApply 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ universityInfoForApplyFixture.코펜하겐IT대학_지원_정보();
+ universityInfoForApplyFixture.그라츠공과대학_지원_정보();
+ universityInfoForApplyFixture.메이지대학_지원_정보();
+
// when
UniversityInfoForApplyPreviewResponses response = universityQueryService.searchUniversity(
- 영미권.getCode(), List.of(), null, null);
+ "AMERICAS", List.of(), null, null);
// then
assertThat(response.universityInfoForApplyPreviewResponses())
- .containsExactlyInAnyOrder(
- UniversityInfoForApplyPreviewResponse.from(괌대학_A_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(괌대학_B_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(메모리얼대학_세인트존스_A_지원_정보)
- );
+ .containsExactlyInAnyOrder(UniversityInfoForApplyPreviewResponse.from(괌대학_A_지원_정보));
}
@Test
void 키워드로_대학을_필터링한다() {
+ // given
+ universityInfoForApplyFixture.괌대학_A_지원_정보();
+ UniversityInfoForApply 그라츠대학_지원_정보 = universityInfoForApplyFixture.그라츠대학_지원_정보();
+ UniversityInfoForApply 메이지대학_지원_정보 = universityInfoForApplyFixture.메이지대학_지원_정보();
+
// when
UniversityInfoForApplyPreviewResponses response = universityQueryService.searchUniversity(
null, List.of("라", "일본"), null, null);
@@ -173,34 +162,45 @@ class UniversityQueryServiceTest extends BaseIntegrationTest {
// then
assertThat(response.universityInfoForApplyPreviewResponses())
.containsExactlyInAnyOrder(
- UniversityInfoForApplyPreviewResponse.from(네바다주립대학_라스베이거스_지원_정보),
UniversityInfoForApplyPreviewResponse.from(그라츠대학_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(그라츠공과대학_지원_정보),
UniversityInfoForApplyPreviewResponse.from(메이지대학_지원_정보)
);
}
@Test
void 어학시험_조건으로_대학을_필터링한다() {
+ // given
+ UniversityInfoForApply 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ languageRequirementFixture.토플_80(괌대학_A_지원_정보);
+ languageRequirementFixture.토익_800(괌대학_A_지원_정보);
+ UniversityInfoForApply 괌대학_B_지원_정보 = universityInfoForApplyFixture.괌대학_B_지원_정보();
+ languageRequirementFixture.토플_70(괌대학_B_지원_정보);
+ languageRequirementFixture.토익_900(괌대학_B_지원_정보);
+
// when
UniversityInfoForApplyPreviewResponses response = universityQueryService.searchUniversity(
null, List.of(), LanguageTestType.TOEFL_IBT, "70");
// then
assertThat(response.universityInfoForApplyPreviewResponses())
- .containsExactlyInAnyOrder(
- UniversityInfoForApplyPreviewResponse.from(괌대학_B_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(서던덴마크대학교_지원_정보)
- );
+ .containsExactlyInAnyOrder(UniversityInfoForApplyPreviewResponse.from(괌대학_B_지원_정보));
}
@Test
void 모든_조건으로_대학을_필터링한다() {
+ // given
+ UniversityInfoForApply 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ languageRequirementFixture.토플_80(괌대학_A_지원_정보);
+ languageRequirementFixture.토익_800(괌대학_A_지원_정보);
+ UniversityInfoForApply 서던덴마크대학교_지원_정보 = universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
+ languageRequirementFixture.토플_70(서던덴마크대학교_지원_정보);
+
// when
UniversityInfoForApplyPreviewResponses response = universityQueryService.searchUniversity(
"EUROPE", List.of(), LanguageTestType.TOEFL_IBT, "70");
// then
- assertThat(response.universityInfoForApplyPreviewResponses()).containsExactly(UniversityInfoForApplyPreviewResponse.from(서던덴마크대학교_지원_정보));
+ assertThat(response.universityInfoForApplyPreviewResponses())
+ .containsExactly(UniversityInfoForApplyPreviewResponse.from(서던덴마크대학교_지원_정보));
}
}
From 5f1474a53f4dd7a63b72325108b19dd038b926c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Mon, 12 May 2025 00:01:05 +0900
Subject: [PATCH 13/90] =?UTF-8?q?refactor:=20=ED=9A=8C=EC=9B=90=20?=
=?UTF-8?q?=ED=83=88=ED=87=B4=20API=20HTTP=20Method=EB=A5=BC=20PATCH?=
=?UTF-8?q?=EC=97=90=EC=84=9C=20DELETE=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#3?=
=?UTF-8?q?11)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 회원 탈퇴 API HTTP Method를 PATCH에서 DELETE로 변경
* chore: 불필요한 import 제거
---
.../solidconnection/auth/controller/AuthController.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
index 553ef4063..064aa88aa 100644
--- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
+++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
@@ -26,7 +26,7 @@
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
-import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -102,7 +102,7 @@ public ResponseEntity signOut(
return ResponseEntity.ok().build();
}
- @PatchMapping("/quit")
+ @DeleteMapping("/quit")
public ResponseEntity quit(
@AuthorizedUser SiteUser siteUser,
Authentication authentication // todo: #299를 작업하며 인자를 (Authentication authentication)만 받도록 수정해야 함
From 8a845356fb4e21141a1f4b58de09b7e4fbfc17e3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Tue, 13 May 2025 00:56:23 +0900
Subject: [PATCH 14/90] =?UTF-8?q?refactor:=20=EB=8C=80=ED=95=99(=EC=B6=94?=
=?UTF-8?q?=EC=B2=9C,=20=EC=A2=8B=EC=95=84=EC=9A=94)=20=ED=86=B5=ED=95=A9?=
=?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20?=
=?UTF-8?q?Fixture=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20=EB=B3=80?=
=?UTF-8?q?=EA=B2=BD=20(#313)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 대학 좋아요 통합 테스트 데이터 Fixture 메서드로 변경
* refactor: 대학 추천 통합 테스트 데이터 Fixture 메서드로 변경
---
...GeneralUniversityRecommendServiceTest.java | 26 +++++++--
.../service/UniversityLikeServiceTest.java | 34 +++++------
.../UniversityRecommendServiceTest.java | 56 +++++++++++++++----
3 files changed, 84 insertions(+), 32 deletions(-)
diff --git a/src/test/java/com/example/solidconnection/university/service/GeneralUniversityRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/GeneralUniversityRecommendServiceTest.java
index d93765a44..c431bca6c 100644
--- a/src/test/java/com/example/solidconnection/university/service/GeneralUniversityRecommendServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/GeneralUniversityRecommendServiceTest.java
@@ -1,8 +1,9 @@
package com.example.solidconnection.university.service;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
+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;
@@ -14,20 +15,37 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
-@DisplayName("공통 추천 대학 서비스 테스트")
@TestContainerSpringBootTest
-class GeneralUniversityRecommendServiceTest extends BaseIntegrationTest {
+@DisplayName("공통 추천 대학 서비스 테스트")
+class GeneralUniversityRecommendServiceTest {
@Autowired
private GeneralUniversityRecommendService generalUniversityRecommendService;
+ @Autowired
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
@Value("${university.term}")
private String term;
+ @BeforeEach
+ void setUp() {
+ universityInfoForApplyFixture.괌대학_A_지원_정보();
+ universityInfoForApplyFixture.괌대학_B_지원_정보();
+ universityInfoForApplyFixture.네바다주립대학_라스베이거스_지원_정보();
+ universityInfoForApplyFixture.메모리얼대학_세인트존스_A_지원_정보();
+ universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
+ universityInfoForApplyFixture.코펜하겐IT대학_지원_정보();
+ universityInfoForApplyFixture.그라츠대학_지원_정보();
+ universityInfoForApplyFixture.그라츠공과대학_지원_정보();
+ universityInfoForApplyFixture.린츠_카톨릭대학_지원_정보();
+ universityInfoForApplyFixture.메이지대학_지원_정보();
+ generalUniversityRecommendService.init();
+ }
+
@Test
void 모집_시기의_대학들_중에서_랜덤하게_N개를_추천_목록으로_구성한다() {
// given
- generalUniversityRecommendService.init();
List universities = generalUniversityRecommendService.getRecommendUniversities();
// when & then
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
index 6bc3c13e3..3b2ab8c22 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
@@ -4,13 +4,15 @@
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.type.PreparationStatus;
import com.example.solidconnection.type.Role;
import com.example.solidconnection.university.domain.LikedUniversity;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.IsLikeResponse;
import com.example.solidconnection.university.dto.LikeResultResponse;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -25,8 +27,9 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("대학교 좋아요 서비스 테스트")
-class UniversityLikeServiceTest extends BaseIntegrationTest {
+class UniversityLikeServiceTest {
@Autowired
private UniversityLikeService universityLikeService;
@@ -37,14 +40,23 @@ class UniversityLikeServiceTest extends BaseIntegrationTest {
@Autowired
private SiteUserRepository siteUserRepository;
+ @Autowired
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
+ private SiteUser testUser;
+ private UniversityInfoForApply 괌대학_A_지원_정보;
+
+ @BeforeEach
+ void setUp() {
+ testUser = createSiteUser();
+ 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ }
+
@Nested
class 대학_좋아요를_등록한다 {
@Test
void 성공적으로_좋아요를_등록한다() {
- // given
- SiteUser testUser = createSiteUser();
-
// when
LikeResultResponse response = universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId());
@@ -60,7 +72,6 @@ class 대학_좋아요를_등록한다 {
@Test
void 이미_좋아요한_대학이면_예외_응답을_반환한다() {
// given
- SiteUser testUser = createSiteUser();
saveLikedUniversity(testUser, 괌대학_A_지원_정보);
// when & then
@@ -76,7 +87,6 @@ class 대학_좋아요를_취소한다 {
@Test
void 성공적으로_좋아요를_취소한다() {
// given
- SiteUser testUser = createSiteUser();
saveLikedUniversity(testUser, 괌대학_A_지원_정보);
// when
@@ -93,9 +103,6 @@ class 대학_좋아요를_취소한다 {
@Test
void 좋아요하지_않은_대학이면_예외_응답을_반환한다() {
- // given
- SiteUser testUser = createSiteUser();
-
// when & then
assertThatCode(() -> universityLikeService.cancelLikeUniversity(testUser, 괌대학_A_지원_정보.getId()))
.isInstanceOf(CustomException.class)
@@ -106,7 +113,6 @@ class 대학_좋아요를_취소한다 {
@Test
void 존재하지_않는_대학_좋아요_시도하면_예외_응답을_반환한다() {
// given
- SiteUser testUser = createSiteUser();
Long invalidUniversityId = 9999L;
// when & then
@@ -118,7 +124,6 @@ class 대학_좋아요를_취소한다 {
@Test
void 좋아요한_대학인지_확인한다() {
// given
- SiteUser testUser = createSiteUser();
saveLikedUniversity(testUser, 괌대학_A_지원_정보);
// when
@@ -130,9 +135,6 @@ class 대학_좋아요를_취소한다 {
@Test
void 좋아요하지_않은_대학인지_확인한다() {
- // given
- SiteUser testUser = createSiteUser();
-
// when
IsLikeResponse response = universityLikeService.getIsLiked(testUser, 괌대학_A_지원_정보.getId());
@@ -143,7 +145,6 @@ class 대학_좋아요를_취소한다 {
@Test
void 존재하지_않는_대학의_좋아요_여부를_조회하면_예외_응답을_반환한다() {
// given
- SiteUser testUser = createSiteUser();
Long invalidUniversityId = 9999L;
// when & then
@@ -152,6 +153,7 @@ class 대학_좋아요를_취소한다 {
.hasMessage(UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND.getMessage());
}
+ // todo : 추후 Fixture로 대체 필요
private SiteUser createSiteUser() {
SiteUser siteUser = new SiteUser(
"test@example.com",
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
index 11591d11f..7645794bf 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
@@ -1,16 +1,20 @@
package com.example.solidconnection.university.service;
+import com.example.solidconnection.country.fixture.CountryFixture;
import com.example.solidconnection.entity.InterestedCountry;
import com.example.solidconnection.entity.InterestedRegion;
+import com.example.solidconnection.region.fixture.RegionFixture;
import com.example.solidconnection.repositories.InterestedCountyRepository;
import com.example.solidconnection.repositories.InterestedRegionRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.type.PreparationStatus;
import com.example.solidconnection.type.Role;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
import com.example.solidconnection.university.dto.UniversityRecommendsResponse;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -21,8 +25,9 @@
import static com.example.solidconnection.university.service.UniversityRecommendService.RECOMMEND_UNIVERSITY_NUM;
import static org.assertj.core.api.Assertions.assertThat;
+@TestContainerSpringBootTest
@DisplayName("대학교 추천 서비스 테스트")
-class UniversityRecommendServiceTest extends BaseIntegrationTest {
+class UniversityRecommendServiceTest {
@Autowired
private UniversityRecommendService universityRecommendService;
@@ -39,16 +44,47 @@ class UniversityRecommendServiceTest extends BaseIntegrationTest {
@Autowired
private GeneralUniversityRecommendService generalUniversityRecommendService;
+ @Autowired
+ private RegionFixture regionFixture;
+
+ @Autowired
+ private CountryFixture countryFixture;
+
+ @Autowired
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
+ private SiteUser testUser;
+ private UniversityInfoForApply 괌대학_A_지원_정보;
+ private UniversityInfoForApply 괌대학_B_지원_정보;
+ private UniversityInfoForApply 네바다주립대학_라스베이거스_지원_정보;
+ private UniversityInfoForApply 메모리얼대학_세인트존스_A_지원_정보;
+ private UniversityInfoForApply 서던덴마크대학교_지원_정보;
+ private UniversityInfoForApply 코펜하겐IT대학_지원_정보;
+ private UniversityInfoForApply 그라츠대학_지원_정보;
+ private UniversityInfoForApply 그라츠공과대학_지원_정보;
+ private UniversityInfoForApply 린츠_카톨릭대학_지원_정보;
+ private UniversityInfoForApply 메이지대학_지원_정보;
+
@BeforeEach
void setUp() {
+ testUser = createSiteUser();
+ 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ 괌대학_B_지원_정보 = universityInfoForApplyFixture.괌대학_B_지원_정보();
+ 네바다주립대학_라스베이거스_지원_정보 = universityInfoForApplyFixture.네바다주립대학_라스베이거스_지원_정보();
+ 메모리얼대학_세인트존스_A_지원_정보 = universityInfoForApplyFixture.메모리얼대학_세인트존스_A_지원_정보();
+ 서던덴마크대학교_지원_정보 = universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
+ 코펜하겐IT대학_지원_정보 = universityInfoForApplyFixture.코펜하겐IT대학_지원_정보();
+ 그라츠대학_지원_정보 = universityInfoForApplyFixture.그라츠대학_지원_정보();
+ 그라츠공과대학_지원_정보 = universityInfoForApplyFixture.그라츠공과대학_지원_정보();
+ 린츠_카톨릭대학_지원_정보 = universityInfoForApplyFixture.린츠_카톨릭대학_지원_정보();
+ 메이지대학_지원_정보 = universityInfoForApplyFixture.메이지대학_지원_정보();
generalUniversityRecommendService.init();
}
@Test
void 관심_지역_설정한_사용자의_맞춤_추천_대학을_조회한다() {
// given
- SiteUser testUser = createSiteUser();
- interestedRegionRepository.save(new InterestedRegion(testUser, 영미권));
+ interestedRegionRepository.save(new InterestedRegion(testUser, regionFixture.영미권()));
// when
UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
@@ -67,8 +103,7 @@ void setUp() {
@Test
void 관심_국가_설정한_사용자의_맞춤_추천_대학을_조회한다() {
// given
- SiteUser testUser = createSiteUser();
- interestedCountyRepository.save(new InterestedCountry(testUser, 덴마크));
+ interestedCountyRepository.save(new InterestedCountry(testUser, countryFixture.덴마크()));
// when
UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
@@ -85,9 +120,8 @@ void setUp() {
@Test
void 관심_지역과_국가_모두_설정한_사용자의_맞춤_추천_대학을_조회한다() {
// given
- SiteUser testUser = createSiteUser();
- interestedRegionRepository.save(new InterestedRegion(testUser, 영미권));
- interestedCountyRepository.save(new InterestedCountry(testUser, 덴마크));
+ interestedRegionRepository.save(new InterestedRegion(testUser, regionFixture.영미권()));
+ interestedCountyRepository.save(new InterestedCountry(testUser, countryFixture.덴마크()));
// when
UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
@@ -107,9 +141,6 @@ void setUp() {
@Test
void 관심사_미설정_사용자는_일반_추천_대학을_조회한다() {
- // given
- SiteUser testUser = createSiteUser();
-
// when
UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
@@ -138,6 +169,7 @@ void setUp() {
);
}
+ // todo : 추후 Fixture로 대체 필요
private SiteUser createSiteUser() {
SiteUser siteUser = new SiteUser(
"test@example.com",
From c4626fdb1a239e026b776cf35c9991c701f11f92 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Mon, 19 May 2025 12:16:29 +0900
Subject: [PATCH 15/90] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=20?=
=?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?=
=?UTF-8?q?=ED=8A=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20fixture=20=EB=A9=94?=
=?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#319)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: SiteUserFixture에 유저 생성 메서드 추가
* refactor: 대학 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: 유저 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: 점수 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: 동시성 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: 인증 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: 어드민 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: 커스텀 관련 테스트 유저 데이터 Fixture 메서드로 변경
* refactor: SiteUserFixtureBuilder에서 비밀번호 인코딩 처리 통일
* refactor: 재사용성 없는 fixture 제거
* refactor: 테스트 유저 메서드명 사용자()로 통일
* refactor: 테스트 어드민 메서드명 관리자()로 통일
* refactor: Repository 테스트는 fixture 대신 entity 사용하도록 변경
* refactor: 커스텀 프로필 사용자로 이름 변경
* refactor: 커스텀 프로필 생성 함수 private로 변경
---
.../service/AdminGpaScoreServiceTest.java | 34 ++---
.../AdminLanguageTestScoreServiceTest.java | 34 ++---
.../auth/service/AuthServiceTest.java | 27 +---
.../auth/service/EmailSignInServiceTest.java | 32 +---
.../auth/service/SignInServiceTest.java | 37 ++---
.../post/service/PostCommandServiceTest.java | 50 ++++---
.../post/service/PostLikeServiceTest.java | 36 +++--
.../post/service/PostQueryServiceTest.java | 26 +++-
.../PostLikeCountConcurrencyTest.java | 27 ++--
.../PostViewCountConcurrencyTest.java | 48 +++---
.../concurrency/ThunderingHerdTest.java | 33 ++---
.../resolver/AuthorizedUserResolverTest.java | 24 +--
.../aspect/AdminAuthorizationAspectTest.java | 32 ++--
.../SiteUserAuthenticationProviderTest.java | 27 +---
.../SiteUserDetailsServiceTest.java | 30 ++--
.../userdetails/SiteUserDetailsTest.java | 22 +--
.../score/service/ScoreServiceTest.java | 57 +++----
.../siteuser/fixture/SiteUserFixture.java | 69 +++++++++
.../fixture/SiteUserFixtureBuilder.java | 72 +++++++++
.../siteuser/service/MyPageServiceTest.java | 139 ++++++++----------
.../siteuser/service/SiteUserServiceTest.java | 28 +---
.../service/UniversityLikeServiceTest.java | 48 +++---
.../UniversityRecommendServiceTest.java | 54 +++----
23 files changed, 464 insertions(+), 522 deletions(-)
create mode 100644 src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
create mode 100644 src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java
diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
index add4115ef..fc7735d86 100644
--- a/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
@@ -9,10 +9,8 @@
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.type.VerifyStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -38,26 +36,23 @@ class AdminGpaScoreServiceTest extends BaseIntegrationTest {
private AdminGpaScoreService adminGpaScoreService;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private GpaScoreRepository gpaScoreRepository;
@Autowired
- private GpaScoreRepository gpaScoreRepository;
+ private SiteUserFixture siteUserFixture;
- private SiteUser siteUser1;
- private SiteUser siteUser2;
- private SiteUser siteUser3;
private GpaScore gpaScore1;
private GpaScore gpaScore2;
private GpaScore gpaScore3;
@BeforeEach
void setUp() {
- siteUser1 = createSiteUser(1, "test1");
- siteUser2 = createSiteUser(2, "test2");
- siteUser3 = createSiteUser(3, "test3");
- gpaScore3 = createGpaScore(siteUser3, VerifyStatus.REJECTED);
- gpaScore2 = createGpaScore(siteUser2, VerifyStatus.PENDING);
- gpaScore1 = createGpaScore(siteUser1, VerifyStatus.PENDING);
+ SiteUser user1 = siteUserFixture.사용자(1, "test1");
+ SiteUser user2 = siteUserFixture.사용자(2, "test2");
+ SiteUser user3 = siteUserFixture.사용자(3, "test3");
+ gpaScore3 = createGpaScore(user3, VerifyStatus.REJECTED);
+ gpaScore2 = createGpaScore(user2, VerifyStatus.PENDING);
+ gpaScore1 = createGpaScore(user1, VerifyStatus.PENDING);
}
@Nested
@@ -209,17 +204,6 @@ class GPA_점수_검증_및_수정 {
}
}
- private SiteUser createSiteUser(int index, String nickname) {
- SiteUser siteUser = new SiteUser(
- "test" + index + " @example.com",
- nickname,
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
private GpaScore createGpaScore(SiteUser siteUser, VerifyStatus status) {
GpaScore gpaScore = new GpaScore(
new Gpa(4.0, 4.5, "/gpa-report.pdf"),
diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
index a3d00457e..edf34670b 100644
--- a/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
@@ -9,10 +9,8 @@
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.type.VerifyStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -39,26 +37,23 @@ class AdminLanguageTestScoreServiceTest extends BaseIntegrationTest {
private AdminLanguageTestScoreService adminLanguageTestScoreService;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private LanguageTestScoreRepository languageTestScoreRepository;
@Autowired
- private LanguageTestScoreRepository languageTestScoreRepository;
+ private SiteUserFixture siteUserFixture;
- private SiteUser siteUser1;
- private SiteUser siteUser2;
- private SiteUser siteUser3;
private LanguageTestScore languageTestScore1;
private LanguageTestScore languageTestScore2;
private LanguageTestScore languageTestScore3;
@BeforeEach
void setUp() {
- siteUser1 = createSiteUser(1, "test1");
- siteUser2 = createSiteUser(2, "test2");
- siteUser3 = createSiteUser(3, "test3");
- languageTestScore3 = createLanguageTestScore(siteUser3, VerifyStatus.REJECTED);
- languageTestScore2 = createLanguageTestScore(siteUser2, VerifyStatus.PENDING);
- languageTestScore1 = createLanguageTestScore(siteUser1, VerifyStatus.PENDING);
+ SiteUser user1 = siteUserFixture.사용자(1, "test1");
+ SiteUser user2 = siteUserFixture.사용자(2, "test2");
+ SiteUser user3 = siteUserFixture.사용자(3, "test3");
+ languageTestScore3 = createLanguageTestScore(user3, VerifyStatus.REJECTED);
+ languageTestScore2 = createLanguageTestScore(user2, VerifyStatus.PENDING);
+ languageTestScore1 = createLanguageTestScore(user1, VerifyStatus.PENDING);
}
@Nested
@@ -219,17 +214,6 @@ class 어학점수_검증_및_수정 {
}
}
- private SiteUser createSiteUser(int index, String nickname) {
- SiteUser siteUser = new SiteUser(
- "test" + index + " @example.com",
- nickname,
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
private LanguageTestScore createLanguageTestScore(SiteUser siteUser, VerifyStatus status) {
LanguageTestScore languageTestScore = new LanguageTestScore(
new LanguageTest(TOEIC, "500", "/toeic-report.pdf"),
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
index 18c7c4ef0..cb0ffbb96 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
@@ -5,10 +5,8 @@
import com.example.solidconnection.auth.dto.ReissueResponse;
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -33,10 +31,10 @@ class AuthServiceTest {
private AuthTokenProvider authTokenProvider;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private RedisTemplate redisTemplate;
@Autowired
- private RedisTemplate redisTemplate;
+ private SiteUserFixture siteUserFixture;
@Test
void 로그아웃한다() {
@@ -58,18 +56,18 @@ class AuthServiceTest {
@Test
void 탈퇴한다() {
// given
- SiteUser siteUser = createSiteUser();
- Subject subject = authTokenProvider.toSubject(siteUser);
+ SiteUser user = siteUserFixture.사용자();
+ Subject subject = authTokenProvider.toSubject(user);
AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: #296
// when
- authService.quit(siteUser, accessToken.token());
+ authService.quit(user, accessToken.token());
// then
LocalDate tomorrow = LocalDate.now().plusDays(1);
String refreshTokenKey = TokenType.REFRESH.addPrefix(subject.value());
assertAll(
- () -> assertThat(siteUser.getQuitedAt()).isEqualTo(tomorrow),
+ () -> assertThat(user.getQuitedAt()).isEqualTo(tomorrow),
() -> assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isNull(),
() -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue()
);
@@ -105,15 +103,4 @@ class 토큰을_재발급한다 {
.hasMessage(REFRESH_TOKEN_EXPIRED.getMessage());
}
}
-
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
}
diff --git a/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java
index 5a32ef362..4a98de6ce 100644
--- a/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java
@@ -4,18 +4,14 @@
import com.example.solidconnection.auth.dto.SignInResponse;
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.custom.exception.ErrorCode;
-import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.password.PasswordEncoder;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
@@ -28,19 +24,15 @@ class EmailSignInServiceTest {
private EmailSignInService emailSignInService;
@Autowired
- private SiteUserRepository siteUserRepository;
-
- @Autowired
- private PasswordEncoder passwordEncoder;
+ private SiteUserFixture siteUserFixture;
@Test
void 로그인에_성공한다() {
// given
String email = "testEmail";
String rawPassword = "testPassword";
- SiteUser siteUser = createSiteUser(email, rawPassword);
- siteUserRepository.save(siteUser);
- EmailSignInRequest signInRequest = new EmailSignInRequest(siteUser.getEmail(), rawPassword);
+ SiteUser user = siteUserFixture.사용자(email, rawPassword);
+ EmailSignInRequest signInRequest = new EmailSignInRequest(user.getEmail(), rawPassword);
// when
SignInResponse signInResponse = emailSignInService.signIn(signInRequest);
@@ -70,8 +62,7 @@ class 로그인에_실패한다 {
void 비밀번호가_일치하지_않으면_예외_응답을_반환한다() {
// given
String email = "testEmail";
- SiteUser siteUser = createSiteUser(email, "testPassword");
- siteUserRepository.save(siteUser);
+ siteUserFixture.사용자(email, "testPassword");
EmailSignInRequest signInRequest = new EmailSignInRequest(email, "틀린비밀번호");
// when & then
@@ -80,17 +71,4 @@ class 로그인에_실패한다 {
.hasMessageContaining(ErrorCode.USER_NOT_FOUND.getMessage());
}
}
-
- private SiteUser createSiteUser(String email, String rawPassword) {
- String encodedPassword = passwordEncoder.encode(rawPassword);
- return new SiteUser(
- email,
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE,
- AuthType.EMAIL,
- encodedPassword
- );
- }
}
diff --git a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
index e40f20b7a..51eee236c 100644
--- a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
@@ -4,10 +4,8 @@
import com.example.solidconnection.auth.dto.SignInResponse;
import com.example.solidconnection.config.security.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.util.JwtUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -31,28 +29,24 @@ class SignInServiceTest {
private JwtProperties jwtProperties;
@Autowired
- private AuthTokenProvider authTokenProvider;
-
- @Autowired
- private SiteUserRepository siteUserRepository;
+ private RedisTemplate redisTemplate;
@Autowired
- private RedisTemplate redisTemplate;
+ private SiteUserFixture siteUserFixture;
- private SiteUser siteUser;
+ private SiteUser user;
private String subject;
@BeforeEach
void setUp() {
- siteUser = createSiteUser();
- siteUserRepository.save(siteUser);
- subject = siteUser.getId().toString();
+ user = siteUserFixture.사용자();
+ subject = user.getId().toString();
}
@Test
void 성공적으로_로그인한다() {
// when
- SignInResponse signInResponse = signInService.signIn(siteUser);
+ SignInResponse signInResponse = signInService.signIn(user);
// then
String accessTokenSubject = JwtUtils.parseSubject(signInResponse.accessToken(), jwtProperties.secret());
@@ -67,23 +61,12 @@ void setUp() {
@Test
void 탈퇴한_이력이_있으면_초기화한다() {
// given
- siteUser.setQuitedAt(LocalDate.now().minusDays(1));
- siteUserRepository.save(siteUser);
+ user.setQuitedAt(LocalDate.now().minusDays(1));
// when
- signInService.signIn(siteUser);
+ signInService.signIn(user);
// then
- assertThat(siteUser.getQuitedAt()).isNull();
- }
-
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
+ assertThat(user.getQuitedAt()).isNull();
}
}
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
index 328a1dc41..d3931008a 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
@@ -15,11 +15,13 @@
import com.example.solidconnection.s3.UploadedFileUrlResponse;
import com.example.solidconnection.service.RedisService;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
import com.example.solidconnection.type.ImgType;
import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
import jakarta.transaction.Transactional;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -63,6 +65,16 @@ class PostCommandServiceTest extends BaseIntegrationTest {
@Autowired
private PostImageRepository postImageRepository;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
+ private SiteUser user1;
+
+ @BeforeEach
+ void setUp() {
+ user1 = siteUserFixture.사용자(1, "test1");
+ }
+
@Nested
class 게시글_생성_테스트 {
@@ -78,7 +90,7 @@ class 게시글_생성_테스트 {
// when
PostCreateResponse response = postCommandService.createPost(
- 테스트유저_1,
+ user1,
request,
imageFiles
);
@@ -107,7 +119,7 @@ class 게시글_생성_테스트 {
// when & then
assertThatThrownBy(() ->
- postCommandService.createPost(테스트유저_1, request, imageFiles))
+ postCommandService.createPost(user1, request, imageFiles))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_POST_CATEGORY.getMessage());
}
@@ -120,7 +132,7 @@ class 게시글_생성_테스트 {
// when & then
assertThatThrownBy(() ->
- postCommandService.createPost(테스트유저_1, request, imageFiles))
+ postCommandService.createPost(user1, request, imageFiles))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_POST_CATEGORY.getMessage());
}
@@ -133,7 +145,7 @@ class 게시글_생성_테스트 {
// when & then
assertThatThrownBy(() ->
- postCommandService.createPost(테스트유저_1, request, imageFiles))
+ postCommandService.createPost(user1, request, imageFiles))
.isInstanceOf(CustomException.class)
.hasMessage(CAN_NOT_UPLOAD_MORE_THAN_FIVE_IMAGES.getMessage());
}
@@ -148,7 +160,7 @@ class 게시글_수정_테스트 {
// given
String originImageUrl = "origin-image-url";
String expectedImageUrl = "update-image-url";
- Post testPost = createPost(자유게시판, 테스트유저_1, originImageUrl);
+ Post testPost = createPost(자유게시판, user1, originImageUrl);
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = List.of(createImageFile());
@@ -157,7 +169,7 @@ class 게시글_수정_테스트 {
// when
PostUpdateResponse response = postCommandService.updatePost(
- 테스트유저_1,
+ user1,
testPost.getId(),
request,
imageFiles
@@ -180,14 +192,15 @@ class 게시글_수정_테스트 {
@Test
void 다른_사용자의_게시글을_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1, "origin-image-url");
+ SiteUser user2 = siteUserFixture.사용자(2, "test2");
+ Post testPost = createPost(자유게시판, user1, "origin-image-url");
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = List.of();
// when & then
assertThatThrownBy(() ->
postCommandService.updatePost(
- 테스트유저_2,
+ user2,
testPost.getId(),
request,
imageFiles
@@ -199,14 +212,14 @@ class 게시글_수정_테스트 {
@Test
void 질문_게시글을_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createQuestionPost(자유게시판, 테스트유저_1, "origin-image-url");
+ Post testPost = createQuestionPost(자유게시판, user1, "origin-image-url");
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = List.of();
// when & then
assertThatThrownBy(() ->
postCommandService.updatePost(
- 테스트유저_1,
+ user1,
testPost.getId(),
request,
imageFiles
@@ -218,14 +231,14 @@ class 게시글_수정_테스트 {
@Test
void 이미지를_5개_초과하여_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1, "origin-image-url");
+ Post testPost = createPost(자유게시판, user1, "origin-image-url");
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = createSixImageFiles();
// when & then
assertThatThrownBy(() ->
postCommandService.updatePost(
- 테스트유저_1,
+ user1,
testPost.getId(),
request,
imageFiles
@@ -242,13 +255,13 @@ class 게시글_삭제_테스트 {
void 게시글을_성공적으로_삭제한다() {
// given
String originImageUrl = "origin-image-url";
- Post testPost = createPost(자유게시판, 테스트유저_1, originImageUrl);
+ Post testPost = createPost(자유게시판, user1, originImageUrl);
String viewCountKey = redisUtils.getPostViewCountRedisKey(testPost.getId());
redisService.increaseViewCount(viewCountKey);
// when
PostDeleteResponse response = postCommandService.deletePostById(
- 테스트유저_1,
+ user1,
testPost.getId()
);
@@ -264,12 +277,13 @@ class 게시글_삭제_테스트 {
@Test
void 다른_사용자의_게시글을_삭제하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1, "origin-image-url");
+ SiteUser user2 = siteUserFixture.사용자(2, "test2");
+ Post testPost = createPost(자유게시판, user1, "origin-image-url");
// when & then
assertThatThrownBy(() ->
postCommandService.deletePostById(
- 테스트유저_2,
+ user2,
testPost.getId()
))
.isInstanceOf(CustomException.class)
@@ -279,12 +293,12 @@ class 게시글_삭제_테스트 {
@Test
void 질문_게시글을_삭제하면_예외_응답을_반환한다() {
// given
- Post testPost = createQuestionPost(자유게시판, 테스트유저_1, "origin-image-url");
+ Post testPost = createQuestionPost(자유게시판, user1, "origin-image-url");
// when & then
assertThatThrownBy(() ->
postCommandService.deletePostById(
- 테스트유저_1,
+ user1,
testPost.getId()
))
.isInstanceOf(CustomException.class)
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
index 23fa6bf50..30026e46a 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
@@ -8,8 +8,10 @@
import com.example.solidconnection.community.post.repository.PostLikeRepository;
import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
import com.example.solidconnection.type.PostCategory;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -33,18 +35,28 @@ class PostLikeServiceTest extends BaseIntegrationTest {
@Autowired
private PostLikeRepository postLikeRepository;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
+ private SiteUser user;
+
+ @BeforeEach
+ void setUp() {
+ user = siteUserFixture.사용자(1, "test1");
+ }
+
@Nested
class 게시글_좋아요_테스트 {
@Test
void 게시글을_성공적으로_좋아요한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
+ Post testPost = createPost(자유게시판, user);
long beforeLikeCount = testPost.getLikeCount();
// when
PostLikeResponse response = postLikeService.likePost(
- 테스트유저_1,
+ user,
testPost.getId()
);
@@ -54,20 +66,20 @@ class 게시글_좋아요_테스트 {
() -> assertThat(response.likeCount()).isEqualTo(beforeLikeCount + 1),
() -> assertThat(response.isLiked()).isTrue(),
() -> assertThat(likedPost.getLikeCount()).isEqualTo(beforeLikeCount + 1),
- () -> assertThat(postLikeRepository.findPostLikeByPostAndSiteUser(likedPost, 테스트유저_1)).isPresent()
+ () -> assertThat(postLikeRepository.findPostLikeByPostAndSiteUser(likedPost, user)).isPresent()
);
}
@Test
void 이미_좋아요한_게시글을_다시_좋아요하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- postLikeService.likePost(테스트유저_1, testPost.getId());
+ Post testPost = createPost(자유게시판, user);
+ postLikeService.likePost(user, testPost.getId());
// when & then
assertThatThrownBy(() ->
postLikeService.likePost(
- 테스트유저_1,
+ user,
testPost.getId()
))
.isInstanceOf(CustomException.class)
@@ -81,13 +93,13 @@ class 게시글_좋아요_취소_테스트 {
@Test
void 게시글_좋아요를_성공적으로_취소한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- PostLikeResponse beforeResponse = postLikeService.likePost(테스트유저_1, testPost.getId());
+ Post testPost = createPost(자유게시판, user);
+ PostLikeResponse beforeResponse = postLikeService.likePost(user, testPost.getId());
long beforeLikeCount = beforeResponse.likeCount();
// when
PostDislikeResponse response = postLikeService.dislikePost(
- 테스트유저_1,
+ user,
testPost.getId()
);
@@ -97,19 +109,19 @@ class 게시글_좋아요_취소_테스트 {
() -> assertThat(response.likeCount()).isEqualTo(beforeLikeCount - 1),
() -> assertThat(response.isLiked()).isFalse(),
() -> assertThat(unlikedPost.getLikeCount()).isEqualTo(beforeLikeCount - 1),
- () -> assertThat(postLikeRepository.findPostLikeByPostAndSiteUser(unlikedPost, 테스트유저_1)).isEmpty()
+ () -> assertThat(postLikeRepository.findPostLikeByPostAndSiteUser(unlikedPost, user)).isEmpty()
);
}
@Test
void 좋아요하지_않은_게시글을_좋아요_취소하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
+ Post testPost = createPost(자유게시판, user);
// when & then
assertThatThrownBy(() ->
postLikeService.dislikePost(
- 테스트유저_1,
+ user,
testPost.getId()
))
.isInstanceOf(CustomException.class)
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
index fc7926698..67212e014 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
@@ -13,10 +13,12 @@
import com.example.solidconnection.community.post.repository.PostImageRepository;
import com.example.solidconnection.service.RedisService;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
import com.example.solidconnection.type.BoardCode;
import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
+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;
@@ -48,6 +50,16 @@ class PostQueryServiceTest extends BaseIntegrationTest {
@Autowired
private PostImageRepository postImageRepository;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
+ private SiteUser user;
+
+ @BeforeEach
+ void setUp() {
+ user = siteUserFixture.사용자(1, "test1");
+ }
+
@Test
void 게시판_코드와_카테고리로_게시글_목록을_조회한다() {
// given
@@ -103,15 +115,15 @@ class PostQueryServiceTest extends BaseIntegrationTest {
// given
String expectedImageUrl = "test-image-url";
List imageUrls = List.of(expectedImageUrl);
- Post testPost = createPost(자유게시판, 테스트유저_1, expectedImageUrl);
- List comments = createComments(testPost, 테스트유저_1, List.of("첫번째 댓글", "두번째 댓글"));
+ Post testPost = createPost(자유게시판, user, expectedImageUrl);
+ List comments = createComments(testPost, user, List.of("첫번째 댓글", "두번째 댓글"));
- String validateKey = redisUtils.getValidatePostViewCountRedisKey(테스트유저_1.getId(), testPost.getId());
+ String validateKey = redisUtils.getValidatePostViewCountRedisKey(user.getId(), testPost.getId());
String viewCountKey = redisUtils.getPostViewCountRedisKey(testPost.getId());
// when
PostFindResponse response = postQueryService.findPostById(
- 테스트유저_1,
+ user,
testPost.getId()
);
@@ -128,9 +140,9 @@ class PostQueryServiceTest extends BaseIntegrationTest {
() -> assertThat(response.postFindBoardResponse().code()).isEqualTo(자유게시판.getCode()),
() -> assertThat(response.postFindBoardResponse().koreanName()).isEqualTo(자유게시판.getKoreanName()),
- () -> assertThat(response.postFindSiteUserResponse().id()).isEqualTo(테스트유저_1.getId()),
- () -> assertThat(response.postFindSiteUserResponse().nickname()).isEqualTo(테스트유저_1.getNickname()),
- () -> assertThat(response.postFindSiteUserResponse().profileImageUrl()).isEqualTo(테스트유저_1.getProfileImageUrl()),
+ () -> assertThat(response.postFindSiteUserResponse().id()).isEqualTo(user.getId()),
+ () -> assertThat(response.postFindSiteUserResponse().nickname()).isEqualTo(user.getNickname()),
+ () -> assertThat(response.postFindSiteUserResponse().profileImageUrl()).isEqualTo(user.getProfileImageUrl()),
() -> assertThat(response.postFindPostImageResponses())
.hasSize(imageUrls.size())
diff --git a/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java b/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java
index fdcf0ec8d..4f2ddf687 100644
--- a/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java
+++ b/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java
@@ -6,11 +6,10 @@
import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.community.post.service.PostLikeService;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.type.PostCategory;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -31,43 +30,39 @@ class PostLikeCountConcurrencyTest {
@Autowired
private PostLikeService postLikeService;
+
@Autowired
private PostRepository postRepository;
+
@Autowired
private BoardRepository boardRepository;
+
@Autowired
private SiteUserRepository siteUserRepository;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
@Value("${view.count.scheduling.delay}")
private int SCHEDULING_DELAY_MS;
+
private int THREAD_NUMS = 1000;
private int THREAD_POOL_SIZE = 200;
private int TIMEOUT_SECONDS = 10;
private Post post;
private Board board;
- private SiteUser siteUser;
+ private SiteUser user;
@BeforeEach
void setUp() {
board = createBoard();
boardRepository.save(board);
- siteUser = createSiteUser();
- siteUserRepository.save(siteUser);
- post = createPost(board, siteUser);
+ user = siteUserFixture.사용자();
+ post = createPost(board, user);
postRepository.save(post);
}
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- }
-
private Board createBoard() {
return new Board(
"FREE", "자유게시판");
diff --git a/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java b/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java
index beeb8b046..6c1a0e18f 100644
--- a/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java
+++ b/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java
@@ -6,11 +6,9 @@
import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.service.RedisService;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.type.PostCategory;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.util.RedisUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -23,54 +21,48 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import static com.example.solidconnection.type.RedisConstants.*;
+import static com.example.solidconnection.type.RedisConstants.VALIDATE_VIEW_COUNT_TTL;
import static org.junit.jupiter.api.Assertions.assertEquals;
@TestContainerSpringBootTest
@DisplayName("게시글 조회수 동시성 테스트")
-public class PostViewCountConcurrencyTest {
+class PostViewCountConcurrencyTest {
@Autowired
private RedisService redisService;
+
@Autowired
private PostRepository postRepository;
+
@Autowired
private BoardRepository boardRepository;
- @Autowired
- private SiteUserRepository siteUserRepository;
+
@Autowired
private RedisUtils redisUtils;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
@Value("${view.count.scheduling.delay}")
private int SCHEDULING_DELAY_MS;
+
private int THREAD_NUMS = 1000;
private int THREAD_POOL_SIZE = 200;
private int TIMEOUT_SECONDS = 10;
private Post post;
private Board board;
- private SiteUser siteUser;
+ private SiteUser user;
@BeforeEach
- public void setUp() {
+ void setUp() {
board = createBoard();
boardRepository.save(board);
- siteUser = createSiteUser();
- siteUserRepository.save(siteUser);
- post = createPost(board, siteUser);
+ user = siteUserFixture.사용자();
+ post = createPost(board, user);
postRepository.save(post);
}
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- }
-
private Board createBoard() {
return new Board(
"FREE", "자유게시판");
@@ -91,9 +83,9 @@ private Post createPost(Board board, SiteUser siteUser) {
}
@Test
- public void 게시글을_조회할_때_조회수_동시성_문제를_해결한다() throws InterruptedException {
+ void 게시글을_조회할_때_조회수_동시성_문제를_해결한다() throws InterruptedException {
- redisService.deleteKey(redisUtils.getValidatePostViewCountRedisKey(siteUser.getId(), post.getId()));
+ redisService.deleteKey(redisUtils.getValidatePostViewCountRedisKey(user.getId(), post.getId()));
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
CountDownLatch doneSignal = new CountDownLatch(THREAD_NUMS);
@@ -121,9 +113,9 @@ private Post createPost(Board board, SiteUser siteUser) {
}
@Test
- public void 게시글을_조회할_때_조회수_조작_문제를_해결한다() throws InterruptedException {
+ void 게시글을_조회할_때_조회수_조작_문제를_해결한다() throws InterruptedException {
- redisService.deleteKey(redisUtils.getValidatePostViewCountRedisKey(siteUser.getId(), post.getId()));
+ redisService.deleteKey(redisUtils.getValidatePostViewCountRedisKey(user.getId(), post.getId()));
ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
CountDownLatch doneSignal = new CountDownLatch(THREAD_NUMS);
@@ -131,7 +123,7 @@ private Post createPost(Board board, SiteUser siteUser) {
for (int i = 0; i < THREAD_NUMS; i++) {
executorService.submit(() -> {
try {
- boolean isFirstTime = redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(siteUser.getId(), post.getId()));
+ boolean isFirstTime = redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(user.getId(), post.getId()));
if (isFirstTime) {
redisService.increaseViewCount(redisUtils.getPostViewCountRedisKey(post.getId()));
}
@@ -144,7 +136,7 @@ private Post createPost(Board board, SiteUser siteUser) {
for (int i = 0; i < THREAD_NUMS; i++) {
executorService.submit(() -> {
try {
- boolean isFirstTime = redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(siteUser.getId(), post.getId()));
+ boolean isFirstTime = redisService.isPresent(redisUtils.getValidatePostViewCountRedisKey(user.getId(), post.getId()));
if (isFirstTime) {
redisService.increaseViewCount(redisUtils.getPostViewCountRedisKey(post.getId()));
}
diff --git a/src/test/java/com/example/solidconnection/concurrency/ThunderingHerdTest.java b/src/test/java/com/example/solidconnection/concurrency/ThunderingHerdTest.java
index 4800a0153..d2cadca65 100644
--- a/src/test/java/com/example/solidconnection/concurrency/ThunderingHerdTest.java
+++ b/src/test/java/com/example/solidconnection/concurrency/ThunderingHerdTest.java
@@ -2,10 +2,8 @@
import com.example.solidconnection.application.service.ApplicationQueryService;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -22,32 +20,25 @@
@TestContainerSpringBootTest
@DisplayName("ThunderingHerd 테스트")
-public class ThunderingHerdTest {
+class ThunderingHerdTest {
+
@Autowired
private ApplicationQueryService applicationQueryService;
+
@Autowired
private RedisTemplate redisTemplate;
+
@Autowired
- private SiteUserRepository siteUserRepository;
+ private SiteUserFixture siteUserFixture;
+
private int THREAD_NUMS = 1000;
private int THREAD_POOL_SIZE = 200;
private int TIMEOUT_SECONDS = 10;
- private SiteUser siteUser;
+ private SiteUser user;
@BeforeEach
public void setUp() {
- siteUser = createSiteUser();
- siteUserRepository.save(siteUser);
- }
-
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
+ user = siteUserFixture.사용자();
}
@Test
@@ -63,9 +54,9 @@ private SiteUser createSiteUser() {
executorService.submit(() -> {
try {
List tasks = Arrays.asList(
- () -> applicationQueryService.getApplicants(siteUser, "", ""),
- () -> applicationQueryService.getApplicants(siteUser, "ASIA", ""),
- () -> applicationQueryService.getApplicants(siteUser, "", "추오")
+ () -> applicationQueryService.getApplicants(user, "", ""),
+ () -> applicationQueryService.getApplicants(user, "ASIA", ""),
+ () -> applicationQueryService.getApplicants(user, "", "추오")
);
Collections.shuffle(tasks);
tasks.forEach(Runnable::run);
diff --git a/src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java b/src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java
index b517681aa..e0c1a006f 100644
--- a/src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java
+++ b/src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java
@@ -1,14 +1,11 @@
package com.example.solidconnection.custom.resolver;
-
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -32,7 +29,7 @@ class AuthorizedUserResolverTest {
private AuthorizedUserResolver authorizedUserResolver;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private SiteUserFixture siteUserFixture;
@BeforeEach
void setUp() {
@@ -42,8 +39,8 @@ void setUp() {
@Test
void security_context_에_저장된_인증된_사용자를_반환한다() {
// given
- SiteUser siteUser = createAndSaveSiteUser();
- Authentication authentication = createAuthenticationWithUser(siteUser);
+ SiteUser user = siteUserFixture.사용자();
+ Authentication authentication = createAuthenticationWithUser(user);
SecurityContextHolder.getContext().setAuthentication(authentication);
MethodParameter parameter = mock(MethodParameter.class);
@@ -55,7 +52,7 @@ void setUp() {
SiteUser resolveSiteUser = (SiteUser) authorizedUserResolver.resolveArgument(parameter, null, null, null);
// then
- assertThat(resolveSiteUser).isEqualTo(siteUser);
+ assertThat(resolveSiteUser).isEqualTo(user);
}
@Nested
@@ -90,17 +87,6 @@ class security_context_에_저장된_사용자가_없는_경우 {
}
}
- private SiteUser createAndSaveSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
private SiteUserAuthentication createAuthenticationWithUser(SiteUser siteUser) {
SiteUserDetails userDetails = new SiteUserDetails(siteUser);
return new SiteUserAuthentication("token", userDetails);
diff --git a/src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java b/src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java
index 0104c9ccd..b733acceb 100644
--- a/src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java
+++ b/src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java
@@ -3,9 +3,8 @@
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.custom.security.annotation.RequireAdminAccess;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,13 +23,16 @@ class AdminAuthorizationAspectTest {
@Autowired
private TestService testService;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
@Test
void 어드민_사용자는_어드민_전용_메소드에_접근할_수_있다() {
// given
- SiteUser adminUser = createSiteUser(Role.ADMIN);
+ SiteUser admin = siteUserFixture.관리자();
// when
- boolean response = testService.adminOnlyMethod(adminUser);
+ boolean response = testService.adminOnlyMethod(admin);
// then
assertThat(response).isTrue();
@@ -39,10 +41,10 @@ class AdminAuthorizationAspectTest {
@Test
void 일반_사용자가_어드민_전용_메소드에_접근하면_예외_응답을_반환한다() {
// given
- SiteUser mentorUser = createSiteUser(Role.MENTOR);
+ SiteUser user = siteUserFixture.사용자();
// when & then
- assertThatCode(() -> testService.adminOnlyMethod(mentorUser))
+ assertThatCode(() -> testService.adminOnlyMethod(user))
.isInstanceOf(CustomException.class)
.hasMessage(ACCESS_DENIED.getMessage());
}
@@ -50,28 +52,18 @@ class AdminAuthorizationAspectTest {
@Test
void 어드민_어노테이션이_없는_메소드는_모두_접근_가능하다() {
// given
- SiteUser menteeUser = createSiteUser(Role.MENTEE);
- SiteUser adminUser = createSiteUser(Role.ADMIN);
+ SiteUser user = siteUserFixture.사용자();
+ SiteUser admin = siteUserFixture.관리자();
// when
- boolean menteeResponse = testService.publicMethod(menteeUser);
- boolean adminResponse = testService.publicMethod(adminUser);
+ boolean menteeResponse = testService.publicMethod(user);
+ boolean adminResponse = testService.publicMethod(admin);
// then
assertThat(menteeResponse).isTrue();
assertThat(adminResponse).isTrue();
}
- private SiteUser createSiteUser(Role role) {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- role
- );
- }
-
@TestConfiguration
static class TestConfig {
diff --git a/src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java b/src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java
index 423bec415..b8999e3f5 100644
--- a/src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java
+++ b/src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java
@@ -5,10 +5,8 @@
import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.BeforeEach;
@@ -38,14 +36,13 @@ class SiteUserAuthenticationProviderTest {
private JwtProperties jwtProperties;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private SiteUserFixture siteUserFixture;
- private SiteUser siteUser;
+ private SiteUser user;
@BeforeEach
void setUp() {
- siteUser = createSiteUser();
- siteUserRepository.save(siteUser);
+ user = siteUserFixture.사용자();
}
@Test
@@ -64,7 +61,7 @@ void setUp() {
@Test
void 유효한_토큰이면_정상적으로_인증_정보를_반환한다() {
// given
- String token = createValidToken(siteUser.getId());
+ String token = createValidToken(user.getId());
SiteUserAuthentication auth = new SiteUserAuthentication(token);
// when
@@ -106,7 +103,7 @@ class 예외_응답을_반환하다 {
@Test
void 유효한_토큰이지만_해당되는_사용자가_없으면_예외_응답을_반환한다() {
// given
- long notExistingUserId = siteUser.getId() + 100;
+ long notExistingUserId = user.getId() + 100;
String token = createValidToken(notExistingUserId);
SiteUserAuthentication auth = new SiteUserAuthentication(token);
@@ -128,7 +125,7 @@ private String createValidToken(long id) {
private String createExpiredToken() {
return Jwts.builder()
- .setSubject(String.valueOf(siteUser.getId()))
+ .setSubject(String.valueOf(user.getId()))
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() - 1000))
.signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
@@ -143,14 +140,4 @@ private String createWrongSubjectTypeToken() {
.signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
.compact();
}
-
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- }
}
diff --git a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java b/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java
index 0b2a0db73..718732a44 100644
--- a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java
+++ b/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java
@@ -2,10 +2,9 @@
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -26,14 +25,17 @@ class SiteUserDetailsServiceTest {
@Autowired
private SiteUserDetailsService userDetailsService;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
@Autowired
private SiteUserRepository siteUserRepository;
@Test
void 사용자_인증_정보를_반환한다() {
// given
- SiteUser siteUser = siteUserRepository.save(createSiteUser());
- String username = getUserName(siteUser);
+ SiteUser user = siteUserFixture.사용자();
+ String username = getUserName(user);
// when
SiteUserDetails userDetails = (SiteUserDetails) userDetailsService.loadUserByUsername(username);
@@ -41,7 +43,7 @@ class SiteUserDetailsServiceTest {
// then
assertAll(
() -> assertThat(userDetails.getUsername()).isEqualTo(username),
- () -> assertThat(userDetails.getSiteUser()).extracting("id").isEqualTo(siteUser.getId())
+ () -> assertThat(userDetails.getSiteUser()).extracting("id").isEqualTo(user.getId())
);
}
@@ -73,10 +75,10 @@ class 예외_응답을_반환한다 {
@Test
void 탈퇴한_사용자이면_예외_응답을_반환한다() {
// given
- SiteUser siteUser = createSiteUser();
- siteUser.setQuitedAt(LocalDate.now());
- siteUserRepository.save(siteUser);
- String username = getUserName(siteUser);
+ SiteUser user = siteUserFixture.사용자();
+ user.setQuitedAt(LocalDate.now());
+ siteUserRepository.save(user);
+ String username = getUserName(user);
// when & then
assertThatCode(() -> userDetailsService.loadUserByUsername(username))
@@ -85,16 +87,6 @@ class 예외_응답을_반환한다 {
}
}
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- }
-
private String getUserName(SiteUser siteUser) {
return siteUser.getId().toString();
}
diff --git a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java b/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java
index b49b9cf27..6fe9b6d69 100644
--- a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java
+++ b/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java
@@ -1,10 +1,8 @@
package com.example.solidconnection.custom.security.userdetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,13 +17,13 @@
class SiteUserDetailsTest {
@Autowired
- private SiteUserRepository siteUserRepository;
+ private SiteUserFixture siteUserFixture;
@Test
void 사용자_권한을_정상적으로_반환한다() {
// given
- SiteUser siteUser = siteUserRepository.save(createSiteUser());
- SiteUserDetails siteUserDetails = new SiteUserDetails(siteUser);
+ SiteUser user = siteUserFixture.사용자();
+ SiteUserDetails siteUserDetails = new SiteUserDetails(user);
// when
Collection extends GrantedAuthority> authorities = siteUserDetails.getAuthorities();
@@ -33,16 +31,6 @@ class SiteUserDetailsTest {
// then
assertThat(authorities)
.extracting("authority")
- .containsExactly("ROLE_" + siteUser.getRole().name());
- }
-
- private SiteUser createSiteUser() {
- return new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
+ .containsExactly("ROLE_" + user.getRole().name());
}
}
diff --git a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
index a8b1ac3d8..27ed7a617 100644
--- a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
@@ -15,13 +15,13 @@
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
import com.example.solidconnection.type.ImgType;
import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.type.VerifyStatus;
+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;
@@ -52,17 +52,26 @@ class ScoreServiceTest extends BaseIntegrationTest {
@MockBean
private S3Service s3Service;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
+ private SiteUser user;
+
+ @BeforeEach
+ void setUp() {
+ user = siteUserFixture.사용자();
+ }
+
@Test
void GPA_점수_상태를_조회한다() {
// given
- SiteUser testUser = createSiteUser();
List scores = List.of(
- createGpaScore(testUser, 3.5, 4.5),
- createGpaScore(testUser, 3.8, 4.5)
+ createGpaScore(user, 3.5, 4.5),
+ createGpaScore(user, 3.8, 4.5)
);
// when
- GpaScoreStatusesResponse response = scoreService.getGpaScoreStatus(testUser);
+ GpaScoreStatusesResponse response = scoreService.getGpaScoreStatus(user);
// then
assertThat(response.gpaScoreStatusResponseList())
@@ -76,11 +85,8 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Test
void GPA_점수가_없는_경우_빈_리스트를_반환한다() {
- // given
- SiteUser testUser = createSiteUser();
-
// when
- GpaScoreStatusesResponse response = scoreService.getGpaScoreStatus(testUser);
+ GpaScoreStatusesResponse response = scoreService.getGpaScoreStatus(user);
// then
assertThat(response.gpaScoreStatusResponseList()).isEmpty();
@@ -89,15 +95,14 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Test
void 어학_시험_점수_상태를_조회한다() {
// given
- SiteUser testUser = createSiteUser();
List scores = List.of(
- createLanguageTestScore(testUser, LanguageTestType.TOEIC, "100"),
- createLanguageTestScore(testUser, LanguageTestType.TOEFL_IBT, "7.5")
+ createLanguageTestScore(user, LanguageTestType.TOEIC, "100"),
+ createLanguageTestScore(user, LanguageTestType.TOEFL_IBT, "7.5")
);
- siteUserRepository.save(testUser);
+ siteUserRepository.save(user);
// when
- LanguageTestScoreStatusesResponse response = scoreService.getLanguageTestScoreStatus(testUser);
+ LanguageTestScoreStatusesResponse response = scoreService.getLanguageTestScoreStatus(user);
// then
assertThat(response.languageTestScoreStatusResponseList())
@@ -111,11 +116,8 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Test
void 어학_시험_점수가_없는_경우_빈_리스트를_반환한다() {
- // given
- SiteUser testUser = createSiteUser();
-
// when
- LanguageTestScoreStatusesResponse response = scoreService.getLanguageTestScoreStatus(testUser);
+ LanguageTestScoreStatusesResponse response = scoreService.getLanguageTestScoreStatus(user);
// then
assertThat(response.languageTestScoreStatusResponseList()).isEmpty();
@@ -124,14 +126,13 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Test
void GPA_점수를_등록한다() {
// given
- SiteUser testUser = createSiteUser();
GpaScoreRequest request = createGpaScoreRequest();
MockMultipartFile file = createFile();
String fileUrl = "/gpa-report.pdf";
given(s3Service.uploadFile(file, ImgType.GPA)).willReturn(new UploadedFileUrlResponse(fileUrl));
// when
- long scoreId = scoreService.submitGpaScore(testUser, request, file);
+ long scoreId = scoreService.submitGpaScore(user, request, file);
GpaScore savedScore = gpaScoreRepository.findById(scoreId).orElseThrow();
// then
@@ -147,14 +148,13 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Test
void 어학_시험_점수를_등록한다() {
// given
- SiteUser testUser = createSiteUser();
LanguageTestScoreRequest request = createLanguageTestScoreRequest();
MockMultipartFile file = createFile();
String fileUrl = "/gpa-report.pdf";
given(s3Service.uploadFile(file, ImgType.LANGUAGE_TEST)).willReturn(new UploadedFileUrlResponse(fileUrl));
// when
- long scoreId = scoreService.submitLanguageTestScore(testUser, request, file);
+ long scoreId = scoreService.submitLanguageTestScore(user, request, file);
LanguageTestScore savedScore = languageTestScoreRepository.findById(scoreId).orElseThrow();
// then
@@ -167,17 +167,6 @@ class ScoreServiceTest extends BaseIntegrationTest {
);
}
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
private GpaScore createGpaScore(SiteUser siteUser, double gpa, double gpaCriteria) {
GpaScore gpaScore = new GpaScore(
new Gpa(gpa, gpaCriteria, "/gpa-report.pdf"),
diff --git a/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
new file mode 100644
index 000000000..000b7bc48
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
@@ -0,0 +1,69 @@
+package com.example.solidconnection.siteuser.fixture;
+
+import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.type.Role;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class SiteUserFixture {
+
+ private final SiteUserFixtureBuilder siteUserFixtureBuilder;
+
+ public SiteUser 사용자() {
+ return siteUserFixtureBuilder.siteUser()
+ .email("test@example.com")
+ .authType(AuthType.EMAIL)
+ .nickname("사용자")
+ .profileImageUrl("profileImageUrl")
+ .role(Role.MENTEE)
+ .password("password123")
+ .create();
+ }
+
+ public SiteUser 사용자(int index, String nickname) {
+ return siteUserFixtureBuilder.siteUser()
+ .email("test" + index + "@example.com")
+ .authType(AuthType.EMAIL)
+ .nickname(nickname)
+ .profileImageUrl("profileImageUrl")
+ .role(Role.MENTEE)
+ .password("password123")
+ .create();
+ }
+
+ public SiteUser 사용자(String email, AuthType authType) {
+ return siteUserFixtureBuilder.siteUser()
+ .email(email)
+ .authType(authType)
+ .nickname("사용자")
+ .profileImageUrl("profileImageUrl")
+ .role(Role.MENTEE)
+ .password("password123")
+ .create();
+ }
+
+ public SiteUser 사용자(String email, String password) {
+ return siteUserFixtureBuilder.siteUser()
+ .email(email)
+ .authType(AuthType.EMAIL)
+ .nickname("사용자")
+ .profileImageUrl("profileImageUrl")
+ .role(Role.MENTEE)
+ .password(password)
+ .create();
+ }
+
+ public SiteUser 관리자() {
+ return siteUserFixtureBuilder.siteUser()
+ .email("admin@example.com")
+ .authType(AuthType.EMAIL)
+ .nickname("관리자")
+ .profileImageUrl("profileImageUrl")
+ .role(Role.ADMIN)
+ .password("admin123")
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java
new file mode 100644
index 000000000..f0d8bd406
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java
@@ -0,0 +1,72 @@
+package com.example.solidconnection.siteuser.fixture;
+
+import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.type.PreparationStatus;
+import com.example.solidconnection.type.Role;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+import org.springframework.security.crypto.password.PasswordEncoder;
+
+@TestComponent
+@RequiredArgsConstructor
+public class SiteUserFixtureBuilder {
+
+ private final SiteUserRepository siteUserRepository;
+ private final PasswordEncoder passwordEncoder;
+
+ private String email;
+ private AuthType authType;
+ private String nickname;
+ private String profileImageUrl;
+ private Role role;
+ private String password;
+
+ public SiteUserFixtureBuilder siteUser() {
+ return new SiteUserFixtureBuilder(siteUserRepository, passwordEncoder);
+ }
+
+ public SiteUserFixtureBuilder email(String email) {
+ this.email = email;
+ return this;
+ }
+
+ public SiteUserFixtureBuilder authType(AuthType authType) {
+ this.authType = authType;
+ return this;
+ }
+
+ public SiteUserFixtureBuilder nickname(String nickname) {
+ this.nickname = nickname;
+ return this;
+ }
+
+ public SiteUserFixtureBuilder profileImageUrl(String profileImageUrl) {
+ this.profileImageUrl = profileImageUrl;
+ return this;
+ }
+
+ public SiteUserFixtureBuilder role(Role role) {
+ this.role = role;
+ return this;
+ }
+
+ public SiteUserFixtureBuilder password(String password) {
+ this.password = password;
+ return this;
+ }
+
+ public SiteUser create() {
+ SiteUser siteUser = new SiteUser(
+ email,
+ nickname,
+ profileImageUrl,
+ PreparationStatus.CONSIDERING,
+ role,
+ authType,
+ passwordEncoder.encode(password)
+ );
+ return siteUserRepository.save(siteUser);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
index 95a887736..1c5680d33 100644
--- a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
+++ b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
@@ -3,17 +3,19 @@
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.s3.S3Service;
import com.example.solidconnection.s3.UploadedFileUrlResponse;
+import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.dto.MyPageResponse;
-import com.example.solidconnection.siteuser.dto.NicknameUpdateRequest;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixtureBuilder;
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.type.ImgType;
-import com.example.solidconnection.type.PreparationStatus;
import com.example.solidconnection.type.Role;
import com.example.solidconnection.university.domain.LikedUniversity;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -38,8 +40,9 @@
import static org.mockito.BDDMockito.never;
import static org.mockito.BDDMockito.then;
+@TestContainerSpringBootTest
@DisplayName("마이페이지 서비스 테스트")
-class MyPageServiceTest extends BaseIntegrationTest {
+class MyPageServiceTest {
@Autowired
private MyPageService myPageService;
@@ -53,22 +56,37 @@ class MyPageServiceTest extends BaseIntegrationTest {
@Autowired
private LikedUniversityRepository likedUniversityRepository;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
+ @Autowired
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
+ @Autowired
+ private SiteUserFixtureBuilder siteUserFixtureBuilder;
+
+ private SiteUser user;
+
+ @BeforeEach
+ void setUp() {
+ user = siteUserFixture.사용자();
+ }
+
@Test
void 마이페이지_정보를_조회한다() {
// given
- SiteUser testUser = createSiteUser();
- int likedUniversityCount = createLikedUniversities(testUser);
+ int likedUniversityCount = createLikedUniversities(user);
// when
- MyPageResponse response = myPageService.getMyPageInfo(testUser);
+ MyPageResponse response = myPageService.getMyPageInfo(user);
// then
Assertions.assertAll(
- () -> assertThat(response.nickname()).isEqualTo(testUser.getNickname()),
- () -> assertThat(response.profileImageUrl()).isEqualTo(testUser.getProfileImageUrl()),
- () -> assertThat(response.role()).isEqualTo(testUser.getRole()),
- () -> assertThat(response.email()).isEqualTo(testUser.getEmail()),
- () -> assertThat(response.likedPostCount()).isEqualTo(testUser.getPostLikeList().size()),
+ () -> assertThat(response.nickname()).isEqualTo(user.getNickname()),
+ () -> assertThat(response.profileImageUrl()).isEqualTo(user.getProfileImageUrl()),
+ () -> assertThat(response.role()).isEqualTo(user.getRole()),
+ () -> assertThat(response.email()).isEqualTo(user.getEmail()),
+ () -> assertThat(response.likedPostCount()).isEqualTo(user.getPostLikeList().size()),
() -> assertThat(response.likedUniversityCount()).isEqualTo(likedUniversityCount)
);
}
@@ -76,21 +94,13 @@ class MyPageServiceTest extends BaseIntegrationTest {
@Test
void 관심_대학교_목록을_조회한다() {
// given
- SiteUser testUser = createSiteUser();
- int likedUniversityCount = createLikedUniversities(testUser);
+ int likedUniversityCount = createLikedUniversities(user);
// when
- List response = myPageService.getWishUniversity(testUser);
+ List response = myPageService.getWishUniversity(user);
// then
- assertThat(response)
- .hasSize(likedUniversityCount)
- .usingRecursiveFieldByFieldElementComparatorIgnoringFields("id")
- .containsAll(List.of(
- UniversityInfoForApplyPreviewResponse.from(괌대학_A_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(메이지대학_지원_정보),
- UniversityInfoForApplyPreviewResponse.from(코펜하겐IT대학_지원_정보)
- ));
+ assertThat(response).hasSize(likedUniversityCount);
}
@Nested
@@ -99,29 +109,27 @@ class 프로필_이미지_수정_테스트 {
@Test
void 새로운_이미지로_성공적으로_업데이트한다() {
// given
- SiteUser testUser = createSiteUser();
String expectedUrl = "newProfileImageUrl";
MockMultipartFile imageFile = createValidImageFile();
given(s3Service.uploadFile(any(), eq(ImgType.PROFILE)))
.willReturn(new UploadedFileUrlResponse(expectedUrl));
// when
- myPageService.updateMyPageInfo(testUser, imageFile, "newNickname");
+ myPageService.updateMyPageInfo(user, imageFile, "newNickname");
// then
- assertThat(testUser.getProfileImageUrl()).isEqualTo(expectedUrl);
+ assertThat(user.getProfileImageUrl()).isEqualTo(expectedUrl);
}
@Test
void 프로필을_처음_수정하는_것이면_이전_이미지를_삭제하지_않는다() {
// given
- SiteUser testUser = createSiteUser();
MockMultipartFile imageFile = createValidImageFile();
given(s3Service.uploadFile(any(), eq(ImgType.PROFILE)))
.willReturn(new UploadedFileUrlResponse("newProfileImageUrl"));
// when
- myPageService.updateMyPageInfo(testUser, imageFile, "newNickname");
+ myPageService.updateMyPageInfo(user, imageFile, "newNickname");
// then
then(s3Service).should(never()).deleteExProfile(any());
@@ -130,16 +138,16 @@ class 프로필_이미지_수정_테스트 {
@Test
void 프로필을_처음_수정하는_것이_아니라면_이전_이미지를_삭제한다() {
// given
- SiteUser testUser = createSiteUserWithCustomProfile();
+ SiteUser 커스텀_프로필_사용자 = createSiteUserWithCustomProfile();
MockMultipartFile imageFile = createValidImageFile();
given(s3Service.uploadFile(any(), eq(ImgType.PROFILE)))
.willReturn(new UploadedFileUrlResponse("newProfileImageUrl"));
// when
- myPageService.updateMyPageInfo(testUser, imageFile, "newNickname");
+ myPageService.updateMyPageInfo(커스텀_프로필_사용자, imageFile, "newNickname");
// then
- then(s3Service).should().deleteExProfile(testUser);
+ then(s3Service).should().deleteExProfile(커스텀_프로필_사용자);
}
}
@@ -155,15 +163,14 @@ void setUp() {
@Test
void 닉네임을_성공적으로_수정한다() {
// given
- SiteUser testUser = createSiteUser();
MockMultipartFile imageFile = createValidImageFile();
String newNickname = "newNickname";
// when
- myPageService.updateMyPageInfo(testUser, imageFile, newNickname);
+ myPageService.updateMyPageInfo(user, imageFile, newNickname);
// then
- SiteUser updatedUser = siteUserRepository.findById(testUser.getId()).get();
+ SiteUser updatedUser = siteUserRepository.findById(user.getId()).get();
assertThat(updatedUser.getNicknameModifiedAt()).isNotNull();
assertThat(updatedUser.getNickname()).isEqualTo(newNickname);
}
@@ -171,12 +178,10 @@ void setUp() {
@Test
void 중복된_닉네임으로_변경하면_예외_응답을_반환한다() {
// given
- createDuplicatedSiteUser();
- SiteUser testUser = createSiteUser();
- MockMultipartFile imageFile = createValidImageFile();
+ SiteUser existingUser = siteUserFixture.사용자(1, "existing nickname");
// when & then
- assertThatCode(() -> myPageService.updateMyPageInfo(testUser, imageFile, "duplicatedNickname"))
+ assertThatCode(() -> myPageService.updateMyPageInfo(user, null, existingUser.getNickname()))
.isInstanceOf(CustomException.class)
.hasMessage(NICKNAME_ALREADY_EXISTED.getMessage());
}
@@ -184,58 +189,21 @@ void setUp() {
@Test
void 최소_대기기간이_지나지_않은_상태에서_변경하면_예외_응답을_반환한다() {
// given
- SiteUser testUser = createSiteUser();
MockMultipartFile imageFile = createValidImageFile();
LocalDateTime modifiedAt = LocalDateTime.now().minusDays(MIN_DAYS_BETWEEN_NICKNAME_CHANGES - 1);
- testUser.setNicknameModifiedAt(modifiedAt);
- siteUserRepository.save(testUser);
-
- NicknameUpdateRequest request = new NicknameUpdateRequest("newNickname");
+ user.setNicknameModifiedAt(modifiedAt);
// when & then
- assertThatCode(() -> myPageService.updateMyPageInfo(testUser, imageFile, "nickname12"))
+ assertThatCode(() -> myPageService.updateMyPageInfo(user, imageFile, "nickname12"))
.isInstanceOf(CustomException.class)
.hasMessage(createExpectedErrorMessage(modifiedAt));
}
}
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
- private SiteUser createSiteUserWithCustomProfile() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profile/profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
- private void createDuplicatedSiteUser() {
- SiteUser siteUser = new SiteUser(
- "duplicated@example.com",
- "duplicatedNickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- siteUserRepository.save(siteUser);
- }
-
private int createLikedUniversities(SiteUser testUser) {
- LikedUniversity likedUniversity1 = new LikedUniversity(null, 괌대학_A_지원_정보, testUser);
- LikedUniversity likedUniversity2 = new LikedUniversity(null, 메이지대학_지원_정보, testUser);
- LikedUniversity likedUniversity3 = new LikedUniversity(null, 코펜하겐IT대학_지원_정보, testUser);
+ LikedUniversity likedUniversity1 = new LikedUniversity(null, universityInfoForApplyFixture.괌대학_A_지원_정보(), testUser);
+ LikedUniversity likedUniversity2 = new LikedUniversity(null, universityInfoForApplyFixture.메이지대학_지원_정보(), testUser);
+ LikedUniversity likedUniversity3 = new LikedUniversity(null, universityInfoForApplyFixture.코펜하겐IT대학_지원_정보(), testUser);
likedUniversityRepository.save(likedUniversity1);
likedUniversityRepository.save(likedUniversity2);
@@ -259,4 +227,15 @@ private String createExpectedErrorMessage(LocalDateTime modifiedAt) {
);
return CAN_NOT_CHANGE_NICKNAME_YET.getMessage() + " : " + formatLastModifiedAt;
}
+
+ private SiteUser createSiteUserWithCustomProfile() {
+ return siteUserFixtureBuilder.siteUser()
+ .email("customProfile@example.com")
+ .authType(AuthType.EMAIL)
+ .nickname("커스텀프로필")
+ .profileImageUrl("profile/profileImageUrl")
+ .role(Role.MENTEE)
+ .password("customPassword123")
+ .create();
+ }
}
diff --git a/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java
index 6c9736198..665fb11da 100644
--- a/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java
+++ b/src/test/java/com/example/solidconnection/siteuser/service/SiteUserServiceTest.java
@@ -2,10 +2,8 @@
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.dto.NicknameExistsResponse;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -14,20 +12,21 @@
import static org.assertj.core.api.Assertions.assertThat;
+@TestContainerSpringBootTest
@DisplayName("유저 서비스 테스트")
-class SiteUserServiceTest extends BaseIntegrationTest {
+class SiteUserServiceTest {
@Autowired
private SiteUserService siteUserService;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private SiteUserFixture siteUserFixture;
- private SiteUser siteUser;
+ private SiteUser user;
@BeforeEach
void setUp() {
- siteUser = createSiteUser();
+ user = siteUserFixture.사용자();
}
@Nested
@@ -36,7 +35,7 @@ class 닉네임_중복_검사 {
@Test
void 존재하는_닉네임이면_true를_반환한다() {
// when
- NicknameExistsResponse response = siteUserService.checkNicknameExists(siteUser.getNickname());
+ NicknameExistsResponse response = siteUserService.checkNicknameExists(user.getNickname());
// then
assertThat(response.exists()).isTrue();
@@ -51,15 +50,4 @@ class 닉네임_중복_검사 {
assertThat(response.exists()).isFalse();
}
}
-
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
}
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
index 3b2ab8c22..7f970108a 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
@@ -2,11 +2,9 @@
import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.university.domain.LikedUniversity;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.IsLikeResponse;
@@ -38,17 +36,17 @@ class UniversityLikeServiceTest {
private LikedUniversityRepository likedUniversityRepository;
@Autowired
- private SiteUserRepository siteUserRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
private UniversityInfoForApplyFixture universityInfoForApplyFixture;
- private SiteUser testUser;
+ private SiteUser user;
private UniversityInfoForApply 괌대학_A_지원_정보;
@BeforeEach
void setUp() {
- testUser = createSiteUser();
+ user = siteUserFixture.사용자();
괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
}
@@ -58,13 +56,13 @@ class 대학_좋아요를_등록한다 {
@Test
void 성공적으로_좋아요를_등록한다() {
// when
- LikeResultResponse response = universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId());
+ LikeResultResponse response = universityLikeService.likeUniversity(user, 괌대학_A_지원_정보.getId());
// then
assertAll(
() -> assertThat(response.result()).isEqualTo(LIKE_SUCCESS_MESSAGE),
() -> assertThat(likedUniversityRepository.findBySiteUserAndUniversityInfoForApply(
- testUser, 괌대학_A_지원_정보
+ user, 괌대학_A_지원_정보
)).isPresent()
);
}
@@ -72,10 +70,10 @@ class 대학_좋아요를_등록한다 {
@Test
void 이미_좋아요한_대학이면_예외_응답을_반환한다() {
// given
- saveLikedUniversity(testUser, 괌대학_A_지원_정보);
+ saveLikedUniversity(user, 괌대학_A_지원_정보);
// when & then
- assertThatCode(() -> universityLikeService.likeUniversity(testUser, 괌대학_A_지원_정보.getId()))
+ assertThatCode(() -> universityLikeService.likeUniversity(user, 괌대학_A_지원_정보.getId()))
.isInstanceOf(CustomException.class)
.hasMessage(ALREADY_LIKED_UNIVERSITY.getMessage());
}
@@ -87,16 +85,16 @@ class 대학_좋아요를_취소한다 {
@Test
void 성공적으로_좋아요를_취소한다() {
// given
- saveLikedUniversity(testUser, 괌대학_A_지원_정보);
+ saveLikedUniversity(user, 괌대학_A_지원_정보);
// when
- LikeResultResponse response = universityLikeService.cancelLikeUniversity(testUser, 괌대학_A_지원_정보.getId());
+ LikeResultResponse response = universityLikeService.cancelLikeUniversity(user, 괌대학_A_지원_정보.getId());
// then
assertAll(
() -> assertThat(response.result()).isEqualTo(LIKE_CANCELED_MESSAGE),
() -> assertThat(likedUniversityRepository.findBySiteUserAndUniversityInfoForApply(
- testUser, 괌대학_A_지원_정보
+ user, 괌대학_A_지원_정보
)).isEmpty()
);
}
@@ -104,7 +102,7 @@ class 대학_좋아요를_취소한다 {
@Test
void 좋아요하지_않은_대학이면_예외_응답을_반환한다() {
// when & then
- assertThatCode(() -> universityLikeService.cancelLikeUniversity(testUser, 괌대학_A_지원_정보.getId()))
+ assertThatCode(() -> universityLikeService.cancelLikeUniversity(user, 괌대학_A_지원_정보.getId()))
.isInstanceOf(CustomException.class)
.hasMessage(NOT_LIKED_UNIVERSITY.getMessage());
}
@@ -116,7 +114,7 @@ class 대학_좋아요를_취소한다 {
Long invalidUniversityId = 9999L;
// when & then
- assertThatCode(() -> universityLikeService.likeUniversity(testUser, invalidUniversityId))
+ assertThatCode(() -> universityLikeService.likeUniversity(user, invalidUniversityId))
.isInstanceOf(CustomException.class)
.hasMessage(UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND.getMessage());
}
@@ -124,10 +122,10 @@ class 대학_좋아요를_취소한다 {
@Test
void 좋아요한_대학인지_확인한다() {
// given
- saveLikedUniversity(testUser, 괌대학_A_지원_정보);
+ saveLikedUniversity(user, 괌대학_A_지원_정보);
// when
- IsLikeResponse response = universityLikeService.getIsLiked(testUser, 괌대학_A_지원_정보.getId());
+ IsLikeResponse response = universityLikeService.getIsLiked(user, 괌대학_A_지원_정보.getId());
// then
assertThat(response.isLike()).isTrue();
@@ -136,7 +134,7 @@ class 대학_좋아요를_취소한다 {
@Test
void 좋아요하지_않은_대학인지_확인한다() {
// when
- IsLikeResponse response = universityLikeService.getIsLiked(testUser, 괌대학_A_지원_정보.getId());
+ IsLikeResponse response = universityLikeService.getIsLiked(user, 괌대학_A_지원_정보.getId());
// then
assertThat(response.isLike()).isFalse();
@@ -148,23 +146,11 @@ class 대학_좋아요를_취소한다 {
Long invalidUniversityId = 9999L;
// when & then
- assertThatCode(() -> universityLikeService.getIsLiked(testUser, invalidUniversityId))
+ assertThatCode(() -> universityLikeService.getIsLiked(user, invalidUniversityId))
.isInstanceOf(CustomException.class)
.hasMessage(UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND.getMessage());
}
- // todo : 추후 Fixture로 대체 필요
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
-
private void saveLikedUniversity(SiteUser siteUser, UniversityInfoForApply universityInfoForApply) {
LikedUniversity likedUniversity = LikedUniversity.builder()
.siteUser(siteUser)
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
index 7645794bf..ffacab33f 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
@@ -7,10 +7,8 @@
import com.example.solidconnection.repositories.InterestedCountyRepository;
import com.example.solidconnection.repositories.InterestedRegionRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
import com.example.solidconnection.university.dto.UniversityRecommendsResponse;
@@ -32,9 +30,6 @@ class UniversityRecommendServiceTest {
@Autowired
private UniversityRecommendService universityRecommendService;
- @Autowired
- private SiteUserRepository siteUserRepository;
-
@Autowired
private InterestedRegionRepository interestedRegionRepository;
@@ -44,6 +39,9 @@ class UniversityRecommendServiceTest {
@Autowired
private GeneralUniversityRecommendService generalUniversityRecommendService;
+ @Autowired
+ private SiteUserFixture siteUserFixture;
+
@Autowired
private RegionFixture regionFixture;
@@ -53,41 +51,37 @@ class UniversityRecommendServiceTest {
@Autowired
private UniversityInfoForApplyFixture universityInfoForApplyFixture;
- private SiteUser testUser;
+ private SiteUser user;
private UniversityInfoForApply 괌대학_A_지원_정보;
private UniversityInfoForApply 괌대학_B_지원_정보;
private UniversityInfoForApply 네바다주립대학_라스베이거스_지원_정보;
private UniversityInfoForApply 메모리얼대학_세인트존스_A_지원_정보;
private UniversityInfoForApply 서던덴마크대학교_지원_정보;
private UniversityInfoForApply 코펜하겐IT대학_지원_정보;
- private UniversityInfoForApply 그라츠대학_지원_정보;
- private UniversityInfoForApply 그라츠공과대학_지원_정보;
- private UniversityInfoForApply 린츠_카톨릭대학_지원_정보;
- private UniversityInfoForApply 메이지대학_지원_정보;
@BeforeEach
void setUp() {
- testUser = createSiteUser();
+ user = siteUserFixture.사용자();
괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
괌대학_B_지원_정보 = universityInfoForApplyFixture.괌대학_B_지원_정보();
네바다주립대학_라스베이거스_지원_정보 = universityInfoForApplyFixture.네바다주립대학_라스베이거스_지원_정보();
메모리얼대학_세인트존스_A_지원_정보 = universityInfoForApplyFixture.메모리얼대학_세인트존스_A_지원_정보();
서던덴마크대학교_지원_정보 = universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
코펜하겐IT대학_지원_정보 = universityInfoForApplyFixture.코펜하겐IT대학_지원_정보();
- 그라츠대학_지원_정보 = universityInfoForApplyFixture.그라츠대학_지원_정보();
- 그라츠공과대학_지원_정보 = universityInfoForApplyFixture.그라츠공과대학_지원_정보();
- 린츠_카톨릭대학_지원_정보 = universityInfoForApplyFixture.린츠_카톨릭대학_지원_정보();
- 메이지대학_지원_정보 = universityInfoForApplyFixture.메이지대학_지원_정보();
+ universityInfoForApplyFixture.그라츠대학_지원_정보();
+ universityInfoForApplyFixture.그라츠공과대학_지원_정보();
+ universityInfoForApplyFixture.린츠_카톨릭대학_지원_정보();
+ universityInfoForApplyFixture.메이지대학_지원_정보();
generalUniversityRecommendService.init();
}
@Test
void 관심_지역_설정한_사용자의_맞춤_추천_대학을_조회한다() {
// given
- interestedRegionRepository.save(new InterestedRegion(testUser, regionFixture.영미권()));
+ interestedRegionRepository.save(new InterestedRegion(user, regionFixture.영미권()));
// when
- UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
+ UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(user);
// then
assertThat(response.recommendedUniversities())
@@ -103,10 +97,10 @@ void setUp() {
@Test
void 관심_국가_설정한_사용자의_맞춤_추천_대학을_조회한다() {
// given
- interestedCountyRepository.save(new InterestedCountry(testUser, countryFixture.덴마크()));
+ interestedCountyRepository.save(new InterestedCountry(user, countryFixture.덴마크()));
// when
- UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
+ UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(user);
// then
assertThat(response.recommendedUniversities())
@@ -120,11 +114,11 @@ void setUp() {
@Test
void 관심_지역과_국가_모두_설정한_사용자의_맞춤_추천_대학을_조회한다() {
// given
- interestedRegionRepository.save(new InterestedRegion(testUser, regionFixture.영미권()));
- interestedCountyRepository.save(new InterestedCountry(testUser, countryFixture.덴마크()));
+ interestedRegionRepository.save(new InterestedRegion(user, regionFixture.영미권()));
+ interestedCountyRepository.save(new InterestedCountry(user, countryFixture.덴마크()));
// when
- UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
+ UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(user);
// then
assertThat(response.recommendedUniversities())
@@ -142,7 +136,7 @@ void setUp() {
@Test
void 관심사_미설정_사용자는_일반_추천_대학을_조회한다() {
// when
- UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(testUser);
+ UniversityRecommendsResponse response = universityRecommendService.getPersonalRecommends(user);
// then
assertThat(response.recommendedUniversities())
@@ -168,16 +162,4 @@ void setUp() {
.toList()
);
}
-
- // todo : 추후 Fixture로 대체 필요
- private SiteUser createSiteUser() {
- SiteUser siteUser = new SiteUser(
- "test@example.com",
- "nickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE
- );
- return siteUserRepository.save(siteUser);
- }
}
From 0518a772ba8e16c4830ca045f4de4c4d8701faa7 Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Mon, 19 May 2025 21:58:42 +0900
Subject: [PATCH 16/90] =?UTF-8?q?refactor:=20=EB=8F=84=EB=A9=94=EC=9D=B8?=
=?UTF-8?q?=EB=B3=84=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EA=B5=AC=EC=A1=B0?=
=?UTF-8?q?=EB=A1=9C=20=EC=9E=AC=EA=B5=AC=EC=84=B1=20(#322)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: community 관련 Type 클래스 패키지 이동
- BoardCode를 community.board.domain 으로
- PostCategory를 community.post.domain 으로
- RedisConstants 를 community.post.service 로
* refactor: s3 관련 Type 클래스 패키지 이동
- ImgType을 s3로
* refactor: university 관련 Type 클래스 패키지 이동
- LanguageTestType, SemesterAvailableForDispatch, TuitionFeeType을 university.domain 으로
* refactor: siteUser 관련 Type 클래스 패키지 이동
- PreparationStatus, Role을 siteuser.domain 로
* refactor: application 관련 Type 클래스 패키지 이동
- VerifyStatus 을 application.domain 로
* refactor: 게시글 관련 redis 클래스 패키지 이동
- RedisService, UpdateViewCountService 를 post.service 로
* refactor: 지역 관련 클래스 패키지 이동
- location 패키지 하위에 region 과 country 를 생성
- Region, InterestedRegion 을 location.region.domain 으로
- Country, InterestedCountry 을 location.country.domain 으로
- RegionRepository, InterestedRegionRepository를 location.region.repository 으로
- CountryRepository, InterestedCountyRepository를 location.country.repository 으로
- 테스트 코드는 프로덕션 코드와 대응하는 위치로
* refactor: security 관련 클래스 패키지 이동
- custom.security에 있던 security를 루트 경로로
- 스프링 시큐리티는 서블릿 밖에 존재하므로, 분리된 하나의 관심사라 볼 수 있다.
* refactor: 공용 코드의 패키지 이름 변경
- custom -> common
* refactor: dto 입력 검증 관련 클래스 패키지 이동
- 특정 dto 에서만 사용하므로, 그 하위로 옮긴다.
- RejectedReasonRequired, RejectedReasonValidator를 admin.dto.validation 으로
- ValidUniversityChoice, ValidUniversityChoiceValidator를 university.dto.validation 으로
* refactor: BaseEntity 패키지 이동
- 여러 도메인에서 쓰이므로 common 하위로
* refactor: 특정 도메인에만 관련된 config 패키지 이동
- 관련 도메인 하위에서만 필요한 설정은 그 도메인 하위로 옮긴다.
- AppleOAuthClientProperties, KakaoOAuthClientProperties 를 auth.client.config 로
- CorsProperties, JwtProperties, SecurityConfiguration, AuthenticationManagerConfig 를 security.config 로
* refactor: config 클래스 패키지 이동
config -> common.config
* refactor: S3 클래스 패키지 이동
- 다른 도메인 패키지들과 마찬가지로, 레이어별로 패키지를 나눈다.
* chore: conflict 해소와 import문 정리
---
.../controller/AdminScoreController.java | 2 +-
.../admin/dto/GpaScoreResponse.java | 2 +-
.../admin/dto/GpaScoreStatusResponse.java | 2 +-
.../admin/dto/GpaScoreUpdateRequest.java | 4 +--
.../admin/dto/LanguageTestResponse.java | 2 +-
.../admin/dto/LanguageTestScoreResponse.java | 4 +--
.../dto/LanguageTestScoreStatusResponse.java | 2 +-
.../dto/LanguageTestScoreUpdateRequest.java | 6 ++--
.../admin/dto/ScoreSearchCondition.java | 2 +-
.../admin/dto/ScoreUpdateRequest.java | 2 +-
.../admin/service/AdminGpaScoreService.java | 6 ++--
.../AdminLanguageTestScoreService.java | 6 ++--
.../controller/ApplicationController.java | 4 +--
.../application/domain/Application.java | 3 +-
.../application/domain/LanguageTest.java | 2 +-
.../domain}/VerifyStatus.java | 2 +-
.../application/dto/ApplicantResponse.java | 2 +-
.../dto/UniversityChoiceRequest.java | 2 +-
.../validation}/RejectedReasonRequired.java | 3 +-
.../validation}/RejectedReasonValidator.java | 7 ++--
.../repository/ApplicationRepository.java | 6 ++--
.../service/ApplicationQueryService.java | 6 ++--
.../service/ApplicationSubmissionService.java | 14 ++++----
.../auth/client/AppleOAuthClient.java | 8 ++---
.../AppleOAuthClientSecretProvider.java | 6 ++--
.../auth/client/ApplePublicKeyProvider.java | 10 +++---
.../auth/client/KakaoOAuthClient.java | 10 +++---
.../config}/AppleOAuthClientProperties.java | 2 +-
.../config}/KakaoOAuthClientProperties.java | 2 +-
.../auth/controller/AuthController.java | 6 ++--
.../auth/dto/SignUpRequest.java | 4 +--
.../auth/service/AuthService.java | 4 +--
.../auth/service/AuthTokenProvider.java | 2 +-
.../service/CommonSignUpTokenProvider.java | 6 ++--
.../auth/service/EmailSignInService.java | 4 +--
.../auth/service/EmailSignUpService.java | 12 +++----
.../service/EmailSignUpTokenProvider.java | 8 ++---
.../auth/service/SignUpService.java | 18 +++++-----
.../auth/service/TokenProvider.java | 2 +-
.../service/oauth/OAuthSignUpService.java | 12 +++----
.../oauth/OAuthSignUpTokenProvider.java | 8 ++---
.../cache/ThunderingHerdCachingAspect.java | 8 ++---
.../{entity => }/common/BaseEntity.java | 2 +-
.../config/client/RestTemplateConfig.java | 2 +-
.../config/redis/RedisConfig.java | 4 +--
.../config/scheduler/SchedulerConfig.java | 2 +-
.../{ => common}/config/sync/AsyncConfig.java | 2 +-
.../{ => common}/config/web/WebMvcConfig.java | 6 ++--
.../exception/CustomAccessDeniedHandler.java | 4 +--
.../CustomAuthenticationEntryPoint.java | 4 +--
.../exception/CustomException.java | 2 +-
.../exception/CustomExceptionHandler.java | 12 +++----
.../exception/ErrorCode.java | 2 +-
.../resolver/AuthorizedUser.java | 2 +-
.../resolver/AuthorizedUserResolver.java | 8 ++---
...PageableHandlerMethodArgumentResolver.java | 2 +-
.../response/ErrorResponse.java | 6 ++--
.../response/PageResponse.java | 2 +-
.../board/controller/BoardController.java | 4 +--
.../board/domain}/BoardCode.java | 2 +-
.../board/repository/BoardRepository.java | 6 ++--
.../comment/controller/CommentController.java | 2 +-
.../community/comment/domain/Comment.java | 2 +-
.../comment/repository/CommentRepository.java | 4 +--
.../comment/service/CommentService.java | 10 +++---
.../post/controller/PostController.java | 2 +-
.../community/post/domain/Post.java | 3 +-
.../community/post/domain/PostCategory.java | 5 +++
.../community/post/dto/PostCreateRequest.java | 2 +-
.../community/post/dto/PostListResponse.java | 2 +-
.../post/repository/PostLikeRepository.java | 4 +--
.../post/repository/PostRepository.java | 4 +--
.../post/service/PostCommandService.java | 21 ++++++------
.../post/service/PostLikeService.java | 6 ++--
.../post/service/PostQueryService.java | 15 ++++----
.../post/service}/RedisConstants.java | 2 +-
.../post}/service/RedisService.java | 8 ++---
.../post}/service/UpdateViewCountService.java | 2 +-
.../country/domain}/Country.java | 3 +-
.../country/domain}/InterestedCountry.java | 2 +-
.../repository}/CountryRepository.java | 4 +--
.../InterestedCountyRepository.java | 4 +--
.../region/domain}/InterestedRegion.java | 2 +-
.../region/domain}/Region.java | 2 +-
.../InterestedRegionRepository.java | 4 +--
.../region/repository}/RegionRepository.java | 4 +--
.../solidconnection/news/domain/News.java | 2 +-
.../s3/{ => config}/AmazonS3Config.java | 2 +-
.../s3/{ => controller}/S3Controller.java | 9 +++--
.../{type => s3/domain}/ImgType.java | 2 +-
.../s3/{ => dto}/UploadedFileUrlResponse.java | 2 +-
.../s3/{ => dto}/urlPrefixResponse.java | 2 +-
.../s3/{ => service}/FileUploadService.java | 8 ++---
.../s3/{ => service}/S3Service.java | 17 +++++-----
.../scheduler/UpdateViewCountScheduler.java | 4 +--
.../score/controller/ScoreController.java | 2 +-
.../score/domain/GpaScore.java | 4 +--
.../score/domain/LanguageTestScore.java | 4 +--
.../score/dto/GpaScoreStatusResponse.java | 2 +-
.../score/dto/LanguageTestResponse.java | 2 +-
.../score/dto/LanguageTestScoreRequest.java | 2 +-
.../dto/LanguageTestScoreStatusResponse.java | 2 +-
.../LanguageTestScoreRepository.java | 2 +-
.../custom/GpaScoreFilterRepositoryImpl.java | 2 +-
...LanguageTestScoreFilterRepositoryImpl.java | 2 +-
.../score/service/ScoreService.java | 10 +++---
.../annotation/RequireAdminAccess.java | 2 +-
.../aspect/AdminAuthorizationAspect.java | 10 +++---
.../authentication/JwtAuthentication.java | 2 +-
.../SiteUserAuthentication.java | 4 +--
.../config}/AuthenticationManagerConfig.java | 4 +--
.../config}/CorsProperties.java | 2 +-
.../config}/JwtProperties.java | 2 +-
.../config}/SecurityConfiguration.java | 14 ++++----
.../filter/ExceptionHandlerFilter.java | 10 +++---
.../filter/JwtAuthenticationFilter.java | 6 ++--
.../security/filter/SignOutCheckFilter.java | 6 ++--
.../SiteUserAuthenticationProvider.java | 12 +++----
.../userdetails/SecurityRoleMapper.java | 4 +--
.../security/userdetails/SiteUserDetails.java | 2 +-
.../userdetails/SiteUserDetailsService.java | 8 ++---
.../siteuser/controller/MyPageController.java | 2 +-
.../domain}/PreparationStatus.java | 2 +-
.../{type => siteuser/domain}/Role.java | 2 +-
.../siteuser/domain/SiteUser.java | 2 --
.../siteuser/dto/MyPageResponse.java | 2 +-
.../siteuser/service/MyPageService.java | 12 +++----
.../solidconnection/type/PostCategory.java | 5 ---
.../controller/UniversityController.java | 4 +--
.../domain/LanguageRequirement.java | 1 -
.../domain}/LanguageTestType.java | 2 +-
.../domain}/SemesterAvailableForDispatch.java | 2 +-
.../domain}/TuitionFeeType.java | 2 +-
.../university/domain/University.java | 4 +--
.../domain/UniversityInfoForApply.java | 2 --
.../dto/LanguageRequirementResponse.java | 2 +-
.../validation}/ValidUniversityChoice.java | 3 +-
.../ValidUniversityChoiceValidator.java | 9 +++--
.../LanguageRequirementRepository.java | 2 +-
.../UniversityInfoForApplyRepository.java | 6 ++--
.../repository/UniversityRepository.java | 4 +--
.../custom/UniversityFilterRepository.java | 2 +-
.../UniversityFilterRepositoryImpl.java | 6 ++--
.../service/UniversityLikeService.java | 6 ++--
.../service/UniversityQueryService.java | 2 +-
.../solidconnection/util/JwtUtils.java | 4 +--
.../solidconnection/util/RedisUtils.java | 8 ++---
.../RejectedReasonValidatorTest.java | 8 ++---
.../service/AdminGpaScoreServiceTest.java | 6 ++--
.../AdminLanguageTestScoreServiceTest.java | 8 ++---
.../service/ApplicationQueryServiceTest.java | 4 +--
.../ApplicationSubmissionServiceTest.java | 14 ++++----
.../auth/service/AuthServiceTest.java | 4 +--
.../auth/service/EmailSignInServiceTest.java | 4 +--
.../auth/service/SignInServiceTest.java | 2 +-
.../oauth/OAuthSignUpTokenProviderTest.java | 10 +++---
.../CustomAccessDeniedHandlerTest.java | 6 ++--
.../CustomAuthenticationEntryPointTest.java | 6 ++--
.../resolver/AuthorizedUserResolverTest.java | 10 +++---
...ableHandlerMethodArgumentResolverTest.java | 2 +-
.../comment/service/CommentServiceTest.java | 12 +++----
.../post/service/PostCommandServiceTest.java | 19 +++++------
.../post/service/PostLikeServiceTest.java | 8 ++---
.../post/service/PostQueryServiceTest.java | 11 +++---
.../PostLikeCountConcurrencyTest.java | 2 +-
.../PostViewCountConcurrencyTest.java | 6 ++--
.../solidconnection/e2e/DynamicFixture.java | 4 +--
.../country/fixture/CountryFixture.java | 6 ++--
.../fixture/CountryFixtureBuilder.java | 8 ++---
.../repository/CountryRepositoryForTest.java | 4 +--
.../region/fixture/RegionFixture.java | 4 +--
.../region/fixture/RegionFixtureBuilder.java | 6 ++--
.../repository/RegionRepositoryForTest.java | 4 +--
.../score/service/ScoreServiceTest.java | 10 +++---
.../aspect/AdminAuthorizationAspectTest.java | 8 ++---
.../SiteUserAuthenticationTest.java | 8 ++---
.../filter/ExceptionHandlerFilterTest.java | 7 ++--
.../filter/JwtAuthenticationFilterTest.java | 8 ++---
.../filter/SignOutCheckFilterTest.java | 20 +++++------
.../SiteUserAuthenticationProviderTest.java | 14 ++++----
.../SiteUserDetailsServiceTest.java | 8 ++---
.../userdetails/SiteUserDetailsTest.java | 2 +-
.../siteuser/fixture/SiteUserFixture.java | 2 +-
.../fixture/SiteUserFixtureBuilder.java | 4 +--
.../repository/SiteUserRepositoryTest.java | 4 +--
.../siteuser/service/MyPageServiceTest.java | 14 ++++----
.../integration/BaseIntegrationTest.java | 34 +++++++++----------
.../ValidUniversityChoiceValidatorTest.java | 8 ++---
.../fixture/LanguageRequirementFixture.java | 2 +-
.../LanguageRequirementFixtureBuilder.java | 2 +-
.../university/fixture/UniversityFixture.java | 4 +--
.../fixture/UniversityFixtureBuilder.java | 4 +--
.../UniversityInfoForApplyFixtureBuilder.java | 4 +--
.../service/UniversityLikeServiceTest.java | 8 ++---
.../service/UniversityQueryServiceTest.java | 10 +++---
.../UniversityRecommendServiceTest.java | 12 +++----
.../solidconnection/util/JwtUtilsTest.java | 4 +--
197 files changed, 527 insertions(+), 536 deletions(-)
rename src/main/java/com/example/solidconnection/{type => application/domain}/VerifyStatus.java (52%)
rename src/main/java/com/example/solidconnection/{custom/validation/annotation => application/dto/validation}/RejectedReasonRequired.java (78%)
rename src/main/java/com/example/solidconnection/{custom/validation/validator => application/dto/validation}/RejectedReasonValidator.java (82%)
rename src/main/java/com/example/solidconnection/{config/client => auth/client/config}/AppleOAuthClientProperties.java (87%)
rename src/main/java/com/example/solidconnection/{config/client => auth/client/config}/KakaoOAuthClientProperties.java (83%)
rename src/main/java/com/example/solidconnection/{entity => }/common/BaseEntity.java (95%)
rename src/main/java/com/example/solidconnection/{ => common}/config/client/RestTemplateConfig.java (90%)
rename src/main/java/com/example/solidconnection/{ => common}/config/redis/RedisConfig.java (95%)
rename src/main/java/com/example/solidconnection/{ => common}/config/scheduler/SchedulerConfig.java (94%)
rename src/main/java/com/example/solidconnection/{ => common}/config/sync/AsyncConfig.java (92%)
rename src/main/java/com/example/solidconnection/{ => common}/config/web/WebMvcConfig.java (82%)
rename src/main/java/com/example/solidconnection/{custom => common}/exception/CustomAccessDeniedHandler.java (90%)
rename src/main/java/com/example/solidconnection/{custom => common}/exception/CustomAuthenticationEntryPoint.java (90%)
rename src/main/java/com/example/solidconnection/{custom => common}/exception/CustomException.java (89%)
rename src/main/java/com/example/solidconnection/{custom => common}/exception/CustomExceptionHandler.java (89%)
rename src/main/java/com/example/solidconnection/{custom => common}/exception/ErrorCode.java (99%)
rename src/main/java/com/example/solidconnection/{custom => common}/resolver/AuthorizedUser.java (85%)
rename src/main/java/com/example/solidconnection/{custom => common}/resolver/AuthorizedUserResolver.java (88%)
rename src/main/java/com/example/solidconnection/{custom => common}/resolver/CustomPageableHandlerMethodArgumentResolver.java (92%)
rename src/main/java/com/example/solidconnection/{custom => common}/response/ErrorResponse.java (64%)
rename src/main/java/com/example/solidconnection/{custom => common}/response/PageResponse.java (92%)
rename src/main/java/com/example/solidconnection/{type => community/board/domain}/BoardCode.java (50%)
create mode 100644 src/main/java/com/example/solidconnection/community/post/domain/PostCategory.java
rename src/main/java/com/example/solidconnection/{type => community/post/service}/RedisConstants.java (90%)
rename src/main/java/com/example/solidconnection/{ => community/post}/service/RedisService.java (82%)
rename src/main/java/com/example/solidconnection/{ => community/post}/service/UpdateViewCountService.java (95%)
rename src/main/java/com/example/solidconnection/{entity => location/country/domain}/Country.java (85%)
rename src/main/java/com/example/solidconnection/{entity => location/country/domain}/InterestedCountry.java (92%)
rename src/main/java/com/example/solidconnection/{repositories => location/country/repository}/CountryRepository.java (78%)
rename src/main/java/com/example/solidconnection/{repositories => location/country/repository}/InterestedCountyRepository.java (72%)
rename src/main/java/com/example/solidconnection/{entity => location/region/domain}/InterestedRegion.java (92%)
rename src/main/java/com/example/solidconnection/{entity => location/region/domain}/Region.java (91%)
rename src/main/java/com/example/solidconnection/{repositories => location/region/repository}/InterestedRegionRepository.java (72%)
rename src/main/java/com/example/solidconnection/{repositories => location/region/repository}/RegionRepository.java (78%)
rename src/main/java/com/example/solidconnection/s3/{ => config}/AmazonS3Config.java (95%)
rename src/main/java/com/example/solidconnection/s3/{ => controller}/S3Controller.java (88%)
rename src/main/java/com/example/solidconnection/{type => s3/domain}/ImgType.java (83%)
rename src/main/java/com/example/solidconnection/s3/{ => dto}/UploadedFileUrlResponse.java (60%)
rename src/main/java/com/example/solidconnection/s3/{ => dto}/urlPrefixResponse.java (78%)
rename src/main/java/com/example/solidconnection/s3/{ => service}/FileUploadService.java (89%)
rename src/main/java/com/example/solidconnection/s3/{ => service}/S3Service.java (90%)
rename src/main/java/com/example/solidconnection/{custom => }/security/annotation/RequireAdminAccess.java (80%)
rename src/main/java/com/example/solidconnection/{custom => }/security/aspect/AdminAuthorizationAspect.java (75%)
rename src/main/java/com/example/solidconnection/{custom => }/security/authentication/JwtAuthentication.java (92%)
rename src/main/java/com/example/solidconnection/{custom => }/security/authentication/SiteUserAuthentication.java (69%)
rename src/main/java/com/example/solidconnection/{config/security => security/config}/AuthenticationManagerConfig.java (81%)
rename src/main/java/com/example/solidconnection/{config/security => security/config}/CorsProperties.java (79%)
rename src/main/java/com/example/solidconnection/{config/security => security/config}/JwtProperties.java (75%)
rename src/main/java/com/example/solidconnection/{config/security => security/config}/SecurityConfiguration.java (87%)
rename src/main/java/com/example/solidconnection/{custom => }/security/filter/ExceptionHandlerFilter.java (87%)
rename src/main/java/com/example/solidconnection/{custom => }/security/filter/JwtAuthenticationFilter.java (87%)
rename src/main/java/com/example/solidconnection/{custom => }/security/filter/SignOutCheckFilter.java (87%)
rename src/main/java/com/example/solidconnection/{custom => }/security/provider/SiteUserAuthenticationProvider.java (72%)
rename src/main/java/com/example/solidconnection/{custom => }/security/userdetails/SecurityRoleMapper.java (77%)
rename src/main/java/com/example/solidconnection/{custom => }/security/userdetails/SiteUserDetails.java (95%)
rename src/main/java/com/example/solidconnection/{custom => }/security/userdetails/SiteUserDetailsService.java (87%)
rename src/main/java/com/example/solidconnection/{type => siteuser/domain}/PreparationStatus.java (83%)
rename src/main/java/com/example/solidconnection/{type => siteuser/domain}/Role.java (52%)
delete mode 100644 src/main/java/com/example/solidconnection/type/PostCategory.java
rename src/main/java/com/example/solidconnection/{type => university/domain}/LanguageTestType.java (96%)
rename src/main/java/com/example/solidconnection/{type => university/domain}/SemesterAvailableForDispatch.java (90%)
rename src/main/java/com/example/solidconnection/{type => university/domain}/TuitionFeeType.java (87%)
rename src/main/java/com/example/solidconnection/{custom/validation/annotation => university/dto/validation}/ValidUniversityChoice.java (78%)
rename src/main/java/com/example/solidconnection/{custom/validation/validator => university/dto/validation}/ValidUniversityChoiceValidator.java (86%)
rename src/test/java/com/example/solidconnection/{custom/validation/validator => admin/dto/validation}/RejectedReasonValidatorTest.java (93%)
rename src/test/java/com/example/solidconnection/{custom => common}/exception/CustomAccessDeniedHandlerTest.java (90%)
rename src/test/java/com/example/solidconnection/{custom => common}/exception/CustomAuthenticationEntryPointTest.java (91%)
rename src/test/java/com/example/solidconnection/{custom => common}/resolver/AuthorizedUserResolverTest.java (91%)
rename src/test/java/com/example/solidconnection/{custom => common}/resolver/CustomPageableHandlerMethodArgumentResolverTest.java (98%)
rename src/test/java/com/example/solidconnection/{ => location}/country/fixture/CountryFixture.java (87%)
rename src/test/java/com/example/solidconnection/{ => location}/country/fixture/CountryFixtureBuilder.java (78%)
rename src/test/java/com/example/solidconnection/{ => location}/country/repository/CountryRepositoryForTest.java (62%)
rename src/test/java/com/example/solidconnection/{ => location}/region/fixture/RegionFixture.java (86%)
rename src/test/java/com/example/solidconnection/{ => location}/region/fixture/RegionFixtureBuilder.java (79%)
rename src/test/java/com/example/solidconnection/{ => location}/region/repository/RegionRepositoryForTest.java (62%)
rename src/test/java/com/example/solidconnection/{custom => }/security/aspect/AdminAuthorizationAspectTest.java (90%)
rename src/test/java/com/example/solidconnection/{custom => }/security/authentication/SiteUserAuthenticationTest.java (88%)
rename src/test/java/com/example/solidconnection/{custom => }/security/filter/ExceptionHandlerFilterTest.java (93%)
rename src/test/java/com/example/solidconnection/{custom => }/security/filter/JwtAuthenticationFilterTest.java (91%)
rename src/test/java/com/example/solidconnection/{custom => }/security/filter/SignOutCheckFilterTest.java (85%)
rename src/test/java/com/example/solidconnection/{custom => }/security/provider/SiteUserAuthenticationProviderTest.java (91%)
rename src/test/java/com/example/solidconnection/{custom => }/security/userdetails/SiteUserDetailsServiceTest.java (92%)
rename src/test/java/com/example/solidconnection/{custom => }/security/userdetails/SiteUserDetailsTest.java (94%)
rename src/test/java/com/example/solidconnection/{custom/validation/validator => university/dto/validation}/ValidUniversityChoiceValidatorTest.java (92%)
diff --git a/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java b/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java
index 47bac37e1..d2869e4d3 100644
--- a/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java
+++ b/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java
@@ -9,7 +9,7 @@
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.admin.service.AdminGpaScoreService;
import com.example.solidconnection.admin.service.AdminLanguageTestScoreService;
-import com.example.solidconnection.custom.response.PageResponse;
+import com.example.solidconnection.common.response.PageResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java
index 5f37e823b..c90ba6a40 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.admin.dto;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.score.domain.GpaScore;
-import com.example.solidconnection.type.VerifyStatus;
public record GpaScoreResponse(
long id,
diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java
index 49afbd4ed..a9d1d0668 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
import java.time.ZonedDateTime;
diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java
index b7fe58c71..c22979ea6 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.application.dto.validation.RejectedReasonRequired;
import jakarta.validation.constraints.NotNull;
@RejectedReasonRequired
diff --git a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestResponse.java b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestResponse.java
index c91fc68c3..257b8fd6f 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestResponse.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestResponse.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
public record LanguageTestResponse(
LanguageTestType languageTestType,
diff --git a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreResponse.java b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreResponse.java
index aee435c9c..978dcae82 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreResponse.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreResponse.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.admin.dto;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.university.domain.LanguageTestType;
public record LanguageTestScoreResponse(
long id,
diff --git a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreStatusResponse.java b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreStatusResponse.java
index c852b5b2a..3094ea18f 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreStatusResponse.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreStatusResponse.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
import java.time.ZonedDateTime;
diff --git a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreUpdateRequest.java b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreUpdateRequest.java
index 3e76e0c93..c072111ec 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreUpdateRequest.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/LanguageTestScoreUpdateRequest.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.application.dto.validation.RejectedReasonRequired;
+import com.example.solidconnection.university.domain.LanguageTestType;
import jakarta.validation.constraints.NotNull;
@RejectedReasonRequired
diff --git a/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java b/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java
index 2e94628e6..1dc284be8 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
import java.time.LocalDate;
diff --git a/src/main/java/com/example/solidconnection/admin/dto/ScoreUpdateRequest.java b/src/main/java/com/example/solidconnection/admin/dto/ScoreUpdateRequest.java
index 184f76100..7223b48e4 100644
--- a/src/main/java/com/example/solidconnection/admin/dto/ScoreUpdateRequest.java
+++ b/src/main/java/com/example/solidconnection/admin/dto/ScoreUpdateRequest.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.admin.dto;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
public interface ScoreUpdateRequest {
VerifyStatus verifyStatus();
diff --git a/src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java b/src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java
index c761ff485..eae555406 100644
--- a/src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java
+++ b/src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java
@@ -5,17 +5,17 @@
import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
-import com.example.solidconnection.type.VerifyStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import static com.example.solidconnection.custom.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreService.java b/src/main/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreService.java
index 380ef02c6..db89ae91c 100644
--- a/src/main/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreService.java
+++ b/src/main/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreService.java
@@ -5,17 +5,17 @@
import com.example.solidconnection.admin.dto.LanguageTestScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
-import com.example.solidconnection.type.VerifyStatus;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import static com.example.solidconnection.custom.exception.ErrorCode.LANGUAGE_TEST_SCORE_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.LANGUAGE_TEST_SCORE_NOT_FOUND;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java b/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java
index 36c7d6af2..228c436ba 100644
--- a/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java
+++ b/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java
@@ -5,8 +5,8 @@
import com.example.solidconnection.application.dto.ApplyRequest;
import com.example.solidconnection.application.service.ApplicationQueryService;
import com.example.solidconnection.application.service.ApplicationSubmissionService;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
-import com.example.solidconnection.custom.security.annotation.RequireAdminAccess;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
+import com.example.solidconnection.security.annotation.RequireAdminAccess;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
diff --git a/src/main/java/com/example/solidconnection/application/domain/Application.java b/src/main/java/com/example/solidconnection/application/domain/Application.java
index 6caa75331..98342ca88 100644
--- a/src/main/java/com/example/solidconnection/application/domain/Application.java
+++ b/src/main/java/com/example/solidconnection/application/domain/Application.java
@@ -1,7 +1,6 @@
package com.example.solidconnection.application.domain;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.VerifyStatus;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
@@ -19,7 +18,7 @@
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
-import static com.example.solidconnection.type.VerifyStatus.PENDING;
+import static com.example.solidconnection.application.domain.VerifyStatus.PENDING;
@Getter
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
diff --git a/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java b/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java
index 4295372d4..4a0544ea7 100644
--- a/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java
+++ b/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.application.domain;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;
diff --git a/src/main/java/com/example/solidconnection/type/VerifyStatus.java b/src/main/java/com/example/solidconnection/application/domain/VerifyStatus.java
similarity index 52%
rename from src/main/java/com/example/solidconnection/type/VerifyStatus.java
rename to src/main/java/com/example/solidconnection/application/domain/VerifyStatus.java
index 95f122715..e6f1afbe6 100644
--- a/src/main/java/com/example/solidconnection/type/VerifyStatus.java
+++ b/src/main/java/com/example/solidconnection/application/domain/VerifyStatus.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.application.domain;
public enum VerifyStatus {
PENDING, REJECTED, APPROVED
diff --git a/src/main/java/com/example/solidconnection/application/dto/ApplicantResponse.java b/src/main/java/com/example/solidconnection/application/dto/ApplicantResponse.java
index 9835491b1..c6161a134 100644
--- a/src/main/java/com/example/solidconnection/application/dto/ApplicantResponse.java
+++ b/src/main/java/com/example/solidconnection/application/dto/ApplicantResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.application.dto;
import com.example.solidconnection.application.domain.Application;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
public record ApplicantResponse(
String nicknameForApply,
diff --git a/src/main/java/com/example/solidconnection/application/dto/UniversityChoiceRequest.java b/src/main/java/com/example/solidconnection/application/dto/UniversityChoiceRequest.java
index d219dbc2e..220b803b3 100644
--- a/src/main/java/com/example/solidconnection/application/dto/UniversityChoiceRequest.java
+++ b/src/main/java/com/example/solidconnection/application/dto/UniversityChoiceRequest.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.application.dto;
-import com.example.solidconnection.custom.validation.annotation.ValidUniversityChoice;
+import com.example.solidconnection.university.dto.validation.ValidUniversityChoice;
@ValidUniversityChoice
public record UniversityChoiceRequest(
diff --git a/src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java b/src/main/java/com/example/solidconnection/application/dto/validation/RejectedReasonRequired.java
similarity index 78%
rename from src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java
rename to src/main/java/com/example/solidconnection/application/dto/validation/RejectedReasonRequired.java
index 4ae4a6618..281be235b 100644
--- a/src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java
+++ b/src/main/java/com/example/solidconnection/application/dto/validation/RejectedReasonRequired.java
@@ -1,6 +1,5 @@
-package com.example.solidconnection.custom.validation.annotation;
+package com.example.solidconnection.application.dto.validation;
-import com.example.solidconnection.custom.validation.validator.RejectedReasonValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
diff --git a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java b/src/main/java/com/example/solidconnection/application/dto/validation/RejectedReasonValidator.java
similarity index 82%
rename from src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java
rename to src/main/java/com/example/solidconnection/application/dto/validation/RejectedReasonValidator.java
index c975a0a0a..0f1837e0e 100644
--- a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java
+++ b/src/main/java/com/example/solidconnection/application/dto/validation/RejectedReasonValidator.java
@@ -1,13 +1,12 @@
-package com.example.solidconnection.custom.validation.validator;
+package com.example.solidconnection.application.dto.validation;
import com.example.solidconnection.admin.dto.ScoreUpdateRequest;
-import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
import io.micrometer.common.util.StringUtils;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
-import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_REQUIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.REJECTED_REASON_REQUIRED;
public class RejectedReasonValidator implements ConstraintValidator {
diff --git a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java
index 5aeb972bf..7df53eae6 100644
--- a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java
+++ b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.application.repository;
import com.example.solidconnection.application.domain.Application;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.VerifyStatus;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
@@ -13,7 +13,7 @@
import java.util.List;
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLICATION_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLICATION_NOT_FOUND;
@Repository
public interface ApplicationRepository extends JpaRepository {
diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java
index 157c6adcd..e13ca7e3f 100644
--- a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java
+++ b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java
@@ -1,14 +1,14 @@
package com.example.solidconnection.application.service;
import com.example.solidconnection.application.domain.Application;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.dto.ApplicantResponse;
import com.example.solidconnection.application.dto.ApplicationsResponse;
import com.example.solidconnection.application.dto.UniversityApplicantsResponse;
import com.example.solidconnection.application.repository.ApplicationRepository;
import com.example.solidconnection.cache.annotation.ThunderingHerdCaching;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.VerifyStatus;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
@@ -25,7 +25,7 @@
import java.util.function.Function;
import java.util.stream.Collectors;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLICATION_NOT_APPROVED;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLICATION_NOT_APPROVED;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java
index 432e93aff..af1678a16 100644
--- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java
+++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java
@@ -1,18 +1,18 @@
package com.example.solidconnection.application.service;
import com.example.solidconnection.application.domain.Application;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.dto.ApplicationSubmissionResponse;
import com.example.solidconnection.application.dto.ApplyRequest;
import com.example.solidconnection.application.dto.UniversityChoiceRequest;
import com.example.solidconnection.application.repository.ApplicationRepository;
import com.example.solidconnection.cache.annotation.DefaultCacheOut;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.VerifyStatus;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
import lombok.RequiredArgsConstructor;
@@ -22,11 +22,11 @@
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED;
-import static com.example.solidconnection.custom.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE_STATUS;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED;
+import static com.example.solidconnection.common.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_GPA_SCORE_STATUS;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java
index aef1309af..733eb5700 100644
--- a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java
+++ b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClient.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.auth.client;
+import com.example.solidconnection.auth.client.config.AppleOAuthClientProperties;
import com.example.solidconnection.auth.dto.oauth.AppleTokenDto;
import com.example.solidconnection.auth.dto.oauth.AppleUserInfoDto;
-import com.example.solidconnection.config.client.AppleOAuthClientProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import io.jsonwebtoken.Jwts;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
@@ -19,8 +19,8 @@
import java.security.PublicKey;
import java.util.Objects;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLE_AUTHORIZATION_FAILED;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_APPLE_ID_TOKEN;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLE_AUTHORIZATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_APPLE_ID_TOKEN;
/*
* 애플 인증을 위한 OAuth2 클라이언트
diff --git a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java
index 31228e5d3..6bdd6a5fb 100644
--- a/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/client/AppleOAuthClientSecretProvider.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.auth.client;
-import com.example.solidconnection.config.client.AppleOAuthClientProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.auth.client.config.AppleOAuthClientProperties;
+import com.example.solidconnection.common.exception.CustomException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import jakarta.annotation.PostConstruct;
@@ -16,7 +16,7 @@
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;
-import static com.example.solidconnection.custom.exception.ErrorCode.FAILED_TO_READ_APPLE_PRIVATE_KEY;
+import static com.example.solidconnection.common.exception.ErrorCode.FAILED_TO_READ_APPLE_PRIVATE_KEY;
/*
* 애플 OAuth 에 필요한 클라이언트 시크릿은 매번 동적으로 생성해야 한다.
diff --git a/src/main/java/com/example/solidconnection/auth/client/ApplePublicKeyProvider.java b/src/main/java/com/example/solidconnection/auth/client/ApplePublicKeyProvider.java
index 1cc708cc7..0fe6b9700 100644
--- a/src/main/java/com/example/solidconnection/auth/client/ApplePublicKeyProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/client/ApplePublicKeyProvider.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.auth.client;
-import com.example.solidconnection.config.client.AppleOAuthClientProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.auth.client.config.AppleOAuthClientProperties;
+import com.example.solidconnection.common.exception.CustomException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -20,9 +20,9 @@
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLE_ID_TOKEN_EXPIRED;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLE_PUBLIC_KEY_NOT_FOUND;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_APPLE_ID_TOKEN;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLE_ID_TOKEN_EXPIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLE_PUBLIC_KEY_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_APPLE_ID_TOKEN;
import static org.apache.tomcat.util.codec.binary.Base64.decodeBase64URLSafe;
/*
diff --git a/src/main/java/com/example/solidconnection/auth/client/KakaoOAuthClient.java b/src/main/java/com/example/solidconnection/auth/client/KakaoOAuthClient.java
index 5d625cb7c..9539116aa 100644
--- a/src/main/java/com/example/solidconnection/auth/client/KakaoOAuthClient.java
+++ b/src/main/java/com/example/solidconnection/auth/client/KakaoOAuthClient.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.auth.client;
+import com.example.solidconnection.auth.client.config.KakaoOAuthClientProperties;
import com.example.solidconnection.auth.dto.oauth.KakaoTokenDto;
import com.example.solidconnection.auth.dto.oauth.KakaoUserInfoDto;
-import com.example.solidconnection.config.client.KakaoOAuthClientProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
@@ -16,9 +16,9 @@
import java.util.Objects;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_OR_EXPIRED_KAKAO_AUTH_CODE;
-import static com.example.solidconnection.custom.exception.ErrorCode.KAKAO_REDIRECT_URI_MISMATCH;
-import static com.example.solidconnection.custom.exception.ErrorCode.KAKAO_USER_INFO_FAIL;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_OR_EXPIRED_KAKAO_AUTH_CODE;
+import static com.example.solidconnection.common.exception.ErrorCode.KAKAO_REDIRECT_URI_MISMATCH;
+import static com.example.solidconnection.common.exception.ErrorCode.KAKAO_USER_INFO_FAIL;
/*
* 카카오 인증을 위한 OAuth2 클라이언트
diff --git a/src/main/java/com/example/solidconnection/config/client/AppleOAuthClientProperties.java b/src/main/java/com/example/solidconnection/auth/client/config/AppleOAuthClientProperties.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/config/client/AppleOAuthClientProperties.java
rename to src/main/java/com/example/solidconnection/auth/client/config/AppleOAuthClientProperties.java
index c04908583..ae62d3561 100644
--- a/src/main/java/com/example/solidconnection/config/client/AppleOAuthClientProperties.java
+++ b/src/main/java/com/example/solidconnection/auth/client/config/AppleOAuthClientProperties.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.client;
+package com.example.solidconnection.auth.client.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/src/main/java/com/example/solidconnection/config/client/KakaoOAuthClientProperties.java b/src/main/java/com/example/solidconnection/auth/client/config/KakaoOAuthClientProperties.java
similarity index 83%
rename from src/main/java/com/example/solidconnection/config/client/KakaoOAuthClientProperties.java
rename to src/main/java/com/example/solidconnection/auth/client/config/KakaoOAuthClientProperties.java
index 73b196d76..f9a476e6a 100644
--- a/src/main/java/com/example/solidconnection/config/client/KakaoOAuthClientProperties.java
+++ b/src/main/java/com/example/solidconnection/auth/client/config/KakaoOAuthClientProperties.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.client;
+package com.example.solidconnection.auth.client.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
index 064aa88aa..da3ea12c1 100644
--- a/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
+++ b/src/main/java/com/example/solidconnection/auth/controller/AuthController.java
@@ -17,9 +17,9 @@
import com.example.solidconnection.auth.service.oauth.AppleOAuthService;
import com.example.solidconnection.auth.service.oauth.KakaoOAuthService;
import com.example.solidconnection.auth.service.oauth.OAuthSignUpService;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.validation.Valid;
diff --git a/src/main/java/com/example/solidconnection/auth/dto/SignUpRequest.java b/src/main/java/com/example/solidconnection/auth/dto/SignUpRequest.java
index 9bf92a295..b43671e82 100644
--- a/src/main/java/com/example/solidconnection/auth/dto/SignUpRequest.java
+++ b/src/main/java/com/example/solidconnection/auth/dto/SignUpRequest.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.auth.dto;
import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.PreparationStatus;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import jakarta.validation.constraints.NotBlank;
import java.util.List;
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthService.java b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
index 50926ca93..496e48724 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
@@ -2,7 +2,7 @@
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -10,7 +10,7 @@
import java.time.LocalDate;
-import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
index 2e43e8be9..fa2a064cc 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.auth.domain.TokenType;
-import com.example.solidconnection.config.security.JwtProperties;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.util.JwtUtils;
import org.springframework.data.redis.core.RedisTemplate;
diff --git a/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java
index 3d0eda53b..d16cb5134 100644
--- a/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java
@@ -1,14 +1,14 @@
package com.example.solidconnection.auth.service;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.util.JwtUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import static com.example.solidconnection.auth.service.EmailSignUpTokenProvider.AUTH_TYPE_CLAIM_KEY;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
@Component
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java b/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java
index 3e26309a5..d80465791 100644
--- a/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/EmailSignInService.java
@@ -2,7 +2,7 @@
import com.example.solidconnection.auth.dto.EmailSignInRequest;
import com.example.solidconnection.auth.dto.SignInResponse;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
@@ -12,7 +12,7 @@
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
/*
* 보안을 위해 이메일과 비밀번호 중 무엇이 틀렸는지 구체적으로 응답하지 않는다.
diff --git a/src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java b/src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java
index 37f6681ea..01e117ea0 100644
--- a/src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java
@@ -1,17 +1,17 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.auth.dto.SignUpRequest;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.repositories.CountryRepository;
-import com.example.solidconnection.repositories.InterestedCountyRepository;
-import com.example.solidconnection.repositories.InterestedRegionRepository;
-import com.example.solidconnection.repositories.RegionRepository;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.location.country.repository.CountryRepository;
+import com.example.solidconnection.location.country.repository.InterestedCountyRepository;
+import com.example.solidconnection.location.region.repository.InterestedRegionRepository;
+import com.example.solidconnection.location.region.repository.RegionRepository;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import org.springframework.stereotype.Service;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_ALREADY_EXISTED;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_ALREADY_EXISTED;
@Service
public class EmailSignUpService extends SignUpService {
diff --git a/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java
index 1c27a87bd..c6bee80ab 100644
--- a/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java
@@ -2,8 +2,8 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.EmailSignUpTokenRequest;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
@@ -17,8 +17,8 @@
import java.util.Map;
import java.util.Objects;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
import static com.example.solidconnection.util.JwtUtils.parseClaims;
import static com.example.solidconnection.util.JwtUtils.parseSubject;
diff --git a/src/main/java/com/example/solidconnection/auth/service/SignUpService.java b/src/main/java/com/example/solidconnection/auth/service/SignUpService.java
index 319083658..95bd4ecac 100644
--- a/src/main/java/com/example/solidconnection/auth/service/SignUpService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/SignUpService.java
@@ -2,20 +2,20 @@
import com.example.solidconnection.auth.dto.SignInResponse;
import com.example.solidconnection.auth.dto.SignUpRequest;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.entity.InterestedCountry;
-import com.example.solidconnection.entity.InterestedRegion;
-import com.example.solidconnection.repositories.CountryRepository;
-import com.example.solidconnection.repositories.InterestedCountyRepository;
-import com.example.solidconnection.repositories.InterestedRegionRepository;
-import com.example.solidconnection.repositories.RegionRepository;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.location.country.domain.InterestedCountry;
+import com.example.solidconnection.location.country.repository.CountryRepository;
+import com.example.solidconnection.location.country.repository.InterestedCountyRepository;
+import com.example.solidconnection.location.region.domain.InterestedRegion;
+import com.example.solidconnection.location.region.repository.InterestedRegionRepository;
+import com.example.solidconnection.location.region.repository.RegionRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
+import static com.example.solidconnection.common.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
/*
* 우리 서버에서 인증되었음을 확인하기 위한 signUpToken 을 검증한다.
@@ -85,6 +85,8 @@ private void saveInterestedCountry(SignUpRequest signUpRequest, SiteUser savedSi
}
protected abstract void validateSignUpToken(SignUpRequest signUpRequest);
+
protected abstract void validateUserNotDuplicated(SignUpRequest signUpRequest);
+
protected abstract SiteUser createSiteUser(SignUpRequest signUpRequest);
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java
index f5f638ab3..0f3552db2 100644
--- a/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.auth.domain.TokenType;
-import com.example.solidconnection.config.security.JwtProperties;
+import com.example.solidconnection.security.config.JwtProperties;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
diff --git a/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpService.java b/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpService.java
index a46728bb2..5676f1c7d 100644
--- a/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpService.java
@@ -3,17 +3,17 @@
import com.example.solidconnection.auth.dto.SignUpRequest;
import com.example.solidconnection.auth.service.SignInService;
import com.example.solidconnection.auth.service.SignUpService;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.repositories.CountryRepository;
-import com.example.solidconnection.repositories.InterestedCountyRepository;
-import com.example.solidconnection.repositories.InterestedRegionRepository;
-import com.example.solidconnection.repositories.RegionRepository;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.location.country.repository.CountryRepository;
+import com.example.solidconnection.location.country.repository.InterestedCountyRepository;
+import com.example.solidconnection.location.region.repository.InterestedRegionRepository;
+import com.example.solidconnection.location.region.repository.RegionRepository;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import org.springframework.stereotype.Service;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_ALREADY_EXISTED;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_ALREADY_EXISTED;
@Service
public class OAuthSignUpService extends SignUpService {
diff --git a/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java
index c3a95dbe9..8fa290d30 100644
--- a/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java
@@ -2,8 +2,8 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.service.TokenProvider;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
@@ -16,8 +16,8 @@
import java.util.Map;
import java.util.Objects;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
import static com.example.solidconnection.util.JwtUtils.parseClaims;
import static com.example.solidconnection.util.JwtUtils.parseSubject;
diff --git a/src/main/java/com/example/solidconnection/cache/ThunderingHerdCachingAspect.java b/src/main/java/com/example/solidconnection/cache/ThunderingHerdCachingAspect.java
index a37e80f51..5527c2523 100644
--- a/src/main/java/com/example/solidconnection/cache/ThunderingHerdCachingAspect.java
+++ b/src/main/java/com/example/solidconnection/cache/ThunderingHerdCachingAspect.java
@@ -22,10 +22,10 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
-import static com.example.solidconnection.type.RedisConstants.CREATE_CHANNEL;
-import static com.example.solidconnection.type.RedisConstants.LOCK_TIMEOUT_MS;
-import static com.example.solidconnection.type.RedisConstants.MAX_WAIT_TIME_MS;
-import static com.example.solidconnection.type.RedisConstants.REFRESH_LIMIT_PERCENT;
+import static com.example.solidconnection.community.post.service.RedisConstants.CREATE_CHANNEL;
+import static com.example.solidconnection.community.post.service.RedisConstants.LOCK_TIMEOUT_MS;
+import static com.example.solidconnection.community.post.service.RedisConstants.MAX_WAIT_TIME_MS;
+import static com.example.solidconnection.community.post.service.RedisConstants.REFRESH_LIMIT_PERCENT;
@Aspect
@Component
diff --git a/src/main/java/com/example/solidconnection/entity/common/BaseEntity.java b/src/main/java/com/example/solidconnection/common/BaseEntity.java
similarity index 95%
rename from src/main/java/com/example/solidconnection/entity/common/BaseEntity.java
rename to src/main/java/com/example/solidconnection/common/BaseEntity.java
index 508953f88..febf5e77c 100644
--- a/src/main/java/com/example/solidconnection/entity/common/BaseEntity.java
+++ b/src/main/java/com/example/solidconnection/common/BaseEntity.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.entity.common;
+package com.example.solidconnection.common;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
diff --git a/src/main/java/com/example/solidconnection/config/client/RestTemplateConfig.java b/src/main/java/com/example/solidconnection/common/config/client/RestTemplateConfig.java
similarity index 90%
rename from src/main/java/com/example/solidconnection/config/client/RestTemplateConfig.java
rename to src/main/java/com/example/solidconnection/common/config/client/RestTemplateConfig.java
index 36ce3f67b..88afde086 100644
--- a/src/main/java/com/example/solidconnection/config/client/RestTemplateConfig.java
+++ b/src/main/java/com/example/solidconnection/common/config/client/RestTemplateConfig.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.client;
+package com.example.solidconnection.common.config.client;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
diff --git a/src/main/java/com/example/solidconnection/config/redis/RedisConfig.java b/src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java
similarity index 95%
rename from src/main/java/com/example/solidconnection/config/redis/RedisConfig.java
rename to src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java
index 22847dc6d..99c98581a 100644
--- a/src/main/java/com/example/solidconnection/config/redis/RedisConfig.java
+++ b/src/main/java/com/example/solidconnection/common/config/redis/RedisConfig.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.redis;
+package com.example.solidconnection.common.config.redis;
import com.example.solidconnection.cache.CacheUpdateListener;
import org.springframework.beans.factory.annotation.Value;
@@ -16,7 +16,7 @@
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
-import static com.example.solidconnection.type.RedisConstants.CREATE_CHANNEL;
+import static com.example.solidconnection.community.post.service.RedisConstants.CREATE_CHANNEL;
@Configuration
@EnableRedisRepositories
diff --git a/src/main/java/com/example/solidconnection/config/scheduler/SchedulerConfig.java b/src/main/java/com/example/solidconnection/common/config/scheduler/SchedulerConfig.java
similarity index 94%
rename from src/main/java/com/example/solidconnection/config/scheduler/SchedulerConfig.java
rename to src/main/java/com/example/solidconnection/common/config/scheduler/SchedulerConfig.java
index 2a2cfa6a5..227b35372 100644
--- a/src/main/java/com/example/solidconnection/config/scheduler/SchedulerConfig.java
+++ b/src/main/java/com/example/solidconnection/common/config/scheduler/SchedulerConfig.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.scheduler;
+package com.example.solidconnection.common.config.scheduler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
diff --git a/src/main/java/com/example/solidconnection/config/sync/AsyncConfig.java b/src/main/java/com/example/solidconnection/common/config/sync/AsyncConfig.java
similarity index 92%
rename from src/main/java/com/example/solidconnection/config/sync/AsyncConfig.java
rename to src/main/java/com/example/solidconnection/common/config/sync/AsyncConfig.java
index 417b040b3..852e3de02 100644
--- a/src/main/java/com/example/solidconnection/config/sync/AsyncConfig.java
+++ b/src/main/java/com/example/solidconnection/common/config/sync/AsyncConfig.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.sync;
+package com.example.solidconnection.common.config.sync;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java b/src/main/java/com/example/solidconnection/common/config/web/WebMvcConfig.java
similarity index 82%
rename from src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java
rename to src/main/java/com/example/solidconnection/common/config/web/WebMvcConfig.java
index 7f56e320f..a6ba76f7b 100644
--- a/src/main/java/com/example/solidconnection/config/web/WebMvcConfig.java
+++ b/src/main/java/com/example/solidconnection/common/config/web/WebMvcConfig.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.config.web;
+package com.example.solidconnection.common.config.web;
-import com.example.solidconnection.custom.resolver.AuthorizedUserResolver;
-import com.example.solidconnection.custom.resolver.CustomPageableHandlerMethodArgumentResolver;
+import com.example.solidconnection.common.resolver.AuthorizedUserResolver;
+import com.example.solidconnection.common.resolver.CustomPageableHandlerMethodArgumentResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
diff --git a/src/main/java/com/example/solidconnection/custom/exception/CustomAccessDeniedHandler.java b/src/main/java/com/example/solidconnection/common/exception/CustomAccessDeniedHandler.java
similarity index 90%
rename from src/main/java/com/example/solidconnection/custom/exception/CustomAccessDeniedHandler.java
rename to src/main/java/com/example/solidconnection/common/exception/CustomAccessDeniedHandler.java
index 52b1725fc..2c7e0fd19 100644
--- a/src/main/java/com/example/solidconnection/custom/exception/CustomAccessDeniedHandler.java
+++ b/src/main/java/com/example/solidconnection/common/exception/CustomAccessDeniedHandler.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
-import com.example.solidconnection.custom.response.ErrorResponse;
+import com.example.solidconnection.common.response.ErrorResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
diff --git a/src/main/java/com/example/solidconnection/custom/exception/CustomAuthenticationEntryPoint.java b/src/main/java/com/example/solidconnection/common/exception/CustomAuthenticationEntryPoint.java
similarity index 90%
rename from src/main/java/com/example/solidconnection/custom/exception/CustomAuthenticationEntryPoint.java
rename to src/main/java/com/example/solidconnection/common/exception/CustomAuthenticationEntryPoint.java
index 20f0786b7..d5eb87705 100644
--- a/src/main/java/com/example/solidconnection/custom/exception/CustomAuthenticationEntryPoint.java
+++ b/src/main/java/com/example/solidconnection/common/exception/CustomAuthenticationEntryPoint.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
-import com.example.solidconnection.custom.response.ErrorResponse;
+import com.example.solidconnection.common.response.ErrorResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
diff --git a/src/main/java/com/example/solidconnection/custom/exception/CustomException.java b/src/main/java/com/example/solidconnection/common/exception/CustomException.java
similarity index 89%
rename from src/main/java/com/example/solidconnection/custom/exception/CustomException.java
rename to src/main/java/com/example/solidconnection/common/exception/CustomException.java
index 2f1962fbf..fab42924c 100644
--- a/src/main/java/com/example/solidconnection/custom/exception/CustomException.java
+++ b/src/main/java/com/example/solidconnection/common/exception/CustomException.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
import lombok.Getter;
diff --git a/src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java b/src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java
similarity index 89%
rename from src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java
rename to src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java
index c0c610bce..bc03ca98a 100644
--- a/src/main/java/com/example/solidconnection/custom/exception/CustomExceptionHandler.java
+++ b/src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
-import com.example.solidconnection.custom.response.ErrorResponse;
+import com.example.solidconnection.common.response.ErrorResponse;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
@@ -13,10 +13,10 @@
import java.util.ArrayList;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_INPUT;
-import static com.example.solidconnection.custom.exception.ErrorCode.JSON_PARSING_FAILED;
-import static com.example.solidconnection.custom.exception.ErrorCode.JWT_EXCEPTION;
-import static com.example.solidconnection.custom.exception.ErrorCode.NOT_DEFINED_ERROR;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_INPUT;
+import static com.example.solidconnection.common.exception.ErrorCode.JSON_PARSING_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.JWT_EXCEPTION;
+import static com.example.solidconnection.common.exception.ErrorCode.NOT_DEFINED_ERROR;
@Slf4j
@ControllerAdvice
diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java
similarity index 99%
rename from src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java
rename to src/main/java/com/example/solidconnection/common/exception/ErrorCode.java
index 1a4e46b72..6e932a159 100644
--- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java
+++ b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
import lombok.AllArgsConstructor;
import lombok.Getter;
diff --git a/src/main/java/com/example/solidconnection/custom/resolver/AuthorizedUser.java b/src/main/java/com/example/solidconnection/common/resolver/AuthorizedUser.java
similarity index 85%
rename from src/main/java/com/example/solidconnection/custom/resolver/AuthorizedUser.java
rename to src/main/java/com/example/solidconnection/common/resolver/AuthorizedUser.java
index fa1db7f74..0f4aa0954 100644
--- a/src/main/java/com/example/solidconnection/custom/resolver/AuthorizedUser.java
+++ b/src/main/java/com/example/solidconnection/common/resolver/AuthorizedUser.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.resolver;
+package com.example.solidconnection.common.resolver;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolver.java b/src/main/java/com/example/solidconnection/common/resolver/AuthorizedUserResolver.java
similarity index 88%
rename from src/main/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolver.java
rename to src/main/java/com/example/solidconnection/common/resolver/AuthorizedUserResolver.java
index f4ba9fe7f..f729eb073 100644
--- a/src/main/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolver.java
+++ b/src/main/java/com/example/solidconnection/common/resolver/AuthorizedUserResolver.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.resolver;
+package com.example.solidconnection.common.resolver;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.userdetails.SiteUserDetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
@@ -13,7 +13,7 @@
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
@Component
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/custom/resolver/CustomPageableHandlerMethodArgumentResolver.java b/src/main/java/com/example/solidconnection/common/resolver/CustomPageableHandlerMethodArgumentResolver.java
similarity index 92%
rename from src/main/java/com/example/solidconnection/custom/resolver/CustomPageableHandlerMethodArgumentResolver.java
rename to src/main/java/com/example/solidconnection/common/resolver/CustomPageableHandlerMethodArgumentResolver.java
index 418c6867f..ecb8bc75b 100644
--- a/src/main/java/com/example/solidconnection/custom/resolver/CustomPageableHandlerMethodArgumentResolver.java
+++ b/src/main/java/com/example/solidconnection/common/resolver/CustomPageableHandlerMethodArgumentResolver.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.resolver;
+package com.example.solidconnection.common.resolver;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
diff --git a/src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java b/src/main/java/com/example/solidconnection/common/response/ErrorResponse.java
similarity index 64%
rename from src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java
rename to src/main/java/com/example/solidconnection/common/response/ErrorResponse.java
index 83cc02622..68b9c259f 100644
--- a/src/main/java/com/example/solidconnection/custom/response/ErrorResponse.java
+++ b/src/main/java/com/example/solidconnection/common/response/ErrorResponse.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.response;
+package com.example.solidconnection.common.response;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
public record ErrorResponse(String message) {
diff --git a/src/main/java/com/example/solidconnection/custom/response/PageResponse.java b/src/main/java/com/example/solidconnection/common/response/PageResponse.java
similarity index 92%
rename from src/main/java/com/example/solidconnection/custom/response/PageResponse.java
rename to src/main/java/com/example/solidconnection/common/response/PageResponse.java
index d1e3479d6..90790d271 100644
--- a/src/main/java/com/example/solidconnection/custom/response/PageResponse.java
+++ b/src/main/java/com/example/solidconnection/common/response/PageResponse.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.response;
+package com.example.solidconnection.common.response;
import org.springframework.data.domain.Page;
diff --git a/src/main/java/com/example/solidconnection/community/board/controller/BoardController.java b/src/main/java/com/example/solidconnection/community/board/controller/BoardController.java
index a87552796..b46c93256 100644
--- a/src/main/java/com/example/solidconnection/community/board/controller/BoardController.java
+++ b/src/main/java/com/example/solidconnection/community/board/controller/BoardController.java
@@ -1,10 +1,10 @@
package com.example.solidconnection.community.board.controller;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
+import com.example.solidconnection.community.board.domain.BoardCode;
import com.example.solidconnection.community.post.dto.PostListResponse;
import com.example.solidconnection.community.post.service.PostQueryService;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.BoardCode;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
diff --git a/src/main/java/com/example/solidconnection/type/BoardCode.java b/src/main/java/com/example/solidconnection/community/board/domain/BoardCode.java
similarity index 50%
rename from src/main/java/com/example/solidconnection/type/BoardCode.java
rename to src/main/java/com/example/solidconnection/community/board/domain/BoardCode.java
index 0d161e941..33266e8ef 100644
--- a/src/main/java/com/example/solidconnection/type/BoardCode.java
+++ b/src/main/java/com/example/solidconnection/community/board/domain/BoardCode.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.community.board.domain;
public enum BoardCode {
EUROPE, AMERICAS, ASIA, FREE;
diff --git a/src/main/java/com/example/solidconnection/community/board/repository/BoardRepository.java b/src/main/java/com/example/solidconnection/community/board/repository/BoardRepository.java
index 06dd01161..4c6f799d3 100644
--- a/src/main/java/com/example/solidconnection/community/board/repository/BoardRepository.java
+++ b/src/main/java/com/example/solidconnection/community/board/repository/BoardRepository.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.community.board.repository;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
import com.example.solidconnection.community.board.domain.Board;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
@@ -10,7 +10,7 @@
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_BOARD_CODE;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_BOARD_CODE;
@Repository
public interface BoardRepository extends JpaRepository {
diff --git a/src/main/java/com/example/solidconnection/community/comment/controller/CommentController.java b/src/main/java/com/example/solidconnection/community/comment/controller/CommentController.java
index d096f6cc9..f17792a75 100644
--- a/src/main/java/com/example/solidconnection/community/comment/controller/CommentController.java
+++ b/src/main/java/com/example/solidconnection/community/comment/controller/CommentController.java
@@ -1,12 +1,12 @@
package com.example.solidconnection.community.comment.controller;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.community.comment.dto.CommentCreateRequest;
import com.example.solidconnection.community.comment.dto.CommentCreateResponse;
import com.example.solidconnection.community.comment.dto.CommentDeleteResponse;
import com.example.solidconnection.community.comment.dto.CommentUpdateRequest;
import com.example.solidconnection.community.comment.dto.CommentUpdateResponse;
import com.example.solidconnection.community.comment.service.CommentService;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
diff --git a/src/main/java/com/example/solidconnection/community/comment/domain/Comment.java b/src/main/java/com/example/solidconnection/community/comment/domain/Comment.java
index abed4b8f0..9bb2dccd9 100644
--- a/src/main/java/com/example/solidconnection/community/comment/domain/Comment.java
+++ b/src/main/java/com/example/solidconnection/community/comment/domain/Comment.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.community.comment.domain;
-import com.example.solidconnection.entity.common.BaseEntity;
+import com.example.solidconnection.common.BaseEntity;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.persistence.CascadeType;
diff --git a/src/main/java/com/example/solidconnection/community/comment/repository/CommentRepository.java b/src/main/java/com/example/solidconnection/community/comment/repository/CommentRepository.java
index e5feb3f04..cd2ae72ae 100644
--- a/src/main/java/com/example/solidconnection/community/comment/repository/CommentRepository.java
+++ b/src/main/java/com/example/solidconnection/community/comment/repository/CommentRepository.java
@@ -1,14 +1,14 @@
package com.example.solidconnection.community.comment.repository;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.comment.domain.Comment;
-import com.example.solidconnection.custom.exception.CustomException;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COMMENT_ID;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_COMMENT_ID;
public interface CommentRepository extends JpaRepository {
diff --git a/src/main/java/com/example/solidconnection/community/comment/service/CommentService.java b/src/main/java/com/example/solidconnection/community/comment/service/CommentService.java
index 76138b356..6a2760cf0 100644
--- a/src/main/java/com/example/solidconnection/community/comment/service/CommentService.java
+++ b/src/main/java/com/example/solidconnection/community/comment/service/CommentService.java
@@ -1,5 +1,6 @@
package com.example.solidconnection.community.comment.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.comment.domain.Comment;
import com.example.solidconnection.community.comment.dto.CommentCreateRequest;
import com.example.solidconnection.community.comment.dto.CommentCreateResponse;
@@ -10,7 +11,6 @@
import com.example.solidconnection.community.comment.repository.CommentRepository;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import lombok.RequiredArgsConstructor;
@@ -20,10 +20,10 @@
import java.util.List;
import java.util.stream.Collectors;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_UPDATE_DEPRECATED_COMMENT;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COMMENT_LEVEL;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_ACCESS;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_UPDATE_DEPRECATED_COMMENT;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_COMMENT_LEVEL;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_ACCESS;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/community/post/controller/PostController.java b/src/main/java/com/example/solidconnection/community/post/controller/PostController.java
index ee422930a..23b34568e 100644
--- a/src/main/java/com/example/solidconnection/community/post/controller/PostController.java
+++ b/src/main/java/com/example/solidconnection/community/post/controller/PostController.java
@@ -1,5 +1,6 @@
package com.example.solidconnection.community.post.controller;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.community.post.dto.PostCreateRequest;
import com.example.solidconnection.community.post.dto.PostCreateResponse;
import com.example.solidconnection.community.post.dto.PostDeleteResponse;
@@ -11,7 +12,6 @@
import com.example.solidconnection.community.post.service.PostCommandService;
import com.example.solidconnection.community.post.service.PostLikeService;
import com.example.solidconnection.community.post.service.PostQueryService;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
diff --git a/src/main/java/com/example/solidconnection/community/post/domain/Post.java b/src/main/java/com/example/solidconnection/community/post/domain/Post.java
index 4d96b9b22..613abbb4b 100644
--- a/src/main/java/com/example/solidconnection/community/post/domain/Post.java
+++ b/src/main/java/com/example/solidconnection/community/post/domain/Post.java
@@ -1,11 +1,10 @@
package com.example.solidconnection.community.post.domain;
+import com.example.solidconnection.common.BaseEntity;
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.comment.domain.Comment;
-import com.example.solidconnection.entity.common.BaseEntity;
import com.example.solidconnection.community.post.dto.PostUpdateRequest;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.PostCategory;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/community/post/domain/PostCategory.java b/src/main/java/com/example/solidconnection/community/post/domain/PostCategory.java
new file mode 100644
index 000000000..3f8819749
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/community/post/domain/PostCategory.java
@@ -0,0 +1,5 @@
+package com.example.solidconnection.community.post.domain;
+
+public enum PostCategory {
+ 전체, 자유, 질문
+}
diff --git a/src/main/java/com/example/solidconnection/community/post/dto/PostCreateRequest.java b/src/main/java/com/example/solidconnection/community/post/dto/PostCreateRequest.java
index 5e6590b20..0cc3afc1f 100644
--- a/src/main/java/com/example/solidconnection/community/post/dto/PostCreateRequest.java
+++ b/src/main/java/com/example/solidconnection/community/post/dto/PostCreateRequest.java
@@ -2,8 +2,8 @@
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.PostCategory;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
diff --git a/src/main/java/com/example/solidconnection/community/post/dto/PostListResponse.java b/src/main/java/com/example/solidconnection/community/post/dto/PostListResponse.java
index f02af017e..15f5ec7a5 100644
--- a/src/main/java/com/example/solidconnection/community/post/dto/PostListResponse.java
+++ b/src/main/java/com/example/solidconnection/community/post/dto/PostListResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.community.post.dto;
-import com.example.solidconnection.community.post.domain.PostImage;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostImage;
import java.time.ZonedDateTime;
import java.util.List;
diff --git a/src/main/java/com/example/solidconnection/community/post/repository/PostLikeRepository.java b/src/main/java/com/example/solidconnection/community/post/repository/PostLikeRepository.java
index 417e97310..fba377899 100644
--- a/src/main/java/com/example/solidconnection/community/post/repository/PostLikeRepository.java
+++ b/src/main/java/com/example/solidconnection/community/post/repository/PostLikeRepository.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.community.post.repository;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.domain.PostLike;
import com.example.solidconnection.siteuser.domain.SiteUser;
@@ -9,7 +9,7 @@
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_LIKE;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_LIKE;
@Repository
public interface PostLikeRepository extends JpaRepository {
diff --git a/src/main/java/com/example/solidconnection/community/post/repository/PostRepository.java b/src/main/java/com/example/solidconnection/community/post/repository/PostRepository.java
index 336189b05..8c1d256a6 100644
--- a/src/main/java/com/example/solidconnection/community/post/repository/PostRepository.java
+++ b/src/main/java/com/example/solidconnection/community/post/repository/PostRepository.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.community.post.repository;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.post.domain.Post;
import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -11,7 +11,7 @@
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_ID;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_ID;
@Repository
public interface PostRepository extends JpaRepository {
diff --git a/src/main/java/com/example/solidconnection/community/post/service/PostCommandService.java b/src/main/java/com/example/solidconnection/community/post/service/PostCommandService.java
index b95cbcf1b..cb553fd0c 100644
--- a/src/main/java/com/example/solidconnection/community/post/service/PostCommandService.java
+++ b/src/main/java/com/example/solidconnection/community/post/service/PostCommandService.java
@@ -1,8 +1,10 @@
package com.example.solidconnection.community.post.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.board.repository.BoardRepository;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.domain.PostImage;
import com.example.solidconnection.community.post.dto.PostCreateRequest;
import com.example.solidconnection.community.post.dto.PostCreateResponse;
@@ -10,14 +12,11 @@
import com.example.solidconnection.community.post.dto.PostUpdateRequest;
import com.example.solidconnection.community.post.dto.PostUpdateResponse;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.s3.S3Service;
-import com.example.solidconnection.s3.UploadedFileUrlResponse;
-import com.example.solidconnection.service.RedisService;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.type.ImgType;
-import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.EnumUtils;
@@ -27,11 +26,11 @@
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_DELETE_OR_UPDATE_QUESTION;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_UPLOAD_MORE_THAN_FIVE_IMAGES;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_ACCESS;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_CATEGORY;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_DELETE_OR_UPDATE_QUESTION;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_UPLOAD_MORE_THAN_FIVE_IMAGES;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_ACCESS;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_CATEGORY;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java b/src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java
index 98d1a239f..e0921e295 100644
--- a/src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java
+++ b/src/main/java/com/example/solidconnection/community/post/service/PostLikeService.java
@@ -1,12 +1,12 @@
package com.example.solidconnection.community.post.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.domain.PostLike;
import com.example.solidconnection.community.post.dto.PostDislikeResponse;
import com.example.solidconnection.community.post.dto.PostLikeResponse;
import com.example.solidconnection.community.post.repository.PostLikeRepository;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import lombok.RequiredArgsConstructor;
@@ -14,8 +14,8 @@
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;
-import static com.example.solidconnection.custom.exception.ErrorCode.DUPLICATE_POST_LIKE;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.DUPLICATE_POST_LIKE;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java b/src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java
index 66cbb5faa..b8d07b54f 100644
--- a/src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java
+++ b/src/main/java/com/example/solidconnection/community/post/service/PostQueryService.java
@@ -1,22 +1,21 @@
package com.example.solidconnection.community.post.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.board.domain.BoardCode;
import com.example.solidconnection.community.board.dto.PostFindBoardResponse;
-import com.example.solidconnection.community.comment.dto.PostFindCommentResponse;
-import com.example.solidconnection.community.post.dto.PostListResponse;
import com.example.solidconnection.community.board.repository.BoardRepository;
+import com.example.solidconnection.community.comment.dto.PostFindCommentResponse;
import com.example.solidconnection.community.comment.service.CommentService;
-import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.dto.PostFindPostImageResponse;
import com.example.solidconnection.community.post.dto.PostFindResponse;
+import com.example.solidconnection.community.post.dto.PostListResponse;
import com.example.solidconnection.community.post.repository.PostLikeRepository;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.service.RedisService;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.dto.PostFindSiteUserResponse;
-import com.example.solidconnection.type.BoardCode;
-import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.EnumUtils;
@@ -26,8 +25,8 @@
import java.util.List;
import java.util.stream.Collectors;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_BOARD_CODE;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_CATEGORY;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_BOARD_CODE;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_CATEGORY;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/type/RedisConstants.java b/src/main/java/com/example/solidconnection/community/post/service/RedisConstants.java
similarity index 90%
rename from src/main/java/com/example/solidconnection/type/RedisConstants.java
rename to src/main/java/com/example/solidconnection/community/post/service/RedisConstants.java
index 7d4c7f2c9..46260596c 100644
--- a/src/main/java/com/example/solidconnection/type/RedisConstants.java
+++ b/src/main/java/com/example/solidconnection/community/post/service/RedisConstants.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.community.post.service;
import lombok.Getter;
diff --git a/src/main/java/com/example/solidconnection/service/RedisService.java b/src/main/java/com/example/solidconnection/community/post/service/RedisService.java
similarity index 82%
rename from src/main/java/com/example/solidconnection/service/RedisService.java
rename to src/main/java/com/example/solidconnection/community/post/service/RedisService.java
index 36be7b66f..38d573d94 100644
--- a/src/main/java/com/example/solidconnection/service/RedisService.java
+++ b/src/main/java/com/example/solidconnection/community/post/service/RedisService.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.service;
+package com.example.solidconnection.community.post.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -9,11 +9,11 @@
import java.util.Collections;
import java.util.concurrent.TimeUnit;
-import static com.example.solidconnection.type.RedisConstants.VALIDATE_VIEW_COUNT_TTL;
-import static com.example.solidconnection.type.RedisConstants.VIEW_COUNT_TTL;
+import static com.example.solidconnection.community.post.service.RedisConstants.VALIDATE_VIEW_COUNT_TTL;
+import static com.example.solidconnection.community.post.service.RedisConstants.VIEW_COUNT_TTL;
@Service
-public class RedisService {
+public class RedisService { // todo: 정말 필요한지 고민 필요
private final RedisTemplate redisTemplate;
private final RedisScript incrViewCountLuaScript;
diff --git a/src/main/java/com/example/solidconnection/service/UpdateViewCountService.java b/src/main/java/com/example/solidconnection/community/post/service/UpdateViewCountService.java
similarity index 95%
rename from src/main/java/com/example/solidconnection/service/UpdateViewCountService.java
rename to src/main/java/com/example/solidconnection/community/post/service/UpdateViewCountService.java
index 2b67e25ec..89a6f341a 100644
--- a/src/main/java/com/example/solidconnection/service/UpdateViewCountService.java
+++ b/src/main/java/com/example/solidconnection/community/post/service/UpdateViewCountService.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.service;
+package com.example.solidconnection.community.post.service;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.repository.PostRepository;
diff --git a/src/main/java/com/example/solidconnection/entity/Country.java b/src/main/java/com/example/solidconnection/location/country/domain/Country.java
similarity index 85%
rename from src/main/java/com/example/solidconnection/entity/Country.java
rename to src/main/java/com/example/solidconnection/location/country/domain/Country.java
index 0a5d974d7..5a14fef86 100644
--- a/src/main/java/com/example/solidconnection/entity/Country.java
+++ b/src/main/java/com/example/solidconnection/location/country/domain/Country.java
@@ -1,5 +1,6 @@
-package com.example.solidconnection.entity;
+package com.example.solidconnection.location.country.domain;
+import com.example.solidconnection.location.region.domain.Region;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
diff --git a/src/main/java/com/example/solidconnection/entity/InterestedCountry.java b/src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java
similarity index 92%
rename from src/main/java/com/example/solidconnection/entity/InterestedCountry.java
rename to src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java
index 8b8b4e735..9d75c51ed 100644
--- a/src/main/java/com/example/solidconnection/entity/InterestedCountry.java
+++ b/src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.entity;
+package com.example.solidconnection.location.country.domain;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/repositories/CountryRepository.java b/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java
similarity index 78%
rename from src/main/java/com/example/solidconnection/repositories/CountryRepository.java
rename to src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java
index d9ba75555..4860e6015 100644
--- a/src/main/java/com/example/solidconnection/repositories/CountryRepository.java
+++ b/src/main/java/com/example/solidconnection/location/country/repository/CountryRepository.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.repositories;
+package com.example.solidconnection.location.country.repository;
-import com.example.solidconnection.entity.Country;
+import com.example.solidconnection.location.country.domain.Country;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
diff --git a/src/main/java/com/example/solidconnection/repositories/InterestedCountyRepository.java b/src/main/java/com/example/solidconnection/location/country/repository/InterestedCountyRepository.java
similarity index 72%
rename from src/main/java/com/example/solidconnection/repositories/InterestedCountyRepository.java
rename to src/main/java/com/example/solidconnection/location/country/repository/InterestedCountyRepository.java
index 68e10b320..879323e28 100644
--- a/src/main/java/com/example/solidconnection/repositories/InterestedCountyRepository.java
+++ b/src/main/java/com/example/solidconnection/location/country/repository/InterestedCountyRepository.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.repositories;
+package com.example.solidconnection.location.country.repository;
-import com.example.solidconnection.entity.InterestedCountry;
+import com.example.solidconnection.location.country.domain.InterestedCountry;
import com.example.solidconnection.siteuser.domain.SiteUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
diff --git a/src/main/java/com/example/solidconnection/entity/InterestedRegion.java b/src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java
similarity index 92%
rename from src/main/java/com/example/solidconnection/entity/InterestedRegion.java
rename to src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java
index 7ec8fa50c..457ee4eb6 100644
--- a/src/main/java/com/example/solidconnection/entity/InterestedRegion.java
+++ b/src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.entity;
+package com.example.solidconnection.location.region.domain;
import com.example.solidconnection.siteuser.domain.SiteUser;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/entity/Region.java b/src/main/java/com/example/solidconnection/location/region/domain/Region.java
similarity index 91%
rename from src/main/java/com/example/solidconnection/entity/Region.java
rename to src/main/java/com/example/solidconnection/location/region/domain/Region.java
index 6bd64c5cc..cb0d5ab7a 100644
--- a/src/main/java/com/example/solidconnection/entity/Region.java
+++ b/src/main/java/com/example/solidconnection/location/region/domain/Region.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.entity;
+package com.example.solidconnection.location.region.domain;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/repositories/InterestedRegionRepository.java b/src/main/java/com/example/solidconnection/location/region/repository/InterestedRegionRepository.java
similarity index 72%
rename from src/main/java/com/example/solidconnection/repositories/InterestedRegionRepository.java
rename to src/main/java/com/example/solidconnection/location/region/repository/InterestedRegionRepository.java
index df5acd696..90d860b3c 100644
--- a/src/main/java/com/example/solidconnection/repositories/InterestedRegionRepository.java
+++ b/src/main/java/com/example/solidconnection/location/region/repository/InterestedRegionRepository.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.repositories;
+package com.example.solidconnection.location.region.repository;
-import com.example.solidconnection.entity.InterestedRegion;
+import com.example.solidconnection.location.region.domain.InterestedRegion;
import com.example.solidconnection.siteuser.domain.SiteUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
diff --git a/src/main/java/com/example/solidconnection/repositories/RegionRepository.java b/src/main/java/com/example/solidconnection/location/region/repository/RegionRepository.java
similarity index 78%
rename from src/main/java/com/example/solidconnection/repositories/RegionRepository.java
rename to src/main/java/com/example/solidconnection/location/region/repository/RegionRepository.java
index 0dc99fb08..094f19f5f 100644
--- a/src/main/java/com/example/solidconnection/repositories/RegionRepository.java
+++ b/src/main/java/com/example/solidconnection/location/region/repository/RegionRepository.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.repositories;
+package com.example.solidconnection.location.region.repository;
-import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.location.region.domain.Region;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
diff --git a/src/main/java/com/example/solidconnection/news/domain/News.java b/src/main/java/com/example/solidconnection/news/domain/News.java
index 1a9f22a4a..6a3bbdf1f 100644
--- a/src/main/java/com/example/solidconnection/news/domain/News.java
+++ b/src/main/java/com/example/solidconnection/news/domain/News.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.news.domain;
-import com.example.solidconnection.entity.common.BaseEntity;
+import com.example.solidconnection.common.BaseEntity;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
diff --git a/src/main/java/com/example/solidconnection/s3/AmazonS3Config.java b/src/main/java/com/example/solidconnection/s3/config/AmazonS3Config.java
similarity index 95%
rename from src/main/java/com/example/solidconnection/s3/AmazonS3Config.java
rename to src/main/java/com/example/solidconnection/s3/config/AmazonS3Config.java
index c12f067dd..3b19cecfa 100644
--- a/src/main/java/com/example/solidconnection/s3/AmazonS3Config.java
+++ b/src/main/java/com/example/solidconnection/s3/config/AmazonS3Config.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.s3;
+package com.example.solidconnection.s3.config;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
diff --git a/src/main/java/com/example/solidconnection/s3/S3Controller.java b/src/main/java/com/example/solidconnection/s3/controller/S3Controller.java
similarity index 88%
rename from src/main/java/com/example/solidconnection/s3/S3Controller.java
rename to src/main/java/com/example/solidconnection/s3/controller/S3Controller.java
index 26f9160c0..20013fa6a 100644
--- a/src/main/java/com/example/solidconnection/s3/S3Controller.java
+++ b/src/main/java/com/example/solidconnection/s3/controller/S3Controller.java
@@ -1,8 +1,11 @@
-package com.example.solidconnection.s3;
+package com.example.solidconnection.s3.controller;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.dto.urlPrefixResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.ImgType;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
diff --git a/src/main/java/com/example/solidconnection/type/ImgType.java b/src/main/java/com/example/solidconnection/s3/domain/ImgType.java
similarity index 83%
rename from src/main/java/com/example/solidconnection/type/ImgType.java
rename to src/main/java/com/example/solidconnection/s3/domain/ImgType.java
index 45eb516bb..df881fe4b 100644
--- a/src/main/java/com/example/solidconnection/type/ImgType.java
+++ b/src/main/java/com/example/solidconnection/s3/domain/ImgType.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.s3.domain;
import lombok.Getter;
diff --git a/src/main/java/com/example/solidconnection/s3/UploadedFileUrlResponse.java b/src/main/java/com/example/solidconnection/s3/dto/UploadedFileUrlResponse.java
similarity index 60%
rename from src/main/java/com/example/solidconnection/s3/UploadedFileUrlResponse.java
rename to src/main/java/com/example/solidconnection/s3/dto/UploadedFileUrlResponse.java
index 6d9b690fa..ca6a08b46 100644
--- a/src/main/java/com/example/solidconnection/s3/UploadedFileUrlResponse.java
+++ b/src/main/java/com/example/solidconnection/s3/dto/UploadedFileUrlResponse.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.s3;
+package com.example.solidconnection.s3.dto;
public record UploadedFileUrlResponse(
String fileUrl) {
diff --git a/src/main/java/com/example/solidconnection/s3/urlPrefixResponse.java b/src/main/java/com/example/solidconnection/s3/dto/urlPrefixResponse.java
similarity index 78%
rename from src/main/java/com/example/solidconnection/s3/urlPrefixResponse.java
rename to src/main/java/com/example/solidconnection/s3/dto/urlPrefixResponse.java
index 59eac23ca..f36838060 100644
--- a/src/main/java/com/example/solidconnection/s3/urlPrefixResponse.java
+++ b/src/main/java/com/example/solidconnection/s3/dto/urlPrefixResponse.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.s3;
+package com.example.solidconnection.s3.dto;
public record urlPrefixResponse(
String s3Default,
diff --git a/src/main/java/com/example/solidconnection/s3/FileUploadService.java b/src/main/java/com/example/solidconnection/s3/service/FileUploadService.java
similarity index 89%
rename from src/main/java/com/example/solidconnection/s3/FileUploadService.java
rename to src/main/java/com/example/solidconnection/s3/service/FileUploadService.java
index 71d9f9c7a..61bc6f89c 100644
--- a/src/main/java/com/example/solidconnection/s3/FileUploadService.java
+++ b/src/main/java/com/example/solidconnection/s3/service/FileUploadService.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.s3;
+package com.example.solidconnection.s3.service;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
@@ -6,7 +6,7 @@
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
@@ -15,8 +15,8 @@
import java.io.IOException;
-import static com.example.solidconnection.custom.exception.ErrorCode.S3_CLIENT_EXCEPTION;
-import static com.example.solidconnection.custom.exception.ErrorCode.S3_SERVICE_EXCEPTION;
+import static com.example.solidconnection.common.exception.ErrorCode.S3_CLIENT_EXCEPTION;
+import static com.example.solidconnection.common.exception.ErrorCode.S3_SERVICE_EXCEPTION;
@Component
@EnableAsync
diff --git a/src/main/java/com/example/solidconnection/s3/S3Service.java b/src/main/java/com/example/solidconnection/s3/service/S3Service.java
similarity index 90%
rename from src/main/java/com/example/solidconnection/s3/S3Service.java
rename to src/main/java/com/example/solidconnection/s3/service/S3Service.java
index 2f3c633dd..1b7daf78f 100644
--- a/src/main/java/com/example/solidconnection/s3/S3Service.java
+++ b/src/main/java/com/example/solidconnection/s3/service/S3Service.java
@@ -1,13 +1,14 @@
-package com.example.solidconnection.s3;
+package com.example.solidconnection.s3.service;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.type.ImgType;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -22,11 +23,11 @@
import java.util.Objects;
import java.util.UUID;
-import static com.example.solidconnection.custom.exception.ErrorCode.FILE_NOT_EXIST;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_FILE_EXTENSIONS;
-import static com.example.solidconnection.custom.exception.ErrorCode.NOT_ALLOWED_FILE_EXTENSIONS;
-import static com.example.solidconnection.custom.exception.ErrorCode.S3_CLIENT_EXCEPTION;
-import static com.example.solidconnection.custom.exception.ErrorCode.S3_SERVICE_EXCEPTION;
+import static com.example.solidconnection.common.exception.ErrorCode.FILE_NOT_EXIST;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_FILE_EXTENSIONS;
+import static com.example.solidconnection.common.exception.ErrorCode.NOT_ALLOWED_FILE_EXTENSIONS;
+import static com.example.solidconnection.common.exception.ErrorCode.S3_CLIENT_EXCEPTION;
+import static com.example.solidconnection.common.exception.ErrorCode.S3_SERVICE_EXCEPTION;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/scheduler/UpdateViewCountScheduler.java b/src/main/java/com/example/solidconnection/scheduler/UpdateViewCountScheduler.java
index 8da1fe1ca..97a546c05 100644
--- a/src/main/java/com/example/solidconnection/scheduler/UpdateViewCountScheduler.java
+++ b/src/main/java/com/example/solidconnection/scheduler/UpdateViewCountScheduler.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.scheduler;
-import com.example.solidconnection.service.UpdateViewCountService;
+import com.example.solidconnection.community.post.service.UpdateViewCountService;
import com.example.solidconnection.util.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -13,7 +13,7 @@
import java.util.List;
-import static com.example.solidconnection.type.RedisConstants.VIEW_COUNT_KEY_PATTERN;
+import static com.example.solidconnection.community.post.service.RedisConstants.VIEW_COUNT_KEY_PATTERN;
@RequiredArgsConstructor
@Component
diff --git a/src/main/java/com/example/solidconnection/score/controller/ScoreController.java b/src/main/java/com/example/solidconnection/score/controller/ScoreController.java
index e67639274..257c3ef4c 100644
--- a/src/main/java/com/example/solidconnection/score/controller/ScoreController.java
+++ b/src/main/java/com/example/solidconnection/score/controller/ScoreController.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.score.controller;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.score.dto.GpaScoreRequest;
import com.example.solidconnection.score.dto.GpaScoreStatusesResponse;
import com.example.solidconnection.score.dto.LanguageTestScoreRequest;
diff --git a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java
index ddc583aa7..0156dae9a 100644
--- a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java
+++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.score.domain;
import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.entity.common.BaseEntity;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.BaseEntity;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.VerifyStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java b/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java
index ec791373e..f2257561d 100644
--- a/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java
+++ b/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.score.domain;
import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.entity.common.BaseEntity;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.BaseEntity;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.VerifyStatus;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java
index df161d358..4804d6874 100644
--- a/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java
+++ b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.score.dto;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.score.domain.GpaScore;
-import com.example.solidconnection.type.VerifyStatus;
public record GpaScoreStatusResponse(
long id,
diff --git a/src/main/java/com/example/solidconnection/score/dto/LanguageTestResponse.java b/src/main/java/com/example/solidconnection/score/dto/LanguageTestResponse.java
index 060574f46..2368e18c7 100644
--- a/src/main/java/com/example/solidconnection/score/dto/LanguageTestResponse.java
+++ b/src/main/java/com/example/solidconnection/score/dto/LanguageTestResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.score.dto;
import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
public record LanguageTestResponse(
LanguageTestType languageTestType,
diff --git a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java
index e49af4369..6173e8f00 100644
--- a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java
+++ b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.score.dto;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
diff --git a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java
index 3ee96906e..4aa033d72 100644
--- a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java
+++ b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.score.dto;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.type.VerifyStatus;
public record LanguageTestScoreStatusResponse(
long id,
diff --git a/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java b/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java
index 5bef377cf..1934a0612 100644
--- a/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java
+++ b/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java
@@ -3,7 +3,7 @@
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.custom.LanguageTestScoreFilterRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
diff --git a/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java
index a02e62b49..a90961c3d 100644
--- a/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java
+++ b/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java
@@ -5,7 +5,7 @@
import com.example.solidconnection.admin.dto.GpaScoreStatusResponse;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.admin.dto.SiteUserResponse;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.querydsl.core.types.ConstructorExpression;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
diff --git a/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java
index 5d88c1451..28baaf521 100644
--- a/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java
+++ b/src/main/java/com/example/solidconnection/score/repository/custom/LanguageTestScoreFilterRepositoryImpl.java
@@ -5,7 +5,7 @@
import com.example.solidconnection.admin.dto.LanguageTestScoreStatusResponse;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.admin.dto.SiteUserResponse;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.querydsl.core.types.ConstructorExpression;
import com.querydsl.core.types.Projections;
import com.querydsl.core.types.dsl.BooleanExpression;
diff --git a/src/main/java/com/example/solidconnection/score/service/ScoreService.java b/src/main/java/com/example/solidconnection/score/service/ScoreService.java
index eb00a14e9..5a6cf9801 100644
--- a/src/main/java/com/example/solidconnection/score/service/ScoreService.java
+++ b/src/main/java/com/example/solidconnection/score/service/ScoreService.java
@@ -2,9 +2,10 @@
import com.example.solidconnection.application.domain.Gpa;
import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.s3.S3Service;
-import com.example.solidconnection.s3.UploadedFileUrlResponse;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.dto.GpaScoreRequest;
@@ -17,7 +18,6 @@
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.type.ImgType;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -28,7 +28,7 @@
import java.util.Optional;
import java.util.stream.Collectors;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/custom/security/annotation/RequireAdminAccess.java b/src/main/java/com/example/solidconnection/security/annotation/RequireAdminAccess.java
similarity index 80%
rename from src/main/java/com/example/solidconnection/custom/security/annotation/RequireAdminAccess.java
rename to src/main/java/com/example/solidconnection/security/annotation/RequireAdminAccess.java
index 559664e25..682d5bdf8 100644
--- a/src/main/java/com/example/solidconnection/custom/security/annotation/RequireAdminAccess.java
+++ b/src/main/java/com/example/solidconnection/security/annotation/RequireAdminAccess.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.security.annotation;
+package com.example.solidconnection.security.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspect.java b/src/main/java/com/example/solidconnection/security/aspect/AdminAuthorizationAspect.java
similarity index 75%
rename from src/main/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspect.java
rename to src/main/java/com/example/solidconnection/security/aspect/AdminAuthorizationAspect.java
index 20e8c27c8..5ebba881f 100644
--- a/src/main/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspect.java
+++ b/src/main/java/com/example/solidconnection/security/aspect/AdminAuthorizationAspect.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.security.aspect;
+package com.example.solidconnection.security.aspect;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.security.annotation.RequireAdminAccess;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.annotation.RequireAdminAccess;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.RequiredArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
@@ -9,8 +9,8 @@
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
-import static com.example.solidconnection.custom.exception.ErrorCode.ACCESS_DENIED;
-import static com.example.solidconnection.type.Role.ADMIN;
+import static com.example.solidconnection.common.exception.ErrorCode.ACCESS_DENIED;
+import static com.example.solidconnection.siteuser.domain.Role.ADMIN;
@Aspect
@Component
diff --git a/src/main/java/com/example/solidconnection/custom/security/authentication/JwtAuthentication.java b/src/main/java/com/example/solidconnection/security/authentication/JwtAuthentication.java
similarity index 92%
rename from src/main/java/com/example/solidconnection/custom/security/authentication/JwtAuthentication.java
rename to src/main/java/com/example/solidconnection/security/authentication/JwtAuthentication.java
index 6c9f2fa21..64e89e891 100644
--- a/src/main/java/com/example/solidconnection/custom/security/authentication/JwtAuthentication.java
+++ b/src/main/java/com/example/solidconnection/security/authentication/JwtAuthentication.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.security.authentication;
+package com.example.solidconnection.security.authentication;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
diff --git a/src/main/java/com/example/solidconnection/custom/security/authentication/SiteUserAuthentication.java b/src/main/java/com/example/solidconnection/security/authentication/SiteUserAuthentication.java
similarity index 69%
rename from src/main/java/com/example/solidconnection/custom/security/authentication/SiteUserAuthentication.java
rename to src/main/java/com/example/solidconnection/security/authentication/SiteUserAuthentication.java
index 3387cee55..60a71b032 100644
--- a/src/main/java/com/example/solidconnection/custom/security/authentication/SiteUserAuthentication.java
+++ b/src/main/java/com/example/solidconnection/security/authentication/SiteUserAuthentication.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.security.authentication;
+package com.example.solidconnection.security.authentication;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.security.userdetails.SiteUserDetails;
public class SiteUserAuthentication extends JwtAuthentication {
diff --git a/src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java b/src/main/java/com/example/solidconnection/security/config/AuthenticationManagerConfig.java
similarity index 81%
rename from src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java
rename to src/main/java/com/example/solidconnection/security/config/AuthenticationManagerConfig.java
index e4af023b7..72601237b 100644
--- a/src/main/java/com/example/solidconnection/config/security/AuthenticationManagerConfig.java
+++ b/src/main/java/com/example/solidconnection/security/config/AuthenticationManagerConfig.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.config.security;
+package com.example.solidconnection.security.config;
-import com.example.solidconnection.custom.security.provider.SiteUserAuthenticationProvider;
+import com.example.solidconnection.security.provider.SiteUserAuthenticationProvider;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
diff --git a/src/main/java/com/example/solidconnection/config/security/CorsProperties.java b/src/main/java/com/example/solidconnection/security/config/CorsProperties.java
similarity index 79%
rename from src/main/java/com/example/solidconnection/config/security/CorsProperties.java
rename to src/main/java/com/example/solidconnection/security/config/CorsProperties.java
index f851692c6..a179a7563 100644
--- a/src/main/java/com/example/solidconnection/config/security/CorsProperties.java
+++ b/src/main/java/com/example/solidconnection/security/config/CorsProperties.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.security;
+package com.example.solidconnection.security.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/src/main/java/com/example/solidconnection/config/security/JwtProperties.java b/src/main/java/com/example/solidconnection/security/config/JwtProperties.java
similarity index 75%
rename from src/main/java/com/example/solidconnection/config/security/JwtProperties.java
rename to src/main/java/com/example/solidconnection/security/config/JwtProperties.java
index e0c63da46..f4afa5245 100644
--- a/src/main/java/com/example/solidconnection/config/security/JwtProperties.java
+++ b/src/main/java/com/example/solidconnection/security/config/JwtProperties.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.config.security;
+package com.example.solidconnection.security.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/src/main/java/com/example/solidconnection/config/security/SecurityConfiguration.java b/src/main/java/com/example/solidconnection/security/config/SecurityConfiguration.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/config/security/SecurityConfiguration.java
rename to src/main/java/com/example/solidconnection/security/config/SecurityConfiguration.java
index 1d0b110bb..46d1793df 100644
--- a/src/main/java/com/example/solidconnection/config/security/SecurityConfiguration.java
+++ b/src/main/java/com/example/solidconnection/security/config/SecurityConfiguration.java
@@ -1,10 +1,10 @@
-package com.example.solidconnection.config.security;
+package com.example.solidconnection.security.config;
-import com.example.solidconnection.custom.exception.CustomAccessDeniedHandler;
-import com.example.solidconnection.custom.exception.CustomAuthenticationEntryPoint;
-import com.example.solidconnection.custom.security.filter.ExceptionHandlerFilter;
-import com.example.solidconnection.custom.security.filter.JwtAuthenticationFilter;
-import com.example.solidconnection.custom.security.filter.SignOutCheckFilter;
+import com.example.solidconnection.common.exception.CustomAccessDeniedHandler;
+import com.example.solidconnection.common.exception.CustomAuthenticationEntryPoint;
+import com.example.solidconnection.security.filter.ExceptionHandlerFilter;
+import com.example.solidconnection.security.filter.JwtAuthenticationFilter;
+import com.example.solidconnection.security.filter.SignOutCheckFilter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -20,7 +20,7 @@
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
-import static com.example.solidconnection.type.Role.ADMIN;
+import static com.example.solidconnection.siteuser.domain.Role.ADMIN;
@Configuration
@EnableWebSecurity
diff --git a/src/main/java/com/example/solidconnection/custom/security/filter/ExceptionHandlerFilter.java b/src/main/java/com/example/solidconnection/security/filter/ExceptionHandlerFilter.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/custom/security/filter/ExceptionHandlerFilter.java
rename to src/main/java/com/example/solidconnection/security/filter/ExceptionHandlerFilter.java
index 2db133b8f..84602a5f8 100644
--- a/src/main/java/com/example/solidconnection/custom/security/filter/ExceptionHandlerFilter.java
+++ b/src/main/java/com/example/solidconnection/security/filter/ExceptionHandlerFilter.java
@@ -1,8 +1,8 @@
-package com.example.solidconnection.custom.security.filter;
+package com.example.solidconnection.security.filter;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
-import com.example.solidconnection.custom.response.ErrorResponse;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
+import com.example.solidconnection.common.response.ErrorResponse;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
@@ -16,7 +16,7 @@
import java.io.IOException;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
@Component
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java
rename to src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java
index d9d8efd65..39917d42e 100644
--- a/src/main/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilter.java
+++ b/src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.security.filter;
+package com.example.solidconnection.security.filter;
-import com.example.solidconnection.custom.security.authentication.JwtAuthentication;
-import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
+import com.example.solidconnection.security.authentication.JwtAuthentication;
+import com.example.solidconnection.security.authentication.SiteUserAuthentication;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
diff --git a/src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java b/src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java
rename to src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java
index a111a7292..5c51c53cd 100644
--- a/src/main/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilter.java
+++ b/src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.security.filter;
+package com.example.solidconnection.security.filter;
import com.example.solidconnection.auth.service.BlacklistChecker;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
@@ -13,7 +13,7 @@
import java.io.IOException;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
import static com.example.solidconnection.util.JwtUtils.parseTokenFromRequest;
@Component
diff --git a/src/main/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProvider.java b/src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java
similarity index 72%
rename from src/main/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProvider.java
rename to src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java
index 25f211710..6ce43b97c 100644
--- a/src/main/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProvider.java
+++ b/src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java
@@ -1,10 +1,10 @@
-package com.example.solidconnection.custom.security.provider;
+package com.example.solidconnection.security.provider;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetailsService;
-import com.example.solidconnection.custom.security.authentication.JwtAuthentication;
-import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
+import com.example.solidconnection.security.authentication.JwtAuthentication;
+import com.example.solidconnection.security.authentication.SiteUserAuthentication;
+import com.example.solidconnection.security.config.JwtProperties;
+import com.example.solidconnection.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.security.userdetails.SiteUserDetailsService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
diff --git a/src/main/java/com/example/solidconnection/custom/security/userdetails/SecurityRoleMapper.java b/src/main/java/com/example/solidconnection/security/userdetails/SecurityRoleMapper.java
similarity index 77%
rename from src/main/java/com/example/solidconnection/custom/security/userdetails/SecurityRoleMapper.java
rename to src/main/java/com/example/solidconnection/security/userdetails/SecurityRoleMapper.java
index 3af238f13..802229e46 100644
--- a/src/main/java/com/example/solidconnection/custom/security/userdetails/SecurityRoleMapper.java
+++ b/src/main/java/com/example/solidconnection/security/userdetails/SecurityRoleMapper.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.security.userdetails;
+package com.example.solidconnection.security.userdetails;
-import com.example.solidconnection.type.Role;
+import com.example.solidconnection.siteuser.domain.Role;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.List;
diff --git a/src/main/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetails.java b/src/main/java/com/example/solidconnection/security/userdetails/SiteUserDetails.java
similarity index 95%
rename from src/main/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetails.java
rename to src/main/java/com/example/solidconnection/security/userdetails/SiteUserDetails.java
index 008f77ef5..d92d5cc32 100644
--- a/src/main/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetails.java
+++ b/src/main/java/com/example/solidconnection/security/userdetails/SiteUserDetails.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.security.userdetails;
+package com.example.solidconnection.security.userdetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.Getter;
diff --git a/src/main/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsService.java b/src/main/java/com/example/solidconnection/security/userdetails/SiteUserDetailsService.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsService.java
rename to src/main/java/com/example/solidconnection/security/userdetails/SiteUserDetailsService.java
index fd23fa899..e13dc1089 100644
--- a/src/main/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsService.java
+++ b/src/main/java/com/example/solidconnection/security/userdetails/SiteUserDetailsService.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.security.userdetails;
+package com.example.solidconnection.security.userdetails;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import lombok.RequiredArgsConstructor;
@@ -9,8 +9,8 @@
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_TOKEN;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_TOKEN;
@Service
@RequiredArgsConstructor
diff --git a/src/main/java/com/example/solidconnection/siteuser/controller/MyPageController.java b/src/main/java/com/example/solidconnection/siteuser/controller/MyPageController.java
index 41862bf8b..ff36d7baa 100644
--- a/src/main/java/com/example/solidconnection/siteuser/controller/MyPageController.java
+++ b/src/main/java/com/example/solidconnection/siteuser/controller/MyPageController.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.siteuser.controller;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.dto.MyPageResponse;
import com.example.solidconnection.siteuser.service.MyPageService;
diff --git a/src/main/java/com/example/solidconnection/type/PreparationStatus.java b/src/main/java/com/example/solidconnection/siteuser/domain/PreparationStatus.java
similarity index 83%
rename from src/main/java/com/example/solidconnection/type/PreparationStatus.java
rename to src/main/java/com/example/solidconnection/siteuser/domain/PreparationStatus.java
index c4f1650e9..6f86853c0 100644
--- a/src/main/java/com/example/solidconnection/type/PreparationStatus.java
+++ b/src/main/java/com/example/solidconnection/siteuser/domain/PreparationStatus.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.siteuser.domain;
public enum PreparationStatus {
CONSIDERING, // 교환학생 지원 고민 상태
diff --git a/src/main/java/com/example/solidconnection/type/Role.java b/src/main/java/com/example/solidconnection/siteuser/domain/Role.java
similarity index 52%
rename from src/main/java/com/example/solidconnection/type/Role.java
rename to src/main/java/com/example/solidconnection/siteuser/domain/Role.java
index 8223e8de0..4ea5bf151 100644
--- a/src/main/java/com/example/solidconnection/type/Role.java
+++ b/src/main/java/com/example/solidconnection/siteuser/domain/Role.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.siteuser.domain;
public enum Role {
diff --git a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java
index 21dfbcc13..bcfb1f9ac 100644
--- a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java
+++ b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java
@@ -5,8 +5,6 @@
import com.example.solidconnection.community.post.domain.PostLike;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
diff --git a/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java b/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java
index 981866632..9185362cf 100644
--- a/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java
+++ b/src/main/java/com/example/solidconnection/siteuser/dto/MyPageResponse.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.siteuser.dto;
import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.Role;
public record MyPageResponse(
String nickname,
diff --git a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java
index e89c6cdfa..2c84f0518 100644
--- a/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java
+++ b/src/main/java/com/example/solidconnection/siteuser/service/MyPageService.java
@@ -1,13 +1,13 @@
package com.example.solidconnection.siteuser.service;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.s3.S3Service;
-import com.example.solidconnection.s3.UploadedFileUrlResponse;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.dto.MyPageResponse;
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.type.ImgType;
import com.example.solidconnection.university.domain.LikedUniversity;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
import lombok.RequiredArgsConstructor;
@@ -19,8 +19,8 @@
import java.time.format.DateTimeFormatter;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET;
-import static com.example.solidconnection.custom.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET;
+import static com.example.solidconnection.common.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/type/PostCategory.java b/src/main/java/com/example/solidconnection/type/PostCategory.java
deleted file mode 100644
index b42b94f95..000000000
--- a/src/main/java/com/example/solidconnection/type/PostCategory.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.example.solidconnection.type;
-
-public enum PostCategory {
- 전체, 자유, 질문
-}
diff --git a/src/main/java/com/example/solidconnection/university/controller/UniversityController.java b/src/main/java/com/example/solidconnection/university/controller/UniversityController.java
index 635693d4c..6345876a9 100644
--- a/src/main/java/com/example/solidconnection/university/controller/UniversityController.java
+++ b/src/main/java/com/example/solidconnection/university/controller/UniversityController.java
@@ -1,9 +1,9 @@
package com.example.solidconnection.university.controller;
-import com.example.solidconnection.custom.resolver.AuthorizedUser;
+import com.example.solidconnection.common.resolver.AuthorizedUser;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.service.MyPageService;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.dto.IsLikeResponse;
import com.example.solidconnection.university.dto.LikeResultResponse;
import com.example.solidconnection.university.dto.UniversityDetailResponse;
diff --git a/src/main/java/com/example/solidconnection/university/domain/LanguageRequirement.java b/src/main/java/com/example/solidconnection/university/domain/LanguageRequirement.java
index 508c7531e..55377131b 100644
--- a/src/main/java/com/example/solidconnection/university/domain/LanguageRequirement.java
+++ b/src/main/java/com/example/solidconnection/university/domain/LanguageRequirement.java
@@ -1,6 +1,5 @@
package com.example.solidconnection.university.domain;
-import com.example.solidconnection.type.LanguageTestType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
diff --git a/src/main/java/com/example/solidconnection/type/LanguageTestType.java b/src/main/java/com/example/solidconnection/university/domain/LanguageTestType.java
similarity index 96%
rename from src/main/java/com/example/solidconnection/type/LanguageTestType.java
rename to src/main/java/com/example/solidconnection/university/domain/LanguageTestType.java
index 29082c98e..f220ac3d3 100644
--- a/src/main/java/com/example/solidconnection/type/LanguageTestType.java
+++ b/src/main/java/com/example/solidconnection/university/domain/LanguageTestType.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.university.domain;
import java.util.Comparator;
diff --git a/src/main/java/com/example/solidconnection/type/SemesterAvailableForDispatch.java b/src/main/java/com/example/solidconnection/university/domain/SemesterAvailableForDispatch.java
similarity index 90%
rename from src/main/java/com/example/solidconnection/type/SemesterAvailableForDispatch.java
rename to src/main/java/com/example/solidconnection/university/domain/SemesterAvailableForDispatch.java
index 2a04805d6..9d44ecd8c 100644
--- a/src/main/java/com/example/solidconnection/type/SemesterAvailableForDispatch.java
+++ b/src/main/java/com/example/solidconnection/university/domain/SemesterAvailableForDispatch.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.university.domain;
public enum SemesterAvailableForDispatch {
ONE_SEMESTER("1개학기"),
diff --git a/src/main/java/com/example/solidconnection/type/TuitionFeeType.java b/src/main/java/com/example/solidconnection/university/domain/TuitionFeeType.java
similarity index 87%
rename from src/main/java/com/example/solidconnection/type/TuitionFeeType.java
rename to src/main/java/com/example/solidconnection/university/domain/TuitionFeeType.java
index 21ab6700e..c7abc09e1 100644
--- a/src/main/java/com/example/solidconnection/type/TuitionFeeType.java
+++ b/src/main/java/com/example/solidconnection/university/domain/TuitionFeeType.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.type;
+package com.example.solidconnection.university.domain;
public enum TuitionFeeType {
HOME_UNIVERSITY_PAYMENT("본교등록금납부형"),
diff --git a/src/main/java/com/example/solidconnection/university/domain/University.java b/src/main/java/com/example/solidconnection/university/domain/University.java
index c3021385e..d010861d4 100644
--- a/src/main/java/com/example/solidconnection/university/domain/University.java
+++ b/src/main/java/com/example/solidconnection/university/domain/University.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.domain;
-import com.example.solidconnection.entity.Country;
-import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.location.country.domain.Country;
+import com.example.solidconnection.location.region.domain.Region;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
diff --git a/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java b/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java
index e1a87fe83..c968a3a1a 100644
--- a/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java
+++ b/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java
@@ -1,7 +1,5 @@
package com.example.solidconnection.university.domain;
-import com.example.solidconnection.type.SemesterAvailableForDispatch;
-import com.example.solidconnection.type.TuitionFeeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
diff --git a/src/main/java/com/example/solidconnection/university/dto/LanguageRequirementResponse.java b/src/main/java/com/example/solidconnection/university/dto/LanguageRequirementResponse.java
index 8cc7b9733..292bd837d 100644
--- a/src/main/java/com/example/solidconnection/university/dto/LanguageRequirementResponse.java
+++ b/src/main/java/com/example/solidconnection/university/dto/LanguageRequirementResponse.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.dto;
-import com.example.solidconnection.type.LanguageTestType;
import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.LanguageTestType;
public record LanguageRequirementResponse(
LanguageTestType languageTestType,
diff --git a/src/main/java/com/example/solidconnection/custom/validation/annotation/ValidUniversityChoice.java b/src/main/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoice.java
similarity index 78%
rename from src/main/java/com/example/solidconnection/custom/validation/annotation/ValidUniversityChoice.java
rename to src/main/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoice.java
index 7e5827113..658de067c 100644
--- a/src/main/java/com/example/solidconnection/custom/validation/annotation/ValidUniversityChoice.java
+++ b/src/main/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoice.java
@@ -1,6 +1,5 @@
-package com.example.solidconnection.custom.validation.annotation;
+package com.example.solidconnection.university.dto.validation;
-import com.example.solidconnection.custom.validation.validator.ValidUniversityChoiceValidator;
import jakarta.validation.Constraint;
import jakarta.validation.Payload;
diff --git a/src/main/java/com/example/solidconnection/custom/validation/validator/ValidUniversityChoiceValidator.java b/src/main/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoiceValidator.java
similarity index 86%
rename from src/main/java/com/example/solidconnection/custom/validation/validator/ValidUniversityChoiceValidator.java
rename to src/main/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoiceValidator.java
index 6ac9fe1c2..63d47b0de 100644
--- a/src/main/java/com/example/solidconnection/custom/validation/validator/ValidUniversityChoiceValidator.java
+++ b/src/main/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoiceValidator.java
@@ -1,7 +1,6 @@
-package com.example.solidconnection.custom.validation.validator;
+package com.example.solidconnection.university.dto.validation;
import com.example.solidconnection.application.dto.UniversityChoiceRequest;
-import com.example.solidconnection.custom.validation.annotation.ValidUniversityChoice;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
@@ -10,9 +9,9 @@
import java.util.Set;
import java.util.stream.Stream;
-import static com.example.solidconnection.custom.exception.ErrorCode.DUPLICATE_UNIVERSITY_CHOICE;
-import static com.example.solidconnection.custom.exception.ErrorCode.FIRST_CHOICE_REQUIRED;
-import static com.example.solidconnection.custom.exception.ErrorCode.THIRD_CHOICE_REQUIRES_SECOND;
+import static com.example.solidconnection.common.exception.ErrorCode.DUPLICATE_UNIVERSITY_CHOICE;
+import static com.example.solidconnection.common.exception.ErrorCode.FIRST_CHOICE_REQUIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.THIRD_CHOICE_REQUIRES_SECOND;
public class ValidUniversityChoiceValidator implements ConstraintValidator {
diff --git a/src/main/java/com/example/solidconnection/university/repository/LanguageRequirementRepository.java b/src/main/java/com/example/solidconnection/university/repository/LanguageRequirementRepository.java
index 4cbebc6f5..cfe9f7050 100644
--- a/src/main/java/com/example/solidconnection/university/repository/LanguageRequirementRepository.java
+++ b/src/main/java/com/example/solidconnection/university/repository/LanguageRequirementRepository.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.repository;
-import com.example.solidconnection.type.LanguageTestType;
import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
diff --git a/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java b/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java
index 60474c13d..58fb7aeec 100644
--- a/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java
+++ b/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.university.repository;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
@@ -12,8 +12,8 @@
import java.util.List;
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
-import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND_FOR_TERM;
+import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND_FOR_TERM;
@Repository
public interface UniversityInfoForApplyRepository extends JpaRepository {
diff --git a/src/main/java/com/example/solidconnection/university/repository/UniversityRepository.java b/src/main/java/com/example/solidconnection/university/repository/UniversityRepository.java
index e4cdeade2..b19285469 100644
--- a/src/main/java/com/example/solidconnection/university/repository/UniversityRepository.java
+++ b/src/main/java/com/example/solidconnection/university/repository/UniversityRepository.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.university.repository;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.repository.custom.UniversityFilterRepository;
import org.springframework.data.jpa.repository.JpaRepository;
@@ -10,7 +10,7 @@
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_NOT_FOUND;
@Repository
public interface UniversityRepository extends JpaRepository, UniversityFilterRepository {
diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java
index 009496be7..c35533877 100644
--- a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java
+++ b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.university.repository.custom;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java
index dd84cfbf5..25da850da 100644
--- a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java
+++ b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.university.repository.custom;
-import com.example.solidconnection.entity.QCountry;
-import com.example.solidconnection.entity.QRegion;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.location.country.domain.QCountry;
+import com.example.solidconnection.location.region.domain.QRegion;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.QUniversity;
import com.example.solidconnection.university.domain.QUniversityInfoForApply;
import com.example.solidconnection.university.domain.University;
diff --git a/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java b/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java
index 85971663b..228cc1ff8 100644
--- a/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java
+++ b/src/main/java/com/example/solidconnection/university/service/UniversityLikeService.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.university.service;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
import com.example.solidconnection.university.domain.LikedUniversity;
@@ -15,8 +15,8 @@
import java.util.Optional;
-import static com.example.solidconnection.custom.exception.ErrorCode.ALREADY_LIKED_UNIVERSITY;
-import static com.example.solidconnection.custom.exception.ErrorCode.NOT_LIKED_UNIVERSITY;
+import static com.example.solidconnection.common.exception.ErrorCode.ALREADY_LIKED_UNIVERSITY;
+import static com.example.solidconnection.common.exception.ErrorCode.NOT_LIKED_UNIVERSITY;
@RequiredArgsConstructor
@Service
diff --git a/src/main/java/com/example/solidconnection/university/service/UniversityQueryService.java b/src/main/java/com/example/solidconnection/university/service/UniversityQueryService.java
index f93f3ffae..e86f5debb 100644
--- a/src/main/java/com/example/solidconnection/university/service/UniversityQueryService.java
+++ b/src/main/java/com/example/solidconnection/university/service/UniversityQueryService.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.service;
import com.example.solidconnection.cache.annotation.ThunderingHerdCaching;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.UniversityDetailResponse;
diff --git a/src/main/java/com/example/solidconnection/util/JwtUtils.java b/src/main/java/com/example/solidconnection/util/JwtUtils.java
index a5c96d092..040beb9ba 100644
--- a/src/main/java/com/example/solidconnection/util/JwtUtils.java
+++ b/src/main/java/com/example/solidconnection/util/JwtUtils.java
@@ -1,13 +1,13 @@
package com.example.solidconnection.util;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_TOKEN;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_TOKEN;
@Component
public class JwtUtils {
diff --git a/src/main/java/com/example/solidconnection/util/RedisUtils.java b/src/main/java/com/example/solidconnection/util/RedisUtils.java
index ed67acac0..6f11eedfa 100644
--- a/src/main/java/com/example/solidconnection/util/RedisUtils.java
+++ b/src/main/java/com/example/solidconnection/util/RedisUtils.java
@@ -11,10 +11,10 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
-import static com.example.solidconnection.type.RedisConstants.CREATE_LOCK_PREFIX;
-import static com.example.solidconnection.type.RedisConstants.REFRESH_LOCK_PREFIX;
-import static com.example.solidconnection.type.RedisConstants.VALIDATE_VIEW_COUNT_KEY_PREFIX;
-import static com.example.solidconnection.type.RedisConstants.VIEW_COUNT_KEY_PREFIX;
+import static com.example.solidconnection.community.post.service.RedisConstants.CREATE_LOCK_PREFIX;
+import static com.example.solidconnection.community.post.service.RedisConstants.REFRESH_LOCK_PREFIX;
+import static com.example.solidconnection.community.post.service.RedisConstants.VALIDATE_VIEW_COUNT_KEY_PREFIX;
+import static com.example.solidconnection.community.post.service.RedisConstants.VIEW_COUNT_KEY_PREFIX;
@Component
public class RedisUtils {
diff --git a/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java b/src/test/java/com/example/solidconnection/admin/dto/validation/RejectedReasonValidatorTest.java
similarity index 93%
rename from src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java
rename to src/test/java/com/example/solidconnection/admin/dto/validation/RejectedReasonValidatorTest.java
index 5af4e8399..8c9af55c6 100644
--- a/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java
+++ b/src/test/java/com/example/solidconnection/admin/dto/validation/RejectedReasonValidatorTest.java
@@ -1,9 +1,9 @@
-package com.example.solidconnection.custom.validation.validator;
+package com.example.solidconnection.admin.dto.validation;
import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest;
import com.example.solidconnection.admin.dto.LanguageTestScoreUpdateRequest;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.university.domain.LanguageTestType;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
@@ -15,7 +15,7 @@
import java.util.Set;
-import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_REQUIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.REJECTED_REASON_REQUIRED;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("거절 사유 유효성 검사 테스트")
diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
index fc7735d86..a891759cd 100644
--- a/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
@@ -5,13 +5,13 @@
import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.VerifyStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -24,7 +24,7 @@
import java.time.LocalDate;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.GPA_SCORE_NOT_FOUND;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
index edf34670b..3fe3eb5a8 100644
--- a/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
@@ -5,13 +5,13 @@
import com.example.solidconnection.admin.dto.LanguageTestScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.VerifyStatus;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -24,8 +24,8 @@
import java.time.LocalDate;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.LANGUAGE_TEST_SCORE_NOT_FOUND;
-import static com.example.solidconnection.type.LanguageTestType.TOEIC;
+import static com.example.solidconnection.common.exception.ErrorCode.LANGUAGE_TEST_SCORE_NOT_FOUND;
+import static com.example.solidconnection.university.domain.LanguageTestType.TOEIC;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
index 583c31d80..240217496 100644
--- a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
@@ -3,6 +3,7 @@
import com.example.solidconnection.application.domain.Application;
import com.example.solidconnection.application.domain.Gpa;
import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.dto.ApplicantResponse;
import com.example.solidconnection.application.dto.ApplicationsResponse;
import com.example.solidconnection.application.dto.UniversityApplicantsResponse;
@@ -13,8 +14,7 @@
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
index f4f442840..3c107424a 100644
--- a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
+++ b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
@@ -3,27 +3,27 @@
import com.example.solidconnection.application.domain.Application;
import com.example.solidconnection.application.domain.Gpa;
import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.dto.ApplicationSubmissionResponse;
import com.example.solidconnection.application.dto.ApplyRequest;
import com.example.solidconnection.application.dto.UniversityChoiceRequest;
import com.example.solidconnection.application.repository.ApplicationRepository;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.university.domain.LanguageTestType;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static com.example.solidconnection.application.service.ApplicationSubmissionService.APPLICATION_UPDATE_COUNT_LIMIT;
-import static com.example.solidconnection.custom.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE_STATUS;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS;
+import static com.example.solidconnection.common.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_GPA_SCORE_STATUS;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
@@ -141,7 +141,7 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
private GpaScore createUnapprovedGpaScore(SiteUser siteUser) {
GpaScore gpaScore = new GpaScore(
- new Gpa(4.0, 4.5, "/gpa-report.pdf"),
+ new Gpa(4.0, 4.5, "/gpa-report.pdf"),
siteUser
);
return gpaScoreRepository.save(gpaScore);
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
index cb0ffbb96..8fd57eae6 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
@@ -3,7 +3,7 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
@@ -15,7 +15,7 @@
import java.time.LocalDate;
-import static com.example.solidconnection.custom.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.REFRESH_TOKEN_EXPIRED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java
index 4a98de6ce..84c0f362b 100644
--- a/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/EmailSignInServiceTest.java
@@ -2,8 +2,8 @@
import com.example.solidconnection.auth.dto.EmailSignInRequest;
import com.example.solidconnection.auth.dto.SignInResponse;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
diff --git a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
index 51eee236c..1656ed4e5 100644
--- a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
@@ -2,7 +2,7 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.SignInResponse;
-import com.example.solidconnection.config.security.JwtProperties;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
diff --git a/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java
index 12ab6f666..233317458 100644
--- a/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.auth.service.oauth;
import com.example.solidconnection.auth.domain.TokenType;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.util.JwtUtils;
@@ -21,8 +21,8 @@
import java.util.Map;
import static com.example.solidconnection.auth.service.oauth.OAuthSignUpTokenProvider.AUTH_TYPE_CLAIM_KEY;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
-import static com.example.solidconnection.custom.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
+import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
@@ -163,7 +163,7 @@ class 주어진_회원가입_토큰을_검증한다 {
// then
assertThat(extractedAuthType).isEqualTo(authType);
}
-
+
private String createExpiredToken() {
return Jwts.builder()
.setSubject("subject")
diff --git a/src/test/java/com/example/solidconnection/custom/exception/CustomAccessDeniedHandlerTest.java b/src/test/java/com/example/solidconnection/common/exception/CustomAccessDeniedHandlerTest.java
similarity index 90%
rename from src/test/java/com/example/solidconnection/custom/exception/CustomAccessDeniedHandlerTest.java
rename to src/test/java/com/example/solidconnection/common/exception/CustomAccessDeniedHandlerTest.java
index 7e4cae5b2..977733785 100644
--- a/src/test/java/com/example/solidconnection/custom/exception/CustomAccessDeniedHandlerTest.java
+++ b/src/test/java/com/example/solidconnection/common/exception/CustomAccessDeniedHandlerTest.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
-import com.example.solidconnection.custom.response.ErrorResponse;
+import com.example.solidconnection.common.response.ErrorResponse;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
@@ -13,7 +13,7 @@
import java.io.IOException;
-import static com.example.solidconnection.custom.exception.ErrorCode.ACCESS_DENIED;
+import static com.example.solidconnection.common.exception.ErrorCode.ACCESS_DENIED;
import static org.assertj.core.api.Assertions.assertThat;
@TestContainerSpringBootTest
diff --git a/src/test/java/com/example/solidconnection/custom/exception/CustomAuthenticationEntryPointTest.java b/src/test/java/com/example/solidconnection/common/exception/CustomAuthenticationEntryPointTest.java
similarity index 91%
rename from src/test/java/com/example/solidconnection/custom/exception/CustomAuthenticationEntryPointTest.java
rename to src/test/java/com/example/solidconnection/common/exception/CustomAuthenticationEntryPointTest.java
index 2cef64481..a10fed5df 100644
--- a/src/test/java/com/example/solidconnection/custom/exception/CustomAuthenticationEntryPointTest.java
+++ b/src/test/java/com/example/solidconnection/common/exception/CustomAuthenticationEntryPointTest.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.exception;
+package com.example.solidconnection.common.exception;
-import com.example.solidconnection.custom.response.ErrorResponse;
+import com.example.solidconnection.common.response.ErrorResponse;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
@@ -14,7 +14,7 @@
import java.io.IOException;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
import static org.assertj.core.api.Assertions.assertThat;
@TestContainerSpringBootTest
diff --git a/src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java b/src/test/java/com/example/solidconnection/common/resolver/AuthorizedUserResolverTest.java
similarity index 91%
rename from src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java
rename to src/test/java/com/example/solidconnection/common/resolver/AuthorizedUserResolverTest.java
index e0c1a006f..7eb144214 100644
--- a/src/test/java/com/example/solidconnection/custom/resolver/AuthorizedUserResolverTest.java
+++ b/src/test/java/com/example/solidconnection/common/resolver/AuthorizedUserResolverTest.java
@@ -1,8 +1,8 @@
-package com.example.solidconnection.custom.resolver;
+package com.example.solidconnection.common.resolver;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.authentication.SiteUserAuthentication;
+import com.example.solidconnection.security.userdetails.SiteUserDetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
@@ -15,7 +15,7 @@
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.BDDMockito.given;
diff --git a/src/test/java/com/example/solidconnection/custom/resolver/CustomPageableHandlerMethodArgumentResolverTest.java b/src/test/java/com/example/solidconnection/common/resolver/CustomPageableHandlerMethodArgumentResolverTest.java
similarity index 98%
rename from src/test/java/com/example/solidconnection/custom/resolver/CustomPageableHandlerMethodArgumentResolverTest.java
rename to src/test/java/com/example/solidconnection/common/resolver/CustomPageableHandlerMethodArgumentResolverTest.java
index dc628bc67..5d1bc0faa 100644
--- a/src/test/java/com/example/solidconnection/custom/resolver/CustomPageableHandlerMethodArgumentResolverTest.java
+++ b/src/test/java/com/example/solidconnection/common/resolver/CustomPageableHandlerMethodArgumentResolverTest.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.resolver;
+package com.example.solidconnection.common.resolver;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
diff --git a/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java b/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
index ee74bb90b..17309e100 100644
--- a/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
@@ -1,5 +1,6 @@
package com.example.solidconnection.community.comment.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.comment.domain.Comment;
import com.example.solidconnection.community.comment.dto.CommentCreateRequest;
@@ -10,11 +11,10 @@
import com.example.solidconnection.community.comment.dto.PostFindCommentResponse;
import com.example.solidconnection.community.comment.repository.CommentRepository;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.PostCategory;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -23,10 +23,10 @@
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_UPDATE_DEPRECATED_COMMENT;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COMMENT_ID;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_COMMENT_LEVEL;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_ACCESS;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_UPDATE_DEPRECATED_COMMENT;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_COMMENT_ID;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_COMMENT_LEVEL;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_ACCESS;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
index d3931008a..2656b2858 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
@@ -1,7 +1,9 @@
package com.example.solidconnection.community.post.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.domain.PostImage;
import com.example.solidconnection.community.post.dto.PostCreateRequest;
import com.example.solidconnection.community.post.dto.PostCreateResponse;
@@ -10,15 +12,12 @@
import com.example.solidconnection.community.post.dto.PostUpdateResponse;
import com.example.solidconnection.community.post.repository.PostImageRepository;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.s3.S3Service;
-import com.example.solidconnection.s3.UploadedFileUrlResponse;
-import com.example.solidconnection.service.RedisService;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.ImgType;
-import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.BeforeEach;
@@ -32,10 +31,10 @@
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_DELETE_OR_UPDATE_QUESTION;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_UPLOAD_MORE_THAN_FIVE_IMAGES;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_ACCESS;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_CATEGORY;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_DELETE_OR_UPDATE_QUESTION;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_UPLOAD_MORE_THAN_FIVE_IMAGES;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_ACCESS;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_CATEGORY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
index 30026e46a..4205019b7 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
@@ -1,8 +1,9 @@
package com.example.solidconnection.community.post.service;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.community.board.domain.Board;
-import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.dto.PostDislikeResponse;
import com.example.solidconnection.community.post.dto.PostLikeResponse;
import com.example.solidconnection.community.post.repository.PostLikeRepository;
@@ -10,15 +11,14 @@
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.PostCategory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import static com.example.solidconnection.custom.exception.ErrorCode.DUPLICATE_POST_LIKE;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_POST_LIKE;
+import static com.example.solidconnection.common.exception.ErrorCode.DUPLICATE_POST_LIKE;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_POST_LIKE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
index 67212e014..13a942ef7 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
@@ -1,22 +1,21 @@
package com.example.solidconnection.community.post.service;
import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.board.domain.BoardCode;
import com.example.solidconnection.community.comment.domain.Comment;
import com.example.solidconnection.community.comment.dto.PostFindCommentResponse;
-import com.example.solidconnection.community.post.dto.PostListResponse;
import com.example.solidconnection.community.comment.repository.CommentRepository;
-import com.example.solidconnection.community.post.domain.PostImage;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
+import com.example.solidconnection.community.post.domain.PostImage;
import com.example.solidconnection.community.post.dto.PostFindPostImageResponse;
import com.example.solidconnection.community.post.dto.PostFindResponse;
-import com.example.solidconnection.community.post.repository.PostRepository;
+import com.example.solidconnection.community.post.dto.PostListResponse;
import com.example.solidconnection.community.post.repository.PostImageRepository;
-import com.example.solidconnection.service.RedisService;
+import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.BoardCode;
-import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
diff --git a/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java b/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java
index 4f2ddf687..188f717ca 100644
--- a/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java
+++ b/src/test/java/com/example/solidconnection/concurrency/PostLikeCountConcurrencyTest.java
@@ -3,13 +3,13 @@
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.board.repository.BoardRepository;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.community.post.service.PostLikeService;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PostCategory;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java b/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java
index 6c1a0e18f..5f2b70d37 100644
--- a/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java
+++ b/src/test/java/com/example/solidconnection/concurrency/PostViewCountConcurrencyTest.java
@@ -3,12 +3,12 @@
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.board.repository.BoardRepository;
import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.service.RedisService;
+import com.example.solidconnection.community.post.service.RedisService;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.PostCategory;
import com.example.solidconnection.util.RedisUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -21,7 +21,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
-import static com.example.solidconnection.type.RedisConstants.VALIDATE_VIEW_COUNT_TTL;
+import static com.example.solidconnection.community.post.service.RedisConstants.VALIDATE_VIEW_COUNT_TTL;
import static org.junit.jupiter.api.Assertions.assertEquals;
@TestContainerSpringBootTest
diff --git a/src/test/java/com/example/solidconnection/e2e/DynamicFixture.java b/src/test/java/com/example/solidconnection/e2e/DynamicFixture.java
index 43af92ea5..4c90e58dc 100644
--- a/src/test/java/com/example/solidconnection/e2e/DynamicFixture.java
+++ b/src/test/java/com/example/solidconnection/e2e/DynamicFixture.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.e2e;
+import com.example.solidconnection.siteuser.domain.PreparationStatus;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
public class DynamicFixture { // todo: test fixture 개선 작업 이후, 이 클래스의 사용이 대체되면 삭제 필요
diff --git a/src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java b/src/test/java/com/example/solidconnection/location/country/fixture/CountryFixture.java
similarity index 87%
rename from src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java
rename to src/test/java/com/example/solidconnection/location/country/fixture/CountryFixture.java
index 53f394eae..cf3e2d6b1 100644
--- a/src/test/java/com/example/solidconnection/country/fixture/CountryFixture.java
+++ b/src/test/java/com/example/solidconnection/location/country/fixture/CountryFixture.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.country.fixture;
+package com.example.solidconnection.location.country.fixture;
-import com.example.solidconnection.entity.Country;
-import com.example.solidconnection.region.fixture.RegionFixture;
+import com.example.solidconnection.location.country.domain.Country;
+import com.example.solidconnection.location.region.fixture.RegionFixture;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java b/src/test/java/com/example/solidconnection/location/country/fixture/CountryFixtureBuilder.java
similarity index 78%
rename from src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java
rename to src/test/java/com/example/solidconnection/location/country/fixture/CountryFixtureBuilder.java
index e3ea004c5..85fdb466f 100644
--- a/src/test/java/com/example/solidconnection/country/fixture/CountryFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/location/country/fixture/CountryFixtureBuilder.java
@@ -1,8 +1,8 @@
-package com.example.solidconnection.country.fixture;
+package com.example.solidconnection.location.country.fixture;
-import com.example.solidconnection.entity.Country;
-import com.example.solidconnection.entity.Region;
-import com.example.solidconnection.country.repository.CountryRepositoryForTest;
+import com.example.solidconnection.location.country.domain.Country;
+import com.example.solidconnection.location.country.repository.CountryRepositoryForTest;
+import com.example.solidconnection.location.region.domain.Region;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java b/src/test/java/com/example/solidconnection/location/country/repository/CountryRepositoryForTest.java
similarity index 62%
rename from src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java
rename to src/test/java/com/example/solidconnection/location/country/repository/CountryRepositoryForTest.java
index fc5dab0f9..c9c7400a9 100644
--- a/src/test/java/com/example/solidconnection/country/repository/CountryRepositoryForTest.java
+++ b/src/test/java/com/example/solidconnection/location/country/repository/CountryRepositoryForTest.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.country.repository;
+package com.example.solidconnection.location.country.repository;
-import com.example.solidconnection.entity.Country;
+import com.example.solidconnection.location.country.domain.Country;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
diff --git a/src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java b/src/test/java/com/example/solidconnection/location/region/fixture/RegionFixture.java
similarity index 86%
rename from src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java
rename to src/test/java/com/example/solidconnection/location/region/fixture/RegionFixture.java
index a1cd97e56..2cf13437e 100644
--- a/src/test/java/com/example/solidconnection/region/fixture/RegionFixture.java
+++ b/src/test/java/com/example/solidconnection/location/region/fixture/RegionFixture.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.region.fixture;
+package com.example.solidconnection.location.region.fixture;
-import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.location.region.domain.Region;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java b/src/test/java/com/example/solidconnection/location/region/fixture/RegionFixtureBuilder.java
similarity index 79%
rename from src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java
rename to src/test/java/com/example/solidconnection/location/region/fixture/RegionFixtureBuilder.java
index a385a53f8..968665e22 100644
--- a/src/test/java/com/example/solidconnection/region/fixture/RegionFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/location/region/fixture/RegionFixtureBuilder.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.region.fixture;
+package com.example.solidconnection.location.region.fixture;
-import com.example.solidconnection.entity.Region;
-import com.example.solidconnection.region.repository.RegionRepositoryForTest;
+import com.example.solidconnection.location.region.domain.Region;
+import com.example.solidconnection.location.region.repository.RegionRepositoryForTest;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java b/src/test/java/com/example/solidconnection/location/region/repository/RegionRepositoryForTest.java
similarity index 62%
rename from src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java
rename to src/test/java/com/example/solidconnection/location/region/repository/RegionRepositoryForTest.java
index 00c35c02d..a27c16b9b 100644
--- a/src/test/java/com/example/solidconnection/region/repository/RegionRepositoryForTest.java
+++ b/src/test/java/com/example/solidconnection/location/region/repository/RegionRepositoryForTest.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.region.repository;
+package com.example.solidconnection.location.region.repository;
-import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.location.region.domain.Region;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
diff --git a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
index 27ed7a617..e03813607 100644
--- a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
@@ -2,8 +2,10 @@
import com.example.solidconnection.application.domain.Gpa;
import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.s3.S3Service;
-import com.example.solidconnection.s3.UploadedFileUrlResponse;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.dto.GpaScoreRequest;
@@ -18,9 +20,7 @@
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.type.ImgType;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.VerifyStatus;
+import com.example.solidconnection.university.domain.LanguageTestType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java b/src/test/java/com/example/solidconnection/security/aspect/AdminAuthorizationAspectTest.java
similarity index 90%
rename from src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java
rename to src/test/java/com/example/solidconnection/security/aspect/AdminAuthorizationAspectTest.java
index b733acceb..343bbbc30 100644
--- a/src/test/java/com/example/solidconnection/custom/security/aspect/AdminAuthorizationAspectTest.java
+++ b/src/test/java/com/example/solidconnection/security/aspect/AdminAuthorizationAspectTest.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.security.aspect;
+package com.example.solidconnection.security.aspect;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.security.annotation.RequireAdminAccess;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.annotation.RequireAdminAccess;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
@@ -12,7 +12,7 @@
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
-import static com.example.solidconnection.custom.exception.ErrorCode.ACCESS_DENIED;
+import static com.example.solidconnection.common.exception.ErrorCode.ACCESS_DENIED;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
diff --git a/src/test/java/com/example/solidconnection/custom/security/authentication/SiteUserAuthenticationTest.java b/src/test/java/com/example/solidconnection/security/authentication/SiteUserAuthenticationTest.java
similarity index 88%
rename from src/test/java/com/example/solidconnection/custom/security/authentication/SiteUserAuthenticationTest.java
rename to src/test/java/com/example/solidconnection/security/authentication/SiteUserAuthenticationTest.java
index 6285727cb..8c3b9e216 100644
--- a/src/test/java/com/example/solidconnection/custom/security/authentication/SiteUserAuthenticationTest.java
+++ b/src/test/java/com/example/solidconnection/security/authentication/SiteUserAuthenticationTest.java
@@ -1,9 +1,9 @@
-package com.example.solidconnection.custom.security.authentication;
+package com.example.solidconnection.security.authentication;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.siteuser.domain.PreparationStatus;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/src/test/java/com/example/solidconnection/custom/security/filter/ExceptionHandlerFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/ExceptionHandlerFilterTest.java
similarity index 93%
rename from src/test/java/com/example/solidconnection/custom/security/filter/ExceptionHandlerFilterTest.java
rename to src/test/java/com/example/solidconnection/security/filter/ExceptionHandlerFilterTest.java
index f1b3c7359..4fa01a234 100644
--- a/src/test/java/com/example/solidconnection/custom/security/filter/ExceptionHandlerFilterTest.java
+++ b/src/test/java/com/example/solidconnection/security/filter/ExceptionHandlerFilterTest.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.security.filter;
+package com.example.solidconnection.security.filter;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
@@ -13,7 +13,6 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
-import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
diff --git a/src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java
similarity index 91%
rename from src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java
rename to src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java
index 61e4c9170..c66037c82 100644
--- a/src/test/java/com/example/solidconnection/custom/security/filter/JwtAuthenticationFilterTest.java
+++ b/src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java
@@ -1,8 +1,8 @@
-package com.example.solidconnection.custom.security.filter;
+package com.example.solidconnection.security.filter;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetailsService;
+import com.example.solidconnection.security.authentication.SiteUserAuthentication;
+import com.example.solidconnection.security.config.JwtProperties;
+import com.example.solidconnection.security.userdetails.SiteUserDetailsService;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
diff --git a/src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
similarity index 85%
rename from src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java
rename to src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
index e76a01c75..5ccc1aa1b 100644
--- a/src/test/java/com/example/solidconnection/custom/security/filter/SignOutCheckFilterTest.java
+++ b/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
@@ -1,7 +1,7 @@
-package com.example.solidconnection.custom.security.filter;
+package com.example.solidconnection.security.filter;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
@@ -20,7 +20,7 @@
import java.util.Objects;
import static com.example.solidconnection.auth.domain.TokenType.BLACKLIST;
-import static com.example.solidconnection.custom.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
+import static com.example.solidconnection.common.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.spy;
@@ -95,12 +95,12 @@ void setUp() {
}
private String createToken(String subject) {
- return Jwts.builder()
- .setSubject(subject)
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() + 1000))
- .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
- .compact();
+ return Jwts.builder()
+ .setSubject(subject)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() + 1000))
+ .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
+ .compact();
}
private HttpServletRequest createRequest(String token) {
diff --git a/src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java b/src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java
similarity index 91%
rename from src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java
rename to src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java
index b8999e3f5..9c51de838 100644
--- a/src/test/java/com/example/solidconnection/custom/security/provider/SiteUserAuthenticationProviderTest.java
+++ b/src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java
@@ -1,9 +1,9 @@
-package com.example.solidconnection.custom.security.provider;
+package com.example.solidconnection.security.provider;
-import com.example.solidconnection.config.security.JwtProperties;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.security.authentication.SiteUserAuthentication;
-import com.example.solidconnection.custom.security.userdetails.SiteUserDetails;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.security.authentication.SiteUserAuthentication;
+import com.example.solidconnection.security.config.JwtProperties;
+import com.example.solidconnection.security.userdetails.SiteUserDetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
@@ -19,8 +19,8 @@
import java.net.PasswordAuthentication;
import java.util.Date;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_TOKEN;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_TOKEN;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java b/src/test/java/com/example/solidconnection/security/userdetails/SiteUserDetailsServiceTest.java
similarity index 92%
rename from src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java
rename to src/test/java/com/example/solidconnection/security/userdetails/SiteUserDetailsServiceTest.java
index 718732a44..c292203af 100644
--- a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsServiceTest.java
+++ b/src/test/java/com/example/solidconnection/security/userdetails/SiteUserDetailsServiceTest.java
@@ -1,6 +1,6 @@
-package com.example.solidconnection.custom.security.userdetails;
+package com.example.solidconnection.security.userdetails;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
@@ -12,8 +12,8 @@
import java.time.LocalDate;
-import static com.example.solidconnection.custom.exception.ErrorCode.AUTHENTICATION_FAILED;
-import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_TOKEN;
+import static com.example.solidconnection.common.exception.ErrorCode.AUTHENTICATION_FAILED;
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_TOKEN;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
diff --git a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java b/src/test/java/com/example/solidconnection/security/userdetails/SiteUserDetailsTest.java
similarity index 94%
rename from src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java
rename to src/test/java/com/example/solidconnection/security/userdetails/SiteUserDetailsTest.java
index 6fe9b6d69..8f533e8b7 100644
--- a/src/test/java/com/example/solidconnection/custom/security/userdetails/SiteUserDetailsTest.java
+++ b/src/test/java/com/example/solidconnection/security/userdetails/SiteUserDetailsTest.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.security.userdetails;
+package com.example.solidconnection.security.userdetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
diff --git a/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
index 000b7bc48..664a727c1 100644
--- a/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
+++ b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.siteuser.fixture;
import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.type.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java
index f0d8bd406..46db8bae4 100644
--- a/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixtureBuilder.java
@@ -1,10 +1,10 @@
package com.example.solidconnection.siteuser.fixture;
import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.PreparationStatus;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
import org.springframework.security.crypto.password.PasswordEncoder;
diff --git a/src/test/java/com/example/solidconnection/siteuser/repository/SiteUserRepositoryTest.java b/src/test/java/com/example/solidconnection/siteuser/repository/SiteUserRepositoryTest.java
index c3d9d240e..41806d6cf 100644
--- a/src/test/java/com/example/solidconnection/siteuser/repository/SiteUserRepositoryTest.java
+++ b/src/test/java/com/example/solidconnection/siteuser/repository/SiteUserRepositoryTest.java
@@ -1,10 +1,10 @@
package com.example.solidconnection.siteuser.repository;
import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.PreparationStatus;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.support.TestContainerDataJpaTest;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
diff --git a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
index 1c5680d33..1168a0eeb 100644
--- a/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
+++ b/src/test/java/com/example/solidconnection/siteuser/service/MyPageServiceTest.java
@@ -1,9 +1,11 @@
package com.example.solidconnection.siteuser.service;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.s3.S3Service;
-import com.example.solidconnection.s3.UploadedFileUrlResponse;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.s3.domain.ImgType;
+import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
+import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.siteuser.domain.AuthType;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.dto.MyPageResponse;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
@@ -11,8 +13,6 @@
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.ImgType;
-import com.example.solidconnection.type.Role;
import com.example.solidconnection.university.domain.LikedUniversity;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
@@ -28,8 +28,8 @@
import java.time.LocalDateTime;
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET;
-import static com.example.solidconnection.custom.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
+import static com.example.solidconnection.common.exception.ErrorCode.CAN_NOT_CHANGE_NICKNAME_YET;
+import static com.example.solidconnection.common.exception.ErrorCode.NICKNAME_ALREADY_EXISTED;
import static com.example.solidconnection.siteuser.service.MyPageService.MIN_DAYS_BETWEEN_NICKNAME_CHANGES;
import static com.example.solidconnection.siteuser.service.MyPageService.NICKNAME_LAST_CHANGE_DATE_FORMAT;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java b/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java
index 05b101985..ae449641f 100644
--- a/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java
+++ b/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java
@@ -3,31 +3,31 @@
import com.example.solidconnection.application.domain.Application;
import com.example.solidconnection.application.domain.Gpa;
import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.repository.ApplicationRepository;
import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.board.repository.BoardRepository;
-import com.example.solidconnection.entity.Country;
-import com.example.solidconnection.community.post.domain.PostImage;
-import com.example.solidconnection.entity.Region;
import com.example.solidconnection.community.post.domain.Post;
-import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.repositories.CountryRepository;
+import com.example.solidconnection.community.post.domain.PostCategory;
+import com.example.solidconnection.community.post.domain.PostImage;
import com.example.solidconnection.community.post.repository.PostImageRepository;
-import com.example.solidconnection.repositories.RegionRepository;
+import com.example.solidconnection.community.post.repository.PostRepository;
+import com.example.solidconnection.location.country.domain.Country;
+import com.example.solidconnection.location.country.repository.CountryRepository;
+import com.example.solidconnection.location.region.domain.Region;
+import com.example.solidconnection.location.region.repository.RegionRepository;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
+import com.example.solidconnection.siteuser.domain.PreparationStatus;
+import com.example.solidconnection.siteuser.domain.Role;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.repository.SiteUserRepository;
import com.example.solidconnection.support.DatabaseClearExtension;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.type.LanguageTestType;
-import com.example.solidconnection.type.PostCategory;
-import com.example.solidconnection.type.PreparationStatus;
-import com.example.solidconnection.type.Role;
-import com.example.solidconnection.type.VerifyStatus;
import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.repository.LanguageRequirementRepository;
@@ -41,12 +41,12 @@
import java.util.HashSet;
import java.util.List;
-import static com.example.solidconnection.type.BoardCode.AMERICAS;
-import static com.example.solidconnection.type.BoardCode.ASIA;
-import static com.example.solidconnection.type.BoardCode.EUROPE;
-import static com.example.solidconnection.type.BoardCode.FREE;
-import static com.example.solidconnection.type.SemesterAvailableForDispatch.ONE_SEMESTER;
-import static com.example.solidconnection.type.TuitionFeeType.HOME_UNIVERSITY_PAYMENT;
+import static com.example.solidconnection.community.board.domain.BoardCode.AMERICAS;
+import static com.example.solidconnection.community.board.domain.BoardCode.ASIA;
+import static com.example.solidconnection.community.board.domain.BoardCode.EUROPE;
+import static com.example.solidconnection.community.board.domain.BoardCode.FREE;
+import static com.example.solidconnection.university.domain.SemesterAvailableForDispatch.ONE_SEMESTER;
+import static com.example.solidconnection.university.domain.TuitionFeeType.HOME_UNIVERSITY_PAYMENT;
@TestContainerSpringBootTest
@ExtendWith(DatabaseClearExtension.class)
diff --git a/src/test/java/com/example/solidconnection/custom/validation/validator/ValidUniversityChoiceValidatorTest.java b/src/test/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoiceValidatorTest.java
similarity index 92%
rename from src/test/java/com/example/solidconnection/custom/validation/validator/ValidUniversityChoiceValidatorTest.java
rename to src/test/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoiceValidatorTest.java
index b0267a08b..e08f49e6a 100644
--- a/src/test/java/com/example/solidconnection/custom/validation/validator/ValidUniversityChoiceValidatorTest.java
+++ b/src/test/java/com/example/solidconnection/university/dto/validation/ValidUniversityChoiceValidatorTest.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.custom.validation.validator;
+package com.example.solidconnection.university.dto.validation;
import com.example.solidconnection.application.dto.UniversityChoiceRequest;
import jakarta.validation.ConstraintViolation;
@@ -11,9 +11,9 @@
import java.util.Set;
-import static com.example.solidconnection.custom.exception.ErrorCode.DUPLICATE_UNIVERSITY_CHOICE;
-import static com.example.solidconnection.custom.exception.ErrorCode.FIRST_CHOICE_REQUIRED;
-import static com.example.solidconnection.custom.exception.ErrorCode.THIRD_CHOICE_REQUIRES_SECOND;
+import static com.example.solidconnection.common.exception.ErrorCode.DUPLICATE_UNIVERSITY_CHOICE;
+import static com.example.solidconnection.common.exception.ErrorCode.FIRST_CHOICE_REQUIRED;
+import static com.example.solidconnection.common.exception.ErrorCode.THIRD_CHOICE_REQUIRES_SECOND;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("대학 선택 유효성 검사 테스트")
diff --git a/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java
index ba32c1b27..c97a1427e 100644
--- a/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java
+++ b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixture.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.fixture;
-import com.example.solidconnection.type.LanguageTestType;
import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java
index e6f3fd4d5..f72e7caba 100644
--- a/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/university/fixture/LanguageRequirementFixtureBuilder.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.fixture;
-import com.example.solidconnection.type.LanguageTestType;
import com.example.solidconnection.university.domain.LanguageRequirement;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.repository.LanguageRequirementRepository;
import lombok.RequiredArgsConstructor;
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java
index f3a41515f..d1c9d2dd4 100644
--- a/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixture.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.fixture;
-import com.example.solidconnection.country.fixture.CountryFixture;
-import com.example.solidconnection.region.fixture.RegionFixture;
+import com.example.solidconnection.location.country.fixture.CountryFixture;
+import com.example.solidconnection.location.region.fixture.RegionFixture;
import com.example.solidconnection.university.domain.University;
import lombok.RequiredArgsConstructor;
import org.springframework.boot.test.context.TestComponent;
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java
index f51ea9677..4da6cdfd7 100644
--- a/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityFixtureBuilder.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.university.fixture;
-import com.example.solidconnection.entity.Country;
-import com.example.solidconnection.entity.Region;
+import com.example.solidconnection.location.country.domain.Country;
+import com.example.solidconnection.location.region.domain.Region;
import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.repository.UniversityRepository;
import lombok.RequiredArgsConstructor;
diff --git a/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java b/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java
index 8041bda1e..260a037d9 100644
--- a/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/university/fixture/UniversityInfoForApplyFixtureBuilder.java
@@ -8,8 +8,8 @@
import java.util.HashSet;
-import static com.example.solidconnection.type.SemesterAvailableForDispatch.ONE_SEMESTER;
-import static com.example.solidconnection.type.TuitionFeeType.HOME_UNIVERSITY_PAYMENT;
+import static com.example.solidconnection.university.domain.SemesterAvailableForDispatch.ONE_SEMESTER;
+import static com.example.solidconnection.university.domain.TuitionFeeType.HOME_UNIVERSITY_PAYMENT;
@TestComponent
@RequiredArgsConstructor
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
index 7f970108a..9ba0df2b1 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityLikeServiceTest.java
@@ -1,6 +1,6 @@
package com.example.solidconnection.university.service;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.siteuser.repository.LikedUniversityRepository;
@@ -16,9 +16,9 @@
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
-import static com.example.solidconnection.custom.exception.ErrorCode.ALREADY_LIKED_UNIVERSITY;
-import static com.example.solidconnection.custom.exception.ErrorCode.NOT_LIKED_UNIVERSITY;
-import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.ALREADY_LIKED_UNIVERSITY;
+import static com.example.solidconnection.common.exception.ErrorCode.NOT_LIKED_UNIVERSITY;
+import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
import static com.example.solidconnection.university.service.UniversityLikeService.LIKE_CANCELED_MESSAGE;
import static com.example.solidconnection.university.service.UniversityLikeService.LIKE_SUCCESS_MESSAGE;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java
index 731ccec5b..d83e77b1d 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityQueryServiceTest.java
@@ -1,14 +1,14 @@
package com.example.solidconnection.university.service;
-import com.example.solidconnection.custom.exception.CustomException;
+import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.university.fixture.LanguageRequirementFixture;
-import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
-import com.example.solidconnection.type.LanguageTestType;
+import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.dto.UniversityDetailResponse;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponse;
import com.example.solidconnection.university.dto.UniversityInfoForApplyPreviewResponses;
+import com.example.solidconnection.university.fixture.LanguageRequirementFixture;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
import com.example.solidconnection.university.repository.custom.UniversityFilterRepository;
import org.junit.jupiter.api.DisplayName;
@@ -18,7 +18,7 @@
import java.util.List;
-import static com.example.solidconnection.custom.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
+import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
import static org.mockito.BDDMockito.then;
diff --git a/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java b/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
index ffacab33f..ff274b96a 100644
--- a/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
+++ b/src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java
@@ -1,11 +1,11 @@
package com.example.solidconnection.university.service;
-import com.example.solidconnection.country.fixture.CountryFixture;
-import com.example.solidconnection.entity.InterestedCountry;
-import com.example.solidconnection.entity.InterestedRegion;
-import com.example.solidconnection.region.fixture.RegionFixture;
-import com.example.solidconnection.repositories.InterestedCountyRepository;
-import com.example.solidconnection.repositories.InterestedRegionRepository;
+import com.example.solidconnection.location.country.domain.InterestedCountry;
+import com.example.solidconnection.location.country.fixture.CountryFixture;
+import com.example.solidconnection.location.country.repository.InterestedCountyRepository;
+import com.example.solidconnection.location.region.domain.InterestedRegion;
+import com.example.solidconnection.location.region.fixture.RegionFixture;
+import com.example.solidconnection.location.region.repository.InterestedRegionRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
diff --git a/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java b/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
index 0c16de671..c57e85193 100644
--- a/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
+++ b/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.util;
-import com.example.solidconnection.custom.exception.CustomException;
-import com.example.solidconnection.custom.exception.ErrorCode;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.junit.jupiter.api.DisplayName;
From f0c83095c2518c95bfd3d204f6c519ca36ff62a7 Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Wed, 21 May 2025 15:01:34 +0900
Subject: [PATCH 17/90] =?UTF-8?q?chore:=20code=20owners=EC=97=90=20?=
=?UTF-8?q?=EC=8B=A0=EA=B7=9C=20=EA=B0=9C=EB=B0=9C=EC=9E=90=20=EC=B6=94?=
=?UTF-8?q?=EA=B0=80=20(#328)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.github/CODEOWNERS | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 201ad5570..e0d720750 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1 @@
-* @Gyuhyeok99 @nayonsoso @wibaek
+* @Gyuhyeok99 @nayonsoso @wibaek @whqtker @lsy1307
From 7c1333802ad1667f79da398c40fcb8d65c265770 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Wed, 21 May 2025 15:34:56 +0900
Subject: [PATCH 18/90] =?UTF-8?q?refactor:=20=EC=84=B1=EC=A0=81=20?=
=?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?=
=?UTF-8?q?=ED=8A=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20fixture=20=EB=A9=94?=
=?UTF-8?q?=EC=84=9C=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#325)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: GpaScoreFixture에 GPA점수 생성 메서드 추가
* refactor: GPA점수 데이터 Fixture 메서드로 변경
* fix: 양방향 연관관계 추가
* refacotr: GPA_점수로 함수명 변경
* feat: LanguageTestScoreFixture에 어학점수 생성 메서드 추가
* refactor: 어학점수 데이터 Fixture 메서드로 변경
* test: score 관련 테스트에서 상세 필드 검증 제거
* test: 어학 점수 fixture 어학 타입 및 점수 파라미터 제거
* test: GPA 점수 fixture GPA 타입 및 점수 파라미터 제거
* refactor: 변수명 순서 오름차순으로 변경
* refactor: 점수 목록 조회 검증 시 닉네임과 상태 추가
---
.../service/AdminGpaScoreServiceTest.java | 75 +++++------------
.../AdminLanguageTestScoreServiceTest.java | 84 +++++--------------
.../score/fixture/GpaScoreFixture.java | 23 +++++
.../score/fixture/GpaScoreFixtureBuilder.java | 46 ++++++++++
.../fixture/LanguageTestScoreFixture.java | 26 ++++++
.../LanguageTestScoreFixtureBuilder.java | 46 ++++++++++
.../score/service/ScoreServiceTest.java | 81 +++++-------------
7 files changed, 202 insertions(+), 179 deletions(-)
create mode 100644 src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixture.java
create mode 100644 src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixture.java
create mode 100644 src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixtureBuilder.java
diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
index a891759cd..c649e1ba9 100644
--- a/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/admin/service/AdminGpaScoreServiceTest.java
@@ -4,14 +4,13 @@
import com.example.solidconnection.admin.dto.GpaScoreSearchResponse;
import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
-import com.example.solidconnection.application.domain.Gpa;
import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
-import com.example.solidconnection.score.repository.GpaScoreRepository;
+import com.example.solidconnection.score.fixture.GpaScoreFixture;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -29,17 +28,18 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("학점 검증 관리자 서비스 테스트")
-class AdminGpaScoreServiceTest extends BaseIntegrationTest {
+class AdminGpaScoreServiceTest {
@Autowired
private AdminGpaScoreService adminGpaScoreService;
@Autowired
- private GpaScoreRepository gpaScoreRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
- private SiteUserFixture siteUserFixture;
+ private GpaScoreFixture gpaScoreFixture;
private GpaScore gpaScore1;
private GpaScore gpaScore2;
@@ -50,9 +50,9 @@ void setUp() {
SiteUser user1 = siteUserFixture.사용자(1, "test1");
SiteUser user2 = siteUserFixture.사용자(2, "test2");
SiteUser user3 = siteUserFixture.사용자(3, "test3");
- gpaScore3 = createGpaScore(user3, VerifyStatus.REJECTED);
- gpaScore2 = createGpaScore(user2, VerifyStatus.PENDING);
- gpaScore1 = createGpaScore(user1, VerifyStatus.PENDING);
+ gpaScore1 = gpaScoreFixture.GPA_점수(VerifyStatus.PENDING, user1);
+ gpaScore2 = gpaScoreFixture.GPA_점수(VerifyStatus.PENDING, user2);
+ gpaScore3 = gpaScoreFixture.GPA_점수(VerifyStatus.REJECTED, user3);
}
@Nested
@@ -69,19 +69,10 @@ class 지원한_GPA_목록_조회 {
Page response = adminGpaScoreService.searchGpaScores(condition, pageable);
// then
+ assertThat(response.getContent()).hasSize(expectedGpaScores.size());
assertThat(response.getContent())
- .hasSize(expectedGpaScores.size())
- .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll(
- () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpa()).isEqualTo(expected.getGpa().getGpa()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()),
- () -> assertThat(actual.gpaScoreStatusResponse().verifyStatus()).isEqualTo(expected.getVerifyStatus()),
-
- () -> assertThat(actual.siteUserResponse().id()).isEqualTo(expected.getSiteUser().getId()),
- () -> assertThat(actual.siteUserResponse().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()),
- () -> assertThat(actual.siteUserResponse().nickname()).isEqualTo(expected.getSiteUser().getNickname())
- ));
+ .extracting(content -> content.gpaScoreStatusResponse().verifyStatus())
+ .containsOnly(VerifyStatus.PENDING);
}
@Test
@@ -95,19 +86,10 @@ class 지원한_GPA_목록_조회 {
Page response = adminGpaScoreService.searchGpaScores(condition, pageable);
// then
+ assertThat(response.getContent()).hasSize(expectedGpaScores.size());
assertThat(response.getContent())
- .hasSize(expectedGpaScores.size())
- .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll(
- () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpa()).isEqualTo(expected.getGpa().getGpa()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()),
- () -> assertThat(actual.gpaScoreStatusResponse().verifyStatus()).isEqualTo(expected.getVerifyStatus()),
-
- () -> assertThat(actual.siteUserResponse().id()).isEqualTo(expected.getSiteUser().getId()),
- () -> assertThat(actual.siteUserResponse().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()),
- () -> assertThat(actual.siteUserResponse().nickname()).isEqualTo(expected.getSiteUser().getNickname())
- ));
+ .extracting(content -> content.siteUserResponse().nickname())
+ .containsOnly("test1", "test2", "test3");
}
@Test
@@ -121,19 +103,13 @@ class 지원한_GPA_목록_조회 {
Page response = adminGpaScoreService.searchGpaScores(condition, pageable);
// then
+ assertThat(response.getContent()).hasSize(expectedGpaScores.size());
+ assertThat(response.getContent())
+ .extracting(content -> content.gpaScoreStatusResponse().verifyStatus())
+ .containsOnly(VerifyStatus.PENDING);
assertThat(response.getContent())
- .hasSize(expectedGpaScores.size())
- .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll(
- () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpa()).isEqualTo(expected.getGpa().getGpa()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()),
- () -> assertThat(actual.gpaScoreStatusResponse().gpaResponse().gpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()),
- () -> assertThat(actual.gpaScoreStatusResponse().verifyStatus()).isEqualTo(expected.getVerifyStatus()),
-
- () -> assertThat(actual.siteUserResponse().id()).isEqualTo(expected.getSiteUser().getId()),
- () -> assertThat(actual.siteUserResponse().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()),
- () -> assertThat(actual.siteUserResponse().nickname()).isEqualTo(expected.getSiteUser().getNickname())
- ));
+ .extracting(content -> content.siteUserResponse().nickname())
+ .containsOnly("test1");
}
}
@@ -203,13 +179,4 @@ class GPA_점수_검증_및_수정 {
.hasMessage(GPA_SCORE_NOT_FOUND.getMessage());
}
}
-
- private GpaScore createGpaScore(SiteUser siteUser, VerifyStatus status) {
- GpaScore gpaScore = new GpaScore(
- new Gpa(4.0, 4.5, "/gpa-report.pdf"),
- siteUser
- );
- gpaScore.setVerifyStatus(status);
- return gpaScoreRepository.save(gpaScore);
- }
}
diff --git a/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
index 3fe3eb5a8..669c0b0be 100644
--- a/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/admin/service/AdminLanguageTestScoreServiceTest.java
@@ -4,14 +4,13 @@
import com.example.solidconnection.admin.dto.LanguageTestScoreSearchResponse;
import com.example.solidconnection.admin.dto.LanguageTestScoreUpdateRequest;
import com.example.solidconnection.admin.dto.ScoreSearchCondition;
-import com.example.solidconnection.application.domain.LanguageTest;
import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
+import com.example.solidconnection.score.fixture.LanguageTestScoreFixture;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -30,17 +29,18 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("어학 검증 관리자 서비스 테스트")
-class AdminLanguageTestScoreServiceTest extends BaseIntegrationTest {
+class AdminLanguageTestScoreServiceTest {
@Autowired
private AdminLanguageTestScoreService adminLanguageTestScoreService;
@Autowired
- private LanguageTestScoreRepository languageTestScoreRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
- private SiteUserFixture siteUserFixture;
+ private LanguageTestScoreFixture languageTestScoreFixture;
private LanguageTestScore languageTestScore1;
private LanguageTestScore languageTestScore2;
@@ -51,9 +51,9 @@ void setUp() {
SiteUser user1 = siteUserFixture.사용자(1, "test1");
SiteUser user2 = siteUserFixture.사용자(2, "test2");
SiteUser user3 = siteUserFixture.사용자(3, "test3");
- languageTestScore3 = createLanguageTestScore(user3, VerifyStatus.REJECTED);
- languageTestScore2 = createLanguageTestScore(user2, VerifyStatus.PENDING);
- languageTestScore1 = createLanguageTestScore(user1, VerifyStatus.PENDING);
+ languageTestScore1 = languageTestScoreFixture.어학_점수(VerifyStatus.PENDING, user1);
+ languageTestScore2 = languageTestScoreFixture.어학_점수(VerifyStatus.PENDING, user2);
+ languageTestScore3 = languageTestScoreFixture.어학_점수(VerifyStatus.REJECTED, user3);
}
@Nested
@@ -70,22 +70,10 @@ class 지원한_어학_목록_조회 {
Page response = adminLanguageTestScoreService.searchLanguageTestScores(condition, pageable);
// then
+ assertThat(response.getContent()).hasSize(expectedLanguageTestScores.size());
assertThat(response.getContent())
- .hasSize(expectedLanguageTestScores.size())
- .zipSatisfy(expectedLanguageTestScores, (actual, expected) -> assertAll(
- () -> assertThat(actual.languageTestScoreStatusResponse().id()).isEqualTo(expected.getId()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestType())
- .isEqualTo(expected.getLanguageTest().getLanguageTestType()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestScore())
- .isEqualTo(expected.getLanguageTest().getLanguageTestScore()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestReportUrl())
- .isEqualTo(expected.getLanguageTest().getLanguageTestReportUrl()),
- () -> assertThat(actual.languageTestScoreStatusResponse().verifyStatus()).isEqualTo(expected.getVerifyStatus()),
-
- () -> assertThat(actual.siteUserResponse().id()).isEqualTo(expected.getSiteUser().getId()),
- () -> assertThat(actual.siteUserResponse().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()),
- () -> assertThat(actual.siteUserResponse().nickname()).isEqualTo(expected.getSiteUser().getNickname())
- ));
+ .extracting(content -> content.languageTestScoreStatusResponse().verifyStatus())
+ .containsOnly(VerifyStatus.PENDING);
}
@Test
@@ -99,22 +87,10 @@ class 지원한_어학_목록_조회 {
Page response = adminLanguageTestScoreService.searchLanguageTestScores(condition, pageable);
// then
+ assertThat(response.getContent()).hasSize(expectedLanguageTestScores.size());
assertThat(response.getContent())
- .hasSize(expectedLanguageTestScores.size())
- .zipSatisfy(expectedLanguageTestScores, (actual, expected) -> assertAll(
- () -> assertThat(actual.languageTestScoreStatusResponse().id()).isEqualTo(expected.getId()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestType())
- .isEqualTo(expected.getLanguageTest().getLanguageTestType()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestScore())
- .isEqualTo(expected.getLanguageTest().getLanguageTestScore()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestReportUrl())
- .isEqualTo(expected.getLanguageTest().getLanguageTestReportUrl()),
- () -> assertThat(actual.languageTestScoreStatusResponse().verifyStatus()).isEqualTo(expected.getVerifyStatus()),
-
- () -> assertThat(actual.siteUserResponse().id()).isEqualTo(expected.getSiteUser().getId()),
- () -> assertThat(actual.siteUserResponse().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()),
- () -> assertThat(actual.siteUserResponse().nickname()).isEqualTo(expected.getSiteUser().getNickname())
- ));
+ .extracting(content -> content.siteUserResponse().nickname())
+ .containsOnly("test1", "test2", "test3");
}
@Test
@@ -128,22 +104,13 @@ class 지원한_어학_목록_조회 {
Page response = adminLanguageTestScoreService.searchLanguageTestScores(condition, pageable);
// then
+ assertThat(response.getContent()).hasSize(expectedLanguageTestScores.size());
+ assertThat(response.getContent())
+ .extracting(content -> content.languageTestScoreStatusResponse().verifyStatus())
+ .containsOnly(VerifyStatus.PENDING);
assertThat(response.getContent())
- .hasSize(expectedLanguageTestScores.size())
- .zipSatisfy(expectedLanguageTestScores, (actual, expected) -> assertAll(
- () -> assertThat(actual.languageTestScoreStatusResponse().id()).isEqualTo(expected.getId()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestType())
- .isEqualTo(expected.getLanguageTest().getLanguageTestType()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestScore())
- .isEqualTo(expected.getLanguageTest().getLanguageTestScore()),
- () -> assertThat(actual.languageTestScoreStatusResponse().languageTestResponse().languageTestReportUrl())
- .isEqualTo(expected.getLanguageTest().getLanguageTestReportUrl()),
- () -> assertThat(actual.languageTestScoreStatusResponse().verifyStatus()).isEqualTo(expected.getVerifyStatus()),
-
- () -> assertThat(actual.siteUserResponse().id()).isEqualTo(expected.getSiteUser().getId()),
- () -> assertThat(actual.siteUserResponse().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()),
- () -> assertThat(actual.siteUserResponse().nickname()).isEqualTo(expected.getSiteUser().getNickname())
- ));
+ .extracting(content -> content.siteUserResponse().nickname())
+ .containsOnly("test1");
}
}
@@ -213,13 +180,4 @@ class 어학점수_검증_및_수정 {
.hasMessage(LANGUAGE_TEST_SCORE_NOT_FOUND.getMessage());
}
}
-
- private LanguageTestScore createLanguageTestScore(SiteUser siteUser, VerifyStatus status) {
- LanguageTestScore languageTestScore = new LanguageTestScore(
- new LanguageTest(TOEIC, "500", "/toeic-report.pdf"),
- siteUser
- );
- languageTestScore.setVerifyStatus(status);
- return languageTestScoreRepository.save(languageTestScore);
- }
}
diff --git a/src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixture.java b/src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixture.java
new file mode 100644
index 000000000..4a61d1557
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixture.java
@@ -0,0 +1,23 @@
+package com.example.solidconnection.score.fixture;
+
+import com.example.solidconnection.application.domain.Gpa;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.score.domain.GpaScore;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class GpaScoreFixture {
+
+ private final GpaScoreFixtureBuilder gpaScoreFixtureBuilder;
+
+ public GpaScore GPA_점수 (VerifyStatus verifyStatus, SiteUser siteUser) {
+ return gpaScoreFixtureBuilder.gpaScore()
+ .gpa(new Gpa(4.0, 4.5, "/gpa-report.pdf"))
+ .verifyStatus(verifyStatus)
+ .siteUser(siteUser)
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixtureBuilder.java b/src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixtureBuilder.java
new file mode 100644
index 000000000..7943008b4
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/score/fixture/GpaScoreFixtureBuilder.java
@@ -0,0 +1,46 @@
+package com.example.solidconnection.score.fixture;
+
+import com.example.solidconnection.application.domain.Gpa;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.score.domain.GpaScore;
+import com.example.solidconnection.score.repository.GpaScoreRepository;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class GpaScoreFixtureBuilder {
+
+ private final GpaScoreRepository gpaScoreRepository;
+
+ private Gpa gpa;
+ private VerifyStatus verifyStatus;
+ private SiteUser siteUser;
+
+ public GpaScoreFixtureBuilder gpaScore() {
+ return new GpaScoreFixtureBuilder(gpaScoreRepository);
+ }
+
+ public GpaScoreFixtureBuilder gpa(Gpa gpa) {
+ this.gpa = gpa;
+ return this;
+ }
+
+ public GpaScoreFixtureBuilder verifyStatus(VerifyStatus verifyStatus) {
+ this.verifyStatus = verifyStatus;
+ return this;
+ }
+
+ public GpaScoreFixtureBuilder siteUser(SiteUser siteUser) {
+ this.siteUser = siteUser;
+ return this;
+ }
+
+ public GpaScore create() {
+ GpaScore gpaScore = new GpaScore(gpa, siteUser);
+ gpaScore.setSiteUser(siteUser);
+ gpaScore.setVerifyStatus(verifyStatus);
+ return gpaScoreRepository.save(gpaScore);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixture.java b/src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixture.java
new file mode 100644
index 000000000..7805692e0
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixture.java
@@ -0,0 +1,26 @@
+package com.example.solidconnection.score.fixture;
+
+import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.score.domain.LanguageTestScore;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.university.domain.LanguageTestType;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+import static com.example.solidconnection.university.domain.LanguageTestType.TOEIC;
+
+@TestComponent
+@RequiredArgsConstructor
+public class LanguageTestScoreFixture {
+
+ private final LanguageTestScoreFixtureBuilder languageTestScoreFixtureBuilder;
+
+ public LanguageTestScore 어학_점수 (VerifyStatus verifyStatus, SiteUser siteUser) {
+ return languageTestScoreFixtureBuilder.languageTestScore()
+ .languageTest(new LanguageTest(TOEIC, "500", "/language-report.pdf"))
+ .verifyStatus(verifyStatus)
+ .siteUser(siteUser)
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixtureBuilder.java b/src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixtureBuilder.java
new file mode 100644
index 000000000..fd5a8d417
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/score/fixture/LanguageTestScoreFixtureBuilder.java
@@ -0,0 +1,46 @@
+package com.example.solidconnection.score.fixture;
+
+import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.score.domain.LanguageTestScore;
+import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class LanguageTestScoreFixtureBuilder {
+
+ private final LanguageTestScoreRepository languageTestScoreRepository;
+
+ private LanguageTest languageTest;
+ private VerifyStatus verifyStatus;
+ private SiteUser siteUser;
+
+ public LanguageTestScoreFixtureBuilder languageTestScore() {
+ return new LanguageTestScoreFixtureBuilder(languageTestScoreRepository);
+ }
+
+ public LanguageTestScoreFixtureBuilder languageTest(LanguageTest languageTest) {
+ this.languageTest = languageTest;
+ return this;
+ }
+
+ public LanguageTestScoreFixtureBuilder verifyStatus(VerifyStatus verifyStatus) {
+ this.verifyStatus = verifyStatus;
+ return this;
+ }
+
+ public LanguageTestScoreFixtureBuilder siteUser(SiteUser siteUser) {
+ this.siteUser = siteUser;
+ return this;
+ }
+
+ public LanguageTestScore create() {
+ LanguageTestScore languageTestScore = new LanguageTestScore(languageTest, siteUser);
+ languageTestScore.setSiteUser(siteUser);
+ languageTestScore.setVerifyStatus(verifyStatus);
+ return languageTestScoreRepository.save(languageTestScore);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
index e03813607..0b1aa0718 100644
--- a/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
+++ b/src/test/java/com/example/solidconnection/score/service/ScoreServiceTest.java
@@ -1,7 +1,5 @@
package com.example.solidconnection.score.service;
-import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.application.domain.LanguageTest;
import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.s3.domain.ImgType;
import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
@@ -9,17 +7,16 @@
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.dto.GpaScoreRequest;
-import com.example.solidconnection.score.dto.GpaScoreStatusResponse;
import com.example.solidconnection.score.dto.GpaScoreStatusesResponse;
import com.example.solidconnection.score.dto.LanguageTestScoreRequest;
-import com.example.solidconnection.score.dto.LanguageTestScoreStatusResponse;
import com.example.solidconnection.score.dto.LanguageTestScoreStatusesResponse;
+import com.example.solidconnection.score.fixture.GpaScoreFixture;
+import com.example.solidconnection.score.fixture.LanguageTestScoreFixture;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.university.domain.LanguageTestType;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -31,11 +28,11 @@
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.junit.jupiter.api.Assertions.assertAll;
import static org.mockito.BDDMockito.given;
+@TestContainerSpringBootTest
@DisplayName("점수 서비스 테스트")
-class ScoreServiceTest extends BaseIntegrationTest {
+class ScoreServiceTest {
@Autowired
private ScoreService scoreService;
@@ -43,9 +40,6 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Autowired
private GpaScoreRepository gpaScoreRepository;
- @Autowired
- private SiteUserRepository siteUserRepository;
-
@Autowired
private LanguageTestScoreRepository languageTestScoreRepository;
@@ -55,6 +49,12 @@ class ScoreServiceTest extends BaseIntegrationTest {
@Autowired
private SiteUserFixture siteUserFixture;
+ @Autowired
+ private GpaScoreFixture gpaScoreFixture;
+
+ @Autowired
+ private LanguageTestScoreFixture languageTestScoreFixture;
+
private SiteUser user;
@BeforeEach
@@ -66,21 +66,15 @@ void setUp() {
void GPA_점수_상태를_조회한다() {
// given
List scores = List.of(
- createGpaScore(user, 3.5, 4.5),
- createGpaScore(user, 3.8, 4.5)
+ gpaScoreFixture.GPA_점수(VerifyStatus.PENDING, user),
+ gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user)
);
// when
GpaScoreStatusesResponse response = scoreService.getGpaScoreStatus(user);
// then
- assertThat(response.gpaScoreStatusResponseList())
- .hasSize(scores.size())
- .containsExactlyInAnyOrder(
- scores.stream()
- .map(GpaScoreStatusResponse::from)
- .toArray(GpaScoreStatusResponse[]::new)
- );
+ assertThat(response.gpaScoreStatusResponseList()).hasSize(scores.size());
}
@Test
@@ -96,22 +90,15 @@ void setUp() {
void 어학_시험_점수_상태를_조회한다() {
// given
List scores = List.of(
- createLanguageTestScore(user, LanguageTestType.TOEIC, "100"),
- createLanguageTestScore(user, LanguageTestType.TOEFL_IBT, "7.5")
+ languageTestScoreFixture.어학_점수(VerifyStatus.PENDING, user),
+ languageTestScoreFixture.어학_점수(VerifyStatus.PENDING, user)
);
- siteUserRepository.save(user);
// when
LanguageTestScoreStatusesResponse response = scoreService.getLanguageTestScoreStatus(user);
// then
- assertThat(response.languageTestScoreStatusResponseList())
- .hasSize(scores.size())
- .containsExactlyInAnyOrder(
- scores.stream()
- .map(LanguageTestScoreStatusResponse::from)
- .toArray(LanguageTestScoreStatusResponse[]::new)
- );
+ assertThat(response.languageTestScoreStatusResponseList()).hasSize(scores.size());
}
@Test
@@ -136,13 +123,7 @@ void setUp() {
GpaScore savedScore = gpaScoreRepository.findById(scoreId).orElseThrow();
// then
- assertAll(
- () -> assertThat(savedScore.getId()).isEqualTo(scoreId),
- () -> assertThat(savedScore.getGpa().getGpa()).isEqualTo(request.gpa()),
- () -> assertThat(savedScore.getGpa().getGpaCriteria()).isEqualTo(request.gpaCriteria()),
- () -> assertThat(savedScore.getVerifyStatus()).isEqualTo(VerifyStatus.PENDING),
- () -> assertThat(savedScore.getGpa().getGpaReportUrl()).isEqualTo(fileUrl)
- );
+ assertThat(savedScore.getId()).isEqualTo(scoreId);
}
@Test
@@ -158,31 +139,7 @@ void setUp() {
LanguageTestScore savedScore = languageTestScoreRepository.findById(scoreId).orElseThrow();
// then
- assertAll(
- () -> assertThat(savedScore.getId()).isEqualTo(scoreId),
- () -> assertThat(savedScore.getLanguageTest().getLanguageTestType()).isEqualTo(request.languageTestType()),
- () -> assertThat(savedScore.getLanguageTest().getLanguageTestScore()).isEqualTo(request.languageTestScore()),
- () -> assertThat(savedScore.getVerifyStatus()).isEqualTo(VerifyStatus.PENDING),
- () -> assertThat(savedScore.getLanguageTest().getLanguageTestReportUrl()).isEqualTo(fileUrl)
- );
- }
-
- private GpaScore createGpaScore(SiteUser siteUser, double gpa, double gpaCriteria) {
- GpaScore gpaScore = new GpaScore(
- new Gpa(gpa, gpaCriteria, "/gpa-report.pdf"),
- siteUser
- );
- gpaScore.setSiteUser(siteUser);
- return gpaScoreRepository.save(gpaScore);
- }
-
- private LanguageTestScore createLanguageTestScore(SiteUser siteUser, LanguageTestType languageTestType, String score) {
- LanguageTestScore languageTestScore = new LanguageTestScore(
- new LanguageTest(languageTestType, score, "/gpa-report.pdf"),
- siteUser
- );
- languageTestScore.setSiteUser(siteUser);
- return languageTestScoreRepository.save(languageTestScore);
+ assertThat(savedScore.getId()).isEqualTo(scoreId);
}
private GpaScoreRequest createGpaScoreRequest() {
From ab9092b65f9c6e8ae34eac60541b2e0da45a86ea Mon Sep 17 00:00:00 2001
From: Yeongseo Na
Date: Thu, 22 May 2025 20:37:34 +0900
Subject: [PATCH 19/90] =?UTF-8?q?refactor:=20Jwt=20=ED=86=A0=ED=81=B0=20?=
=?UTF-8?q?=EA=B4=80=EB=A0=A8=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20?=
=?UTF-8?q?=EC=83=81=EC=86=8D=EC=9D=B4=20=EC=95=84=EB=8B=88=EB=9D=BC=20?=
=?UTF-8?q?=EC=A1=B0=ED=95=A9=ED=95=98=EB=8F=84=EB=A1=9D=20(#324)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: 스프링 빈으로 활용하기 위해 private 생성자 제거
* refactor: 헤더에서 토큰 추출하는 코드 클래스로 분리
- 추가로, null 이 아니라 Optional 을 반환하여 빈 값 처리를 강제하도록 수정
* refactor: 토큰의 블랙리스트를 관리하는 코드 분리
* refactor: 토큰 제공과 관련된 코드 TokenProvider로 이동
- JwtUtils를 사용하던 곳에서 TokenProvider를 주입받아 사용하게 하기 위한 사전 작업
* refactor: TokenProvider를 abstract 클래스가 아니라 컴포넌트로
* refactor: TokenProvider를 상속하여 쓰던 곳에서 주입받아 쓰도록
* refactor: JwtUtils를 쓰던 곳에서 TokenProvider 쓰도록
* refactor: TokenProvider의 함수 인자 수정
- AS-IS: JwtUtils에 정의된 xxxParse 함수를 사용하기 위해서는, 함수 자체가 static이라서 호출하는 곳으로부터 jwt 시크릿 키를 건네받아야했다. 이를 위해 여러곳에서 JwtProperties를 주입받아 jwtProperties.secret()을 호출하며 xxxParse()함수에 값을 넘겨줬다.
- TO-BE: TokenProvider를 컴포넌트로 만듦으로서, TokenProvider의 내부에서 jwt 시크릿 키를 주입받을 수 있게 되었다. 함수의 인자로 시크릿키를 받을 필요가 없게 되었으므로 함수 인자를 수정한다.
* test: TokenProvider 테스트 코드 작성
- AS-IS : TokenProvider가 추상 클래스일 때는 이를 상속하는 클래스들로 TokenProvider의 기능을 테스트했다.
- TO-BE : TokenProvider도 컴포넌트가 되었으므로, 테스트 코드를 작성한다.
* refactor: 더 작은 작업에서 예외를 발생시키도록
- parseSubject가 parseClaims를 호출하는데, 이들이 발생시키는 예외의 종류가 다르면 안된다.
* chore: 개행 수정, 안쓰는 의존 제거
* refactor: 제대로 된 DIP를 위해 패키지 이동
- security가 auth를 의존하지 않게 하기 위해, BlackListChecker 인터페이스를 security패키지 내부로 옮긴다.
* chore: todo 삭제
* refactor: jwt 토큰 관련 코드 패키지 이동
- TokenProvider, TokenBlackListService를 auth.token 으로
- JwtProperties를 auth.token.config 로
* refactor: TokenProvider 인터페이스 생성
* refactor: TokenProvider 인터페이스에 의존하도록
* style: 개행 삭제
---
.../auth/service/AuthService.java | 4 +-
.../auth/service/AuthTokenProvider.java | 45 ++---
.../service/CommonSignUpTokenProvider.java | 6 +-
.../service/EmailSignUpTokenProvider.java | 25 ++-
.../auth/service/TokenProvider.java | 42 +----
.../oauth/OAuthSignUpTokenProvider.java | 22 +--
.../auth/token/JwtTokenProvider.java | 67 +++++++
.../auth/token/TokenBlackListService.java | 34 ++++
.../token}/config/JwtProperties.java | 2 +-
.../filter/AuthorizationHeaderParser.java | 29 +++
.../filter}/BlacklistChecker.java | 2 +-
.../filter/JwtAuthenticationFilter.java | 10 +-
.../security/filter/SignOutCheckFilter.java | 12 +-
.../SiteUserAuthenticationProvider.java | 8 +-
.../solidconnection/util/JwtUtils.java | 42 -----
.../auth/service/AuthServiceTest.java | 12 +-
.../auth/service/AuthTokenProviderTest.java | 42 +----
.../auth/service/JwtTokenProviderTest.java | 176 ++++++++++++++++++
.../auth/service/SignInServiceTest.java | 8 +-
.../service/TokenBlackListServiceTest.java | 58 ++++++
.../oauth/OAuthSignUpTokenProviderTest.java | 9 +-
.../filter/AuthorizationHeaderParserTest.java | 54 ++++++
.../filter/JwtAuthenticationFilterTest.java | 2 +-
.../filter/SignOutCheckFilterTest.java | 2 +-
.../SiteUserAuthenticationProviderTest.java | 2 +-
.../solidconnection/util/JwtUtilsTest.java | 106 -----------
26 files changed, 502 insertions(+), 319 deletions(-)
create mode 100644 src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java
create mode 100644 src/main/java/com/example/solidconnection/auth/token/TokenBlackListService.java
rename src/main/java/com/example/solidconnection/{security => auth/token}/config/JwtProperties.java (75%)
create mode 100644 src/main/java/com/example/solidconnection/security/filter/AuthorizationHeaderParser.java
rename src/main/java/com/example/solidconnection/{auth/service => security/filter}/BlacklistChecker.java (61%)
delete mode 100644 src/main/java/com/example/solidconnection/util/JwtUtils.java
create mode 100644 src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java
create mode 100644 src/test/java/com/example/solidconnection/auth/service/TokenBlackListServiceTest.java
create mode 100644 src/test/java/com/example/solidconnection/security/filter/AuthorizationHeaderParserTest.java
delete mode 100644 src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthService.java b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
index 496e48724..6053e8716 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthService.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthService.java
@@ -2,6 +2,7 @@
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
+import com.example.solidconnection.auth.token.TokenBlackListService;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import lombok.RequiredArgsConstructor;
@@ -17,6 +18,7 @@
public class AuthService {
private final AuthTokenProvider authTokenProvider;
+ private final TokenBlackListService tokenBlackListService;
/*
* 로그아웃한다.
@@ -26,7 +28,7 @@ public class AuthService {
public void signOut(String token) {
AccessToken accessToken = authTokenProvider.toAccessToken(token);
authTokenProvider.deleteRefreshTokenByAccessToken(accessToken);
- authTokenProvider.addToBlacklist(accessToken);
+ tokenBlackListService.addToBlacklist(accessToken);
}
/*
diff --git a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
index fa2a064cc..2ff3e5650 100644
--- a/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/AuthTokenProvider.java
@@ -1,49 +1,38 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.auth.domain.TokenType;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.util.JwtUtils;
+import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Objects;
@Component
-public class AuthTokenProvider extends TokenProvider implements BlacklistChecker {
+@RequiredArgsConstructor
+public class AuthTokenProvider {
- public AuthTokenProvider(JwtProperties jwtProperties, RedisTemplate redisTemplate) {
- super(jwtProperties, redisTemplate);
- }
+ private final RedisTemplate redisTemplate;
+ private final TokenProvider tokenProvider;
public AccessToken generateAccessToken(Subject subject) {
- String token = generateToken(subject.value(), TokenType.ACCESS);
+ String token = tokenProvider.generateToken(subject.value(), TokenType.ACCESS);
return new AccessToken(subject, token);
}
public RefreshToken generateAndSaveRefreshToken(Subject subject) {
- String token = generateToken(subject.value(), TokenType.REFRESH);
- saveToken(token, TokenType.REFRESH);
+ String token = tokenProvider.generateToken(subject.value(), TokenType.REFRESH);
+ tokenProvider.saveToken(token, TokenType.REFRESH);
return new RefreshToken(subject, token);
}
/*
- * 액세스 토큰을 블랙리스트에 저장한다.
- * - key = BLACKLIST:{accessToken}
- * - value = "signOut" -> key 의 존재만 확인하므로, value 에는 무슨 값이 들어가도 상관없다.
- * */
- public void addToBlacklist(AccessToken accessToken) {
- String blackListKey = TokenType.BLACKLIST.addPrefix(accessToken.token());
- redisTemplate.opsForValue().set(blackListKey, "signOut");
- }
-
- /*
- * 유효한 리프레시 토큰인지 확인한다.
- * - 요청된 토큰과 같은 subject 의 리프레시 토큰을 조회한다.
- * - 조회된 리프레시 토큰과 요청된 토큰이 같은지 비교한다.
- * */
+ * 유효한 리프레시 토큰인지 확인한다.
+ * - 요청된 토큰과 같은 subject 의 리프레시 토큰을 조회한다.
+ * - 조회된 리프레시 토큰과 요청된 토큰이 같은지 비교한다.
+ * */
public boolean isValidRefreshToken(String requestedRefreshToken) {
- String subject = JwtUtils.parseSubject(requestedRefreshToken, jwtProperties.secret());
+ String subject = tokenProvider.parseSubject(requestedRefreshToken);
String refreshTokenKey = TokenType.REFRESH.addPrefix(subject);
String foundRefreshToken = redisTemplate.opsForValue().get(refreshTokenKey);
return Objects.equals(requestedRefreshToken, foundRefreshToken);
@@ -55,14 +44,8 @@ public void deleteRefreshTokenByAccessToken(AccessToken accessToken) {
redisTemplate.delete(refreshTokenKey);
}
- @Override
- public boolean isTokenBlacklisted(String accessToken) {
- String blackListTokenKey = TokenType.BLACKLIST.addPrefix(accessToken);
- return redisTemplate.hasKey(blackListTokenKey);
- }
-
public Subject parseSubject(String token) {
- String subject = JwtUtils.parseSubject(token, jwtProperties.secret());
+ String subject = tokenProvider.parseSubject(token);
return new Subject(subject);
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java
index d16cb5134..d1ebe3b52 100644
--- a/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/CommonSignUpTokenProvider.java
@@ -1,9 +1,7 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
-import com.example.solidconnection.util.JwtUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
@@ -14,11 +12,11 @@
@RequiredArgsConstructor
public class CommonSignUpTokenProvider {
- private final JwtProperties jwtProperties;
+ private final TokenProvider tokenProvider;
public AuthType parseAuthType(String signUpToken) {
try {
- String authTypeStr = JwtUtils.parseClaims(signUpToken, jwtProperties.secret()).get(AUTH_TYPE_CLAIM_KEY, String.class);
+ String authTypeStr = tokenProvider.parseClaims(signUpToken).get(AUTH_TYPE_CLAIM_KEY, String.class);
return AuthType.valueOf(authTypeStr);
} catch (Exception e) {
throw new CustomException(SIGN_UP_TOKEN_INVALID);
diff --git a/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java
index c6bee80ab..fe9a176d3 100644
--- a/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/EmailSignUpTokenProvider.java
@@ -2,12 +2,13 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.EmailSignUpTokenRequest;
+import com.example.solidconnection.auth.token.config.JwtProperties;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
@@ -19,22 +20,18 @@
import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
-import static com.example.solidconnection.util.JwtUtils.parseClaims;
-import static com.example.solidconnection.util.JwtUtils.parseSubject;
@Component
-public class EmailSignUpTokenProvider extends TokenProvider {
+@RequiredArgsConstructor
+public class EmailSignUpTokenProvider {
static final String PASSWORD_CLAIM_KEY = "password";
static final String AUTH_TYPE_CLAIM_KEY = "authType";
private final PasswordEncoder passwordEncoder;
-
- public EmailSignUpTokenProvider(JwtProperties jwtProperties, RedisTemplate redisTemplate,
- PasswordEncoder passwordEncoder) {
- super(jwtProperties, redisTemplate);
- this.passwordEncoder = passwordEncoder;
- }
+ private final JwtProperties jwtProperties;
+ private final RedisTemplate redisTemplate;
+ private final TokenProvider tokenProvider;
public String generateAndSaveSignUpToken(EmailSignUpTokenRequest request) {
String email = request.email();
@@ -54,7 +51,7 @@ public String generateAndSaveSignUpToken(EmailSignUpTokenRequest request) {
.setExpiration(expiredDate)
.signWith(SignatureAlgorithm.HS512, jwtProperties.secret())
.compact();
- return saveToken(signUpToken, TokenType.SIGN_UP);
+ return tokenProvider.saveToken(signUpToken, TokenType.SIGN_UP);
}
public void validateSignUpToken(String token) {
@@ -65,7 +62,7 @@ public void validateSignUpToken(String token) {
private void validateFormatAndExpiration(String token) {
try {
- Claims claims = parseClaims(token, jwtProperties.secret());
+ Claims claims = tokenProvider.parseClaims(token);
Objects.requireNonNull(claims.getSubject());
String encodedPassword = claims.get(PASSWORD_CLAIM_KEY, String.class);
Objects.requireNonNull(encodedPassword);
@@ -82,11 +79,11 @@ private void validateIssuedByServer(String email) {
}
public String parseEmail(String token) {
- return parseSubject(token, jwtProperties.secret());
+ return tokenProvider.parseSubject(token);
}
public String parseEncodedPassword(String token) {
- Claims claims = parseClaims(token, jwtProperties.secret());
+ Claims claims = tokenProvider.parseClaims(token);
return claims.get(PASSWORD_CLAIM_KEY, String.class);
}
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java
index 0f3552db2..2cd93fb8e 100644
--- a/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/TokenProvider.java
@@ -1,47 +1,15 @@
package com.example.solidconnection.auth.service;
import com.example.solidconnection.auth.domain.TokenType;
-import com.example.solidconnection.security.config.JwtProperties;
import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.springframework.data.redis.core.RedisTemplate;
-import java.util.Date;
-import java.util.concurrent.TimeUnit;
+public interface TokenProvider {
-import static com.example.solidconnection.util.JwtUtils.parseSubject;
+ String generateToken(String string, TokenType tokenType);
-public abstract class TokenProvider {
+ String saveToken(String token, TokenType tokenType);
- protected final JwtProperties jwtProperties;
- protected final RedisTemplate redisTemplate;
+ String parseSubject(String token);
- public TokenProvider(JwtProperties jwtProperties, RedisTemplate redisTemplate) {
- this.jwtProperties = jwtProperties;
- this.redisTemplate = redisTemplate;
- }
-
- protected final String generateToken(String string, TokenType tokenType) {
- Claims claims = Jwts.claims().setSubject(string);
- Date now = new Date();
- Date expiredDate = new Date(now.getTime() + tokenType.getExpireTime());
- return Jwts.builder()
- .setClaims(claims)
- .setIssuedAt(now)
- .setExpiration(expiredDate)
- .signWith(SignatureAlgorithm.HS512, jwtProperties.secret())
- .compact();
- }
-
- protected final String saveToken(String token, TokenType tokenType) {
- String subject = parseSubject(token, jwtProperties.secret());
- redisTemplate.opsForValue().set(
- tokenType.addPrefix(subject),
- token,
- tokenType.getExpireTime(),
- TimeUnit.MILLISECONDS
- );
- return token;
- }
+ Claims parseClaims(String token);
}
diff --git a/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java b/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java
index 8fa290d30..1aae0338e 100644
--- a/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java
+++ b/src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProvider.java
@@ -2,12 +2,13 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.service.TokenProvider;
+import com.example.solidconnection.auth.token.config.JwtProperties;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
@@ -18,17 +19,16 @@
import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_INVALID;
import static com.example.solidconnection.common.exception.ErrorCode.SIGN_UP_TOKEN_NOT_ISSUED_BY_SERVER;
-import static com.example.solidconnection.util.JwtUtils.parseClaims;
-import static com.example.solidconnection.util.JwtUtils.parseSubject;
@Component
-public class OAuthSignUpTokenProvider extends TokenProvider {
+@RequiredArgsConstructor
+public class OAuthSignUpTokenProvider {
static final String AUTH_TYPE_CLAIM_KEY = "authType";
- public OAuthSignUpTokenProvider(JwtProperties jwtProperties, RedisTemplate redisTemplate) {
- super(jwtProperties, redisTemplate);
- }
+ private final JwtProperties jwtProperties;
+ private final RedisTemplate redisTemplate;
+ private final TokenProvider tokenProvider;
public String generateAndSaveSignUpToken(String email, AuthType authType) {
Map authTypeClaim = new HashMap<>(Map.of(AUTH_TYPE_CLAIM_KEY, authType));
@@ -42,7 +42,7 @@ public String generateAndSaveSignUpToken(String email, AuthType authType) {
.setExpiration(expiredDate)
.signWith(SignatureAlgorithm.HS512, jwtProperties.secret())
.compact();
- return saveToken(signUpToken, TokenType.SIGN_UP);
+ return tokenProvider.saveToken(signUpToken, TokenType.SIGN_UP);
}
public void validateSignUpToken(String token) {
@@ -53,7 +53,7 @@ public void validateSignUpToken(String token) {
private void validateFormatAndExpiration(String token) {
try {
- Claims claims = parseClaims(token, jwtProperties.secret());
+ Claims claims = tokenProvider.parseClaims(token);
Objects.requireNonNull(claims.getSubject());
String serializedAuthType = claims.get(AUTH_TYPE_CLAIM_KEY, String.class);
AuthType.valueOf(serializedAuthType);
@@ -70,11 +70,11 @@ private void validateIssuedByServer(String email) {
}
public String parseEmail(String token) {
- return parseSubject(token, jwtProperties.secret());
+ return tokenProvider.parseSubject(token);
}
public AuthType parseAuthType(String token) {
- Claims claims = parseClaims(token, jwtProperties.secret());
+ Claims claims = tokenProvider.parseClaims(token);
String authTypeStr = claims.get(AUTH_TYPE_CLAIM_KEY, String.class);
return AuthType.valueOf(authTypeStr);
}
diff --git a/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java b/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java
new file mode 100644
index 000000000..839e58362
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/token/JwtTokenProvider.java
@@ -0,0 +1,67 @@
+package com.example.solidconnection.auth.token;
+
+import com.example.solidconnection.auth.domain.TokenType;
+import com.example.solidconnection.auth.service.TokenProvider;
+import com.example.solidconnection.auth.token.config.JwtProperties;
+import com.example.solidconnection.common.exception.CustomException;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import static com.example.solidconnection.common.exception.ErrorCode.INVALID_TOKEN;
+
+@Component
+@RequiredArgsConstructor
+public class JwtTokenProvider implements TokenProvider {
+
+ private final JwtProperties jwtProperties;
+ private final RedisTemplate redisTemplate;
+
+ @Override
+ public final String generateToken(String string, TokenType tokenType) {
+ Claims claims = Jwts.claims().setSubject(string);
+ Date now = new Date();
+ Date expiredDate = new Date(now.getTime() + tokenType.getExpireTime());
+ return Jwts.builder()
+ .setClaims(claims)
+ .setIssuedAt(now)
+ .setExpiration(expiredDate)
+ .signWith(SignatureAlgorithm.HS512, jwtProperties.secret())
+ .compact();
+ }
+
+ @Override
+ public final String saveToken(String token, TokenType tokenType) {
+ String subject = parseSubject(token);
+ redisTemplate.opsForValue().set(
+ tokenType.addPrefix(subject),
+ token,
+ tokenType.getExpireTime(),
+ TimeUnit.MILLISECONDS
+ );
+ return token;
+ }
+
+ @Override
+ public String parseSubject(String token) {
+ return parseClaims(token).getSubject();
+ }
+
+ @Override
+ public Claims parseClaims(String token) {
+ try {
+ return Jwts.parser()
+ .setSigningKey(jwtProperties.secret())
+ .parseClaimsJws(token)
+ .getBody();
+ } catch (Exception e) {
+ throw new CustomException(INVALID_TOKEN);
+ }
+ }
+}
diff --git a/src/main/java/com/example/solidconnection/auth/token/TokenBlackListService.java b/src/main/java/com/example/solidconnection/auth/token/TokenBlackListService.java
new file mode 100644
index 000000000..4175a577f
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/auth/token/TokenBlackListService.java
@@ -0,0 +1,34 @@
+package com.example.solidconnection.auth.token;
+
+import com.example.solidconnection.auth.service.AccessToken;
+import com.example.solidconnection.security.filter.BlacklistChecker;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import static com.example.solidconnection.auth.domain.TokenType.BLACKLIST;
+
+@Component
+@RequiredArgsConstructor
+public class TokenBlackListService implements BlacklistChecker {
+
+ private static final String SIGN_OUT_VALUE = "signOut";
+
+ private final RedisTemplate redisTemplate;
+
+ /*
+ * 액세스 토큰을 블랙리스트에 저장한다.
+ * - key = BLACKLIST:{accessToken}
+ * - value = {SIGN_OUT_VALUE} -> key 의 존재만 확인하므로, value 에는 무슨 값이 들어가도 상관없다.
+ * */
+ public void addToBlacklist(AccessToken accessToken) {
+ String blackListKey = BLACKLIST.addPrefix(accessToken.token());
+ redisTemplate.opsForValue().set(blackListKey, SIGN_OUT_VALUE);
+ }
+
+ @Override
+ public boolean isTokenBlacklisted(String accessToken) {
+ String blackListTokenKey = BLACKLIST.addPrefix(accessToken);
+ return redisTemplate.hasKey(blackListTokenKey);
+ }
+}
diff --git a/src/main/java/com/example/solidconnection/security/config/JwtProperties.java b/src/main/java/com/example/solidconnection/auth/token/config/JwtProperties.java
similarity index 75%
rename from src/main/java/com/example/solidconnection/security/config/JwtProperties.java
rename to src/main/java/com/example/solidconnection/auth/token/config/JwtProperties.java
index f4afa5245..bf5180218 100644
--- a/src/main/java/com/example/solidconnection/security/config/JwtProperties.java
+++ b/src/main/java/com/example/solidconnection/auth/token/config/JwtProperties.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.security.config;
+package com.example.solidconnection.auth.token.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
diff --git a/src/main/java/com/example/solidconnection/security/filter/AuthorizationHeaderParser.java b/src/main/java/com/example/solidconnection/security/filter/AuthorizationHeaderParser.java
new file mode 100644
index 000000000..8bbbc30e4
--- /dev/null
+++ b/src/main/java/com/example/solidconnection/security/filter/AuthorizationHeaderParser.java
@@ -0,0 +1,29 @@
+package com.example.solidconnection.security.filter;
+
+import jakarta.servlet.http.HttpServletRequest;
+import org.springframework.stereotype.Component;
+
+import java.util.Optional;
+
+@Component
+public class AuthorizationHeaderParser {
+
+ private static final String TOKEN_HEADER = "Authorization";
+ private static final String TOKEN_PREFIX = "Bearer ";
+ private static final int TOKEN_PREFIX_LENGTH = TOKEN_PREFIX.length();
+
+ public Optional parseToken(HttpServletRequest request) {
+ String token = request.getHeader(TOKEN_HEADER);
+ if (isInvalidFormat(token)) {
+ return Optional.empty();
+ }
+ return Optional.of(token.substring(TOKEN_PREFIX_LENGTH));
+ }
+
+ private boolean isInvalidFormat(String token) {
+ return token == null ||
+ token.isBlank() ||
+ !token.startsWith(TOKEN_PREFIX) ||
+ token.substring(TOKEN_PREFIX_LENGTH).isBlank();
+ }
+}
diff --git a/src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java b/src/main/java/com/example/solidconnection/security/filter/BlacklistChecker.java
similarity index 61%
rename from src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java
rename to src/main/java/com/example/solidconnection/security/filter/BlacklistChecker.java
index b4e174906..f093d8e8f 100644
--- a/src/main/java/com/example/solidconnection/auth/service/BlacklistChecker.java
+++ b/src/main/java/com/example/solidconnection/security/filter/BlacklistChecker.java
@@ -1,4 +1,4 @@
-package com.example.solidconnection.auth.service;
+package com.example.solidconnection.security.filter;
public interface BlacklistChecker {
diff --git a/src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java
index 39917d42e..8ee6a98e4 100644
--- a/src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java
+++ b/src/main/java/com/example/solidconnection/security/filter/JwtAuthenticationFilter.java
@@ -15,8 +15,7 @@
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
-
-import static com.example.solidconnection.util.JwtUtils.parseTokenFromRequest;
+import java.util.Optional;
@Component
@@ -24,18 +23,19 @@
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private final AuthenticationManager authenticationManager;
+ private final AuthorizationHeaderParser authorizationHeaderParser;
@Override
public void doFilterInternal(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
- String token = parseTokenFromRequest(request);
- if (token == null) {
+ Optional token = authorizationHeaderParser.parseToken(request);
+ if (token.isEmpty()) {
filterChain.doFilter(request, response);
return;
}
- JwtAuthentication authToken = createAuthentication(token);
+ JwtAuthentication authToken = createAuthentication(token.get());
Authentication auth = authenticationManager.authenticate(authToken);
SecurityContextHolder.getContext().setAuthentication(auth);
diff --git a/src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java b/src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java
index 5c51c53cd..c3926d67f 100644
--- a/src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java
+++ b/src/main/java/com/example/solidconnection/security/filter/SignOutCheckFilter.java
@@ -1,6 +1,5 @@
package com.example.solidconnection.security.filter;
-import com.example.solidconnection.auth.service.BlacklistChecker;
import com.example.solidconnection.common.exception.CustomException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
@@ -12,28 +11,29 @@
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
+import java.util.Optional;
import static com.example.solidconnection.common.exception.ErrorCode.USER_ALREADY_SIGN_OUT;
-import static com.example.solidconnection.util.JwtUtils.parseTokenFromRequest;
@Component
@RequiredArgsConstructor
public class SignOutCheckFilter extends OncePerRequestFilter {
- private final BlacklistChecker tokenBlacklistChecker;
+ private final AuthorizationHeaderParser authorizationHeaderParser;
+ private final BlacklistChecker blacklistChecker;
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain) throws ServletException, IOException {
- String token = parseTokenFromRequest(request);
- if (token != null && hasSignedOut(token)) {
+ Optional token = authorizationHeaderParser.parseToken(request);
+ if (token.isPresent() && hasSignedOut(token.get())) {
throw new CustomException(USER_ALREADY_SIGN_OUT);
}
filterChain.doFilter(request, response);
}
private boolean hasSignedOut(String accessToken) {
- return tokenBlacklistChecker.isTokenBlacklisted(accessToken);
+ return blacklistChecker.isTokenBlacklisted(accessToken);
}
}
diff --git a/src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java b/src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java
index 6ce43b97c..a00b77f9a 100644
--- a/src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java
+++ b/src/main/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProvider.java
@@ -1,8 +1,8 @@
package com.example.solidconnection.security.provider;
+import com.example.solidconnection.auth.service.TokenProvider;
import com.example.solidconnection.security.authentication.JwtAuthentication;
import com.example.solidconnection.security.authentication.SiteUserAuthentication;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.security.userdetails.SiteUserDetails;
import com.example.solidconnection.security.userdetails.SiteUserDetailsService;
import lombok.RequiredArgsConstructor;
@@ -11,21 +11,19 @@
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
-import static com.example.solidconnection.util.JwtUtils.parseSubject;
-
@Component
@RequiredArgsConstructor
public class SiteUserAuthenticationProvider implements AuthenticationProvider {
- private final JwtProperties jwtProperties;
private final SiteUserDetailsService siteUserDetailsService;
+ private final TokenProvider tokenProvider;
@Override
public Authentication authenticate(Authentication auth) throws AuthenticationException {
JwtAuthentication jwtAuth = (JwtAuthentication) auth;
String token = jwtAuth.getToken();
- String username = parseSubject(token, jwtProperties.secret());
+ String username = tokenProvider.parseSubject(token);
SiteUserDetails userDetails = (SiteUserDetails) siteUserDetailsService.loadUserByUsername(username);
return new SiteUserAuthentication(token, userDetails);
}
diff --git a/src/main/java/com/example/solidconnection/util/JwtUtils.java b/src/main/java/com/example/solidconnection/util/JwtUtils.java
deleted file mode 100644
index 040beb9ba..000000000
--- a/src/main/java/com/example/solidconnection/util/JwtUtils.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package com.example.solidconnection.util;
-
-import com.example.solidconnection.common.exception.CustomException;
-import io.jsonwebtoken.Claims;
-import io.jsonwebtoken.ExpiredJwtException;
-import io.jsonwebtoken.Jwts;
-import jakarta.servlet.http.HttpServletRequest;
-import org.springframework.stereotype.Component;
-
-import static com.example.solidconnection.common.exception.ErrorCode.INVALID_TOKEN;
-
-@Component
-public class JwtUtils {
-
- private static final String TOKEN_HEADER = "Authorization";
- private static final String TOKEN_PREFIX = "Bearer ";
-
- private JwtUtils() {
- }
-
- public static String parseTokenFromRequest(HttpServletRequest request) {
- String token = request.getHeader(TOKEN_HEADER);
- if (token == null || token.isBlank() || !token.startsWith(TOKEN_PREFIX)) {
- return null;
- }
- return token.substring(TOKEN_PREFIX.length());
- }
-
- public static String parseSubject(String token, String secretKey) {
- try {
- return parseClaims(token, secretKey).getSubject();
- } catch (Exception e) {
- throw new CustomException(INVALID_TOKEN);
- }
- }
- public static Claims parseClaims(String token, String secretKey) throws ExpiredJwtException {
- return Jwts.parser()
- .setSigningKey(secretKey)
- .parseClaimsJws(token)
- .getBody();
- }
-}
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
index 8fd57eae6..c4c2a1708 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthServiceTest.java
@@ -3,6 +3,7 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.ReissueRequest;
import com.example.solidconnection.auth.dto.ReissueResponse;
+import com.example.solidconnection.auth.token.TokenBlackListService;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
@@ -30,6 +31,9 @@ class AuthServiceTest {
@Autowired
private AuthTokenProvider authTokenProvider;
+ @Autowired
+ private TokenBlackListService tokenBlackListService;
+
@Autowired
private RedisTemplate redisTemplate;
@@ -40,7 +44,7 @@ class AuthServiceTest {
void 로그아웃한다() {
// given
Subject subject = new Subject("subject");
- AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: #296
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
// when
authService.signOut(accessToken.token());
@@ -49,7 +53,7 @@ class AuthServiceTest {
String refreshTokenKey = TokenType.REFRESH.addPrefix(subject.value());
assertAll(
() -> assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isNull(),
- () -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue()
+ () -> assertThat(tokenBlackListService.isTokenBlacklisted(accessToken.token())).isTrue()
);
}
@@ -58,7 +62,7 @@ class AuthServiceTest {
// given
SiteUser user = siteUserFixture.사용자();
Subject subject = authTokenProvider.toSubject(user);
- AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: #296
+ AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
// when
authService.quit(user, accessToken.token());
@@ -69,7 +73,7 @@ class AuthServiceTest {
assertAll(
() -> assertThat(user.getQuitedAt()).isEqualTo(tomorrow),
() -> assertThat(redisTemplate.opsForValue().get(refreshTokenKey)).isNull(),
- () -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue()
+ () -> assertThat(tokenBlackListService.isTokenBlacklisted(accessToken.token())).isTrue()
);
}
diff --git a/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
index dc35ab3a7..b6c111f24 100644
--- a/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/AuthTokenProviderTest.java
@@ -61,7 +61,7 @@ class 리프레시_토큰을_제공한다 {
void 유효한_리프레시_토큰인지_확인한다() {
// given
RefreshToken refreshToken = authTokenProvider.generateAndSaveRefreshToken(subject);
- AccessToken fakeRefreshToken = authTokenProvider.generateAccessToken(subject); // todo: issue#296
+ AccessToken fakeRefreshToken = authTokenProvider.generateAccessToken(subject);
// when, then
assertAll(
@@ -71,7 +71,7 @@ class 리프레시_토큰을_제공한다 {
}
@Test
- void 액세서_토큰에_해당하는_리프레시_토큰을_삭제한다() {
+ void 액세스_토큰에_해당하는_리프레시_토큰을_삭제한다() {
// given
authTokenProvider.generateAndSaveRefreshToken(subject);
AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
@@ -85,44 +85,6 @@ class 리프레시_토큰을_제공한다 {
}
}
- @Nested
- class 블랙리스트를_관리한다 {
-
- @Test
- void 액세스_토큰을_블랙리스트에_추가한다() {
- // given
- AccessToken accessToken = authTokenProvider.generateAccessToken(subject); // todo: issue#296
-
- // when
- authTokenProvider.addToBlacklist(accessToken);
-
- // then
- String blackListTokenKey = TokenType.BLACKLIST.addPrefix(accessToken.token());
- String foundBlackListToken = redisTemplate.opsForValue().get(blackListTokenKey);
- assertThat(foundBlackListToken).isNotNull();
- }
-
- /*
- * todo: JwtUtils 나 TokenProvider 를 스프링 빈으로 주입받도록 변경한다. (issue#296)
- * - 아래 테스트 코드에서는, 내부적으로 JwtUtils.parseSubject() 메서드가 호출될 때 발생하는 예외를 피하기 위해 jwt토큰을 생성한다.
- * - 테스트 작성자는 예외 발생을 피하기 위해 "제대로된 jwt 토큰 생성이 필요하다"는 것을 몰라야한다.
- * - 따라서, JwtUtils 나 TokenProvider 를 스프링 빈으로 주입받도록 변경하고, 테스트에서 mock 을 사용하여 의존성을 끊을 필요가 있다.
- */
- @Test
- void 블랙리스트에_있는_토큰인지_확인한다() {
- // given
- AccessToken accessToken = authTokenProvider.generateAccessToken(subject);
- authTokenProvider.addToBlacklist(accessToken);
- AccessToken notRegisteredAccessToken = authTokenProvider.generateAccessToken(new Subject("!"));
-
- // when, then
- assertAll(
- () -> assertThat(authTokenProvider.isTokenBlacklisted(accessToken.token())).isTrue(),
- () -> assertThat(authTokenProvider.isTokenBlacklisted(notRegisteredAccessToken.token())).isFalse()
- );
- }
- }
-
@Test
void 토큰으로부터_Subject_를_추출한다() {
// given
diff --git a/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java
new file mode 100644
index 000000000..c36a0bb39
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/auth/service/JwtTokenProviderTest.java
@@ -0,0 +1,176 @@
+package com.example.solidconnection.auth.service;
+
+import com.example.solidconnection.auth.domain.TokenType;
+import com.example.solidconnection.auth.token.JwtTokenProvider;
+import com.example.solidconnection.common.exception.CustomException;
+import com.example.solidconnection.common.exception.ErrorCode;
+import com.example.solidconnection.auth.token.config.JwtProperties;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+import io.jsonwebtoken.SignatureAlgorithm;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+@DisplayName("토큰 제공자 테스트")
+@TestContainerSpringBootTest
+class JwtTokenProviderTest {
+
+ @Autowired
+ private JwtTokenProvider tokenProvider;
+
+ @Autowired
+ private JwtProperties jwtProperties;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Test
+ void 토큰을_생성한다() {
+ // given
+ String actualSubject = "subject123";
+ TokenType actualTokenType = TokenType.ACCESS;
+
+ // when
+ String token = tokenProvider.generateToken(actualSubject, actualTokenType);
+
+ // then - subject와 만료 시간이 일치하는지 검증
+ Claims claims = tokenProvider.parseClaims(token);
+ long expectedExpireTime = claims.getExpiration().getTime() - claims.getIssuedAt().getTime();
+ assertAll(
+ () -> assertThat(claims.getSubject()).isEqualTo(actualSubject),
+ () -> assertThat(expectedExpireTime).isEqualTo(actualTokenType.getExpireTime())
+ );
+ }
+
+ @Test
+ void 토큰을_저장한다() {
+ // given
+ String subject = "subject123";
+ TokenType tokenType = TokenType.ACCESS;
+ String token = tokenProvider.generateToken(subject, tokenType);
+
+ // when
+ String savedToken = tokenProvider.saveToken(token, tokenType);
+
+ // then - key: "{TokenType.Prefix}:subject", value: {token} 로 저장되어있는지 검증, 반환하는 값이 value와 같은지 검증
+ String key = tokenType.addPrefix(subject);
+ String value = redisTemplate.opsForValue().get(key);
+ assertAll(
+ () -> assertThat(value).isEqualTo(token),
+ () -> assertThat(savedToken).isEqualTo(value)
+ );
+ }
+
+ @Nested
+ class 토큰으로부터_subject_를_추출한다 {
+
+ @Test
+ void 유효한_토큰의_subject_를_추출한다() {
+ // given
+ String subject = "subject000";
+ String token = createValidToken(subject);
+
+ // when
+ String extractedSubject = tokenProvider.parseSubject(token);
+
+ // then
+ assertThat(extractedSubject).isEqualTo(subject);
+ }
+
+ @Test
+ void 유효하지_않은_토큰의_subject_를_추출하면_예외_응답을_반환한다() {
+ // given
+ String subject = "subject123";
+ String token = createExpiredToken(subject);
+
+ // when, then
+ assertThatCode(() -> tokenProvider.parseSubject(token))
+ .isInstanceOf(CustomException.class)
+ .hasMessage(ErrorCode.INVALID_TOKEN.getMessage());
+ }
+ }
+
+ @Nested
+ class 토큰으로부터_claim_을_추출한다 {
+
+ @Test
+ void 유효한_토큰의_claim_을_추출한다() {
+ // given
+ String subject = "subject";
+ String claimKey = "key";
+ String claimValue = "value";
+ Claims expectedClaims = Jwts.claims(new HashMap<>(Map.of(claimKey, claimValue))).setSubject(subject);
+ String token = createValidToken(expectedClaims);
+
+ // when
+ Claims actualClaims = tokenProvider.parseClaims(token);
+
+ // then
+ assertAll(
+ () -> assertThat(actualClaims.getSubject()).isEqualTo(subject),
+ () -> assertThat(actualClaims.get(claimKey)).isEqualTo(claimValue)
+ );
+ }
+
+ @Test
+ void 유효하지_않은_토큰의_claim_을_추출하면_예외_응답을_반환한다() {
+ // given
+ String subject = "subject";
+ Claims expectedClaims = Jwts.claims().setSubject(subject);
+ String token = createExpiredToken(expectedClaims);
+
+ // when
+ assertThatCode(() -> tokenProvider.parseClaims(token))
+ .isInstanceOf(CustomException.class)
+ .hasMessage(ErrorCode.INVALID_TOKEN.getMessage());
+ }
+ }
+
+ private String createValidToken(String subject) {
+ return Jwts.builder()
+ .setSubject(subject)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() + 1000))
+ .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
+ .compact();
+ }
+
+ private String createValidToken(Claims claims) {
+ return Jwts.builder()
+ .setClaims(claims)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() + 1000))
+ .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
+ .compact();
+ }
+
+ private String createExpiredToken(String subject) {
+ return Jwts.builder()
+ .setSubject(subject)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() - 1000))
+ .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
+ .compact();
+ }
+
+ private String createExpiredToken(Claims claims) {
+ return Jwts.builder()
+ .setClaims(claims)
+ .setIssuedAt(new Date())
+ .setExpiration(new Date(System.currentTimeMillis() - 1000))
+ .signWith(SignatureAlgorithm.HS256, jwtProperties.secret())
+ .compact();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
index 1656ed4e5..463bc4957 100644
--- a/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/SignInServiceTest.java
@@ -2,11 +2,9 @@
import com.example.solidconnection.auth.domain.TokenType;
import com.example.solidconnection.auth.dto.SignInResponse;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.util.JwtUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@@ -26,7 +24,7 @@ class SignInServiceTest {
private SignInService signInService;
@Autowired
- private JwtProperties jwtProperties;
+ private TokenProvider tokenProvider;
@Autowired
private RedisTemplate redisTemplate;
@@ -49,8 +47,8 @@ void setUp() {
SignInResponse signInResponse = signInService.signIn(user);
// then
- String accessTokenSubject = JwtUtils.parseSubject(signInResponse.accessToken(), jwtProperties.secret());
- String refreshTokenSubject = JwtUtils.parseSubject(signInResponse.refreshToken(), jwtProperties.secret());
+ String accessTokenSubject = tokenProvider.parseSubject(signInResponse.accessToken());
+ String refreshTokenSubject = tokenProvider.parseSubject(signInResponse.refreshToken());
String savedRefreshToken = redisTemplate.opsForValue().get(TokenType.REFRESH.addPrefix(refreshTokenSubject));
assertAll(
() -> assertThat(accessTokenSubject).isEqualTo(subject),
diff --git a/src/test/java/com/example/solidconnection/auth/service/TokenBlackListServiceTest.java b/src/test/java/com/example/solidconnection/auth/service/TokenBlackListServiceTest.java
new file mode 100644
index 000000000..e1974cc93
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/auth/service/TokenBlackListServiceTest.java
@@ -0,0 +1,58 @@
+package com.example.solidconnection.auth.service;
+
+import com.example.solidconnection.auth.token.TokenBlackListService;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import static com.example.solidconnection.auth.domain.TokenType.BLACKLIST;
+import static org.assertj.core.api.Assertions.assertThat;
+
+@TestContainerSpringBootTest
+class TokenBlackListServiceTest {
+
+ @Autowired
+ private TokenBlackListService tokenBlackListService;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ @Test
+ void 액세스_토큰을_블랙리스트에_추가한다() {
+ // given
+ AccessToken accessToken = new AccessToken("subject", "token");
+
+ // when
+ tokenBlackListService.addToBlacklist(accessToken);
+
+ // then
+ String blackListTokenKey = BLACKLIST.addPrefix(accessToken.token());
+ String foundBlackListToken = redisTemplate.opsForValue().get(blackListTokenKey);
+ assertThat(foundBlackListToken).isNotNull();
+ }
+
+ @Nested
+ class 블랙리스트에_있는_토큰인지_확인한다 {
+
+ @Test
+ void 블랙리스트에_토큰이_있는_경우() {
+ // given
+ AccessToken accessToken = new AccessToken("subject", "token");
+ tokenBlackListService.addToBlacklist(accessToken);
+
+ // when, then
+ assertThat(tokenBlackListService.isTokenBlacklisted(accessToken.token())).isTrue();
+ }
+
+ @Test
+ void 블랙리스트에_토큰이_없는_경우() {
+ // given
+ AccessToken accessToken = new AccessToken("subject", "token");
+
+ // when, then
+ assertThat(tokenBlackListService.isTokenBlacklisted(accessToken.token())).isFalse();
+ }
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java b/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java
index 233317458..c748987c1 100644
--- a/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java
+++ b/src/test/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpTokenProviderTest.java
@@ -1,11 +1,11 @@
package com.example.solidconnection.auth.service.oauth;
import com.example.solidconnection.auth.domain.TokenType;
+import com.example.solidconnection.auth.service.TokenProvider;
+import com.example.solidconnection.auth.token.config.JwtProperties;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.security.config.JwtProperties;
import com.example.solidconnection.siteuser.domain.AuthType;
import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.util.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
@@ -34,6 +34,9 @@ class OAuthSignUpTokenProviderTest {
@Autowired
private OAuthSignUpTokenProvider OAuthSignUpTokenProvider;
+ @Autowired
+ private TokenProvider tokenProvider;
+
@Autowired
private RedisTemplate redisTemplate;
@@ -50,7 +53,7 @@ class OAuthSignUpTokenProviderTest {
String signUpToken = OAuthSignUpTokenProvider.generateAndSaveSignUpToken(email, authType);
// then
- Claims claims = JwtUtils.parseClaims(signUpToken, jwtProperties.secret());
+ Claims claims = tokenProvider.parseClaims(signUpToken);
String actualSubject = claims.getSubject();
AuthType actualAuthType = AuthType.valueOf(claims.get(AUTH_TYPE_CLAIM_KEY, String.class));
String signUpTokenKey = TokenType.SIGN_UP.addPrefix(email);
diff --git a/src/test/java/com/example/solidconnection/security/filter/AuthorizationHeaderParserTest.java b/src/test/java/com/example/solidconnection/security/filter/AuthorizationHeaderParserTest.java
new file mode 100644
index 000000000..1d4ba2533
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/security/filter/AuthorizationHeaderParserTest.java
@@ -0,0 +1,54 @@
+package com.example.solidconnection.security.filter;
+
+import com.example.solidconnection.support.TestContainerSpringBootTest;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mock.web.MockHttpServletRequest;
+
+import java.util.Optional;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertAll;
+
+@TestContainerSpringBootTest
+class AuthorizationHeaderParserTest {
+
+ @Autowired
+ private AuthorizationHeaderParser authorizationHeaderParser;
+
+ @Nested
+ class 요청으로부터_토큰을_추출한다 {
+
+ @Test
+ void 지정한_형식의_토큰이_있으면_토큰을_반환한다() {
+ // given
+ MockHttpServletRequest request = new MockHttpServletRequest();
+ String token = "token";
+ request.addHeader("Authorization", "Bearer " + token);
+
+ // when
+ Optional extractedToken = authorizationHeaderParser.parseToken(request);
+
+ // then
+ assertThat(extractedToken).get().isEqualTo(token);
+ }
+
+ @Test
+ void 형식에_맞는_토큰이_없으면_빈_값을_반환한다() {
+ // given
+ MockHttpServletRequest noHeader = new MockHttpServletRequest();
+ MockHttpServletRequest wrongPrefix = new MockHttpServletRequest();
+ wrongPrefix.addHeader("Authorization", "Wrong token");
+ MockHttpServletRequest emptyToken = new MockHttpServletRequest();
+ emptyToken.addHeader("Authorization", "Bearer ");
+
+ // when & then
+ assertAll(
+ () -> assertThat(authorizationHeaderParser.parseToken(noHeader)).isEmpty(),
+ () -> assertThat(authorizationHeaderParser.parseToken(wrongPrefix)).isEmpty(),
+ () -> assertThat(authorizationHeaderParser.parseToken(emptyToken)).isEmpty()
+ );
+ }
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java
index c66037c82..229fed27b 100644
--- a/src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java
+++ b/src/test/java/com/example/solidconnection/security/filter/JwtAuthenticationFilterTest.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.security.filter;
import com.example.solidconnection.security.authentication.SiteUserAuthentication;
-import com.example.solidconnection.security.config.JwtProperties;
+import com.example.solidconnection.auth.token.config.JwtProperties;
import com.example.solidconnection.security.userdetails.SiteUserDetailsService;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import io.jsonwebtoken.Jwts;
diff --git a/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java b/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
index 5ccc1aa1b..80e927203 100644
--- a/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
+++ b/src/test/java/com/example/solidconnection/security/filter/SignOutCheckFilterTest.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.security.filter;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.security.config.JwtProperties;
+import com.example.solidconnection.auth.token.config.JwtProperties;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
diff --git a/src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java b/src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java
index 9c51de838..0bbb6677f 100644
--- a/src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java
+++ b/src/test/java/com/example/solidconnection/security/provider/SiteUserAuthenticationProviderTest.java
@@ -2,7 +2,7 @@
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.security.authentication.SiteUserAuthentication;
-import com.example.solidconnection.security.config.JwtProperties;
+import com.example.solidconnection.auth.token.config.JwtProperties;
import com.example.solidconnection.security.userdetails.SiteUserDetails;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
diff --git a/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java b/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
deleted file mode 100644
index c57e85193..000000000
--- a/src/test/java/com/example/solidconnection/util/JwtUtilsTest.java
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.example.solidconnection.util;
-
-import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.common.exception.ErrorCode;
-import io.jsonwebtoken.Jwts;
-import io.jsonwebtoken.SignatureAlgorithm;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Nested;
-import org.junit.jupiter.api.Test;
-import org.springframework.mock.web.MockHttpServletRequest;
-
-import java.util.Date;
-
-import static com.example.solidconnection.util.JwtUtils.parseSubject;
-import static com.example.solidconnection.util.JwtUtils.parseTokenFromRequest;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatCode;
-import static org.junit.jupiter.api.Assertions.assertAll;
-
-@DisplayName("JwtUtils 테스트")
-class JwtUtilsTest {
-
- private final String jwtSecretKey = "jwt-secret-key";
-
- @Nested
- class 요청으로부터_토큰을_추출한다 {
-
- @Test
- void 토큰이_있으면_토큰을_반환한다() {
- // given
- MockHttpServletRequest request = new MockHttpServletRequest();
- String token = "token";
- request.addHeader("Authorization", "Bearer " + token);
-
- // when
- String extractedToken = parseTokenFromRequest(request);
-
- // then
- assertThat(extractedToken).isEqualTo(token);
- }
-
- @Test
- void 토큰이_없으면_null_을_반환한다() {
- // given
- MockHttpServletRequest noHeader = new MockHttpServletRequest();
- MockHttpServletRequest wrongPrefix = new MockHttpServletRequest();
- wrongPrefix.addHeader("Authorization", "Wrong token");
- MockHttpServletRequest emptyToken = new MockHttpServletRequest();
- wrongPrefix.addHeader("Authorization", "Bearer ");
-
- // when & then
- assertAll(
- () -> assertThat(parseTokenFromRequest(noHeader)).isNull(),
- () -> assertThat(parseTokenFromRequest(wrongPrefix)).isNull(),
- () -> assertThat(parseTokenFromRequest(emptyToken)).isNull()
- );
- }
- }
-
- @Nested
- class 토큰으로부터_subject_를_추출한다 {
-
- @Test
- void 유효한_토큰의_subject_를_추출한다() {
- // given
- String subject = "subject000";
- String token = createValidToken(subject);
-
- // when
- String extractedSubject = parseSubject(token, jwtSecretKey);
-
- // then
- assertThat(extractedSubject).isEqualTo(subject);
- }
-
- @Test
- void 유효하지_않은_토큰의_subject_를_추출하면_예외_응답을_반환한다() {
- // given
- String subject = "subject123";
- String token = createExpiredToken(subject);
-
- // when
- assertThatCode(() -> parseSubject(token, jwtSecretKey))
- .isInstanceOf(CustomException.class)
- .hasMessage(ErrorCode.INVALID_TOKEN.getMessage());
- }
- }
-
- private String createValidToken(String subject) {
- return Jwts.builder()
- .setSubject(subject)
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() + 1000))
- .signWith(SignatureAlgorithm.HS256, jwtSecretKey)
- .compact();
- }
-
- private String createExpiredToken(String subject) {
- return Jwts.builder()
- .setSubject(subject)
- .setIssuedAt(new Date())
- .setExpiration(new Date(System.currentTimeMillis() - 1000))
- .signWith(SignatureAlgorithm.HS256, jwtSecretKey)
- .compact();
- }
-}
From ac0f60ed13140a799d16c0bad3fc6084630a5f68 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Thu, 22 May 2025 20:52:47 +0900
Subject: [PATCH 20/90] =?UTF-8?q?refactor:=20Application=20=EA=B4=80?=
=?UTF-8?q?=EB=A0=A8=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?=
=?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20fixture=20=EB=A9=94=EC=84=9C?=
=?UTF-8?q?=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#329)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: ApplicationFixture에 지원서 생성 메서드 추가
* refactor: 지원서 데이터 Fixture 메서드로 변경
* refactor: 불필요한 성적 요구사항 세팅 제거
---
.../fixture/ApplicationFixture.java | 38 ++
.../fixture/ApplicationFixtureBuilder.java | 86 ++++
.../service/ApplicationQueryServiceTest.java | 453 +++++++++++-------
.../ApplicationSubmissionServiceTest.java | 118 ++---
4 files changed, 468 insertions(+), 227 deletions(-)
create mode 100644 src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java
create mode 100644 src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java
diff --git a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java
new file mode 100644
index 000000000..b2cbc6460
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java
@@ -0,0 +1,38 @@
+package com.example.solidconnection.application.fixture;
+
+import com.example.solidconnection.application.domain.Application;
+import com.example.solidconnection.application.domain.Gpa;
+import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class ApplicationFixture {
+
+ private final ApplicationFixtureBuilder applicationFixtureBuilder;
+
+ public Application 지원서(
+ SiteUser siteUser,
+ String nicknameForApply,
+ String term,
+ Gpa gpa,
+ LanguageTest languageTest,
+ UniversityInfoForApply firstChoiceUniversity,
+ UniversityInfoForApply secondChoiceUniversity,
+ UniversityInfoForApply thirdChoiceUniversity
+ ) {
+ return applicationFixtureBuilder.application()
+ .siteUser(siteUser)
+ .gpa(gpa)
+ .languageTest(languageTest)
+ .nicknameForApply(nicknameForApply)
+ .term(term)
+ .firstChoiceUniversity(firstChoiceUniversity)
+ .secondChoiceUniversity(secondChoiceUniversity)
+ .thirdChoiceUniversity(thirdChoiceUniversity)
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java
new file mode 100644
index 000000000..5f6c06741
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java
@@ -0,0 +1,86 @@
+package com.example.solidconnection.application.fixture;
+
+import com.example.solidconnection.application.domain.Application;
+import com.example.solidconnection.application.domain.Gpa;
+import com.example.solidconnection.application.domain.LanguageTest;
+import com.example.solidconnection.application.domain.VerifyStatus;
+import com.example.solidconnection.application.repository.ApplicationRepository;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class ApplicationFixtureBuilder {
+
+ private final ApplicationRepository applicationRepository;
+
+ private Gpa gpa;
+ private LanguageTest languageTest;
+ private UniversityInfoForApply firstChoiceUniversity;
+ private UniversityInfoForApply secondChoiceUniversity;
+ private UniversityInfoForApply thirdChoiceUniversity;
+ private SiteUser siteUser;
+ private String nicknameForApply;
+ private String term;
+
+ public ApplicationFixtureBuilder application() {
+ return new ApplicationFixtureBuilder(applicationRepository);
+ }
+
+ public ApplicationFixtureBuilder gpa(Gpa gpa) {
+ this.gpa = gpa;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder languageTest(LanguageTest languageTest) {
+ this.languageTest = languageTest;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder firstChoiceUniversity(UniversityInfoForApply firstChoiceUniversity) {
+ this.firstChoiceUniversity = firstChoiceUniversity;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder secondChoiceUniversity(UniversityInfoForApply secondChoiceUniversity) {
+ this.secondChoiceUniversity = secondChoiceUniversity;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder thirdChoiceUniversity(UniversityInfoForApply thirdChoiceUniversity) {
+ this.thirdChoiceUniversity = thirdChoiceUniversity;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder siteUser(SiteUser siteUser) {
+ this.siteUser = siteUser;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder nicknameForApply(String nicknameForApply) {
+ this.nicknameForApply = nicknameForApply;
+ return this;
+ }
+
+ public ApplicationFixtureBuilder term(String term) {
+ this.term = term;
+ return this;
+ }
+
+ public Application create() {
+ Application application = new Application(
+ siteUser,
+ gpa,
+ languageTest,
+ term,
+ firstChoiceUniversity,
+ secondChoiceUniversity,
+ thirdChoiceUniversity,
+ nicknameForApply
+ );
+ application.setVerifyStatus(VerifyStatus.APPROVED);
+ return applicationRepository.save(application);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
index 240217496..ac0b83619 100644
--- a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
@@ -1,32 +1,36 @@
package com.example.solidconnection.application.service;
import com.example.solidconnection.application.domain.Application;
-import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.application.domain.LanguageTest;
import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.dto.ApplicantResponse;
import com.example.solidconnection.application.dto.ApplicationsResponse;
import com.example.solidconnection.application.dto.UniversityApplicantsResponse;
+import com.example.solidconnection.application.fixture.ApplicationFixture;
import com.example.solidconnection.application.repository.ApplicationRepository;
+import com.example.solidconnection.location.region.fixture.RegionFixture;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.score.repository.GpaScoreRepository;
-import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
+import com.example.solidconnection.score.fixture.GpaScoreFixture;
+import com.example.solidconnection.score.fixture.LanguageTestScoreFixture;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.university.domain.LanguageTestType;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
+@TestContainerSpringBootTest
@DisplayName("지원서 조회 서비스 테스트")
-class ApplicationQueryServiceTest extends BaseIntegrationTest {
+class ApplicationQueryServiceTest {
@Autowired
private ApplicationQueryService applicationQueryService;
@@ -35,19 +39,101 @@ class ApplicationQueryServiceTest extends BaseIntegrationTest {
private ApplicationRepository applicationRepository;
@Autowired
- private GpaScoreRepository gpaScoreRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
- private LanguageTestScoreRepository languageTestScoreRepository;
+ private RegionFixture regionFixture;
+
+ @Autowired
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
+ @Autowired
+ private GpaScoreFixture gpaScoreFixture;
+
+ @Autowired
+ private LanguageTestScoreFixture languageTestScoreFixture;
+
+ @Autowired
+ private ApplicationFixture applicationFixture;
+
+ @Value("${university.term}")
+ private String term;
+
+ private SiteUser user1;
+ private SiteUser user2;
+ private SiteUser user3;
+
+ private GpaScore gpaScore1;
+ private GpaScore gpaScore2;
+ private GpaScore gpaScore3;
+
+ private LanguageTestScore languageTestScore1;
+ private LanguageTestScore languageTestScore2;
+ private LanguageTestScore languageTestScore3;
+
+ private UniversityInfoForApply 괌대학_A_지원_정보;
+ private UniversityInfoForApply 괌대학_B_지원_정보;
+ private UniversityInfoForApply 서던덴마크대학교_지원_정보;
+
+ @BeforeEach
+ void setUp() {
+ user1 = siteUserFixture.사용자(1, "test1");
+ gpaScore1 = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user1);
+ languageTestScore1 = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user1);
+
+ user2 = siteUserFixture.사용자(2, "test2");
+ gpaScore2 = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user2);
+ languageTestScore2 = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user2);
+
+ user3 = siteUserFixture.사용자(3, "test3");
+ gpaScore3 = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user3);
+ languageTestScore3 = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user3);
+
+ 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ 괌대학_B_지원_정보 = universityInfoForApplyFixture.괌대학_B_지원_정보();
+ 서던덴마크대학교_지원_정보 = universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
+ }
@Nested
class 지원자_목록_조회_테스트 {
@Test
void 이번_학기_전체_지원자를_조회한다() {
+ // given
+ Application application1 = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+ Application application2 = applicationFixture.지원서(
+ user2,
+ "nickname2",
+ term,
+ gpaScore2.getGpa(),
+ languageTestScore2.getLanguageTest(),
+ 괌대학_B_지원_정보,
+ null,
+ null
+ );
+ Application application3 = applicationFixture.지원서(
+ user3,
+ "nickname3",
+ term,
+ gpaScore3.getGpa(),
+ languageTestScore3.getLanguageTest(),
+ 서던덴마크대학교_지원_정보,
+ null,
+ null
+ );
+
// when
ApplicationsResponse response = applicationQueryService.getApplicants(
- 테스트유저_2,
+ user1,
"",
""
);
@@ -55,128 +141,174 @@ class 지원자_목록_조회_테스트 {
// then
assertThat(response.firstChoice()).containsAll(List.of(
UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false))),
+ List.of(ApplicantResponse.of(application1, true))),
UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(메이지대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서, false))),
- UniversityApplicantsResponse.of(네바다주립대학_라스베이거스_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서, false))),
- UniversityApplicantsResponse.of(코펜하겐IT대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_7_코펜하겐IT대학_X_X_지원서, false)))
- ));
-
- assertThat(response.secondChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false))),
- UniversityApplicantsResponse.of(그라츠대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서, false))),
- UniversityApplicantsResponse.of(그라츠공과대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서, false)))
- ));
-
- assertThat(response.thirdChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(린츠_카톨릭대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(그라츠공과대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false))),
+ List.of(ApplicantResponse.of(application2, false))),
UniversityApplicantsResponse.of(서던덴마크대학교_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서, false))),
- UniversityApplicantsResponse.of(메이지대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서, false)))
+ List.of(ApplicantResponse.of(application3, false)))
));
}
@Test
void 이번_학기_특정_지역_지원자를_조회한다() {
+ //given
+ Application application1 = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+ Application application2 = applicationFixture.지원서(
+ user2,
+ "nickname2",
+ term,
+ gpaScore2.getGpa(),
+ languageTestScore2.getLanguageTest(),
+ 괌대학_B_지원_정보,
+ null,
+ null
+ );
+ applicationFixture.지원서(
+ user3,
+ "nickname3",
+ term,
+ gpaScore3.getGpa(),
+ languageTestScore3.getLanguageTest(),
+ 서던덴마크대학교_지원_정보,
+ null,
+ null
+ );
+
// when
ApplicationsResponse response = applicationQueryService.getApplicants(
- 테스트유저_2,
- 영미권.getCode(),
+ user1,
+ regionFixture.영미권().getCode(),
""
);
// then
- assertThat(response.firstChoice()).containsAll(List.of(
+ assertThat(response.firstChoice()).containsExactlyInAnyOrder(
UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false))),
+ List.of(ApplicantResponse.of(application1, true))),
UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(네바다주립대학_라스베이거스_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서, false)))
- ));
-
- assertThat(response.secondChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false)))
- ));
+ List.of(ApplicantResponse.of(application2, false)))
+ );
}
@Test
void 이번_학기_지원자를_대학_국문_이름으로_필터링해서_조회한다() {
+ //given
+ Application application1 = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+ Application application2 = applicationFixture.지원서(
+ user2,
+ "nickname2",
+ term,
+ gpaScore2.getGpa(),
+ languageTestScore2.getLanguageTest(),
+ 괌대학_B_지원_정보,
+ null,
+ null
+ );
+ applicationFixture.지원서(
+ user3,
+ "nickname3",
+ term,
+ gpaScore3.getGpa(),
+ languageTestScore3.getLanguageTest(),
+ 서던덴마크대학교_지원_정보,
+ null,
+ null
+ );
+
// when
ApplicationsResponse response = applicationQueryService.getApplicants(
- 테스트유저_2,
+ user1,
null,
- "일본"
+ "괌"
);
// then
- assertThat(response.firstChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(메이지대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서, false)))
- ));
-
- assertThat(response.secondChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(메이지대학_지원_정보, List.of())
- ));
-
- assertThat(response.thirdChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(메이지대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서, false)))
+ assertThat(response.firstChoice()).containsExactlyInAnyOrder(
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보,
+ List.of(ApplicantResponse.of(application1, true))),
+ UniversityApplicantsResponse.of(괌대학_B_지원_정보,
+ List.of(ApplicantResponse.of(application2, false)))
);
}
@Test
void 이전_학기_지원자는_조회되지_않는다() {
+ // given
+ Application application = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ "1988-1",
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+
// when
ApplicationsResponse response = applicationQueryService.getApplicants(
- 테스트유저_1,
+ user1,
"",
""
);
// then
assertThat(response.firstChoice()).doesNotContainAnyElementsOf(List.of(
- UniversityApplicantsResponse.of(네바다주립대학_라스베이거스_지원_정보,
- List.of(ApplicantResponse.of(이전학기_지원서, false)))
- ));
- assertThat(response.secondChoice()).doesNotContainAnyElementsOf(List.of(
- UniversityApplicantsResponse.of(그라츠공과대학_지원_정보,
- List.of(ApplicantResponse.of(이전학기_지원서, false)))
- ));
- assertThat(response.thirdChoice()).doesNotContainAnyElementsOf(List.of(
- UniversityApplicantsResponse.of(메이지대학_지원_정보,
- List.of(ApplicantResponse.of(이전학기_지원서, false)))
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보,
+ List.of(ApplicantResponse.of(application, true)))
));
}
@Test
void 동일_유저의_여러_지원서_중_최신_지원서만_조회된다() {
// given
- Application firstApplication = createApplication(테스트유저_1, 괌대학_A_지원_정보);
+ Application firstApplication = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
firstApplication.setIsDeleteTrue();
applicationRepository.save(firstApplication);
- Application secondApplication = createApplication(테스트유저_1, 네바다주립대학_라스베이거스_지원_정보);
-
+ Application secondApplication = applicationFixture.지원서(
+ user1,
+ "nickname2",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_B_지원_정보,
+ null,
+ null
+ );
// when
ApplicationsResponse response = applicationQueryService.getApplicants(
- 테스트유저_1, "", "");
+ user1,
+ "",
+ ""
+ );
// then
assertThat(response.firstChoice().stream()
@@ -191,100 +323,99 @@ class 경쟁자_목록_조회_테스트 {
@Test
void 이번_학기_지원한_대학의_경쟁자_목록을_조회한다() {
- // when
- ApplicationsResponse response = applicationQueryService.getApplicantsByUserApplications(
- 테스트유저_2
+ // given
+ Application application1 = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+ Application application2 = applicationFixture.지원서(
+ user2,
+ "nickname2",
+ term,
+ gpaScore2.getGpa(),
+ languageTestScore2.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+ applicationFixture.지원서(
+ user3,
+ "nickname3",
+ term,
+ gpaScore3.getGpa(),
+ languageTestScore3.getLanguageTest(),
+ 괌대학_B_지원_정보,
+ null,
+ null
);
+ // when
+ ApplicationsResponse response = applicationQueryService.getApplicantsByUserApplications(user1);
// then
- assertThat(response.firstChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false)))
- ));
-
- assertThat(response.secondChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true))),
- UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, false)))
- ));
-
- assertThat(response.thirdChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(린츠_카톨릭대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, true)))
- ));
+ assertThat(response.firstChoice()).containsExactlyInAnyOrder(
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보, List.of(
+ ApplicantResponse.of(application1, true),
+ ApplicantResponse.of(application2, false)
+ ))
+ );
}
@Test
void 이번_학기_지원한_대학_중_미선택이_있을_때_경쟁자_목록을_조회한다() {
- // when
- ApplicationsResponse response = applicationQueryService.getApplicantsByUserApplications(
- 테스트유저_7
+ // given
+ Application application1 = applicationFixture.지원서(
+ user1,
+ "nickname1",
+ term,
+ gpaScore1.getGpa(),
+ languageTestScore1.getLanguageTest(),
+ 괌대학_A_지원_정보,
+ null,
+ null
+ );
+ applicationFixture.지원서(
+ user2,
+ "nickname2",
+ term,
+ gpaScore2.getGpa(),
+ languageTestScore2.getLanguageTest(),
+ null,
+ 괌대학_B_지원_정보,
+ null
+ );
+ applicationFixture.지원서(
+ user3,
+ "nickname3",
+ term,
+ gpaScore3.getGpa(),
+ languageTestScore3.getLanguageTest(),
+ null,
+ null,
+ 서던덴마크대학교_지원_정보
);
+ // when
+ ApplicationsResponse response = applicationQueryService.getApplicantsByUserApplications(user1);
+
// then
- assertThat(response.firstChoice()).containsAll(List.of(
- UniversityApplicantsResponse.of(코펜하겐IT대학_지원_정보,
- List.of(ApplicantResponse.of(테스트유저_7_코펜하겐IT대학_X_X_지원서, true)))
- ));
+ assertThat(response.firstChoice()).containsExactlyInAnyOrder(
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보,
+ List.of(ApplicantResponse.of(application1, true)))
+ );
assertThat(response.secondChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(코펜하겐IT대학_지원_정보, List.of())
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보, List.of())
);
assertThat(response.thirdChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(코펜하겐IT대학_지원_정보, List.of())
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보, List.of())
);
}
-
- @Test
- void 이번_학기_지원한_대학이_모두_미선택일_때_경쟁자_목록을_조회한다() {
- //when
- ApplicationsResponse response = applicationQueryService.getApplicantsByUserApplications(
- 테스트유저_6
- );
-
- // then
- assertThat(response.firstChoice()).isEmpty();
- assertThat(response.secondChoice()).isEmpty();
- assertThat(response.thirdChoice()).isEmpty();
- }
- }
-
- private GpaScore createApprovedGpaScore(SiteUser siteUser) {
- GpaScore gpaScore = new GpaScore(
- new Gpa(4.0, 4.5, "/gpa-report.pdf"),
- siteUser
- );
- gpaScore.setVerifyStatus(VerifyStatus.APPROVED);
- return gpaScoreRepository.save(gpaScore);
- }
-
- private LanguageTestScore createApprovedLanguageTestScore(SiteUser siteUser) {
- LanguageTestScore languageTestScore = new LanguageTestScore(
- new LanguageTest(LanguageTestType.TOEIC, "100", "/gpa-report.pdf"),
- siteUser
- );
- languageTestScore.setVerifyStatus(VerifyStatus.APPROVED);
- return languageTestScoreRepository.save(languageTestScore);
- }
-
- private Application createApplication(
- SiteUser siteUser,
- UniversityInfoForApply universityInfoForApply) {
- Application application = new Application(
- siteUser,
- createApprovedGpaScore(siteUser).getGpa(),
- createApprovedLanguageTestScore(siteUser).getLanguageTest(),
- term,
- universityInfoForApply,
- null,
- null,
- null
- );
- application.setVerifyStatus(VerifyStatus.APPROVED);
- return applicationRepository.save(application);
}
}
diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
index 3c107424a..f70cd9fc0 100644
--- a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
+++ b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
@@ -1,8 +1,6 @@
package com.example.solidconnection.application.service;
import com.example.solidconnection.application.domain.Application;
-import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.application.domain.LanguageTest;
import com.example.solidconnection.application.domain.VerifyStatus;
import com.example.solidconnection.application.dto.ApplicationSubmissionResponse;
import com.example.solidconnection.application.dto.ApplyRequest;
@@ -11,14 +9,18 @@
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.score.repository.GpaScoreRepository;
-import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
+import com.example.solidconnection.score.fixture.GpaScoreFixture;
+import com.example.solidconnection.score.fixture.LanguageTestScoreFixture;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
-import com.example.solidconnection.university.domain.LanguageTestType;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
+import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import com.example.solidconnection.university.fixture.UniversityInfoForApplyFixture;
+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 org.springframework.beans.factory.annotation.Value;
import static com.example.solidconnection.application.service.ApplicationSubmissionService.APPLICATION_UPDATE_COUNT_LIMIT;
import static com.example.solidconnection.common.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED;
@@ -28,8 +30,9 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("지원서 제출 서비스 테스트")
-class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
+class ApplicationSubmissionServiceTest {
@Autowired
private ApplicationSubmissionService applicationSubmissionService;
@@ -38,48 +41,65 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
private ApplicationRepository applicationRepository;
@Autowired
- private GpaScoreRepository gpaScoreRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
- private LanguageTestScoreRepository languageTestScoreRepository;
+ private UniversityInfoForApplyFixture universityInfoForApplyFixture;
+
+ @Autowired
+ private GpaScoreFixture gpaScoreFixture;
+
+ @Autowired
+ private LanguageTestScoreFixture languageTestScoreFixture;
+
+ @Value("${university.term}")
+ private String term;
+
+ private SiteUser user;
+ private UniversityInfoForApply 괌대학_A_지원_정보;
+ private UniversityInfoForApply 괌대학_B_지원_정보;
+ private UniversityInfoForApply 서던덴마크대학교_지원_정보;
+
+ @BeforeEach
+ void setUp() {
+ user = siteUserFixture.사용자();
+ 괌대학_A_지원_정보 = universityInfoForApplyFixture.괌대학_A_지원_정보();
+ 괌대학_B_지원_정보 = universityInfoForApplyFixture.괌대학_B_지원_정보();
+ 서던덴마크대학교_지원_정보 = universityInfoForApplyFixture.서던덴마크대학교_지원_정보();
+ }
@Test
void 정상적으로_지원서를_제출한다() {
// given
- GpaScore gpaScore = createApprovedGpaScore(테스트유저_1);
- LanguageTestScore languageTestScore = createApprovedLanguageTestScore(테스트유저_1);
+ GpaScore gpaScore = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user);
+ LanguageTestScore languageTestScore = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user);
UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest(
괌대학_A_지원_정보.getId(),
- 네바다주립대학_라스베이거스_지원_정보.getId(),
- 메모리얼대학_세인트존스_A_지원_정보.getId()
+ 괌대학_B_지원_정보.getId(),
+ 서던덴마크대학교_지원_정보.getId()
);
ApplyRequest request = new ApplyRequest(gpaScore.getId(), languageTestScore.getId(), universityChoiceRequest);
// when
- ApplicationSubmissionResponse response = applicationSubmissionService.apply(테스트유저_1, request);
+ ApplicationSubmissionResponse response = applicationSubmissionService.apply(user, request);
// then
- Application savedApplication = applicationRepository.findBySiteUserAndTerm(테스트유저_1, term).orElseThrow();
+ Application savedApplication = applicationRepository.findBySiteUserAndTerm(user, term).orElseThrow();
assertAll(
() -> assertThat(response.applyCount()).isEqualTo(savedApplication.getUpdateCount()),
- () -> assertThat(savedApplication.getGpa()).isEqualTo(gpaScore.getGpa()),
- () -> assertThat(savedApplication.getLanguageTest()).isEqualTo(languageTestScore.getLanguageTest()),
() -> assertThat(savedApplication.getVerifyStatus()).isEqualTo(VerifyStatus.APPROVED),
- () -> assertThat(savedApplication.getNicknameForApply()).isNotNull(),
- () -> assertThat(savedApplication.getTerm()).isEqualTo(term),
() -> assertThat(savedApplication.isDelete()).isFalse(),
() -> assertThat(savedApplication.getFirstChoiceUniversity().getId()).isEqualTo(괌대학_A_지원_정보.getId()),
- () -> assertThat(savedApplication.getSecondChoiceUniversity().getId()).isEqualTo(네바다주립대학_라스베이거스_지원_정보.getId()),
- () -> assertThat(savedApplication.getThirdChoiceUniversity().getId()).isEqualTo(메모리얼대학_세인트존스_A_지원_정보.getId()),
- () -> assertThat(savedApplication.getSiteUser().getId()).isEqualTo(테스트유저_1.getId())
+ () -> assertThat(savedApplication.getSecondChoiceUniversity().getId()).isEqualTo(괌대학_B_지원_정보.getId()),
+ () -> assertThat(savedApplication.getThirdChoiceUniversity().getId()).isEqualTo(서던덴마크대학교_지원_정보.getId())
);
}
@Test
void 미승인된_GPA_성적으로_지원하면_예외_응답을_반환한다() {
// given
- GpaScore gpaScore = createUnapprovedGpaScore(테스트유저_1);
- LanguageTestScore languageTestScore = createApprovedLanguageTestScore(테스트유저_1);
+ GpaScore gpaScore = gpaScoreFixture.GPA_점수(VerifyStatus.PENDING, user);
+ LanguageTestScore languageTestScore = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user);
UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest(
괌대학_A_지원_정보.getId(),
null,
@@ -89,7 +109,7 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
// when & then
assertThatCode(() ->
- applicationSubmissionService.apply(테스트유저_1, request)
+ applicationSubmissionService.apply(user, request)
)
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_GPA_SCORE_STATUS.getMessage());
@@ -98,8 +118,8 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
@Test
void 미승인된_어학성적으로_지원하면_예외_응답을_반환한다() {
// given
- GpaScore gpaScore = createApprovedGpaScore(테스트유저_1);
- LanguageTestScore languageTestScore = createUnapprovedLanguageTestScore(테스트유저_1);
+ GpaScore gpaScore = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user);
+ LanguageTestScore languageTestScore = languageTestScoreFixture.어학_점수(VerifyStatus.PENDING, user);
UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest(
괌대학_A_지원_정보.getId(),
null,
@@ -109,7 +129,7 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
// when & then
assertThatCode(() ->
- applicationSubmissionService.apply(테스트유저_1, request)
+ applicationSubmissionService.apply(user, request)
)
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_LANGUAGE_TEST_SCORE_STATUS.getMessage());
@@ -118,8 +138,8 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
@Test
void 지원서_수정_횟수를_초과하면_예외_응답을_반환한다() {
// given
- GpaScore gpaScore = createApprovedGpaScore(테스트유저_1);
- LanguageTestScore languageTestScore = createApprovedLanguageTestScore(테스트유저_1);
+ GpaScore gpaScore = gpaScoreFixture.GPA_점수(VerifyStatus.APPROVED, user);
+ LanguageTestScore languageTestScore = languageTestScoreFixture.어학_점수(VerifyStatus.APPROVED, user);
UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest(
괌대학_A_지원_정보.getId(),
null,
@@ -128,48 +148,14 @@ class ApplicationSubmissionServiceTest extends BaseIntegrationTest {
ApplyRequest request = new ApplyRequest(gpaScore.getId(), languageTestScore.getId(), universityChoiceRequest);
for (int i = 0; i < APPLICATION_UPDATE_COUNT_LIMIT; i++) {
- applicationSubmissionService.apply(테스트유저_1, request);
+ applicationSubmissionService.apply(user, request);
}
// when & then
assertThatCode(() ->
- applicationSubmissionService.apply(테스트유저_1, request)
+ applicationSubmissionService.apply(user, request)
)
.isInstanceOf(CustomException.class)
.hasMessage(APPLY_UPDATE_LIMIT_EXCEED.getMessage());
}
-
- private GpaScore createUnapprovedGpaScore(SiteUser siteUser) {
- GpaScore gpaScore = new GpaScore(
- new Gpa(4.0, 4.5, "/gpa-report.pdf"),
- siteUser
- );
- return gpaScoreRepository.save(gpaScore);
- }
-
- private GpaScore createApprovedGpaScore(SiteUser siteUser) {
- GpaScore gpaScore = new GpaScore(
- new Gpa(4.0, 4.5, "/gpa-report.pdf"),
- siteUser
- );
- gpaScore.setVerifyStatus(VerifyStatus.APPROVED);
- return gpaScoreRepository.save(gpaScore);
- }
-
- private LanguageTestScore createUnapprovedLanguageTestScore(SiteUser siteUser) {
- LanguageTestScore languageTestScore = new LanguageTestScore(
- new LanguageTest(LanguageTestType.TOEIC, "100", "/gpa-report.pdf"),
- siteUser
- );
- return languageTestScoreRepository.save(languageTestScore);
- }
-
- private LanguageTestScore createApprovedLanguageTestScore(SiteUser siteUser) {
- LanguageTestScore languageTestScore = new LanguageTestScore(
- new LanguageTest(LanguageTestType.TOEIC, "100", "/gpa-report.pdf"),
- siteUser
- );
- languageTestScore.setVerifyStatus(VerifyStatus.APPROVED);
- return languageTestScoreRepository.save(languageTestScore);
- }
}
From 3d5820c70808481eb9718e9b7bcf96f060c5522b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=ED=99=A9=EA=B7=9C=ED=98=81?=
<126947828+Gyuhyeok99@users.noreply.github.com>
Date: Wed, 18 Jun 2025 12:50:29 +0900
Subject: [PATCH 21/90] =?UTF-8?q?refactor:=20=EC=BB=A4=EB=AE=A4=EB=8B=88?=
=?UTF-8?q?=ED=8B=B0=20=EA=B4=80=EB=A0=A8=20=ED=86=B5=ED=95=A9=20=ED=85=8C?=
=?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20fixture=20?=
=?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#3?=
=?UTF-8?q?35)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* feat: BoardFixture에 Board 생성 메서드 추가
- 지연로딩 문제를 방지하기 위해 Board 조회 시 fetch join 사용
* feat: PostFixture에 Post 생성 메서드 추가
* feat: PostImageFixture에 PostImage 생성 메서드 추가
* feat: CommentFixture에 Comment 생성 메서드 추가
* refactor: Community 관련 데이터 fixture 메서드로 변경
* refactor: BaseIntegrationTest 제거
* refactor: BoardFixture에서 BoardCode enum 상수 일관되게 사용
---
.../community/board/fixture/BoardFixture.java | 41 ++
.../board/fixture/BoardFixtureBuilder.java | 31 ++
.../repository/BoardRepositoryForTest.java | 14 +
.../comment/fixture/CommentFixture.java | 35 ++
.../fixture/CommentFixtureBuilder.java | 53 ++
.../comment/service/CommentServiceTest.java | 221 +++-----
.../community/post/fixture/PostFixture.java | 35 ++
.../post/fixture/PostFixtureBuilder.java | 77 +++
.../post/fixture/PostImageFixture.java | 20 +
.../post/fixture/PostImageFixtureBuilder.java | 33 ++
.../post/service/PostCommandServiceTest.java | 123 ++--
.../post/service/PostLikeServiceTest.java | 68 +--
.../post/service/PostQueryServiceTest.java | 150 +++--
.../integration/BaseIntegrationTest.java | 527 ------------------
14 files changed, 565 insertions(+), 863 deletions(-)
create mode 100644 src/test/java/com/example/solidconnection/community/board/fixture/BoardFixture.java
create mode 100644 src/test/java/com/example/solidconnection/community/board/fixture/BoardFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/community/board/repository/BoardRepositoryForTest.java
create mode 100644 src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixture.java
create mode 100644 src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/community/post/fixture/PostFixture.java
create mode 100644 src/test/java/com/example/solidconnection/community/post/fixture/PostFixtureBuilder.java
create mode 100644 src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixture.java
create mode 100644 src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixtureBuilder.java
delete mode 100644 src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java
diff --git a/src/test/java/com/example/solidconnection/community/board/fixture/BoardFixture.java b/src/test/java/com/example/solidconnection/community/board/fixture/BoardFixture.java
new file mode 100644
index 000000000..16dc920d2
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/board/fixture/BoardFixture.java
@@ -0,0 +1,41 @@
+package com.example.solidconnection.community.board.fixture;
+
+import com.example.solidconnection.community.board.domain.Board;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+import static com.example.solidconnection.community.board.domain.BoardCode.AMERICAS;
+import static com.example.solidconnection.community.board.domain.BoardCode.ASIA;
+import static com.example.solidconnection.community.board.domain.BoardCode.EUROPE;
+import static com.example.solidconnection.community.board.domain.BoardCode.FREE;
+
+@TestComponent
+@RequiredArgsConstructor
+public class BoardFixture {
+
+ private final BoardFixtureBuilder boardFixtureBuilder;
+
+ public Board 미주권() {
+ return boardFixtureBuilder.code(AMERICAS.name())
+ .koreanName("미주권")
+ .findOrCreate();
+ }
+
+ public Board 아시아권() {
+ return boardFixtureBuilder.code(ASIA.name())
+ .koreanName("아시아권")
+ .findOrCreate();
+ }
+
+ public Board 유럽권() {
+ return boardFixtureBuilder.code(EUROPE.name())
+ .koreanName("유럽권")
+ .findOrCreate();
+ }
+
+ public Board 자유게시판() {
+ return boardFixtureBuilder.code(FREE.name())
+ .koreanName("자유게시판")
+ .findOrCreate();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/board/fixture/BoardFixtureBuilder.java b/src/test/java/com/example/solidconnection/community/board/fixture/BoardFixtureBuilder.java
new file mode 100644
index 000000000..1b7eff6ba
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/board/fixture/BoardFixtureBuilder.java
@@ -0,0 +1,31 @@
+package com.example.solidconnection.community.board.fixture;
+
+import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.board.repository.BoardRepositoryForTest;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class BoardFixtureBuilder {
+
+ private final BoardRepositoryForTest boardRepositoryForTest;
+
+ private String code;
+ private String koreanName;
+
+ public BoardFixtureBuilder code(String code) {
+ this.code = code;
+ return this;
+ }
+
+ public BoardFixtureBuilder koreanName(String koreanName) {
+ this.koreanName = koreanName;
+ return this;
+ }
+
+ public Board findOrCreate() {
+ return boardRepositoryForTest.findByCodeWithPosts(code)
+ .orElseGet(() -> boardRepositoryForTest.save(new Board(code, koreanName)));
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/board/repository/BoardRepositoryForTest.java b/src/test/java/com/example/solidconnection/community/board/repository/BoardRepositoryForTest.java
new file mode 100644
index 000000000..0d94e8d41
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/board/repository/BoardRepositoryForTest.java
@@ -0,0 +1,14 @@
+package com.example.solidconnection.community.board.repository;
+
+import com.example.solidconnection.community.board.domain.Board;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.util.Optional;
+
+public interface BoardRepositoryForTest extends JpaRepository {
+
+ @Query("SELECT b FROM Board b LEFT JOIN FETCH b.postList WHERE b.code = :code")
+ Optional findByCodeWithPosts(@Param("code") String code);
+}
diff --git a/src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixture.java b/src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixture.java
new file mode 100644
index 000000000..4d0f3b438
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixture.java
@@ -0,0 +1,35 @@
+package com.example.solidconnection.community.comment.fixture;
+
+import com.example.solidconnection.community.comment.domain.Comment;
+import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class CommentFixture {
+
+ private final CommentFixtureBuilder commentFixtureBuilder;
+
+ public Comment 부모_댓글(String content, Post post, SiteUser siteUser) {
+ return commentFixtureBuilder
+ .content(content)
+ .post(post)
+ .siteUser(siteUser)
+ .createParent();
+ }
+
+ public Comment 자식_댓글(
+ String content,
+ Post post,
+ SiteUser siteUser,
+ Comment parentComment) {
+ return commentFixtureBuilder
+ .content(content)
+ .post(post)
+ .siteUser(siteUser)
+ .parentComment(parentComment)
+ .createChild();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixtureBuilder.java b/src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixtureBuilder.java
new file mode 100644
index 000000000..f5dc10ac2
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/comment/fixture/CommentFixtureBuilder.java
@@ -0,0 +1,53 @@
+package com.example.solidconnection.community.comment.fixture;
+
+import com.example.solidconnection.community.comment.domain.Comment;
+import com.example.solidconnection.community.comment.repository.CommentRepository;
+import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class CommentFixtureBuilder {
+
+ private final CommentRepository commentRepository;
+
+ private String content;
+ private Post post;
+ private SiteUser siteUser;
+ private Comment parentComment;
+
+ public CommentFixtureBuilder content(String content) {
+ this.content = content;
+ return this;
+ }
+
+ public CommentFixtureBuilder post(Post post) {
+ this.post = post;
+ return this;
+ }
+
+ public CommentFixtureBuilder siteUser(SiteUser siteUser) {
+ this.siteUser = siteUser;
+ return this;
+ }
+
+ public CommentFixtureBuilder parentComment(Comment parentComment) {
+ this.parentComment = parentComment;
+ return this;
+ }
+
+ public Comment createParent() {
+ Comment comment = new Comment(content);
+ comment.setPostAndSiteUser(post, siteUser);
+ return commentRepository.save(comment);
+ }
+
+ public Comment createChild() {
+ Comment comment = new Comment(content);
+ comment.setPostAndSiteUser(post, siteUser);
+ comment.setParentCommentAndPostAndSiteUser(parentComment, post, siteUser);
+ return commentRepository.save(comment);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java b/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
index 17309e100..8e5e5c995 100644
--- a/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/comment/service/CommentServiceTest.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.community.comment.service;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.board.fixture.BoardFixture;
import com.example.solidconnection.community.comment.domain.Comment;
import com.example.solidconnection.community.comment.dto.CommentCreateRequest;
import com.example.solidconnection.community.comment.dto.CommentCreateResponse;
@@ -9,13 +9,16 @@
import com.example.solidconnection.community.comment.dto.CommentUpdateRequest;
import com.example.solidconnection.community.comment.dto.CommentUpdateResponse;
import com.example.solidconnection.community.comment.dto.PostFindCommentResponse;
+import com.example.solidconnection.community.comment.fixture.CommentFixture;
import com.example.solidconnection.community.comment.repository.CommentRepository;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.domain.PostCategory;
-import com.example.solidconnection.community.post.repository.PostRepository;
+import com.example.solidconnection.community.post.fixture.PostFixture;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import jakarta.transaction.Transactional;
+import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@@ -31,8 +34,9 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("댓글 서비스 테스트")
-class CommentServiceTest extends BaseIntegrationTest {
+class CommentServiceTest {
@Autowired
private CommentService commentService;
@@ -41,7 +45,34 @@ class CommentServiceTest extends BaseIntegrationTest {
private CommentRepository commentRepository;
@Autowired
- private PostRepository postRepository;
+ private SiteUserFixture siteUserFixture;
+
+ @Autowired
+ private BoardFixture boardFixture;
+
+ @Autowired
+ private PostFixture postFixture;
+
+ @Autowired
+ private CommentFixture commentFixture;
+
+ private SiteUser user1;
+ private SiteUser user2;
+ private Post post;
+
+ @BeforeEach
+ void setUp() {
+ user1 = siteUserFixture.사용자(1, "test1");
+ user2 = siteUserFixture.사용자(2, "test2");
+ post = postFixture.게시글(
+ "제목1",
+ "내용1",
+ false,
+ PostCategory.자유,
+ boardFixture.자유게시판(),
+ user1
+ );
+ }
@Nested
class 댓글_조회_테스트 {
@@ -49,16 +80,12 @@ class 댓글_조회_테스트 {
@Test
void 게시글의_모든_댓글을_조회한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment parentComment = createComment(testPost, 테스트유저_1, "부모 댓글");
- Comment childComment = createChildComment(testPost, 테스트유저_2, parentComment, "자식 댓글");
+ Comment parentComment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ Comment childComment = commentFixture.자식_댓글("자식 댓글 1", post, user2, parentComment);
List comments = List.of(parentComment, childComment);
// when
- List responses = commentService.findCommentsByPostId(
- 테스트유저_1,
- testPost.getId()
- );
+ List responses = commentService.findCommentsByPostId(user1, post.getId());
// then
assertAll(
@@ -69,17 +96,7 @@ class 댓글_조회_테스트 {
.satisfies(response -> assertAll(
() -> assertThat(response.id()).isEqualTo(parentComment.getId()),
() -> assertThat(response.parentId()).isNull(),
- () -> assertThat(response.content()).isEqualTo(parentComment.getContent()),
- () -> assertThat(response.isOwner()).isTrue(),
- () -> assertThat(response.createdAt()).isEqualTo(parentComment.getCreatedAt()),
- () -> assertThat(response.updatedAt()).isEqualTo(parentComment.getUpdatedAt()),
-
- () -> assertThat(response.postFindSiteUserResponse().id())
- .isEqualTo(parentComment.getSiteUser().getId()),
- () -> assertThat(response.postFindSiteUserResponse().nickname())
- .isEqualTo(parentComment.getSiteUser().getNickname()),
- () -> assertThat(response.postFindSiteUserResponse().profileImageUrl())
- .isEqualTo(parentComment.getSiteUser().getProfileImageUrl())
+ () -> assertThat(response.isOwner()).isTrue()
)),
() -> assertThat(responses)
.filteredOn(response -> response.id().equals(childComment.getId()))
@@ -87,17 +104,7 @@ class 댓글_조회_테스트 {
.satisfies(response -> assertAll(
() -> assertThat(response.id()).isEqualTo(childComment.getId()),
() -> assertThat(response.parentId()).isEqualTo(parentComment.getId()),
- () -> assertThat(response.content()).isEqualTo(childComment.getContent()),
- () -> assertThat(response.isOwner()).isFalse(),
- () -> assertThat(response.createdAt()).isEqualTo(childComment.getCreatedAt()),
- () -> assertThat(response.updatedAt()).isEqualTo(childComment.getUpdatedAt()),
-
- () -> assertThat(response.postFindSiteUserResponse().id())
- .isEqualTo(childComment.getSiteUser().getId()),
- () -> assertThat(response.postFindSiteUserResponse().nickname())
- .isEqualTo(childComment.getSiteUser().getNickname()),
- () -> assertThat(response.postFindSiteUserResponse().profileImageUrl())
- .isEqualTo(childComment.getSiteUser().getProfileImageUrl())
+ () -> assertThat(response.isOwner()).isFalse()
))
);
}
@@ -109,14 +116,10 @@ class 댓글_생성_테스트 {
@Test
void 댓글을_성공적으로_생성한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- CommentCreateRequest request = new CommentCreateRequest(testPost.getId(), "테스트 댓글", null);
+ CommentCreateRequest request = new CommentCreateRequest(post.getId(),"댓글", null);
// when
- CommentCreateResponse response = commentService.createComment(
- 테스트유저_1,
- request
- );
+ CommentCreateResponse response = commentService.createComment(user1, request);
// then
Comment savedComment = commentRepository.findById(response.id()).orElseThrow();
@@ -124,23 +127,19 @@ class 댓글_생성_테스트 {
() -> assertThat(savedComment.getId()).isEqualTo(response.id()),
() -> assertThat(savedComment.getContent()).isEqualTo(request.content()),
() -> assertThat(savedComment.getParentComment()).isNull(),
- () -> assertThat(savedComment.getPost().getId()).isEqualTo(testPost.getId()),
- () -> assertThat(savedComment.getSiteUser().getId()).isEqualTo(테스트유저_1.getId())
+ () -> assertThat(savedComment.getPost().getId()).isEqualTo(post.getId()),
+ () -> assertThat(savedComment.getSiteUser().getId()).isEqualTo(user1.getId())
);
}
@Test
void 대댓글을_성공적으로_생성한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment parentComment = createComment(testPost, 테스트유저_1, "부모 댓글");
- CommentCreateRequest request = new CommentCreateRequest(testPost.getId(), "테스트 대댓글", parentComment.getId());
+ Comment parentComment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ CommentCreateRequest request = new CommentCreateRequest(post.getId(), "자식 댓글", parentComment.getId());
// when
- CommentCreateResponse response = commentService.createComment(
- 테스트유저_2,
- request
- );
+ CommentCreateResponse response = commentService.createComment(user2, request);
// then
Comment savedComment = commentRepository.findById(response.id()).orElseThrow();
@@ -148,23 +147,22 @@ class 댓글_생성_테스트 {
() -> assertThat(savedComment.getId()).isEqualTo(response.id()),
() -> assertThat(savedComment.getContent()).isEqualTo(request.content()),
() -> assertThat(savedComment.getParentComment().getId()).isEqualTo(parentComment.getId()),
- () -> assertThat(savedComment.getPost().getId()).isEqualTo(testPost.getId()),
- () -> assertThat(savedComment.getSiteUser().getId()).isEqualTo(테스트유저_2.getId())
+ () -> assertThat(savedComment.getPost().getId()).isEqualTo(post.getId()),
+ () -> assertThat(savedComment.getSiteUser().getId()).isEqualTo(user2.getId())
);
}
@Test
void 대대댓글_생성_시도하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment parentComment = createComment(testPost, 테스트유저_1, "부모 댓글");
- Comment childComment = createChildComment(testPost, 테스트유저_2, parentComment, "자식 댓글");
- CommentCreateRequest request = new CommentCreateRequest(testPost.getId(), "테스트 대대댓글", childComment.getId());
+ Comment parentComment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ Comment childComment = commentFixture.자식_댓글("자식 댓글", post, user2, parentComment);
+ CommentCreateRequest request = new CommentCreateRequest(post.getId(), "대대댓글", childComment.getId());
// when & then
assertThatThrownBy(() ->
commentService.createComment(
- 테스트유저_1,
+ user1,
request
))
.isInstanceOf(CustomException.class)
@@ -174,14 +172,13 @@ class 댓글_생성_테스트 {
@Test
void 존재하지_않는_부모댓글로_대댓글_작성시_예외를_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
long invalidCommentId = 9999L;
- CommentCreateRequest request = new CommentCreateRequest(testPost.getId(), "테스트 대댓글", invalidCommentId);
+ CommentCreateRequest request = new CommentCreateRequest(post.getId(), "자식 댓글", invalidCommentId);
// when & then
assertThatThrownBy(() ->
commentService.createComment(
- 테스트유저_1,
+ user1,
request
))
.isInstanceOf(CustomException.class)
@@ -195,16 +192,11 @@ class 댓글_수정_테스트 {
@Test
void 댓글을_성공적으로_수정한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment comment = createComment(testPost, 테스트유저_1, "원본 댓글");
+ Comment comment = commentFixture.부모_댓글("원본 댓글", post, user1);
CommentUpdateRequest request = new CommentUpdateRequest("수정된 댓글");
// when
- CommentUpdateResponse response = commentService.updateComment(
- 테스트유저_1,
- comment.getId(),
- request
- );
+ CommentUpdateResponse response = commentService.updateComment(user1, comment.getId(), request);
// then
Comment updatedComment = commentRepository.findById(response.id()).orElseThrow();
@@ -212,22 +204,21 @@ class 댓글_수정_테스트 {
() -> assertThat(updatedComment.getId()).isEqualTo(comment.getId()),
() -> assertThat(updatedComment.getContent()).isEqualTo(request.content()),
() -> assertThat(updatedComment.getParentComment()).isNull(),
- () -> assertThat(updatedComment.getPost().getId()).isEqualTo(testPost.getId()),
- () -> assertThat(updatedComment.getSiteUser().getId()).isEqualTo(테스트유저_1.getId())
+ () -> assertThat(updatedComment.getPost().getId()).isEqualTo(post.getId()),
+ () -> assertThat(updatedComment.getSiteUser().getId()).isEqualTo(user1.getId())
);
}
@Test
void 다른_사용자의_댓글을_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment comment = createComment(testPost, 테스트유저_1, "원본 댓글");
+ Comment comment = commentFixture.부모_댓글("원본 댓글", post, user1);
CommentUpdateRequest request = new CommentUpdateRequest("수정된 댓글");
// when & then
assertThatThrownBy(() ->
commentService.updateComment(
- 테스트유저_2,
+ user2,
comment.getId(),
request
))
@@ -238,14 +229,13 @@ class 댓글_수정_테스트 {
@Test
void 삭제된_댓글을_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment comment = createComment(testPost, 테스트유저_1, null);
+ Comment comment = commentFixture.부모_댓글(null, post, user1);
CommentUpdateRequest request = new CommentUpdateRequest("수정된 댓글");
// when & then
assertThatThrownBy(() ->
commentService.updateComment(
- 테스트유저_1,
+ user1,
comment.getId(),
request
))
@@ -261,22 +251,18 @@ class 댓글_삭제_테스트 {
@Transactional
void 대댓글이_없는_댓글을_삭제한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment comment = createComment(testPost, 테스트유저_1, "테스트 댓글");
- List comments = testPost.getCommentList();
+ Comment comment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ List comments = post.getCommentList();
int expectedCommentsCount = comments.size() - 1;
// when
- CommentDeleteResponse response = commentService.deleteCommentById(
- 테스트유저_1,
- comment.getId()
- );
+ CommentDeleteResponse response = commentService.deleteCommentById(user1, comment.getId());
// then
assertAll(
() -> assertThat(response.id()).isEqualTo(comment.getId()),
() -> assertThat(commentRepository.findById(comment.getId())).isEmpty(),
- () -> assertThat(testPost.getCommentList()).hasSize(expectedCommentsCount)
+ () -> assertThat(post.getCommentList()).hasSize(expectedCommentsCount)
);
}
@@ -284,17 +270,13 @@ class 댓글_삭제_테스트 {
@Transactional
void 대댓글이_있는_댓글을_삭제하면_내용만_삭제된다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment parentComment = createComment(testPost, 테스트유저_1, "부모 댓글");
- Comment childComment = createChildComment(testPost, 테스트유저_2, parentComment, "자식 댓글");
- List comments = testPost.getCommentList();
+ Comment parentComment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ Comment childComment = commentFixture.자식_댓글("자식 댓글", post, user2, parentComment);
+ List comments = post.getCommentList();
List childComments = parentComment.getCommentList();
// when
- CommentDeleteResponse response = commentService.deleteCommentById(
- 테스트유저_1,
- parentComment.getId()
- );
+ CommentDeleteResponse response = commentService.deleteCommentById(user1, parentComment.getId());
// then
Comment deletedComment = commentRepository.findById(response.id()).orElseThrow();
@@ -303,7 +285,7 @@ class 댓글_삭제_테스트 {
() -> assertThat(deletedComment.getCommentList())
.extracting(Comment::getId)
.containsExactlyInAnyOrder(childComment.getId()),
- () -> assertThat(testPost.getCommentList()).hasSize(comments.size()),
+ () -> assertThat(post.getCommentList()).hasSize(comments.size()),
() -> assertThat(deletedComment.getCommentList()).hasSize(childComments.size())
);
}
@@ -312,18 +294,14 @@ class 댓글_삭제_테스트 {
@Transactional
void 대댓글을_삭제하면_부모댓글이_삭제되지_않는다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment parentComment = createComment(testPost, 테스트유저_1, "부모 댓글");
- Comment childComment1 = createChildComment(testPost, 테스트유저_2, parentComment, "자식 댓글 1");
- Comment childComment2 = createChildComment(testPost, 테스트유저_2, parentComment, "자식 댓글 2");
+ Comment parentComment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ Comment childComment1 = commentFixture.자식_댓글("자식 댓글1", post, user2, parentComment);
+ Comment childComment2 = commentFixture.자식_댓글("자식 댓글2", post, user2, parentComment);
List childComments = parentComment.getCommentList();
int expectedChildCommentsCount = childComments.size() - 1;
// when
- CommentDeleteResponse response = commentService.deleteCommentById(
- 테스트유저_2,
- childComment1.getId()
- );
+ CommentDeleteResponse response = commentService.deleteCommentById(user2, childComment1.getId());
// then
Comment remainingParentComment = commentRepository.findById(parentComment.getId()).orElseThrow();
@@ -342,67 +320,36 @@ class 댓글_삭제_테스트 {
@Transactional
void 대댓글을_삭제하고_부모댓글이_삭제된_상태면_부모댓글도_삭제된다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment parentComment = createComment(testPost, 테스트유저_1, "부모 댓글");
- Comment childComment = createChildComment(testPost, 테스트유저_2, parentComment, "자식 댓글");
- List comments = testPost.getCommentList();
+ Comment parentComment = commentFixture.부모_댓글("부모 댓글", post, user1);
+ Comment childComment = commentFixture.자식_댓글("자식 댓글", post, user2, parentComment);
+ List comments = post.getCommentList();
int expectedCommentsCount = comments.size() - 2;
parentComment.deprecateComment();
// when
- CommentDeleteResponse response = commentService.deleteCommentById(
- 테스트유저_2,
- childComment.getId()
- );
+ CommentDeleteResponse response = commentService.deleteCommentById(user2, childComment.getId());
// then
assertAll(
() -> assertThat(commentRepository.findById(response.id())).isEmpty(),
() -> assertThat(commentRepository.findById(parentComment.getId())).isEmpty(),
- () -> assertThat(testPost.getCommentList()).hasSize(expectedCommentsCount)
+ () -> assertThat(post.getCommentList()).hasSize(expectedCommentsCount)
);
}
@Test
void 다른_사용자의_댓글을_삭제하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, 테스트유저_1);
- Comment comment = createComment(testPost, 테스트유저_1, "테스트 댓글");
+ Comment comment = commentFixture.부모_댓글("부모 댓글", post, user1);
// when & then
assertThatThrownBy(() ->
commentService.deleteCommentById(
- 테스트유저_2,
+ user2,
comment.getId()
))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_POST_ACCESS.getMessage());
}
}
-
- private Post createPost(Board board, SiteUser siteUser) {
- Post post = new Post(
- "테스트 제목",
- "테스트 내용",
- false,
- 0L,
- 0L,
- PostCategory.자유
- );
- post.setBoardAndSiteUser(board, siteUser);
- return postRepository.save(post);
- }
-
- private Comment createComment(Post post, SiteUser siteUser, String content) {
- Comment comment = new Comment(content);
- comment.setPostAndSiteUser(post, siteUser);
- return commentRepository.save(comment);
- }
-
- private Comment createChildComment(Post post, SiteUser siteUser, Comment parentComment, String content) {
- Comment comment = new Comment(content);
- comment.setPostAndSiteUser(post, siteUser);
- comment.setParentCommentAndPostAndSiteUser(parentComment, post, siteUser);
- return commentRepository.save(comment);
- }
}
diff --git a/src/test/java/com/example/solidconnection/community/post/fixture/PostFixture.java b/src/test/java/com/example/solidconnection/community/post/fixture/PostFixture.java
new file mode 100644
index 000000000..92fa64a37
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/post/fixture/PostFixture.java
@@ -0,0 +1,35 @@
+package com.example.solidconnection.community.post.fixture;
+
+import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class PostFixture {
+
+ private final PostFixtureBuilder postFixtureBuilder;
+
+ public Post 게시글(
+ String title,
+ String content,
+ Boolean isQuestion,
+ PostCategory postCategory,
+ Board board,
+ SiteUser siteUser
+ ) {
+ return postFixtureBuilder
+ .title(title)
+ .content(content)
+ .isQuestion(isQuestion)
+ .likeCount(0L)
+ .viewCount(0L)
+ .postCategory(postCategory)
+ .board(board)
+ .siteUser(siteUser)
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/post/fixture/PostFixtureBuilder.java b/src/test/java/com/example/solidconnection/community/post/fixture/PostFixtureBuilder.java
new file mode 100644
index 000000000..ac3440b42
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/post/fixture/PostFixtureBuilder.java
@@ -0,0 +1,77 @@
+package com.example.solidconnection.community.post.fixture;
+
+import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostCategory;
+import com.example.solidconnection.community.post.repository.PostRepository;
+import com.example.solidconnection.siteuser.domain.SiteUser;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class PostFixtureBuilder {
+
+ private final PostRepository postRepository;
+
+ private String title;
+ private String content;
+ private Boolean isQuestion;
+ private Long likeCount;
+ private Long viewCount;
+ private PostCategory postCategory;
+ private Board board;
+ private SiteUser siteUser;
+
+ public PostFixtureBuilder title(String title) {
+ this.title = title;
+ return this;
+ }
+
+ public PostFixtureBuilder content(String content) {
+ this.content = content;
+ return this;
+ }
+
+ public PostFixtureBuilder isQuestion(Boolean isQuestion) {
+ this.isQuestion = isQuestion;
+ return this;
+ }
+
+ public PostFixtureBuilder likeCount(Long likeCount) {
+ this.likeCount = likeCount;
+ return this;
+ }
+
+ public PostFixtureBuilder viewCount(Long viewCount) {
+ this.viewCount = viewCount;
+ return this;
+ }
+
+ public PostFixtureBuilder postCategory(PostCategory postCategory) {
+ this.postCategory = postCategory;
+ return this;
+ }
+
+ public PostFixtureBuilder board(Board board) {
+ this.board = board;
+ return this;
+ }
+
+ public PostFixtureBuilder siteUser(SiteUser siteUser) {
+ this.siteUser = siteUser;
+ return this;
+ }
+
+ public Post create() {
+ Post post = new Post(
+ title,
+ content,
+ isQuestion,
+ likeCount,
+ viewCount,
+ postCategory);
+ post.setBoardAndSiteUser(board, siteUser);
+ return postRepository.save(post);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixture.java b/src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixture.java
new file mode 100644
index 000000000..565f9fde0
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixture.java
@@ -0,0 +1,20 @@
+package com.example.solidconnection.community.post.fixture;
+
+import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostImage;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class PostImageFixture {
+
+ private final PostImageFixtureBuilder postImageFixtureBuilder;
+
+ public PostImage 게시글_이미지(String url, Post post) {
+ return postImageFixtureBuilder
+ .url(url)
+ .post(post)
+ .create();
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixtureBuilder.java b/src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixtureBuilder.java
new file mode 100644
index 000000000..e12e0f0a0
--- /dev/null
+++ b/src/test/java/com/example/solidconnection/community/post/fixture/PostImageFixtureBuilder.java
@@ -0,0 +1,33 @@
+package com.example.solidconnection.community.post.fixture;
+
+import com.example.solidconnection.community.post.domain.Post;
+import com.example.solidconnection.community.post.domain.PostImage;
+import com.example.solidconnection.community.post.repository.PostImageRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.boot.test.context.TestComponent;
+
+@TestComponent
+@RequiredArgsConstructor
+public class PostImageFixtureBuilder {
+
+ private final PostImageRepository postImageRepository;
+
+ private String url;
+ private Post post;
+
+ public PostImageFixtureBuilder url(String url) {
+ this.url = url;
+ return this;
+ }
+
+ public PostImageFixtureBuilder post(Post post) {
+ this.post = post;
+ return this;
+ }
+
+ public PostImage create() {
+ PostImage postImage = new PostImage(url);
+ postImage.setPost(post);
+ return postImageRepository.save(postImage);
+ }
+}
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
index 2656b2858..2cf253cf7 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostCommandServiceTest.java
@@ -1,7 +1,7 @@
package com.example.solidconnection.community.post.service;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.board.fixture.BoardFixture;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.domain.PostImage;
@@ -10,14 +10,15 @@
import com.example.solidconnection.community.post.dto.PostDeleteResponse;
import com.example.solidconnection.community.post.dto.PostUpdateRequest;
import com.example.solidconnection.community.post.dto.PostUpdateResponse;
-import com.example.solidconnection.community.post.repository.PostImageRepository;
+import com.example.solidconnection.community.post.fixture.PostFixture;
+import com.example.solidconnection.community.post.fixture.PostImageFixture;
import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.s3.domain.ImgType;
import com.example.solidconnection.s3.dto.UploadedFileUrlResponse;
import com.example.solidconnection.s3.service.S3Service;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.util.RedisUtils;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.BeforeEach;
@@ -43,8 +44,9 @@
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
+@TestContainerSpringBootTest
@DisplayName("게시글 생성/수정/삭제 서비스 테스트")
-class PostCommandServiceTest extends BaseIntegrationTest {
+class PostCommandServiceTest {
@Autowired
private PostCommandService postCommandService;
@@ -62,16 +64,40 @@ class PostCommandServiceTest extends BaseIntegrationTest {
private PostRepository postRepository;
@Autowired
- private PostImageRepository postImageRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
- private SiteUserFixture siteUserFixture;
+ private BoardFixture boardFixture;
+
+ @Autowired
+ private PostFixture postFixture;
+
+ @Autowired
+ private PostImageFixture postImageFixture;
private SiteUser user1;
+ private Post post;
+ private Post questionPost;
@BeforeEach
void setUp() {
user1 = siteUserFixture.사용자(1, "test1");
+ post = postFixture.게시글(
+ "제목",
+ "내용",
+ false,
+ PostCategory.자유,
+ boardFixture.자유게시판(),
+ user1
+ );
+ questionPost = postFixture.게시글(
+ "제목",
+ "내용",
+ true,
+ PostCategory.질문,
+ boardFixture.자유게시판(),
+ user1
+ );
}
@Nested
@@ -88,21 +114,12 @@ class 게시글_생성_테스트 {
.willReturn(List.of(new UploadedFileUrlResponse(expectedImageUrl)));
// when
- PostCreateResponse response = postCommandService.createPost(
- user1,
- request,
- imageFiles
- );
+ PostCreateResponse response = postCommandService.createPost(user1, request, imageFiles);
// then
Post savedPost = postRepository.findById(response.id()).orElseThrow();
assertAll(
() -> assertThat(response.id()).isEqualTo(savedPost.getId()),
- () -> assertThat(savedPost.getTitle()).isEqualTo(request.title()),
- () -> assertThat(savedPost.getContent()).isEqualTo(request.content()),
- () -> assertThat(savedPost.getIsQuestion()).isEqualTo(request.isQuestion()),
- () -> assertThat(savedPost.getCategory().name()).isEqualTo(request.postCategory()),
- () -> assertThat(savedPost.getBoard().getCode()).isEqualTo(자유게시판.getCode()),
() -> assertThat(savedPost.getPostImageList()).hasSize(imageFiles.size()),
() -> assertThat(savedPost.getPostImageList())
.extracting(PostImage::getUrl)
@@ -158,8 +175,8 @@ class 게시글_수정_테스트 {
void 게시글을_성공적으로_수정한다() {
// given
String originImageUrl = "origin-image-url";
+ postImageFixture.게시글_이미지(originImageUrl, post);
String expectedImageUrl = "update-image-url";
- Post testPost = createPost(자유게시판, user1, originImageUrl);
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = List.of(createImageFile());
@@ -169,7 +186,7 @@ class 게시글_수정_테스트 {
// when
PostUpdateResponse response = postCommandService.updatePost(
user1,
- testPost.getId(),
+ post.getId(),
request,
imageFiles
);
@@ -177,9 +194,7 @@ class 게시글_수정_테스트 {
// then
Post updatedPost = postRepository.findById(response.id()).orElseThrow();
assertAll(
- () -> assertThat(updatedPost.getTitle()).isEqualTo(request.title()),
- () -> assertThat(updatedPost.getContent()).isEqualTo(request.content()),
- () -> assertThat(updatedPost.getCategory().name()).isEqualTo(request.postCategory()),
+ () -> assertThat(response.id()).isEqualTo(updatedPost.getId()),
() -> assertThat(updatedPost.getPostImageList()).hasSize(imageFiles.size()),
() -> assertThat(updatedPost.getPostImageList())
.extracting(PostImage::getUrl)
@@ -192,7 +207,6 @@ class 게시글_수정_테스트 {
void 다른_사용자의_게시글을_수정하면_예외_응답을_반환한다() {
// given
SiteUser user2 = siteUserFixture.사용자(2, "test2");
- Post testPost = createPost(자유게시판, user1, "origin-image-url");
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = List.of();
@@ -200,7 +214,7 @@ class 게시글_수정_테스트 {
assertThatThrownBy(() ->
postCommandService.updatePost(
user2,
- testPost.getId(),
+ post.getId(),
request,
imageFiles
))
@@ -211,7 +225,6 @@ class 게시글_수정_테스트 {
@Test
void 질문_게시글을_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createQuestionPost(자유게시판, user1, "origin-image-url");
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = List.of();
@@ -219,7 +232,7 @@ class 게시글_수정_테스트 {
assertThatThrownBy(() ->
postCommandService.updatePost(
user1,
- testPost.getId(),
+ questionPost.getId(),
request,
imageFiles
))
@@ -230,7 +243,6 @@ class 게시글_수정_테스트 {
@Test
void 이미지를_5개_초과하여_수정하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, user1, "origin-image-url");
PostUpdateRequest request = createPostUpdateRequest();
List imageFiles = createSixImageFiles();
@@ -238,7 +250,7 @@ class 게시글_수정_테스트 {
assertThatThrownBy(() ->
postCommandService.updatePost(
user1,
- testPost.getId(),
+ post.getId(),
request,
imageFiles
))
@@ -254,20 +266,17 @@ class 게시글_삭제_테스트 {
void 게시글을_성공적으로_삭제한다() {
// given
String originImageUrl = "origin-image-url";
- Post testPost = createPost(자유게시판, user1, originImageUrl);
- String viewCountKey = redisUtils.getPostViewCountRedisKey(testPost.getId());
+ postImageFixture.게시글_이미지(originImageUrl, post);
+ String viewCountKey = redisUtils.getPostViewCountRedisKey(post.getId());
redisService.increaseViewCount(viewCountKey);
// when
- PostDeleteResponse response = postCommandService.deletePostById(
- user1,
- testPost.getId()
- );
+ PostDeleteResponse response = postCommandService.deletePostById(user1, post.getId());
// then
assertAll(
- () -> assertThat(response.id()).isEqualTo(testPost.getId()),
- () -> assertThat(postRepository.findById(testPost.getId())).isEmpty(),
+ () -> assertThat(response.id()).isEqualTo(post.getId()),
+ () -> assertThat(postRepository.findById(post.getId())).isEmpty(),
() -> assertThat(redisService.isKeyExists(viewCountKey)).isFalse()
);
then(s3Service).should().deletePostImage(originImageUrl);
@@ -277,13 +286,12 @@ class 게시글_삭제_테스트 {
void 다른_사용자의_게시글을_삭제하면_예외_응답을_반환한다() {
// given
SiteUser user2 = siteUserFixture.사용자(2, "test2");
- Post testPost = createPost(자유게시판, user1, "origin-image-url");
// when & then
assertThatThrownBy(() ->
postCommandService.deletePostById(
user2,
- testPost.getId()
+ post.getId()
))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_POST_ACCESS.getMessage());
@@ -291,14 +299,11 @@ class 게시글_삭제_테스트 {
@Test
void 질문_게시글을_삭제하면_예외_응답을_반환한다() {
- // given
- Post testPost = createQuestionPost(자유게시판, user1, "origin-image-url");
-
// when & then
assertThatThrownBy(() ->
postCommandService.deletePostById(
user1,
- testPost.getId()
+ questionPost.getId()
))
.isInstanceOf(CustomException.class)
.hasMessage(CAN_NOT_DELETE_OR_UPDATE_QUESTION.getMessage());
@@ -307,7 +312,7 @@ class 게시글_삭제_테스트 {
private PostCreateRequest createPostCreateRequest(String category) {
return new PostCreateRequest(
- 자유게시판.getCode(),
+ boardFixture.자유게시판().getCode(),
category,
"테스트 제목",
"테스트 내용",
@@ -335,40 +340,6 @@ private List createSixImageFiles() {
);
}
- private Post createPost(Board board, SiteUser siteUser, String originImageUrl) {
- Post post = new Post(
- "원본 제목",
- "원본 내용",
- false,
- 0L,
- 0L,
- PostCategory.자유
- );
- post.setBoardAndSiteUser(board, siteUser);
- Post savedPost = postRepository.save(post);
- PostImage postImage = new PostImage(originImageUrl);
- postImage.setPost(savedPost);
- postImageRepository.save(postImage);
- return savedPost;
- }
-
- private Post createQuestionPost(Board board, SiteUser siteUser, String originImageUrl) {
- Post post = new Post(
- "질문 제목",
- "질문 내용",
- true,
- 0L,
- 0L,
- PostCategory.질문
- );
- post.setBoardAndSiteUser(board, siteUser);
- Post savedPost = postRepository.save(post);
- PostImage postImage = new PostImage(originImageUrl);
- postImage.setPost(savedPost);
- postImageRepository.save(postImage);
- return savedPost;
- }
-
private PostUpdateRequest createPostUpdateRequest() {
return new PostUpdateRequest(
PostCategory.자유.name(),
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
index 4205019b7..9e36edeb9 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostLikeServiceTest.java
@@ -1,16 +1,17 @@
package com.example.solidconnection.community.post.service;
import com.example.solidconnection.common.exception.CustomException;
-import com.example.solidconnection.community.board.domain.Board;
+import com.example.solidconnection.community.board.fixture.BoardFixture;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.domain.PostCategory;
import com.example.solidconnection.community.post.dto.PostDislikeResponse;
import com.example.solidconnection.community.post.dto.PostLikeResponse;
+import com.example.solidconnection.community.post.fixture.PostFixture;
import com.example.solidconnection.community.post.repository.PostLikeRepository;
import com.example.solidconnection.community.post.repository.PostRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@@ -23,8 +24,9 @@
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("게시글 좋아요 서비스 테스트")
-class PostLikeServiceTest extends BaseIntegrationTest {
+class PostLikeServiceTest {
@Autowired
private PostLikeService postLikeService;
@@ -38,11 +40,26 @@ class PostLikeServiceTest extends BaseIntegrationTest {
@Autowired
private SiteUserFixture siteUserFixture;
+ @Autowired
+ private BoardFixture boardFixture;
+
+ @Autowired
+ private PostFixture postFixture;
+
private SiteUser user;
+ private Post post;
@BeforeEach
void setUp() {
- user = siteUserFixture.사용자(1, "test1");
+ user = siteUserFixture.사용자();
+ post = postFixture.게시글(
+ "제목1",
+ "내용1",
+ false,
+ PostCategory.자유,
+ boardFixture.자유게시판(),
+ user
+ );
}
@Nested
@@ -51,17 +68,13 @@ class 게시글_좋아요_테스트 {
@Test
void 게시글을_성공적으로_좋아요한다() {
// given
- Post testPost = createPost(자유게시판, user);
- long beforeLikeCount = testPost.getLikeCount();
+ long beforeLikeCount = post.getLikeCount();
// when
- PostLikeResponse response = postLikeService.likePost(
- user,
- testPost.getId()
- );
+ PostLikeResponse response = postLikeService.likePost(user, post.getId());
// then
- Post likedPost = postRepository.findById(testPost.getId()).orElseThrow();
+ Post likedPost = postRepository.findById(post.getId()).orElseThrow();
assertAll(
() -> assertThat(response.likeCount()).isEqualTo(beforeLikeCount + 1),
() -> assertThat(response.isLiked()).isTrue(),
@@ -73,14 +86,13 @@ class 게시글_좋아요_테스트 {
@Test
void 이미_좋아요한_게시글을_다시_좋아요하면_예외_응답을_반환한다() {
// given
- Post testPost = createPost(자유게시판, user);
- postLikeService.likePost(user, testPost.getId());
+ postLikeService.likePost(user, post.getId());
// when & then
assertThatThrownBy(() ->
postLikeService.likePost(
user,
- testPost.getId()
+ post.getId()
))
.isInstanceOf(CustomException.class)
.hasMessage(DUPLICATE_POST_LIKE.getMessage());
@@ -93,18 +105,14 @@ class 게시글_좋아요_취소_테스트 {
@Test
void 게시글_좋아요를_성공적으로_취소한다() {
// given
- Post testPost = createPost(자유게시판, user);
- PostLikeResponse beforeResponse = postLikeService.likePost(user, testPost.getId());
+ PostLikeResponse beforeResponse = postLikeService.likePost(user, post.getId());
long beforeLikeCount = beforeResponse.likeCount();
// when
- PostDislikeResponse response = postLikeService.dislikePost(
- user,
- testPost.getId()
- );
+ PostDislikeResponse response = postLikeService.dislikePost(user, post.getId());
// then
- Post unlikedPost = postRepository.findById(testPost.getId()).orElseThrow();
+ Post unlikedPost = postRepository.findById(post.getId()).orElseThrow();
assertAll(
() -> assertThat(response.likeCount()).isEqualTo(beforeLikeCount - 1),
() -> assertThat(response.isLiked()).isFalse(),
@@ -115,30 +123,14 @@ class 게시글_좋아요_취소_테스트 {
@Test
void 좋아요하지_않은_게시글을_좋아요_취소하면_예외_응답을_반환한다() {
- // given
- Post testPost = createPost(자유게시판, user);
-
// when & then
assertThatThrownBy(() ->
postLikeService.dislikePost(
user,
- testPost.getId()
+ post.getId()
))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_POST_LIKE.getMessage());
}
}
-
- private Post createPost(Board board, SiteUser siteUser) {
- Post post = new Post(
- "테스트 제목",
- "테스트 내용",
- false,
- 0L,
- 0L,
- PostCategory.자유
- );
- post.setBoardAndSiteUser(board, siteUser);
- return postRepository.save(post);
- }
}
diff --git a/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java b/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
index 13a942ef7..dc1e80746 100644
--- a/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java
@@ -1,21 +1,18 @@
package com.example.solidconnection.community.post.service;
-import com.example.solidconnection.community.board.domain.Board;
import com.example.solidconnection.community.board.domain.BoardCode;
+import com.example.solidconnection.community.board.fixture.BoardFixture;
import com.example.solidconnection.community.comment.domain.Comment;
-import com.example.solidconnection.community.comment.dto.PostFindCommentResponse;
-import com.example.solidconnection.community.comment.repository.CommentRepository;
+import com.example.solidconnection.community.comment.fixture.CommentFixture;
import com.example.solidconnection.community.post.domain.Post;
import com.example.solidconnection.community.post.domain.PostCategory;
-import com.example.solidconnection.community.post.domain.PostImage;
-import com.example.solidconnection.community.post.dto.PostFindPostImageResponse;
import com.example.solidconnection.community.post.dto.PostFindResponse;
import com.example.solidconnection.community.post.dto.PostListResponse;
-import com.example.solidconnection.community.post.repository.PostImageRepository;
-import com.example.solidconnection.community.post.repository.PostRepository;
+import com.example.solidconnection.community.post.fixture.PostFixture;
+import com.example.solidconnection.community.post.fixture.PostImageFixture;
import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.siteuser.fixture.SiteUserFixture;
-import com.example.solidconnection.support.integration.BaseIntegrationTest;
+import com.example.solidconnection.support.TestContainerSpringBootTest;
import com.example.solidconnection.util.RedisUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@@ -28,8 +25,9 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertAll;
+@TestContainerSpringBootTest
@DisplayName("게시글 조회 서비스 테스트")
-class PostQueryServiceTest extends BaseIntegrationTest {
+class PostQueryServiceTest {
@Autowired
private PostQueryService postQueryService;
@@ -41,33 +39,61 @@ class PostQueryServiceTest extends BaseIntegrationTest {
private RedisUtils redisUtils;
@Autowired
- private PostRepository postRepository;
+ private SiteUserFixture siteUserFixture;
@Autowired
- private CommentRepository commentRepository;
+ private BoardFixture boardFixture;
@Autowired
- private PostImageRepository postImageRepository;
+ private PostFixture postFixture;
@Autowired
- private SiteUserFixture siteUserFixture;
+ private PostImageFixture postImageFixture;
+
+ @Autowired
+ private CommentFixture commentFixture;
private SiteUser user;
+ private Post post1;
+ private Post post2;
+ private Post post3;
@BeforeEach
void setUp() {
- user = siteUserFixture.사용자(1, "test1");
+ user = siteUserFixture.사용자();
+ post1 = postFixture.게시글(
+ "제목1",
+ "내용1",
+ false,
+ PostCategory.자유,
+ boardFixture.자유게시판(),
+ user
+ );
+ post2 = postFixture.게시글(
+ "제목2",
+ "내용2",
+ false,
+ PostCategory.자유,
+ boardFixture.미주권(),
+ user
+ );
+ post3 = postFixture.게시글(
+ "제목3",
+ "내용3",
+ true,
+ PostCategory.질문,
+ boardFixture.자유게시판(),
+ user
+ );
}
@Test
void 게시판_코드와_카테고리로_게시글_목록을_조회한다() {
// given
- List posts = List.of(
- 미주권_자유게시글, 아시아권_자유게시글, 유럽권_자유게시글, 자유게시판_자유게시글,
- 미주권_질문게시글, 아시아권_질문게시글, 유럽권_질문게시글, 자유게시판_질문게시글
- );
+ List posts = List.of(post1, post2, post3);
List expectedPosts = posts.stream()
- .filter(post -> post.getCategory().equals(PostCategory.자유) && post.getBoard().getCode().equals(BoardCode.FREE.name()))
+ .filter(post -> post.getCategory().equals(PostCategory.자유)
+ && post.getBoard().getCode().equals(BoardCode.FREE.name()))
.toList();
List expectedResponses = PostListResponse.from(expectedPosts);
@@ -87,10 +113,7 @@ void setUp() {
@Test
void 전체_카테고리로_조회시_해당_게시판의_모든_게시글을_조회한다() {
// given
- List posts = List.of(
- 미주권_자유게시글, 아시아권_자유게시글, 유럽권_자유게시글, 자유게시판_자유게시글,
- 미주권_질문게시글, 아시아권_질문게시글, 유럽권_질문게시글, 자유게시판_질문게시글
- );
+ List posts = List.of(post1, post2, post3);
List expectedPosts = posts.stream()
.filter(post -> post.getBoard().getCode().equals(BoardCode.FREE.name()))
.toList();
@@ -114,77 +137,34 @@ void setUp() {
// given
String expectedImageUrl = "test-image-url";
List imageUrls = List.of(expectedImageUrl);
- Post testPost = createPost(자유게시판, user, expectedImageUrl);
- List comments = createComments(testPost, user, List.of("첫번째 댓글", "두번째 댓글"));
+ Post post = postFixture.게시글(
+ "제목",
+ "내용",
+ false,
+ PostCategory.자유,
+ boardFixture.자유게시판(),
+ user
+ );
+ postImageFixture.게시글_이미지(expectedImageUrl, post);
+ Comment comment1 = commentFixture.부모_댓글("댓글1", post, user);
+ Comment comment2 = commentFixture.부모_댓글("댓글2", post, user);
+ List comments = List.of(comment1, comment2);
- String validateKey = redisUtils.getValidatePostViewCountRedisKey(user.getId(), testPost.getId());
- String viewCountKey = redisUtils.getPostViewCountRedisKey(testPost.getId());
+ String validateKey = redisUtils.getValidatePostViewCountRedisKey(user.getId(), post.getId());
+ String viewCountKey = redisUtils.getPostViewCountRedisKey(post.getId());
// when
- PostFindResponse response = postQueryService.findPostById(
- user,
- testPost.getId()
- );
+ PostFindResponse response = postQueryService.findPostById(user, post.getId());
// then
assertAll(
- () -> assertThat(response.id()).isEqualTo(testPost.getId()),
- () -> assertThat(response.title()).isEqualTo(testPost.getTitle()),
- () -> assertThat(response.content()).isEqualTo(testPost.getContent()),
- () -> assertThat(response.isQuestion()).isEqualTo(testPost.getIsQuestion()),
- () -> assertThat(response.likeCount()).isEqualTo(testPost.getLikeCount()),
- () -> assertThat(response.viewCount()).isEqualTo(testPost.getViewCount()),
- () -> assertThat(response.postCategory()).isEqualTo(String.valueOf(testPost.getCategory())),
-
- () -> assertThat(response.postFindBoardResponse().code()).isEqualTo(자유게시판.getCode()),
- () -> assertThat(response.postFindBoardResponse().koreanName()).isEqualTo(자유게시판.getKoreanName()),
-
+ () -> assertThat(response.id()).isEqualTo(post.getId()),
+ () -> assertThat(response.postFindBoardResponse().code()).isEqualTo(boardFixture.자유게시판().getCode()),
() -> assertThat(response.postFindSiteUserResponse().id()).isEqualTo(user.getId()),
- () -> assertThat(response.postFindSiteUserResponse().nickname()).isEqualTo(user.getNickname()),
- () -> assertThat(response.postFindSiteUserResponse().profileImageUrl()).isEqualTo(user.getProfileImageUrl()),
-
- () -> assertThat(response.postFindPostImageResponses())
- .hasSize(imageUrls.size())
- .extracting(PostFindPostImageResponse::url)
- .containsExactlyElementsOf(imageUrls),
-
- () -> assertThat(response.postFindCommentResponses())
- .hasSize(comments.size())
- .extracting(PostFindCommentResponse::content)
- .containsExactlyElementsOf(comments.stream().map(Comment::getContent).toList()),
-
- () -> assertThat(response.isOwner()).isTrue(),
- () -> assertThat(response.isLiked()).isFalse(),
-
+ () -> assertThat(response.postFindPostImageResponses()).hasSize(imageUrls.size()),
+ () -> assertThat(response.postFindCommentResponses()).hasSize(comments.size()),
() -> assertThat(redisService.isKeyExists(viewCountKey)).isTrue(),
() -> assertThat(redisService.isKeyExists(validateKey)).isTrue()
);
}
-
- private Post createPost(Board board, SiteUser siteUser, String originImageUrl) {
- Post post = new Post(
- "원본 제목",
- "원본 내용",
- false,
- 0L,
- 0L,
- PostCategory.자유
- );
- post.setBoardAndSiteUser(board, siteUser);
- Post savedPost = postRepository.save(post);
- PostImage postImage = new PostImage(originImageUrl);
- postImage.setPost(savedPost);
- postImageRepository.save(postImage);
- return savedPost;
- }
-
- private List createComments(Post post, SiteUser siteUser, List contents) {
- return contents.stream()
- .map(content -> {
- Comment comment = new Comment(content);
- comment.setPostAndSiteUser(post, siteUser);
- return commentRepository.save(comment);
- })
- .toList();
- }
}
diff --git a/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java b/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java
deleted file mode 100644
index ae449641f..000000000
--- a/src/test/java/com/example/solidconnection/support/integration/BaseIntegrationTest.java
+++ /dev/null
@@ -1,527 +0,0 @@
-package com.example.solidconnection.support.integration;
-
-import com.example.solidconnection.application.domain.Application;
-import com.example.solidconnection.application.domain.Gpa;
-import com.example.solidconnection.application.domain.LanguageTest;
-import com.example.solidconnection.application.domain.VerifyStatus;
-import com.example.solidconnection.application.repository.ApplicationRepository;
-import com.example.solidconnection.community.board.domain.Board;
-import com.example.solidconnection.community.board.repository.BoardRepository;
-import com.example.solidconnection.community.post.domain.Post;
-import com.example.solidconnection.community.post.domain.PostCategory;
-import com.example.solidconnection.community.post.domain.PostImage;
-import com.example.solidconnection.community.post.repository.PostImageRepository;
-import com.example.solidconnection.community.post.repository.PostRepository;
-import com.example.solidconnection.location.country.domain.Country;
-import com.example.solidconnection.location.country.repository.CountryRepository;
-import com.example.solidconnection.location.region.domain.Region;
-import com.example.solidconnection.location.region.repository.RegionRepository;
-import com.example.solidconnection.score.domain.GpaScore;
-import com.example.solidconnection.score.domain.LanguageTestScore;
-import com.example.solidconnection.score.repository.GpaScoreRepository;
-import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
-import com.example.solidconnection.siteuser.domain.PreparationStatus;
-import com.example.solidconnection.siteuser.domain.Role;
-import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.siteuser.repository.SiteUserRepository;
-import com.example.solidconnection.support.DatabaseClearExtension;
-import com.example.solidconnection.support.TestContainerSpringBootTest;
-import com.example.solidconnection.university.domain.LanguageRequirement;
-import com.example.solidconnection.university.domain.LanguageTestType;
-import com.example.solidconnection.university.domain.University;
-import com.example.solidconnection.university.domain.UniversityInfoForApply;
-import com.example.solidconnection.university.repository.LanguageRequirementRepository;
-import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
-import com.example.solidconnection.university.repository.UniversityRepository;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-
-import java.util.HashSet;
-import java.util.List;
-
-import static com.example.solidconnection.community.board.domain.BoardCode.AMERICAS;
-import static com.example.solidconnection.community.board.domain.BoardCode.ASIA;
-import static com.example.solidconnection.community.board.domain.BoardCode.EUROPE;
-import static com.example.solidconnection.community.board.domain.BoardCode.FREE;
-import static com.example.solidconnection.university.domain.SemesterAvailableForDispatch.ONE_SEMESTER;
-import static com.example.solidconnection.university.domain.TuitionFeeType.HOME_UNIVERSITY_PAYMENT;
-
-@TestContainerSpringBootTest
-@ExtendWith(DatabaseClearExtension.class)
-public abstract class BaseIntegrationTest {
-
- public static SiteUser 테스트유저_1;
- public static SiteUser 테스트유저_2;
- public static SiteUser 테스트유저_3;
- public static SiteUser 테스트유저_4;
- public static SiteUser 테스트유저_5;
- public static SiteUser 테스트유저_6;
- public static SiteUser 테스트유저_7;
- public static SiteUser 이전학기_지원자;
-
- public static Region 영미권;
- public static Region 유럽;
- public static Region 아시아;
- public static Country 미국;
- public static Country 캐나다;
- public static Country 덴마크;
- public static Country 오스트리아;
- public static Country 일본;
-
- public static University 영미권_미국_괌대학;
- public static University 영미권_미국_네바다주립대학_라스베이거스;
- public static University 영미권_캐나다_메모리얼대학_세인트존스;
- public static University 유럽_덴마크_서던덴마크대학교;
- public static University 유럽_덴마크_코펜하겐IT대학;
- public static University 유럽_오스트리아_그라츠대학;
- public static University 유럽_오스트리아_그라츠공과대학;
- public static University 유럽_오스트리아_린츠_카톨릭대학;
- public static University 아시아_일본_메이지대학;
-
- public static UniversityInfoForApply 괌대학_A_지원_정보;
- public static UniversityInfoForApply 괌대학_B_지원_정보;
- public static UniversityInfoForApply 네바다주립대학_라스베이거스_지원_정보;
- public static UniversityInfoForApply 메모리얼대학_세인트존스_A_지원_정보;
- public static UniversityInfoForApply 서던덴마크대학교_지원_정보;
- public static UniversityInfoForApply 코펜하겐IT대학_지원_정보;
- public static UniversityInfoForApply 그라츠대학_지원_정보;
- public static UniversityInfoForApply 그라츠공과대학_지원_정보;
- public static UniversityInfoForApply 린츠_카톨릭대학_지원_정보;
- public static UniversityInfoForApply 메이지대학_지원_정보;
-
- public static Application 테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서;
- public static Application 테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서;
- public static Application 테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서;
- public static Application 테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서;
- public static Application 테스트유저_6_X_X_X_지원서;
- public static Application 테스트유저_7_코펜하겐IT대학_X_X_지원서;
- public static Application 이전학기_지원서;
-
- public static Board 미주권;
- public static Board 아시아권;
- public static Board 유럽권;
- public static Board 자유게시판;
-
- public static Post 미주권_자유게시글;
- public static Post 아시아권_자유게시글;
- public static Post 유럽권_자유게시글;
- public static Post 자유게시판_자유게시글;
- public static Post 미주권_질문게시글;
- public static Post 아시아권_질문게시글;
- public static Post 유럽권_질문게시글;
- public static Post 자유게시판_질문게시글;
-
- @Autowired
- private SiteUserRepository siteUserRepository;
-
- @Autowired
- private RegionRepository regionRepository;
-
- @Autowired
- private CountryRepository countryRepository;
-
- @Autowired
- private UniversityRepository universityRepository;
-
- @Autowired
- private UniversityInfoForApplyRepository universityInfoForApplyRepository;
-
- @Autowired
- private LanguageRequirementRepository languageRequirementRepository;
-
- @Autowired
- private ApplicationRepository applicationRepository;
-
- @Autowired
- private GpaScoreRepository gpaScoreRepository;
-
- @Autowired
- private LanguageTestScoreRepository languageTestScoreRepository;
-
- @Autowired
- private BoardRepository boardRepository;
-
- @Autowired
- private PostRepository postRepository;
-
- @Autowired
- private PostImageRepository postImageRepository;
-
- @Value("${university.term}")
- public String term;
-
- @BeforeEach
- public void setUpBaseData() {
- setUpSiteUsers();
- setUpRegions();
- setUpCountries();
- setUpUniversities();
- setUpUniversityInfos();
- setUpLanguageRequirements();
- setUpApplications();
- setUpBoards();
- setUpPosts();
- }
-
- private void setUpSiteUsers() {
- 테스트유저_1 = siteUserRepository.save(new SiteUser(
- "test1@example.com",
- "nickname1",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 테스트유저_2 = siteUserRepository.save(new SiteUser(
- "test2@example.com",
- "nickname2",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 테스트유저_3 = siteUserRepository.save(new SiteUser(
- "test3@example.com",
- "nickname3",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 테스트유저_4 = siteUserRepository.save(new SiteUser(
- "test4@example.com",
- "nickname4",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 테스트유저_5 = siteUserRepository.save(new SiteUser(
- "test5@example.com",
- "nickname5",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 테스트유저_6 = siteUserRepository.save(new SiteUser(
- "test6@example.com",
- "nickname6",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 테스트유저_7 = siteUserRepository.save(new SiteUser(
- "test7@example.com",
- "nickname7",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
-
- 이전학기_지원자 = siteUserRepository.save(new SiteUser(
- "old@example.com",
- "oldNickname",
- "profileImageUrl",
- PreparationStatus.CONSIDERING,
- Role.MENTEE));
- }
-
- private void setUpRegions() {
- 영미권 = regionRepository.save(new Region("AMERICAS", "영미권"));
- 유럽 = regionRepository.save(new Region("EUROPE", "유럽"));
- 아시아 = regionRepository.save(new Region("ASIA", "아시아"));
- }
-
- private void setUpCountries() {
- 미국 = countryRepository.save(new Country("US", "미국", 영미권));
- 캐나다 = countryRepository.save(new Country("CA", "캐나다", 영미권));
- 덴마크 = countryRepository.save(new Country("DK", "덴마크", 유럽));
- 오스트리아 = countryRepository.save(new Country("AT", "오스트리아", 유럽));
- 일본 = countryRepository.save(new Country("JP", "일본", 아시아));
- }
-
- private void setUpUniversities() {
- 영미권_미국_괌대학 = universityRepository.save(new University(
- null, "괌대학", "University of Guam", "university_of_guam",
- "https://www.uog.edu/admissions/international-students",
- "https://www.uog.edu/admissions/course-schedule",
- "https://www.uog.edu/life-at-uog/residence-halls/",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_guam/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_guam/1.png",
- null, 미국, 영미권
- ));
-
- 영미권_미국_네바다주립대학_라스베이거스 = universityRepository.save(new University(
- null, "네바다주립대학 라스베이거스", "University of Nevada, Las Vegas", "university_of_nevada_las_vegas",
- "https://www.unlv.edu/engineering/eip",
- "https://www.unlv.edu/engineering/academic-programs",
- "https://www.unlv.edu/housing",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_nevada_las_vegas/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_nevada_las_vegas/1.png",
- null, 미국, 영미권
- ));
-
- 영미권_캐나다_메모리얼대학_세인트존스 = universityRepository.save(new University(
- null, "메모리얼 대학 세인트존스", "Memorial University of Newfoundland St. John's", "memorial_university_of_newfoundland_st_johns",
- "https://mun.ca/goabroad/visiting-students-inbound/",
- "https://www.unlv.edu/engineering/academic-programs",
- "https://www.mun.ca/residences/",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/memorial_university_of_newfoundland_st_johns/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/memorial_university_of_newfoundland_st_johns/1.png",
- null, 캐나다, 영미권
- ));
-
- 유럽_덴마크_서던덴마크대학교 = universityRepository.save(new University(
- null, "서던덴마크대학교", "University of Southern Denmark", "university_of_southern_denmark",
- "https://www.sdu.dk/en",
- "https://www.sdu.dk/en",
- "https://www.sdu.dk/en/uddannelse/information_for_international_students/studenthousing",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_southern_denmark/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_southern_denmark/1.png",
- null, 덴마크, 유럽
- ));
-
- 유럽_덴마크_코펜하겐IT대학 = universityRepository.save(new University(
- null, "코펜하겐 IT대학", "IT University of Copenhagen", "it_university_of_copenhagen",
- "https://en.itu.dk/", null,
- "https://en.itu.dk/Programmes/Student-Life/Practical-information-for-international-students",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/it_university_of_copenhagen/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/it_university_of_copenhagen/1.png",
- null, 덴마크, 유럽
- ));
-
- 유럽_오스트리아_그라츠대학 = universityRepository.save(new University(
- null, "그라츠 대학", "University of Graz", "university_of_graz",
- "https://www.uni-graz.at/en/",
- "https://static.uni-graz.at/fileadmin/veranstaltungen/orientation/documents/incstud_application-courses.pdf",
- "https://orientation.uni-graz.at/de/planning-the-arrival/accommodation/",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_graz/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/university_of_graz/1.png",
- null, 오스트리아, 유럽
- ));
-
- 유럽_오스트리아_그라츠공과대학 = universityRepository.save(new University(
- null, "그라츠공과대학", "Graz University of Technology", "graz_university_of_technology",
- "https://www.tugraz.at/en/home", null,
- "https://www.tugraz.at/en/studying-and-teaching/studying-internationally/incoming-students-exchange-at-tu-graz/your-stay-at-tu-graz/preparation#c75033",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/graz_university_of_technology/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/graz_university_of_technology/1.png",
- null, 오스트리아, 유럽
- ));
-
- 유럽_오스트리아_린츠_카톨릭대학 = universityRepository.save(new University(
- null, "린츠 카톨릭 대학교", "Catholic Private University Linz", "catholic_private_university_linz",
- "https://ku-linz.at/en", null,
- "https://ku-linz.at/en/ku_international/incomings/kulis",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/catholic_private_university_linz/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/catholic_private_university_linz/1.png",
- null, 오스트리아, 유럽
- ));
-
- 아시아_일본_메이지대학 = universityRepository.save(new University(
- null, "메이지대학", "Meiji University", "meiji_university",
- "https://www.meiji.ac.jp/cip/english/admissions/co7mm90000000461-att/co7mm900000004fa.pdf", null,
- "https://www.meiji.ac.jp/cip/english/admissions/co7mm90000000461-att/co7mm900000004fa.pdf",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/meiji_university/logo.png",
- "https://solid-connection.s3.ap-northeast-2.amazonaws.com/original/meiji_university/1.png",
- null, 일본, 아시아
- ));
- }
-
- private void setUpUniversityInfos() {
- 괌대학_A_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "괌대학(A형)", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 영미권_미국_괌대학
- ));
-
- 괌대학_B_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "괌대학(B형)", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 영미권_미국_괌대학
- ));
-
- 네바다주립대학_라스베이거스_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "네바다주립대학 라스베이거스(B형)", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 영미권_미국_네바다주립대학_라스베이거스
- ));
-
- 메모리얼대학_세인트존스_A_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "메모리얼 대학 세인트존스(A형)", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 영미권_캐나다_메모리얼대학_세인트존스
- ));
-
- 서던덴마크대학교_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "서던덴마크대학교", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 유럽_덴마크_서던덴마크대학교
- ));
-
- 코펜하겐IT대학_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "코펜하겐 IT대학", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 유럽_덴마크_코펜하겐IT대학
- ));
-
- 그라츠대학_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "그라츠 대학", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 유럽_오스트리아_그라츠대학
- ));
-
- 그라츠공과대학_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "그라츠공과대학", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 유럽_오스트리아_그라츠공과대학
- ));
-
- 린츠_카톨릭대학_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "린츠 카톨릭 대학교", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 유럽_오스트리아_린츠_카톨릭대학
- ));
-
- 메이지대학_지원_정보 = universityInfoForApplyRepository.save(new UniversityInfoForApply(
- null, term, "메이지대학", 1, HOME_UNIVERSITY_PAYMENT, ONE_SEMESTER,
- "1", "detailsForLanguage", "gpaRequirement",
- "gpaRequirementCriteria", "detailsForApply", "detailsForMajor",
- "detailsForAccommodation", "detailsForEnglishCourse", "details",
- new HashSet<>(), 아시아_일본_메이지대학
- ));
- }
-
- private void setUpLanguageRequirements() {
- saveLanguageTestRequirement(괌대학_A_지원_정보, LanguageTestType.TOEFL_IBT, "80");
- saveLanguageTestRequirement(괌대학_A_지원_정보, LanguageTestType.TOEIC, "800");
- saveLanguageTestRequirement(괌대학_B_지원_정보, LanguageTestType.TOEFL_IBT, "70");
- saveLanguageTestRequirement(괌대학_B_지원_정보, LanguageTestType.TOEIC, "900");
- saveLanguageTestRequirement(네바다주립대학_라스베이거스_지원_정보, LanguageTestType.TOEIC, "800");
- saveLanguageTestRequirement(메모리얼대학_세인트존스_A_지원_정보, LanguageTestType.TOEIC, "800");
- saveLanguageTestRequirement(서던덴마크대학교_지원_정보, LanguageTestType.TOEFL_IBT, "70");
- saveLanguageTestRequirement(코펜하겐IT대학_지원_정보, LanguageTestType.TOEFL_IBT, "80");
- saveLanguageTestRequirement(그라츠대학_지원_정보, LanguageTestType.TOEFL_IBT, "80");
- saveLanguageTestRequirement(그라츠공과대학_지원_정보, LanguageTestType.TOEIC, "800");
- saveLanguageTestRequirement(린츠_카톨릭대학_지원_정보, LanguageTestType.TOEIC, "800");
- saveLanguageTestRequirement(메이지대학_지원_정보, LanguageTestType.JLPT, "N2");
- }
-
- private void setUpApplications() {
- 테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서 = new Application(테스트유저_2, createApprovedGpaScore(테스트유저_2).getGpa(), createApprovedLanguageTestScore(테스트유저_2).getLanguageTest(),
- term, 괌대학_B_지원_정보, 괌대학_A_지원_정보, 린츠_카톨릭대학_지원_정보, "user2_nickname");
-
- 테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서 = new Application(테스트유저_3, createApprovedGpaScore(테스트유저_3).getGpa(), createApprovedLanguageTestScore(테스트유저_3).getLanguageTest(),
- term, 괌대학_A_지원_정보, 괌대학_B_지원_정보, 그라츠공과대학_지원_정보, "user3_nickname");
-
- 테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서 = new Application(테스트유저_4, createApprovedGpaScore(테스트유저_4).getGpa(), createApprovedLanguageTestScore(테스트유저_4).getLanguageTest(),
- term, 메이지대학_지원_정보, 그라츠대학_지원_정보, 서던덴마크대학교_지원_정보, "user4_nickname");
-
- 테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서 = new Application(테스트유저_5, createApprovedGpaScore(테스트유저_5).getGpa(), createApprovedLanguageTestScore(테스트유저_5).getLanguageTest(),
- term, 네바다주립대학_라스베이거스_지원_정보, 그라츠공과대학_지원_정보, 메이지대학_지원_정보, "user5_nickname");
-
- 테스트유저_6_X_X_X_지원서 = new Application(테스트유저_6, createApprovedGpaScore(테스트유저_6).getGpa(), createApprovedLanguageTestScore(테스트유저_6).getLanguageTest(),
- term, null, null, null, "user6_nickname");
-
- 테스트유저_7_코펜하겐IT대학_X_X_지원서 = new Application(테스트유저_7, createApprovedGpaScore(테스트유저_7).getGpa(), createApprovedLanguageTestScore(테스트유저_7).getLanguageTest(),
- term, 코펜하겐IT대학_지원_정보, null, null, "user7_nickname");
-
- 이전학기_지원서 = new Application(이전학기_지원자, createApprovedGpaScore(이전학기_지원자).getGpa(), createApprovedLanguageTestScore(이전학기_지원자).getLanguageTest(),
- "1988-1", 네바다주립대학_라스베이거스_지원_정보, 그라츠공과대학_지원_정보, 메이지대학_지원_정보, "old_nickname");
-
- 테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서.setVerifyStatus(VerifyStatus.APPROVED);
- 테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서.setVerifyStatus(VerifyStatus.APPROVED);
- 테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서.setVerifyStatus(VerifyStatus.APPROVED);
- 테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서.setVerifyStatus(VerifyStatus.APPROVED);
- 테스트유저_6_X_X_X_지원서.setVerifyStatus(VerifyStatus.APPROVED);
- 테스트유저_7_코펜하겐IT대학_X_X_지원서.setVerifyStatus(VerifyStatus.APPROVED);
- 이전학기_지원서.setVerifyStatus(VerifyStatus.APPROVED);
-
- applicationRepository.saveAll(List.of(
- 테스트유저_2_괌대학_B_괌대학_A_린츠_카톨릭대학_지원서, 테스트유저_3_괌대학_A_괌대학_B_그라츠공과대학_지원서, 테스트유저_4_메이지대학_그라츠대학_서던덴마크대학_지원서, 테스트유저_5_네바다주립대학_그라츠공과대학_메이지대학_지원서,
- 테스트유저_6_X_X_X_지원서, 테스트유저_7_코펜하겐IT대학_X_X_지원서, 이전학기_지원서));
- }
-
- private void setUpBoards() {
- 미주권 = boardRepository.save(new Board(AMERICAS.name(), "미주권"));
- 아시아권 = boardRepository.save(new Board(ASIA.name(), "아시아권"));
- 유럽권 = boardRepository.save(new Board(EUROPE.name(), "유럽권"));
- 자유게시판 = boardRepository.save(new Board(FREE.name(), "자유게시판"));
- }
-
- private void setUpPosts() {
- 미주권_자유게시글 = createPost(미주권, 테스트유저_1, "미주권 자유게시글", "미주권 자유게시글 내용", PostCategory.자유);
- 아시아권_자유게시글 = createPost(아시아권, 테스트유저_2, "아시아권 자유게시글", "아시아권 자유게시글 내용", PostCategory.자유);
- 유럽권_자유게시글 = createPost(유럽권, 테스트유저_1, "유럽권 자유게시글", "유럽권 자유게시글 내용", PostCategory.자유);
- 자유게시판_자유게시글 = createPost(자유게시판, 테스트유저_2, "자유게시판 자유게시글", "자유게시판 자유게시글 내용", PostCategory.자유);
- 미주권_질문게시글 = createPost(미주권, 테스트유저_1, "미주권 질문게시글", "미주권 질문게시글 내용", PostCategory.질문);
- 아시아권_질문게시글 = createPost(아시아권, 테스트유저_2, "아시아권 질문게시글", "아시아권 질문게시글 내용", PostCategory.질문);
- 유럽권_질문게시글 = createPost(유럽권, 테스트유저_1, "유럽권 질문게시글", "유럽권 질문게시글 내용", PostCategory.질문);
- 자유게시판_질문게시글 = createPost(자유게시판, 테스트유저_2, "자유게시판 질문게시글", "자유게시판 질문게시글 내용", PostCategory.질문);
- }
-
- private void saveLanguageTestRequirement(
- UniversityInfoForApply universityInfoForApply,
- LanguageTestType testType,
- String minScore
- ) {
- LanguageRequirement languageRequirement = new LanguageRequirement(
- null,
- testType,
- minScore,
- universityInfoForApply);
- universityInfoForApply.addLanguageRequirements(languageRequirement);
- universityInfoForApplyRepository.save(universityInfoForApply);
- languageRequirementRepository.save(languageRequirement);
- }
-
- private GpaScore createApprovedGpaScore(SiteUser siteUser) {
- GpaScore gpaScore = new GpaScore(
- new Gpa(4.0, 4.5, "/gpa-report.pdf"),
- siteUser
- );
- gpaScore.setVerifyStatus(VerifyStatus.APPROVED);
- return gpaScoreRepository.save(gpaScore);
- }
-
- private LanguageTestScore createApprovedLanguageTestScore(SiteUser siteUser) {
- LanguageTestScore languageTestScore = new LanguageTestScore(
- new LanguageTest(LanguageTestType.TOEIC, "100", "/gpa-report.pdf"),
- siteUser
- );
- languageTestScore.setVerifyStatus(VerifyStatus.APPROVED);
- return languageTestScoreRepository.save(languageTestScore);
- }
-
- private Post createPost(Board board, SiteUser siteUser, String title, String content, PostCategory category) {
- Post post = new Post(
- title,
- content,
- false,
- 0L,
- 0L,
- category
- );
- post.setBoardAndSiteUser(board, siteUser);
- Post savedPost = postRepository.save(post);
- PostImage postImage = new PostImage("imageUrl");
- postImage.setPost(savedPost);
- postImageRepository.save(postImage);
- return savedPost;
- }
-}
From a14a510693f70cfe3bb13f301609925d3ee4c95f Mon Sep 17 00:00:00 2001
From: Yeon <84384499+lsy1307@users.noreply.github.com>
Date: Tue, 24 Jun 2025 16:40:26 +0900
Subject: [PATCH 22/90] =?UTF-8?q?refactor:=20application=20=EB=8F=84?=
=?UTF-8?q?=EB=A9=94=EC=9D=B8=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81=20(#3?=
=?UTF-8?q?30)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: Application Entity 변경
- UniversityInfoForApply FK매핑 삭제 및 Long타입으로 변경, 네이밍 변경
- 사용하지 않는 updateUniversityChoice 메서드 제거
* refactor: ApplicationQueryService 변경
- AS-IS: 각 지망별로 Repository를 호출하여 N+1 문제 발생
단일키 임시 캐싱
- TO-BE: 매핑 제거 후 직접 데이터를 분류하여 N+1문제 제거 및 성능 향상
캐싱 제거
* refactor: University관련 Repository 변경
- AS-IS: 기존 Repository에서 University타입으로 반환
- TO-BE: Entity변경, 비즈니스 로직 변환에 맞춰 반환타입 Long으로 수정
findByIdsWithUniversityAndLocation 메서드 추가
사용하지 않게 된 getUniversityInfoForApplyByIdAndTerm 메서드 삭제
* refactor: ApplicationRepository 변경
- 서비스 로직 변경을 위해 3개로 분리되어 있는 기존 메서드를 한 번의 쿼리로 조회하도록 변경
* refactor: ApplicationSubmissionService 변경
- Entity변경에 따른 수정. 기존 로직은 변화 없음
* refactor: ApplicationTest코드 수정
- Entity변경에 따른 수정
- 전원 통과
- ApplicationQueryService 마지막 메서드 테스트 의도에 맞게 수정
* refactor: ApplicationTest코드 수정
- UniversityInfoForApplyId 하드코딩 되어있는 부분 수정
- 테스트 통과 확인
* refactor: 테스트 코드 제외 코드 리뷰 수정사항 반영
- 코드 컨벤션 통일
- 변수명 이해하기 쉽도록 수정
- Application Repository universityId기반과 uiaId기반으로 분기
* refactor: ApplicationTest코드 수정
- 마지막 메서드 테스트 의도에 맞게 수정
- 컨벤션에 맞게 수정
- BaseIntegrationTest에서 firstUIAId에 null값을 입력하는 부분 수정
* refactor: Application Entity Index 추가
- 조회 성능 향상을 위해 Application Entity Index추가
- Application Repository 불필요한 공백 삭제
* refactor: Flyway V13 script 등록
- Application FK제약조건 제거
- column명 변경
- Index 추가
* refactor: 테스트 코드 제외 코드 리뷰 수정사항 반영
- 가벼운 수정 사항(공백 삭제 및 함수 명 변경)
- Application Column명 수정
- 쿼리 간결화
- DTO에 매핑책임 이관
* refactor: 테스트 코드 수정 및 Flyway 수정
- 테스트 코드 데이터 형식 수정
- Flyway Column명 수정
* refactor: Flyway V13 FK제약조건 유지로 변경
---
.../application/domain/Application.java | 73 ++++-----
.../dto/UniversityApplicantsResponse.java | 13 +-
.../repository/ApplicationRepository.java | 31 ++--
.../service/ApplicationQueryService.java | 153 +++++++++---------
.../service/ApplicationSubmissionService.java | 34 ++--
.../UniversityInfoForApplyRepository.java | 35 +++-
.../custom/UniversityFilterRepository.java | 2 +-
.../UniversityFilterRepositoryImpl.java | 22 ++-
..._index_and_delete_manny_to_one_mapping.sql | 15 ++
.../fixture/ApplicationFixture.java | 12 +-
.../fixture/ApplicationFixtureBuilder.java | 24 +--
.../service/ApplicationQueryServiceTest.java | 89 +++++-----
.../ApplicationSubmissionServiceTest.java | 18 ++-
13 files changed, 283 insertions(+), 238 deletions(-)
create mode 100644 src/main/resources/db/migration/V13_add_application_index_and_delete_manny_to_one_mapping.sql
diff --git a/src/main/java/com/example/solidconnection/application/domain/Application.java b/src/main/java/com/example/solidconnection/application/domain/Application.java
index 98342ca88..5f982410e 100644
--- a/src/main/java/com/example/solidconnection/application/domain/Application.java
+++ b/src/main/java/com/example/solidconnection/application/domain/Application.java
@@ -1,7 +1,6 @@
package com.example.solidconnection.application.domain;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.university.domain.UniversityInfoForApply;
import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
@@ -11,7 +10,9 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
+import jakarta.persistence.Index;
import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@@ -25,6 +26,16 @@
@DynamicUpdate
@DynamicInsert
@Entity
+@Table(indexes = {
+ @Index(name = "idx_app_user_term_delete",
+ columnList = "site_user_id, term, is_delete"),
+ @Index(name = "idx_app_first_choice_search",
+ columnList = "verify_status, term, is_delete, first_choice_university_info_for_apply_id"),
+ @Index(name = "idx_app_second_choice_search",
+ columnList = "verify_status, term, is_delete, second_choice_university_info_for_apply_id"),
+ @Index(name = "idx_app_third_choice_search",
+ columnList = "verify_status, term, is_delete, third_choice_university_info_for_apply_id")
+})
public class Application {
@Id
@@ -38,30 +49,30 @@ public class Application {
private LanguageTest languageTest;
@Setter
- @Column(columnDefinition = "varchar(50) not null default 'PENDING'")
+ @Column(columnDefinition = "varchar(50) not null default 'PENDING'", name="verify_status")
@Enumerated(EnumType.STRING)
private VerifyStatus verifyStatus;
- @Column(length = 100)
+ @Column(length = 100, name="nickname_for_apply")
private String nicknameForApply;
- @Column(columnDefinition = "int not null default 1")
+ @Column(columnDefinition = "int not null default 1", name="update_count")
private Integer updateCount;
- @Column(length = 50, nullable = false)
+ @Column(length = 50, nullable = false, name="term")
private String term;
- @Column
+ @Column(name="is_delete")
private boolean isDelete = false;
- @ManyToOne(fetch = FetchType.LAZY)
- private UniversityInfoForApply firstChoiceUniversity;
+ @Column(nullable = false , name = "first_choice_university_info_for_apply_id")
+ private long firstChoiceUnivApplyInfoId;
- @ManyToOne(fetch = FetchType.LAZY)
- private UniversityInfoForApply secondChoiceUniversity;
+ @Column(name = "second_choice_university_info_for_apply_id")
+ private Long secondChoiceUnivApplyInfoId;
- @ManyToOne(fetch = FetchType.LAZY)
- private UniversityInfoForApply thirdChoiceUniversity;
+ @Column(name = "third_choice_university_info_for_apply_id")
+ private Long thirdChoiceUnivApplyInfoId;
@ManyToOne(fetch = FetchType.LAZY)
private SiteUser siteUser;
@@ -85,18 +96,18 @@ public Application(
LanguageTest languageTest,
String term,
Integer updateCount,
- UniversityInfoForApply firstChoiceUniversity,
- UniversityInfoForApply secondChoiceUniversity,
- UniversityInfoForApply thirdChoiceUniversity,
+ long firstChoiceUnivApplyInfoId,
+ Long secondChoiceUnivApplyInfoId,
+ Long thirdChoiceUnivApplyInfoId,
String nicknameForApply) {
this.siteUser = siteUser;
this.gpa = gpa;
this.languageTest = languageTest;
this.term = term;
this.updateCount = updateCount;
- this.firstChoiceUniversity = firstChoiceUniversity;
- this.secondChoiceUniversity = secondChoiceUniversity;
- this.thirdChoiceUniversity = thirdChoiceUniversity;
+ this.firstChoiceUnivApplyInfoId = firstChoiceUnivApplyInfoId;
+ this.secondChoiceUnivApplyInfoId = secondChoiceUnivApplyInfoId;
+ this.thirdChoiceUnivApplyInfoId = thirdChoiceUnivApplyInfoId;
this.nicknameForApply = nicknameForApply;
this.verifyStatus = PENDING;
}
@@ -106,18 +117,18 @@ public Application(
Gpa gpa,
LanguageTest languageTest,
String term,
- UniversityInfoForApply firstChoiceUniversity,
- UniversityInfoForApply secondChoiceUniversity,
- UniversityInfoForApply thirdChoiceUniversity,
+ long firstChoiceUnivApplyInfoId,
+ Long secondChoiceUnivApplyInfoId,
+ Long thirdChoiceUnivApplyInfoId,
String nicknameForApply) {
this.siteUser = siteUser;
this.gpa = gpa;
this.languageTest = languageTest;
this.term = term;
this.updateCount = 1;
- this.firstChoiceUniversity = firstChoiceUniversity;
- this.secondChoiceUniversity = secondChoiceUniversity;
- this.thirdChoiceUniversity = thirdChoiceUniversity;
+ this.firstChoiceUnivApplyInfoId = firstChoiceUnivApplyInfoId;
+ this.secondChoiceUnivApplyInfoId = secondChoiceUnivApplyInfoId;
+ this.thirdChoiceUnivApplyInfoId = thirdChoiceUnivApplyInfoId;
this.nicknameForApply = nicknameForApply;
this.verifyStatus = PENDING;
}
@@ -125,18 +136,4 @@ public Application(
public void setIsDeleteTrue() {
this.isDelete = true;
}
-
- public void updateUniversityChoice(
- UniversityInfoForApply firstChoiceUniversity,
- UniversityInfoForApply secondChoiceUniversity,
- UniversityInfoForApply thirdChoiceUniversity,
- String nicknameForApply) {
- if (this.firstChoiceUniversity != null) {
- this.updateCount++;
- }
- this.firstChoiceUniversity = firstChoiceUniversity;
- this.secondChoiceUniversity = secondChoiceUniversity;
- this.thirdChoiceUniversity = thirdChoiceUniversity;
- this.nicknameForApply = nicknameForApply;
- }
}
diff --git a/src/main/java/com/example/solidconnection/application/dto/UniversityApplicantsResponse.java b/src/main/java/com/example/solidconnection/application/dto/UniversityApplicantsResponse.java
index 1d3415003..2e43ab851 100644
--- a/src/main/java/com/example/solidconnection/application/dto/UniversityApplicantsResponse.java
+++ b/src/main/java/com/example/solidconnection/application/dto/UniversityApplicantsResponse.java
@@ -1,5 +1,7 @@
package com.example.solidconnection.application.dto;
+import com.example.solidconnection.application.domain.Application;
+import com.example.solidconnection.siteuser.domain.SiteUser;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import java.util.List;
@@ -10,13 +12,18 @@ public record UniversityApplicantsResponse(
String region,
String country,
List applicants) {
-
- public static UniversityApplicantsResponse of(UniversityInfoForApply universityInfoForApply, List applicant) {
+ public static UniversityApplicantsResponse of(UniversityInfoForApply universityInfoForApply, List applications, SiteUser siteUser) {
return new UniversityApplicantsResponse(
universityInfoForApply.getKoreanName(),
universityInfoForApply.getStudentCapacity(),
universityInfoForApply.getUniversity().getRegion().getKoreanName(),
universityInfoForApply.getUniversity().getCountry().getKoreanName(),
- applicant);
+ applications.stream()
+ .map(application -> ApplicantResponse.of(application, isUsers(application, siteUser)))
+ .toList());
+ }
+
+ private static boolean isUsers(Application application, SiteUser siteUser) {
+ return application.getSiteUser().getId().equals(siteUser.getId());
}
}
diff --git a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java
index 7df53eae6..badbc8254 100644
--- a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java
+++ b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java
@@ -20,21 +20,26 @@ public interface ApplicationRepository extends JpaRepository
boolean existsByNicknameForApply(String nicknameForApply);
- List findAllByFirstChoiceUniversityAndVerifyStatusAndTermAndIsDeleteFalse(
- UniversityInfoForApply firstChoiceUniversity, VerifyStatus verifyStatus, String term);
-
- List findAllBySecondChoiceUniversityAndVerifyStatusAndTermAndIsDeleteFalse(
- UniversityInfoForApply secondChoiceUniversity, VerifyStatus verifyStatus, String term);
-
- List findAllByThirdChoiceUniversityAndVerifyStatusAndTermAndIsDeleteFalse(
- UniversityInfoForApply thirdChoiceUniversity, VerifyStatus verifyStatus, String term);
+ @Query("""
+ SELECT a
+ FROM Application a
+ JOIN FETCH a.siteUser
+ WHERE (a.firstChoiceUnivApplyInfoId IN :universityIds
+ OR a.secondChoiceUnivApplyInfoId IN :universityIds
+ OR a.thirdChoiceUnivApplyInfoId IN :universityIds)
+ AND a.verifyStatus = :status
+ AND a.term = :term
+ AND a.isDelete = false
+ """)
+ List findAllByUnivApplyInfoIds(@Param("universityIds") List universityIds, @Param("status") VerifyStatus status, @Param("term") String term);
@Query("""
- SELECT a FROM Application a
- WHERE a.siteUser = :siteUser
- AND a.term = :term
- AND a.isDelete = false
- """)
+ SELECT a
+ FROM Application a
+ WHERE a.siteUser = :siteUser
+ AND a.term = :term
+ AND a.isDelete = false
+ """)
Optional findBySiteUserAndTerm(@Param("siteUser") SiteUser siteUser, @Param("term") String term);
default Application getApplicationBySiteUserAndTerm(SiteUser siteUser, String term) {
diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java
index e13ca7e3f..8e06ad79f 100644
--- a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java
+++ b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java
@@ -6,10 +6,8 @@
import com.example.solidconnection.application.dto.ApplicationsResponse;
import com.example.solidconnection.application.dto.UniversityApplicantsResponse;
import com.example.solidconnection.application.repository.ApplicationRepository;
-import com.example.solidconnection.cache.annotation.ThunderingHerdCaching;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
import com.example.solidconnection.university.repository.custom.UniversityFilterRepositoryImpl;
@@ -18,12 +16,14 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.List;
+import java.util.Objects;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.ArrayList;
import static com.example.solidconnection.common.exception.ErrorCode.APPLICATION_NOT_APPROVED;
@@ -38,97 +38,92 @@ public class ApplicationQueryService {
@Value("${university.term}")
public String term;
- /*
- * 다른 지원자들의 성적을 조회한다.
- * - 유저가 다른 지원자들을 볼 수 있는지 검증한다.
- * - 지역과 키워드를 통해 대학을 필터링한다.
- * - 지역은 영어 대문자로 받는다 e.g. ASIA
- * - 1지망, 2지망 지원자들을 조회한다.
- * */
+ // todo: 캐싱 정책 변경 시 수정 필요
@Transactional(readOnly = true)
- // todo: 임시로 단일 키로 캐시 적용. 추후 캐싱 전략 재검토 필요.
- @ThunderingHerdCaching(key = "applications:all", cacheManager = "customCacheManager", ttlSec = 86400)
public ApplicationsResponse getApplicants(SiteUser siteUser, String regionCode, String keyword) {
- // 국가와 키워드와 지역을 통해 대학을 필터링한다.
- List universities
- = universityFilterRepository.findByRegionCodeAndKeywords(regionCode, List.of(keyword));
-
- // 1지망, 2지망, 3지망 지원자들을 조회한다.
- List firstChoiceApplicants = getFirstChoiceApplicants(universities, siteUser, term);
- List secondChoiceApplicants = getSecondChoiceApplicants(universities, siteUser, term);
- List thirdChoiceApplicants = getThirdChoiceApplicants(universities, siteUser, term);
- return new ApplicationsResponse(firstChoiceApplicants, secondChoiceApplicants, thirdChoiceApplicants);
+ // 1. 대학 지원 정보 필터링 (regionCode, keyword)
+ List univApplyInfos = universityFilterRepository.findByRegionCodeAndKeywords(regionCode, List.of(keyword));
+ if (univApplyInfos.isEmpty()) {
+ return new ApplicationsResponse(List.of(), List.of(), List.of());
+ }
+ // 2. 조건에 맞는 모든 Application 한 번에 조회
+ List univApplyInfoIds = univApplyInfos.stream()
+ .map(UniversityInfoForApply::getId)
+ .toList();
+ List applications = applicationRepository.findAllByUnivApplyInfoIds(univApplyInfoIds, VerifyStatus.APPROVED, term);
+ // 3. 지원서 분류 및 DTO 변환
+ return classifyApplicationsByChoice(univApplyInfos, applications, siteUser);
}
@Transactional(readOnly = true)
public ApplicationsResponse getApplicantsByUserApplications(SiteUser siteUser) {
Application userLatestApplication = applicationRepository.getApplicationBySiteUserAndTerm(siteUser, term);
- List userAppliedUniversities = Arrays.asList(
- Optional.ofNullable(userLatestApplication.getFirstChoiceUniversity())
- .map(UniversityInfoForApply::getUniversity)
- .orElse(null),
- Optional.ofNullable(userLatestApplication.getSecondChoiceUniversity())
- .map(UniversityInfoForApply::getUniversity)
- .orElse(null),
- Optional.ofNullable(userLatestApplication.getThirdChoiceUniversity())
- .map(UniversityInfoForApply::getUniversity)
- .orElse(null)
- ).stream()
+
+ List universityInfoForApplyIds = Stream.of(
+ userLatestApplication.getFirstChoiceUnivApplyInfoId(),
+ userLatestApplication.getSecondChoiceUnivApplyInfoId(),
+ userLatestApplication.getThirdChoiceUnivApplyInfoId()
+ )
.filter(Objects::nonNull)
.collect(Collectors.toList());
- List firstChoiceApplicants = getFirstChoiceApplicants(userAppliedUniversities, siteUser, term);
- List secondChoiceApplicants = getSecondChoiceApplicants(userAppliedUniversities, siteUser, term);
- List thirdChoiceApplicants = getThirdChoiceApplicants(userAppliedUniversities, siteUser, term);
- return new ApplicationsResponse(firstChoiceApplicants, secondChoiceApplicants, thirdChoiceApplicants);
- }
-
- // 학기별로 상태가 관리된다.
- // 금학기에 지원이력이 있는 사용자만 지원정보를 확인할 수 있도록 한다.
- @Transactional(readOnly = true)
- public void validateSiteUserCanViewApplicants(SiteUser siteUser) {
- VerifyStatus verifyStatus = applicationRepository.getApplicationBySiteUserAndTerm(siteUser, term).getVerifyStatus();
- if (verifyStatus != VerifyStatus.APPROVED) {
- throw new CustomException(APPLICATION_NOT_APPROVED);
+ if (universityInfoForApplyIds.isEmpty()) {
+ return new ApplicationsResponse(List.of(), List.of(), List.of());
}
- }
- private List getFirstChoiceApplicants(List universities, SiteUser siteUser, String term) {
- return getApplicantsByChoice(
- universities,
- siteUser,
- uia -> applicationRepository.findAllByFirstChoiceUniversityAndVerifyStatusAndTermAndIsDeleteFalse(uia, VerifyStatus.APPROVED, term)
- );
+ List applications = applicationRepository.findAllByUnivApplyInfoIds(universityInfoForApplyIds, VerifyStatus.APPROVED, term);
+ List universityInfosForApply = universityInfoForApplyRepository.findAllByUniversityIds(universityInfoForApplyIds);
+
+ return classifyApplicationsByChoice(universityInfosForApply, applications, siteUser);
}
- private List getSecondChoiceApplicants(List universities, SiteUser siteUser, String term) {
- return getApplicantsByChoice(
- universities,
- siteUser,
- uia -> applicationRepository.findAllBySecondChoiceUniversityAndVerifyStatusAndTermAndIsDeleteFalse(uia, VerifyStatus.APPROVED, term)
- );
+ private ApplicationsResponse classifyApplicationsByChoice(
+ List universityInfosForApply,
+ List applications,
+ SiteUser siteUser) {
+ Map> firstChoiceMap = createChoiceMap(applications, Application::getFirstChoiceUnivApplyInfoId);
+ Map> secondChoiceMap = createChoiceMap(applications, Application::getSecondChoiceUnivApplyInfoId);
+ Map> thirdChoiceMap = createChoiceMap(applications, Application::getThirdChoiceUnivApplyInfoId);
+
+ List firstChoiceApplicants =
+ createUniversityApplicantsResponses(universityInfosForApply, firstChoiceMap, siteUser);
+ List secondChoiceApplicants =
+ createUniversityApplicantsResponses(universityInfosForApply, secondChoiceMap, siteUser);
+ List thirdChoiceApplicants =
+ createUniversityApplicantsResponses(universityInfosForApply, thirdChoiceMap, siteUser);
+
+ return new ApplicationsResponse(firstChoiceApplicants, secondChoiceApplicants, thirdChoiceApplicants);
}
- private List getThirdChoiceApplicants(List universities, SiteUser siteUser, String term) {
- return getApplicantsByChoice(
- universities,
- siteUser,
- uia -> applicationRepository.findAllByThirdChoiceUniversityAndVerifyStatusAndTermAndIsDeleteFalse(uia, VerifyStatus.APPROVED, term)
- );
+ private Map> createChoiceMap(
+ List applications,
+ Function choiceIdExtractor) {
+ Map> choiceMap = new HashMap<>();
+
+ for (Application application : applications) {
+ Long choiceId = choiceIdExtractor.apply(application);
+ if (choiceId != null) {
+ choiceMap.computeIfAbsent(choiceId, k -> new ArrayList<>()).add(application);
+ }
+ }
+
+ return choiceMap;
}
- private List getApplicantsByChoice(
- List searchedUniversities,
- SiteUser siteUser,
- Function> findApplicationsByChoice) {
- return universityInfoForApplyRepository.findByUniversitiesAndTerm(searchedUniversities, term).stream()
- .map(universityInfoForApply -> UniversityApplicantsResponse.of(
- universityInfoForApply,
- findApplicationsByChoice.apply(universityInfoForApply).stream()
- .map(ap -> ApplicantResponse.of(
- ap,
- Objects.equals(siteUser.getId(), ap.getSiteUser().getId())))
- .toList()))
+ private List createUniversityApplicantsResponses(
+ List universityInfosForApply,
+ Map> choiceMap,
+ SiteUser siteUser) {
+ return universityInfosForApply.stream()
+ .map(uia -> UniversityApplicantsResponse.of(uia, choiceMap.getOrDefault(uia.getId(), List.of()), siteUser))
.toList();
}
+
+ @Transactional(readOnly = true)
+ public void validateSiteUserCanViewApplicants(SiteUser siteUser) {
+ VerifyStatus verifyStatus = applicationRepository.getApplicationBySiteUserAndTerm(siteUser, term).getVerifyStatus();
+ if (verifyStatus != VerifyStatus.APPROVED) {
+ throw new CustomException(APPLICATION_NOT_APPROVED);
+ }
+ }
}
diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java
index af1678a16..721693f38 100644
--- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java
+++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java
@@ -6,14 +6,12 @@
import com.example.solidconnection.application.dto.ApplyRequest;
import com.example.solidconnection.application.dto.UniversityChoiceRequest;
import com.example.solidconnection.application.repository.ApplicationRepository;
-import com.example.solidconnection.cache.annotation.DefaultCacheOut;
import com.example.solidconnection.common.exception.CustomException;
import com.example.solidconnection.score.domain.GpaScore;
import com.example.solidconnection.score.domain.LanguageTestScore;
import com.example.solidconnection.score.repository.GpaScoreRepository;
import com.example.solidconnection.score.repository.LanguageTestScoreRepository;
import com.example.solidconnection.siteuser.domain.SiteUser;
-import com.example.solidconnection.university.domain.UniversityInfoForApply;
import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
@@ -45,24 +43,14 @@ public class ApplicationSubmissionService {
// 학점 및 어학성적이 모두 유효한 경우에만 지원서 등록이 가능하다.
// 기존에 있던 status field 우선 APRROVED로 입력시킨다.
@Transactional
- // todo: 임시로 새로운 신청 생성 시 기존 캐싱 데이터를 삭제한다. 추후 수정 필요
- @DefaultCacheOut(
- key = {"applications:all"},
- cacheManager = "customCacheManager"
- )
public ApplicationSubmissionResponse apply(SiteUser siteUser, ApplyRequest applyRequest) {
UniversityChoiceRequest universityChoiceRequest = applyRequest.universityChoiceRequest();
GpaScore gpaScore = getValidGpaScore(siteUser, applyRequest.gpaScoreId());
LanguageTestScore languageTestScore = getValidLanguageTestScore(siteUser, applyRequest.languageTestScoreId());
- UniversityInfoForApply firstChoiceUniversity = universityInfoForApplyRepository
- .getUniversityInfoForApplyByIdAndTerm(universityChoiceRequest.firstChoiceUniversityId(), term);
- UniversityInfoForApply secondChoiceUniversity = Optional.ofNullable(universityChoiceRequest.secondChoiceUniversityId())
- .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term))
- .orElse(null);
- UniversityInfoForApply thirdChoiceUniversity = Optional.ofNullable(universityChoiceRequest.thirdChoiceUniversityId())
- .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term))
- .orElse(null);
+ long firstChoiceUniversityId = universityChoiceRequest.firstChoiceUniversityId();
+ Long secondChoiceUniversityId = universityChoiceRequest.secondChoiceUniversityId();
+ Long thirdChoiceUniversityId = universityChoiceRequest.thirdChoiceUniversityId();
Optional existingApplication = applicationRepository.findBySiteUserAndTerm(siteUser, term);
int updateCount = existingApplication
@@ -72,10 +60,22 @@ public ApplicationSubmissionResponse apply(SiteUser siteUser, ApplyRequest apply
return application.getUpdateCount() + 1;
})
.orElse(1);
- Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(),
- term, updateCount, firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname());
+
+ Application newApplication = new Application(
+ siteUser,
+ gpaScore.getGpa(),
+ languageTestScore.getLanguageTest(),
+ term,
+ updateCount,
+ firstChoiceUniversityId,
+ secondChoiceUniversityId,
+ thirdChoiceUniversityId,
+ getRandomNickname()
+ );
+
newApplication.setVerifyStatus(VerifyStatus.APPROVED);
applicationRepository.save(newApplication);
+
return ApplicationSubmissionResponse.from(newApplication);
}
diff --git a/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java b/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java
index 58fb7aeec..73a5ee14b 100644
--- a/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java
+++ b/src/main/java/com/example/solidconnection/university/repository/UniversityInfoForApplyRepository.java
@@ -22,7 +22,12 @@ public interface UniversityInfoForApplyRepository extends JpaRepository findFirstByKoreanNameAndTerm(String koreanName, String term);
- @Query("SELECT c FROM UniversityInfoForApply c WHERE c.university IN :universities AND c.term = :term")
+ @Query("""
+ SELECT uifa
+ FROM UniversityInfoForApply uifa
+ WHERE uifa.university IN :universities
+ AND uifa.term = :term
+ """)
List findByUniversitiesAndTerm(@Param("universities") List universities, @Param("term") String term);
@Query("""
@@ -49,7 +54,8 @@ OR u.region.code IN (
SELECT *
FROM university_info_for_apply
WHERE term = :term
- ORDER BY RAND() LIMIT :limitNum
+ ORDER BY RAND()
+ LIMIT :limitNum
""", nativeQuery = true)
List findRandomByTerm(@Param("term") String term, @Param("limitNum") int limitNum);
@@ -58,8 +64,23 @@ default UniversityInfoForApply getUniversityInfoForApplyById(Long id) {
.orElseThrow(() -> new CustomException(UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND));
}
- default UniversityInfoForApply getUniversityInfoForApplyByIdAndTerm(Long id, String term) {
- return findByIdAndTerm(id, term)
- .orElseThrow(() -> new CustomException(UNIVERSITY_INFO_FOR_APPLY_NOT_FOUND_FOR_TERM));
- }
-}
+ @Query("""
+ SELECT DISTINCT uifa
+ FROM UniversityInfoForApply uifa
+ JOIN FETCH uifa.university u
+ JOIN FETCH u.country c
+ JOIN FETCH u.region r
+ WHERE uifa.id IN :ids
+ """)
+ List findAllByUniversityIds(@Param("ids") List ids);
+
+ @Query("""
+ SELECT DISTINCT uifa
+ FROM UniversityInfoForApply uifa
+ JOIN FETCH uifa.university u
+ JOIN FETCH u.country c
+ JOIN FETCH u.region r
+ WHERE u.id IN :universityIds
+ """)
+ List findByUniversityIdsWithUniversityAndLocation(@Param("universityIds") List universityIds);
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java
index c35533877..93850a2f4 100644
--- a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java
+++ b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepository.java
@@ -8,7 +8,7 @@
public interface UniversityFilterRepository {
- List findByRegionCodeAndKeywords(String regionCode, List keywords);
+ List findByRegionCodeAndKeywords(String regionCode, List keywords);
List findByRegionCodeAndKeywordsAndLanguageTestTypeAndTestScoreAndTerm(
String regionCode, List keywords, LanguageTestType testType, String testScore, String term);
diff --git a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java
index 25da850da..b01095996 100644
--- a/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java
+++ b/src/main/java/com/example/solidconnection/university/repository/custom/UniversityFilterRepositoryImpl.java
@@ -5,8 +5,8 @@
import com.example.solidconnection.university.domain.LanguageTestType;
import com.example.solidconnection.university.domain.QUniversity;
import com.example.solidconnection.university.domain.QUniversityInfoForApply;
-import com.example.solidconnection.university.domain.University;
import com.example.solidconnection.university.domain.UniversityInfoForApply;
+import com.example.solidconnection.university.domain.QLanguageRequirement;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringPath;
@@ -28,21 +28,28 @@ public UniversityFilterRepositoryImpl(EntityManager em) {
}
@Override
- public List findByRegionCodeAndKeywords(String regionCode, List keywords) {
+ public List findByRegionCodeAndKeywords(String regionCode, List keywords) {
+ QUniversityInfoForApply universityInfoForApply = QUniversityInfoForApply.universityInfoForApply;
QUniversity university = QUniversity.university;
QCountry country = QCountry.country;
QRegion region = QRegion.region;
+ QLanguageRequirement languageRequirement = QLanguageRequirement.languageRequirement;
return queryFactory
- .selectFrom(university)
- .join(university.country, country)
- .join(country.region, region)
- .where(regionCodeEq(region, regionCode)
- .and(countryOrUniversityContainsKeyword(country, university, keywords))
+ .selectFrom(universityInfoForApply)
+ .join(universityInfoForApply.university, university).fetchJoin()
+ .join(university.country, country).fetchJoin()
+ .join(country.region, region).fetchJoin()
+ .leftJoin(universityInfoForApply.languageRequirements, languageRequirement).fetchJoin()
+ .where(
+ regionCodeEq(region, regionCode)
+ .and(countryOrUniversityContainsKeyword(country, university, keywords))
)
+ .distinct()
.fetch();
}
+
private BooleanExpression regionCodeEq(QRegion region, String regionCode) {
if (regionCode == null || regionCode.isEmpty()) {
return Expressions.asBoolean(true).isTrue();
@@ -69,7 +76,6 @@ private BooleanExpression createKeywordCondition(StringPath namePath, List findByRegionCodeAndKeywordsAndLanguageTestTypeAndTestScoreAndTerm(
String regionCode, List keywords, LanguageTestType testType, String testScore, String term) {
-
QUniversity university = QUniversity.university;
QCountry country = QCountry.country;
QRegion region = QRegion.region;
diff --git a/src/main/resources/db/migration/V13_add_application_index_and_delete_manny_to_one_mapping.sql b/src/main/resources/db/migration/V13_add_application_index_and_delete_manny_to_one_mapping.sql
new file mode 100644
index 000000000..3f3018724
--- /dev/null
+++ b/src/main/resources/db/migration/V13_add_application_index_and_delete_manny_to_one_mapping.sql
@@ -0,0 +1,15 @@
+ALTER TABLE application RENAME COLUMN first_choice_university_id TO first_choice_university_info_for_apply_id;
+ALTER TABLE application RENAME COLUMN second_choice_university_id TO second_choice_university_info_for_apply_id;
+ALTER TABLE application RENAME COLUMN third_choice_university_id TO third_choice_university_info_for_apply_id;
+
+CREATE INDEX idx_app_user_term_delete
+ ON application(site_user_id, term, is_delete);
+
+CREATE INDEX idx_app_first_choice_search
+ ON application(verify_status, term, is_delete, first_choice_university_apply_info_id);
+
+CREATE INDEX idx_app_second_choice_search
+ ON application(verify_status, term, is_delete, second_choice_university_apply_info_id);
+
+CREATE INDEX idx_app_third_choice_search
+ ON application(verify_status, term, is_delete, third_choice_university_apply_info_id);
diff --git a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java
index b2cbc6460..91dc29c59 100644
--- a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java
+++ b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixture.java
@@ -20,9 +20,9 @@ public class ApplicationFixture {
String term,
Gpa gpa,
LanguageTest languageTest,
- UniversityInfoForApply firstChoiceUniversity,
- UniversityInfoForApply secondChoiceUniversity,
- UniversityInfoForApply thirdChoiceUniversity
+ Long firstChoiceUniversityApplyInfoId,
+ Long secondChoiceUniversityApplyInfoId,
+ Long thirdChoiceUniversityApplyInfoId
) {
return applicationFixtureBuilder.application()
.siteUser(siteUser)
@@ -30,9 +30,9 @@ public class ApplicationFixture {
.languageTest(languageTest)
.nicknameForApply(nicknameForApply)
.term(term)
- .firstChoiceUniversity(firstChoiceUniversity)
- .secondChoiceUniversity(secondChoiceUniversity)
- .thirdChoiceUniversity(thirdChoiceUniversity)
+ .firstChoiceUniversityApplyInfoId(firstChoiceUniversityApplyInfoId)
+ .secondChoiceUniversityApplyInfoId(secondChoiceUniversityApplyInfoId)
+ .thirdChoiceUniversityApplyInfoId(thirdChoiceUniversityApplyInfoId)
.create();
}
}
diff --git a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java
index 5f6c06741..c9bf33c3e 100644
--- a/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java
+++ b/src/test/java/com/example/solidconnection/application/fixture/ApplicationFixtureBuilder.java
@@ -18,9 +18,9 @@ public class ApplicationFixtureBuilder {
private Gpa gpa;
private LanguageTest languageTest;
- private UniversityInfoForApply firstChoiceUniversity;
- private UniversityInfoForApply secondChoiceUniversity;
- private UniversityInfoForApply thirdChoiceUniversity;
+ private Long firstChoiceUniversityApplyInfoId;
+ private Long secondChoiceUniversityApplyInfoId;
+ private Long thirdChoiceUniversityApplyInfoId;
private SiteUser siteUser;
private String nicknameForApply;
private String term;
@@ -39,18 +39,18 @@ public ApplicationFixtureBuilder languageTest(LanguageTest languageTest) {
return this;
}
- public ApplicationFixtureBuilder firstChoiceUniversity(UniversityInfoForApply firstChoiceUniversity) {
- this.firstChoiceUniversity = firstChoiceUniversity;
+ public ApplicationFixtureBuilder firstChoiceUniversityApplyInfoId(Long firstChoiceUniversityApplyInfoId) {
+ this.firstChoiceUniversityApplyInfoId = firstChoiceUniversityApplyInfoId;
return this;
}
- public ApplicationFixtureBuilder secondChoiceUniversity(UniversityInfoForApply secondChoiceUniversity) {
- this.secondChoiceUniversity = secondChoiceUniversity;
+ public ApplicationFixtureBuilder secondChoiceUniversityApplyInfoId(Long secondChoiceUniversityApplyInfoId) {
+ this.secondChoiceUniversityApplyInfoId = secondChoiceUniversityApplyInfoId;
return this;
}
- public ApplicationFixtureBuilder thirdChoiceUniversity(UniversityInfoForApply thirdChoiceUniversity) {
- this.thirdChoiceUniversity = thirdChoiceUniversity;
+ public ApplicationFixtureBuilder thirdChoiceUniversityApplyInfoId(Long thirdChoiceUniversityApplyInfoId) {
+ this.thirdChoiceUniversityApplyInfoId = thirdChoiceUniversityApplyInfoId;
return this;
}
@@ -75,9 +75,9 @@ public Application create() {
gpa,
languageTest,
term,
- firstChoiceUniversity,
- secondChoiceUniversity,
- thirdChoiceUniversity,
+ firstChoiceUniversityApplyInfoId,
+ secondChoiceUniversityApplyInfoId,
+ thirdChoiceUniversityApplyInfoId,
nicknameForApply
);
application.setVerifyStatus(VerifyStatus.APPROVED);
diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
index ac0b83619..1a0f927a2 100644
--- a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
+++ b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java
@@ -106,7 +106,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -116,7 +116,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore2.getGpa(),
languageTestScore2.getLanguageTest(),
- 괌대학_B_지원_정보,
+ 괌대학_B_지원_정보.getId(),
null,
null
);
@@ -126,7 +126,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore3.getGpa(),
languageTestScore3.getLanguageTest(),
- 서던덴마크대학교_지원_정보,
+ 서던덴마크대학교_지원_정보.getId(),
null,
null
);
@@ -141,11 +141,11 @@ class 지원자_목록_조회_테스트 {
// then
assertThat(response.firstChoice()).containsAll(List.of(
UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(application1, true))),
+ List.of(application1), user1),
UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(application2, false))),
+ List.of(application2), user1),
UniversityApplicantsResponse.of(서던덴마크대학교_지원_정보,
- List.of(ApplicantResponse.of(application3, false)))
+ List.of(application3), user1)
));
}
@@ -158,7 +158,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -168,7 +168,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore2.getGpa(),
languageTestScore2.getLanguageTest(),
- 괌대학_B_지원_정보,
+ 괌대학_B_지원_정보.getId(),
null,
null
);
@@ -178,7 +178,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore3.getGpa(),
languageTestScore3.getLanguageTest(),
- 서던덴마크대학교_지원_정보,
+ 서던덴마크대학교_지원_정보.getId(),
null,
null
);
@@ -193,9 +193,9 @@ class 지원자_목록_조회_테스트 {
// then
assertThat(response.firstChoice()).containsExactlyInAnyOrder(
UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(application1, true))),
+ List.of(application1), user1),
UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(application2, false)))
+ List.of(application2), user1)
);
}
@@ -208,7 +208,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -218,7 +218,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore2.getGpa(),
languageTestScore2.getLanguageTest(),
- 괌대학_B_지원_정보,
+ 괌대학_B_지원_정보.getId(),
null,
null
);
@@ -228,7 +228,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore3.getGpa(),
languageTestScore3.getLanguageTest(),
- 서던덴마크대학교_지원_정보,
+ 서던덴마크대학교_지원_정보.getId(),
null,
null
);
@@ -243,9 +243,9 @@ class 지원자_목록_조회_테스트 {
// then
assertThat(response.firstChoice()).containsExactlyInAnyOrder(
UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(application1, true))),
+ List.of(application1), user1),
UniversityApplicantsResponse.of(괌대학_B_지원_정보,
- List.of(ApplicantResponse.of(application2, false)))
+ List.of(application2), user1)
);
}
@@ -258,7 +258,7 @@ class 지원자_목록_조회_테스트 {
"1988-1",
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -273,7 +273,7 @@ class 지원자_목록_조회_테스트 {
// then
assertThat(response.firstChoice()).doesNotContainAnyElementsOf(List.of(
UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(application, true)))
+ List.of(application), user1)
));
}
@@ -286,7 +286,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -298,7 +298,7 @@ class 지원자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_B_지원_정보,
+ 괌대학_B_지원_정보.getId(),
null,
null
);
@@ -320,7 +320,6 @@ class 지원자_목록_조회_테스트 {
@Nested
class 경쟁자_목록_조회_테스트 {
-
@Test
void 이번_학기_지원한_대학의_경쟁자_목록을_조회한다() {
// given
@@ -330,7 +329,7 @@ class 경쟁자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -340,7 +339,7 @@ class 경쟁자_목록_조회_테스트 {
term,
gpaScore2.getGpa(),
languageTestScore2.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
@@ -350,7 +349,7 @@ class 경쟁자_목록_조회_테스트 {
term,
gpaScore3.getGpa(),
languageTestScore3.getLanguageTest(),
- 괌대학_B_지원_정보,
+ 서던덴마크대학교_지원_정보.getId(),
null,
null
);
@@ -359,10 +358,8 @@ class 경쟁자_목록_조회_테스트 {
// then
assertThat(response.firstChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보, List.of(
- ApplicantResponse.of(application1, true),
- ApplicantResponse.of(application2, false)
- ))
+ UniversityApplicantsResponse.of(괌대학_A_지원_정보,
+ List.of(application1, application2), user1)
);
}
@@ -375,47 +372,43 @@ class 경쟁자_목록_조회_테스트 {
term,
gpaScore1.getGpa(),
languageTestScore1.getLanguageTest(),
- 괌대학_A_지원_정보,
+ 괌대학_A_지원_정보.getId(),
null,
null
);
- applicationFixture.지원서(
+ Application application2 = applicationFixture.지원서(
user2,
"nickname2",
term,
gpaScore2.getGpa(),
languageTestScore2.getLanguageTest(),
- null,
- 괌대학_B_지원_정보,
- null
+ 괌대학_A_지원_정보.getId(),
+ 괌대학_B_지원_정보.getId(),
+ 서던덴마크대학교_지원_정보.getId()
);
- applicationFixture.지원서(
+ Application application3 = applicationFixture.지원서(
user3,
"nickname3",
term,
gpaScore3.getGpa(),
languageTestScore3.getLanguageTest(),
+ 서던덴마크대학교_지원_정보.getId(),
null,
- null,
- 서던덴마크대학교_지원_정보
+ null
);
// when
ApplicationsResponse response = applicationQueryService.getApplicantsByUserApplications(user1);
// then
- assertThat(response.firstChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보,
- List.of(ApplicantResponse.of(application1, true)))
- );
-
- assertThat(response.secondChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보, List.of())
- );
-
- assertThat(response.thirdChoice()).containsExactlyInAnyOrder(
- UniversityApplicantsResponse.of(괌대학_A_지원_정보, List.of())
- );
+ assertThat(response.firstChoice())
+ .hasSize(1)
+ .allSatisfy(uar -> {
+ assertThat(uar.koreanName()).isEqualTo(괌대학_A_지원_정보.getKoreanName());
+ assertThat(uar.applicants())
+ .extracting(ApplicantResponse::nicknameForApply)
+ .containsExactlyInAnyOrder("nickname1", "nickname2");
+ });
}
}
}
diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
index f70cd9fc0..2718fb90b 100644
--- a/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
+++ b/src/test/java/com/example/solidconnection/application/service/ApplicationSubmissionServiceTest.java
@@ -86,12 +86,18 @@ void setUp() {
// then
Application savedApplication = applicationRepository.findBySiteUserAndTerm(user, term).orElseThrow();
assertAll(
- () -> assertThat(response.applyCount()).isEqualTo(savedApplication.getUpdateCount()),
- () -> assertThat(savedApplication.getVerifyStatus()).isEqualTo(VerifyStatus.APPROVED),
- () -> assertThat(savedApplication.isDelete()).isFalse(),
- () -> assertThat(savedApplication.getFirstChoiceUniversity().getId()).isEqualTo(괌대학_A_지원_정보.getId()),
- () -> assertThat(savedApplication.getSecondChoiceUniversity().getId()).isEqualTo(괌대학_B_지원_정보.getId()),
- () -> assertThat(savedApplication.getThirdChoiceUniversity().getId()).isEqualTo(서던덴마크대학교_지원_정보.getId())
+ () -> assertThat(response.applyCount())
+ .isEqualTo(savedApplication.getUpdateCount()),
+ () -> assertThat(savedApplication.getVerifyStatus())
+ .isEqualTo(VerifyStatus.APPROVED),
+ () -> assertThat(savedApplication.isDelete())
+ .isFalse(),
+ () -> assertThat(savedApplication.getFirstChoiceUnivApplyInfoId())
+ .isEqualTo(괌대학_A_지원_정보.getId()),
+ () -> assertThat(savedApplication.getSecondChoiceUnivApplyInfoId())
+ .isEqualTo(괌대학_B_지원_정보.getId()),
+ () -> assertThat(savedApplication.getThirdChoiceUnivApplyInfoId())
+ .isEqualTo(서던덴마크대학교_지원_정보.getId())
);
}
From af2ba816391146b1a5c5967712b5a146f70248e6 Mon Sep 17 00:00:00 2001
From: seonghyeok cho <65901319+whqtker@users.noreply.github.com>
Date: Tue, 24 Jun 2025 16:58:17 +0900
Subject: [PATCH 23/90] =?UTF-8?q?refactor:=20Siteuser=20=EB=8F=84=EB=A9=94?=
=?UTF-8?q?=EC=9D=B8=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81=20(#336)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* refactor: SiteUser 엔티티
- SiteUser 엔티티의 nickname 컬럼에 unique 제약 조건 추가
* fix: site_user 테이블의 nickname 컬럼에 unique 제약 조건 추가
* refactor: SiteUser 도메인 관련
- MyPageService에서 중복 닉네임 검증 로직 제거
- 컨트롤러에서 try-catch 문을 통해 예외 처리
* refactor: 회원 정보 변경 관련 로직 수정
- 변경된 컬럼만 업데이트하는 쿼리 사용
* refactor: sign up 시 닉네임 검증 로직 제거
- nickname 제약 조건의 이름 명시적으로 지정
* refactor: 도메인 로직 변경에 따른 테스트 코드 수정
- 게시글_좋아요_동시성_문제를_해결한다: 동일한 닉네임을 사용하지 않도록 변경
- 이메일이_같더라도_인증_유형이_다른_사용자는_정상_저장한다: 동일한 닉네임을 사용하지 않도록 변경
- 닉네임 무결성 테스트는 repository test로 분리
- 새로운_이미지로_성공적으로_업데이트한다: DB에서 사용자 조회 후 URL 비교
* refactor: 예외 처리를 컨트롤러가 아닌 서비스 계층에서 처리하도록 변경
* refactor: JPQL이 아닌 dirty check를 사용하도록 변경 외
- 중복 닉네임 검증보다 닉네임 수정 시간 검증이 선행되도록 변경
- 준영속 엔티티를 save()하는 과정에서 발생하는 N+1 문제 해결
- DB 레벨, 애플리케이션 레벨 검증 모두 사용하도록
- 위 변경사항에 따른 테스트 코드 수정
* refactor: 로그에만 예외 원문 포함하도록 변경 및 상태코드 수정
* refactor: 회원가입 시 닉네임 관련 애플리케이션 레벨 검증 추가
- CustomExceptionHandler에 DB 레벨에서 중복 닉네임 검증 추가에 따라 try-catch 문 삭제
* refactor: 미사용 코드 제거 (JPQL 관련)
* test: 중복된_닉네임으로_사용자를_저장하면_예외_응답을_반환한다 테스트 수정
- save -> saveAndFlush
* chore: 미사용 import문 제거
* chore: 함수명과 중괄호 사이 띄어쓰기 추가 (컨벤션 관련)
* chore: 호출 순서에 따라 메서드 선언 재배치
* chore: 마이그레이션 파일 버전 수정 V13 -> V14
---
.../exception/CustomExceptionHandler.java | 11 +++++
.../common/exception/ErrorCode.java | 3 ++
.../siteuser/controller/MyPageController.java | 1 +
.../siteuser/domain/SiteUser.java | 4 ++
.../repository/SiteUserRepository.java | 1 +
.../siteuser/service/MyPageService.java | 29 ++++++------
...V14__set_unique_constraint_to_nickname.sql | 3 ++
.../PostLikeCountConcurrencyTest.java | 5 ++-
.../solidconnection/e2e/DynamicFixture.java | 4 +-
.../repository/SiteUserRepositoryTest.java | 44 ++++++++++++++++---
.../siteuser/service/MyPageServiceTest.java | 20 +++------
11 files changed, 88 insertions(+), 37 deletions(-)
create mode 100644 src/main/resources/db/migration/V14__set_unique_constraint_to_nickname.sql
diff --git a/src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java b/src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java
index bc03ca98a..57d6f4769 100644
--- a/src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java
+++ b/src/main/java/com/example/solidconnection/common/exception/CustomExceptionHandler.java
@@ -4,6 +4,7 @@
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
@@ -13,6 +14,7 @@
import java.util.ArrayList;
import java.util.List;
+import static com.example.solidconnection.common.exception.ErrorCode.DATA_INTEGRITY_VIOLATION;
import static com.example.solidconnection.common.exception.ErrorCode.INVALID_INPUT;
import static com.example.solidconnection.common.exception.ErrorCode.JSON_PARSING_FAILED;
import static com.example.solidconnection.common.exception.ErrorCode.JWT_EXCEPTION;
@@ -56,6 +58,15 @@ public ResponseEntity handleValidationExceptions(MethodArgumentNo
.body(errorResponse);
}
+ @ExceptionHandler(DataIntegrityViolationException.class)
+ public ResponseEntity