From 4ad60d6bdb4f6edd6691fbc9e1669af9c95c1ab3 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:34:12 +0900 Subject: [PATCH 01/22] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=EC=9D=84=20=EC=9C=84=ED=95=9C=20util=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/exception/ErrorCode.java | 4 ++ .../solidconnection/util/PagingUtils.java | 24 +++++++++ .../solidconnection/util/PagingUtilsTest.java | 50 +++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/util/PagingUtils.java create mode 100644 src/test/java/com/example/solidconnection/util/PagingUtilsTest.java diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 8c74ea55b..23cd52786 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -92,6 +92,10 @@ public enum ErrorCode { INVALID_LANGUAGE_TEST_SCORE_STATUS(HttpStatus.BAD_REQUEST.value(), "어학성적이 승인되지 않았습니다."), USER_DO_NOT_HAVE_GPA(HttpStatus.BAD_REQUEST.value(), "해당 유저의 학점을 찾을 수 없음"), + // page + INVALID_PAGE(HttpStatus.BAD_REQUEST.value(), "페이지 번호가 최소값보다 작습니다."), + INVALID_SIZE(HttpStatus.BAD_REQUEST.value(), "페이지 크기가 최소값보다 작습니다."), + // general JSON_PARSING_FAILED(HttpStatus.BAD_REQUEST.value(), "JSON 파싱을 할 수 없습니다."), JWT_EXCEPTION(HttpStatus.BAD_REQUEST.value(), "JWT 토큰을 처리할 수 없습니다."), diff --git a/src/main/java/com/example/solidconnection/util/PagingUtils.java b/src/main/java/com/example/solidconnection/util/PagingUtils.java new file mode 100644 index 000000000..b98d65426 --- /dev/null +++ b/src/main/java/com/example/solidconnection/util/PagingUtils.java @@ -0,0 +1,24 @@ +package com.example.solidconnection.util; + +import com.example.solidconnection.custom.exception.CustomException; + +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_PAGE; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SIZE; + +public class PagingUtils { + + private static final int MIN_PAGE = 1; + private static final int MIN_SIZE = 1; + + private PagingUtils() { + } + + public static void validatePage(int page, int size) { + if (page < MIN_PAGE) { + throw new CustomException(INVALID_PAGE); + } + if (size < MIN_SIZE) { + throw new CustomException(INVALID_SIZE); + } + } +} diff --git a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java new file mode 100644 index 000000000..1557898a8 --- /dev/null +++ b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java @@ -0,0 +1,50 @@ +package com.example.solidconnection.util; + +import com.example.solidconnection.custom.exception.CustomException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_PAGE; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SIZE; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +@DisplayName("PagingUtils 테스트") +class PagingUtilsTest { + + @Test + @DisplayName("유효한 페이지 번호와 크기가 주어지면 예외가 발생하지 않는다") + void validateValidPageAndSize() { + // given + int validPage = 1; + int validSize = 10; + + // when & then + assertThatCode(() -> PagingUtils.validatePage(validPage, validSize)) + .doesNotThrowAnyException(); + } + + @Test + void 페이지_번호가_1보다_작으면_예외_응답을_반환한다() { + // given + int invalidPage = 0; + int validSize = 10; + + // when & then + assertThatThrownBy(() -> PagingUtils.validatePage(invalidPage, validSize)) + .isInstanceOf(CustomException.class) + .hasMessage(INVALID_PAGE.getMessage()); + } + + @Test + void 페이지_크기가_1보다_작으면_예외_응답을_반환한다() { + // given + int validPage = 1; + int invalidSize = 0; + + // when & then + assertThatThrownBy(() -> PagingUtils.validatePage(validPage, invalidSize)) + .isInstanceOf(CustomException.class) + .hasMessage(INVALID_SIZE.getMessage()); + } +} From e66cd7723232365cefacc28c8ac7d548dc605fa4 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:35:29 +0900 Subject: [PATCH 02/22] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20GPA=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminController.java | 33 ++++++ .../admin/dto/GpaScoreSearchResponse.java | 7 ++ .../admin/dto/GpaScoreStatus.java | 16 +++ .../admin/dto/ScoreSearchCondition.java | 11 ++ .../admin/dto/SiteUserDto.java | 8 ++ .../ScoreVerificationAdminService.java | 27 +++++ .../score/repository/GpaScoreRepository.java | 3 +- .../custom/GpaScoreFilterRepository.java | 11 ++ .../custom/GpaScoreFilterRepositoryImpl.java | 101 ++++++++++++++++++ 9 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java create mode 100644 src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java create mode 100644 src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java create mode 100644 src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java create mode 100644 src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepository.java create mode 100644 src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java new file mode 100644 index 000000000..597bd7507 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -0,0 +1,33 @@ +package com.example.solidconnection.admin.controller; + +import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.ScoreSearchCondition; +import com.example.solidconnection.admin.service.ScoreVerificationAdminService; +import com.example.solidconnection.util.PagingUtils; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RequestMapping("/admin/scores") +@RestController +public class ScoreVerificationAdminController { + + private final ScoreVerificationAdminService scoreVerificationAdminService; + + @GetMapping + public ResponseEntity> searchGpaScores( + @Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition, + Pageable pageable + ) { + PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); + Page gpaScoreSearchResponses = scoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); + return ResponseEntity.ok(gpaScoreSearchResponses); + } +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java new file mode 100644 index 000000000..14fc60af9 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java @@ -0,0 +1,7 @@ +package com.example.solidconnection.admin.dto; + +public record GpaScoreSearchResponse( + GpaScoreStatus gpaScoreStatus, + SiteUserDto siteUserDto +) { +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java new file mode 100644 index 000000000..e16206290 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java @@ -0,0 +1,16 @@ +package com.example.solidconnection.admin.dto; + +import com.example.solidconnection.application.domain.Gpa; +import com.example.solidconnection.type.VerifyStatus; + +import java.time.ZonedDateTime; + +public record GpaScoreStatus( + Long id, + Gpa gpa, + VerifyStatus verifyStatus, + String rejectedReason, + ZonedDateTime createdAt, + ZonedDateTime updatedAt +) { +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java b/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java new file mode 100644 index 000000000..2e94628e6 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/ScoreSearchCondition.java @@ -0,0 +1,11 @@ +package com.example.solidconnection.admin.dto; + +import com.example.solidconnection.type.VerifyStatus; + +import java.time.LocalDate; + +public record ScoreSearchCondition( + VerifyStatus verifyStatus, + String nickname, + LocalDate createdAt) { +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java b/src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java new file mode 100644 index 000000000..dbbb8cbd8 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java @@ -0,0 +1,8 @@ +package com.example.solidconnection.admin.dto; + +public record SiteUserDto( + Long id, + String nickname, + String profileImageUrl +) { +} diff --git a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java new file mode 100644 index 000000000..bbe19db85 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java @@ -0,0 +1,27 @@ +package com.example.solidconnection.admin.service; + +import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.ScoreSearchCondition; +import com.example.solidconnection.score.repository.GpaScoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service +public class ScoreVerificationAdminService { + + private final GpaScoreRepository gpaScoreRepository; + + @Transactional(readOnly = true) + public Page searchGpaScores(ScoreSearchCondition scoreSearchCondition, Pageable pageable) { + Pageable sortedPageable = PageRequest.of( + pageable.getPageNumber() - 1, + pageable.getPageSize() + ); + return gpaScoreRepository.searchGpaScores(scoreSearchCondition, sortedPageable); + } +} diff --git a/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java b/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java index e3c26665b..5610c8de3 100644 --- a/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java +++ b/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java @@ -1,6 +1,7 @@ package com.example.solidconnection.score.repository; import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.score.repository.custom.GpaScoreFilterRepository; import com.example.solidconnection.siteuser.domain.SiteUser; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -8,7 +9,7 @@ import java.util.Optional; @Repository -public interface GpaScoreRepository extends JpaRepository { +public interface GpaScoreRepository extends JpaRepository, GpaScoreFilterRepository { Optional findGpaScoreBySiteUser(SiteUser siteUser); diff --git a/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepository.java b/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepository.java new file mode 100644 index 000000000..9429b877a --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepository.java @@ -0,0 +1,11 @@ +package com.example.solidconnection.score.repository.custom; + +import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.ScoreSearchCondition; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface GpaScoreFilterRepository { + + Page searchGpaScores(ScoreSearchCondition scoreSearchCondition, Pageable pageable); +} 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 new file mode 100644 index 000000000..56226c058 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/repository/custom/GpaScoreFilterRepositoryImpl.java @@ -0,0 +1,101 @@ +package com.example.solidconnection.score.repository.custom; + +import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.GpaScoreStatus; +import com.example.solidconnection.admin.dto.ScoreSearchCondition; +import com.example.solidconnection.admin.dto.SiteUserDto; +import com.example.solidconnection.type.VerifyStatus; +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.List; + +import static com.example.solidconnection.score.domain.QGpaScore.gpaScore; +import static com.example.solidconnection.siteuser.domain.QSiteUser.siteUser; +import static org.springframework.util.StringUtils.hasText; + +@Repository +public class GpaScoreFilterRepositoryImpl implements GpaScoreFilterRepository { + private final JPAQueryFactory queryFactory; + + @Autowired + public GpaScoreFilterRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + + @Override + public Page searchGpaScores(ScoreSearchCondition condition, Pageable pageable) { + List content = queryFactory + .select(Projections.constructor(GpaScoreSearchResponse.class, + Projections.constructor(GpaScoreStatus.class, + gpaScore.id, + gpaScore.gpa, + gpaScore.verifyStatus, + gpaScore.rejectedReason, + gpaScore.createdAt, + gpaScore.updatedAt + ), + Projections.constructor(SiteUserDto.class, + siteUser.id, + siteUser.nickname, + siteUser.profileImageUrl + ) + )) + .from(gpaScore) + .join(gpaScore.siteUser, siteUser) + .where( + verifyStatusEq(condition.verifyStatus()), + nicknameContains(condition.nickname()), + createdAtEq(condition.createdAt()) + ) + .orderBy(gpaScore.createdAt.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + Long totalCount = queryFactory + .select(gpaScore.count()) + .from(gpaScore) + .join(gpaScore.siteUser, siteUser) + .where( + verifyStatusEq(condition.verifyStatus()), + nicknameContains(condition.nickname()), + createdAtEq(condition.createdAt()) + ) + .fetchOne(); + + return new PageImpl<>(content, pageable, totalCount != null ? totalCount : 0L); + } + + private BooleanExpression verifyStatusEq(VerifyStatus verifyStatus) { + return verifyStatus != null ? gpaScore.verifyStatus.eq(verifyStatus) : null; + } + + private BooleanExpression nicknameContains(String nickname) { + return hasText(nickname) ? siteUser.nickname.contains(nickname) : null; + } + + private BooleanExpression createdAtEq(LocalDate createdAt) { + if (createdAt == null) { + return null; + } + + LocalDateTime startOfDay = createdAt.atStartOfDay(); + LocalDateTime endOfDay = createdAt.plusDays(1).atStartOfDay().minusNanos(1); + + return gpaScore.createdAt.between( + startOfDay.atZone(ZoneId.systemDefault()), + endOfDay.atZone(ZoneId.systemDefault()) + ); + } +} From ee2e26ff44206c927e2d2c30e1872c4a16936d47 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:35:42 +0900 Subject: [PATCH 03/22] =?UTF-8?q?test:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20GPA=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20api=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminServiceTest.java | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java diff --git a/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java new file mode 100644 index 000000000..3c360cc81 --- /dev/null +++ b/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java @@ -0,0 +1,162 @@ +package com.example.solidconnection.admin.service; + +import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.ScoreSearchCondition; +import com.example.solidconnection.application.domain.Gpa; +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.support.integration.BaseIntegrationTest; +import com.example.solidconnection.type.Gender; +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.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import java.time.LocalDate; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; + +@DisplayName("성적 검증 관리자 서비스 테스트") +class ScoreVerificationAdminServiceTest extends BaseIntegrationTest { + + @Autowired + private ScoreVerificationAdminService scoreVerificationAdminService; + + @Autowired + private SiteUserRepository siteUserRepository; + + @Autowired + private GpaScoreRepository gpaScoreRepository; + + 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); + } + + @Nested + class 지원한_GPA_목록_조회 { + + @Test + void 검증_상태를_조건으로_페이징하여_조회한다() { + // given + ScoreSearchCondition condition = new ScoreSearchCondition(VerifyStatus.PENDING, null, null); + Pageable pageable = PageRequest.of(1, 10); + List expectedGpaScores = List.of(gpaScore1, gpaScore2); + + // when + Page response = scoreVerificationAdminService.searchGpaScores(condition, pageable); + + // then + assertThat(response.getContent()) + .hasSize(expectedGpaScores.size()) + .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( + () -> assertThat(actual.gpaScoreStatus().id()).isEqualTo(expected.getId()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), + () -> assertThat(actual.gpaScoreStatus().verifyStatus()).isEqualTo(expected.getVerifyStatus()), + + () -> assertThat(actual.siteUserDto().id()).isEqualTo(expected.getSiteUser().getId()), + () -> assertThat(actual.siteUserDto().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()), + () -> assertThat(actual.siteUserDto().nickname()).isEqualTo(expected.getSiteUser().getNickname()) + )); + } + + @Test + void 닉네임으로_페이징하여_조회한다() { + // given + ScoreSearchCondition condition = new ScoreSearchCondition(null, "test", null); + Pageable pageable = PageRequest.of(1, 10); + List expectedGpaScores = List.of(gpaScore1, gpaScore2, gpaScore3); + + // when + Page response = scoreVerificationAdminService.searchGpaScores(condition, pageable); + + // then + assertThat(response.getContent()) + .hasSize(expectedGpaScores.size()) + .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( + () -> assertThat(actual.gpaScoreStatus().id()).isEqualTo(expected.getId()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), + () -> assertThat(actual.gpaScoreStatus().verifyStatus()).isEqualTo(expected.getVerifyStatus()), + + () -> assertThat(actual.siteUserDto().id()).isEqualTo(expected.getSiteUser().getId()), + () -> assertThat(actual.siteUserDto().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()), + () -> assertThat(actual.siteUserDto().nickname()).isEqualTo(expected.getSiteUser().getNickname()) + )); + } + + @Test + void 모든_조건으로_페이징하여_조회한다() { + // given + ScoreSearchCondition condition = new ScoreSearchCondition(VerifyStatus.PENDING, "test1", LocalDate.now()); + Pageable pageable = PageRequest.of(1, 10); + List expectedGpaScores = List.of(gpaScore1); + + // when + Page response = scoreVerificationAdminService.searchGpaScores(condition, pageable); + + // then + assertThat(response.getContent()) + .hasSize(expectedGpaScores.size()) + .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( + () -> assertThat(actual.gpaScoreStatus().id()).isEqualTo(expected.getId()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), + () -> assertThat(actual.gpaScoreStatus().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), + () -> assertThat(actual.gpaScoreStatus().verifyStatus()).isEqualTo(expected.getVerifyStatus()), + + () -> assertThat(actual.siteUserDto().id()).isEqualTo(expected.getSiteUser().getId()), + () -> assertThat(actual.siteUserDto().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()), + () -> assertThat(actual.siteUserDto().nickname()).isEqualTo(expected.getSiteUser().getNickname()) + )); + } + } + + private SiteUser createSiteUser(int index, String nickname) { + SiteUser siteUser = new SiteUser( + "test" + index + " @example.com", + nickname, + "profileImageUrl", + "1999-01-01", + PreparationStatus.CONSIDERING, + Role.MENTEE, + Gender.MALE + ); + return siteUserRepository.save(siteUser); + } + + 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); + } +} From e51a714cf6b28add8ea3a804288c8e5d1140f73f Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:47:12 +0900 Subject: [PATCH 04/22] =?UTF-8?q?refactor:=20GPA=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=95=20=EC=A1=B0=ED=9A=8C=20uri=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/ScoreVerificationAdminController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 597bd7507..6c2555139 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -11,6 +11,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -21,7 +22,7 @@ public class ScoreVerificationAdminController { private final ScoreVerificationAdminService scoreVerificationAdminService; - @GetMapping + @GetMapping("/gpas") public ResponseEntity> searchGpaScores( @Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition, Pageable pageable From 0111dbf10979051a1d93bf444b3fc05f4b2a5e1b Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:59:52 +0900 Subject: [PATCH 05/22] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminController.java | 9 ++++---- .../custom/response/PageResponse.java | 23 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/example/solidconnection/custom/response/PageResponse.java diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 6c2555139..172768295 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -3,6 +3,7 @@ import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; import com.example.solidconnection.admin.dto.ScoreSearchCondition; import com.example.solidconnection.admin.service.ScoreVerificationAdminService; +import com.example.solidconnection.custom.response.PageResponse; import com.example.solidconnection.util.PagingUtils; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -11,7 +12,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -23,12 +23,13 @@ public class ScoreVerificationAdminController { private final ScoreVerificationAdminService scoreVerificationAdminService; @GetMapping("/gpas") - public ResponseEntity> searchGpaScores( + public ResponseEntity> searchGpaScores( @Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition, Pageable pageable ) { PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); - Page gpaScoreSearchResponses = scoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); - return ResponseEntity.ok(gpaScoreSearchResponses); + PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); + Page page = scoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); + return ResponseEntity.ok(PageResponse.of(page)); } } diff --git a/src/main/java/com/example/solidconnection/custom/response/PageResponse.java b/src/main/java/com/example/solidconnection/custom/response/PageResponse.java new file mode 100644 index 000000000..de128aea3 --- /dev/null +++ b/src/main/java/com/example/solidconnection/custom/response/PageResponse.java @@ -0,0 +1,23 @@ +package com.example.solidconnection.custom.response; + +import org.springframework.data.domain.Page; + +import java.util.List; + +public record PageResponse( + List content, + int pageNumber, + int pageSize, + long totalElements, + int totalPages +) { + public static PageResponse of(Page page) { + return new PageResponse<>( + page.getContent(), + page.getNumber() + 1, + page.getSize(), + page.getTotalElements(), + page.getTotalPages() + ); + } +} From 98ac050df9585dda795f74516bbadd34aa965f45 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Thu, 13 Feb 2025 19:01:01 +0900 Subject: [PATCH 06/22] =?UTF-8?q?chore:=20=EC=9E=98=EB=AA=BB=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=20=EB=9D=BC=EC=9D=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/ScoreVerificationAdminController.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 172768295..65b0c1833 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -27,7 +27,6 @@ public ResponseEntity> searchGpaScores( @Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition, Pageable pageable ) { - PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); Page page = scoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); return ResponseEntity.ok(PageResponse.of(page)); From 0866334d45280acc16bb51c2cc383cce5f52fb37 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 17:53:53 +0900 Subject: [PATCH 07/22] =?UTF-8?q?feat:=20=EA=B1=B0=EC=A0=88=20=EC=82=AC?= =?UTF-8?q?=EC=9C=A0=20=EA=B4=80=EB=A0=A8=20=EA=B2=80=EC=A6=9D=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/exception/ErrorCode.java | 2 + .../annotation/RejectedReasonRequired.java | 20 +++++ .../validator/RejectedReasonValidator.java | 49 +++++++++++ .../RejectedReasonValidatorTest.java | 83 +++++++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java create mode 100644 src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java create mode 100644 src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 23cd52786..93e224174 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -91,6 +91,8 @@ public enum ErrorCode { INVALID_LANGUAGE_TEST_SCORE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 어학성적입니다."), INVALID_LANGUAGE_TEST_SCORE_STATUS(HttpStatus.BAD_REQUEST.value(), "어학성적이 승인되지 않았습니다."), USER_DO_NOT_HAVE_GPA(HttpStatus.BAD_REQUEST.value(), "해당 유저의 학점을 찾을 수 없음"), + REJECTED_REASON_REQUIRED(HttpStatus.BAD_REQUEST.value(), "거절 상태일 경우에만 거절 사유가 필요합니다."), + REJECTED_REASON_NOT_ALLOWED(HttpStatus.BAD_REQUEST.value(), "거절 상태가 아닐 경우 거절 사유를 입력할 수 없습니다."), // page INVALID_PAGE(HttpStatus.BAD_REQUEST.value(), "페이지 번호가 최소값보다 작습니다."), diff --git a/src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java b/src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java new file mode 100644 index 000000000..4ae4a6618 --- /dev/null +++ b/src/main/java/com/example/solidconnection/custom/validation/annotation/RejectedReasonRequired.java @@ -0,0 +1,20 @@ +package com.example.solidconnection.custom.validation.annotation; + +import com.example.solidconnection.custom.validation.validator.RejectedReasonValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = RejectedReasonValidator.class) +public @interface RejectedReasonRequired { + + String message() default "거절 사유 입력값이 올바르지 않습니다."; + Class[] groups() default {}; + Class[] payload() default {}; +} diff --git a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java b/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java new file mode 100644 index 000000000..77914589e --- /dev/null +++ b/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java @@ -0,0 +1,49 @@ +package com.example.solidconnection.custom.validation.validator; + +import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired; +import com.example.solidconnection.type.VerifyStatus; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_NOT_ALLOWED; +import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_REQUIRED; + +public class RejectedReasonValidator implements ConstraintValidator { + + private static final String REJECTED_REASON = "rejectedReason"; + + @Override + public boolean isValid(GpaScoreVerifyRequest request, ConstraintValidatorContext context) { + context.disableDefaultConstraintViolation(); + + if (isRejectedWithoutReason(request)) { + addValidationError(context, REJECTED_REASON_REQUIRED.getMessage()); + return false; + } + + if (hasReasonWhenNotRejected(request)) { + addValidationError(context, REJECTED_REASON_NOT_ALLOWED.getMessage()); + return false; + } + + return true; + } + + private boolean isRejectedWithoutReason(GpaScoreVerifyRequest request) { + return request.verifyStatus().equals(VerifyStatus.REJECTED) + && (request.rejectedReason() == null || request.rejectedReason().trim().isEmpty()); + } + + private boolean hasReasonWhenNotRejected(GpaScoreVerifyRequest request) { + return !request.verifyStatus().equals(VerifyStatus.REJECTED) + && request.rejectedReason() != null + && !request.rejectedReason().trim().isEmpty(); + } + + private void addValidationError(ConstraintValidatorContext context, String message) { + context.buildConstraintViolationWithTemplate(message) + .addPropertyNode(REJECTED_REASON) + .addConstraintViolation(); + } +} diff --git a/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java b/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java new file mode 100644 index 000000000..7702167c5 --- /dev/null +++ b/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java @@ -0,0 +1,83 @@ +package com.example.solidconnection.custom.validation.validator; + +import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.type.VerifyStatus; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.Validation; +import jakarta.validation.Validator; +import jakarta.validation.ValidatorFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.Set; + +import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_NOT_ALLOWED; +import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_REQUIRED; +import static org.assertj.core.api.Assertions.assertThat; + +@DisplayName("거절 사유 유효성 검사 테스트") +class RejectedReasonValidatorTest { + + private static final String MESSAGE = "message"; + + private Validator validator; + + @BeforeEach + void setUp() { + ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); + validator = factory.getValidator(); + } + + @Test + void 거절상태일때_거절사유가_있으면_유효하다() { + // given + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.REJECTED, "부적합"); + + // when + Set> violations = validator.validate(request); + + // then + assertThat(violations).isEmpty(); + } + + @Test + void 승인상태일때_거절사유가_없으면_유효하다() { + // given + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.APPROVED, null); + + // when + Set> violations = validator.validate(request); + + // then + assertThat(violations).isEmpty(); + } + + @Test + void 거절상태일때_거절사유_없으면_예외_응답을_반환한다() { + // given + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.REJECTED, null); + + // when + Set> violations = validator.validate(request); + + // then + assertThat(violations) + .extracting(MESSAGE) + .contains(REJECTED_REASON_REQUIRED.getMessage()); + } + + @Test + void 거절상태아닐때_거절사유_입력하면_예외_응답을_반환한다() { + // given + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.APPROVED, "사유"); + + // when + Set> violations = validator.validate(request); + + // then + assertThat(violations) + .extracting(MESSAGE) + .contains(REJECTED_REASON_NOT_ALLOWED.getMessage()); + } +} From 57a8190f9fc0a6944cd7462533b54bffba70a2bc Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 17:54:30 +0900 Subject: [PATCH 08/22] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20GPA=20=EA=B2=80=EC=A6=9D=20api=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminController.java | 14 ++++++++++++++ .../admin/dto/GpaScoreVerificationResponse.java | 15 +++++++++++++++ .../admin/dto/GpaScoreVerifyRequest.java | 14 ++++++++++++++ .../service/ScoreVerificationAdminService.java | 14 ++++++++++++++ .../solidconnection/score/domain/GpaScore.java | 5 +++++ 5 files changed, 62 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 65b0c1833..d6e52bc4d 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -1,6 +1,8 @@ package com.example.solidconnection.admin.controller; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; +import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; import com.example.solidconnection.admin.dto.ScoreSearchCondition; import com.example.solidconnection.admin.service.ScoreVerificationAdminService; import com.example.solidconnection.custom.response.PageResponse; @@ -12,6 +14,9 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -31,4 +36,13 @@ public ResponseEntity> searchGpaScores( Page page = scoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); return ResponseEntity.ok(PageResponse.of(page)); } + + @PatchMapping("/gpas/{gpa_score_id}/verify") + public ResponseEntity verifyGpaScore( + @PathVariable("gpa_score_id") Long gpaScoreId, + @Valid @RequestBody GpaScoreVerifyRequest gpaScoreVerifyRequest + ) { + GpaScoreVerificationResponse response = scoreVerificationAdminService.verifyGpaScore(gpaScoreId, gpaScoreVerifyRequest); + return ResponseEntity.ok(response); + } } diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java new file mode 100644 index 000000000..35535db4f --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java @@ -0,0 +1,15 @@ +package com.example.solidconnection.admin.dto; + +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.type.VerifyStatus; + +public record GpaScoreVerificationResponse( + Long id, + VerifyStatus verifyStatus +) { + public static GpaScoreVerificationResponse of(GpaScore gpaScore) { + return new GpaScoreVerificationResponse( + gpaScore.getId(), + gpaScore.getVerifyStatus()); + } +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java new file mode 100644 index 000000000..55d3ad69b --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java @@ -0,0 +1,14 @@ +package com.example.solidconnection.admin.dto; + +import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired; +import com.example.solidconnection.type.VerifyStatus; +import jakarta.validation.constraints.NotNull; + +@RejectedReasonRequired +public record GpaScoreVerifyRequest( + @NotNull(message = "승인 여부를 설정해주세요.") + VerifyStatus verifyStatus, + + String rejectedReason +) { +} diff --git a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java index bbe19db85..878b16030 100644 --- a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java @@ -1,7 +1,11 @@ package com.example.solidconnection.admin.service; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; +import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; import com.example.solidconnection.admin.dto.ScoreSearchCondition; +import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.score.domain.GpaScore; import com.example.solidconnection.score.repository.GpaScoreRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; @@ -10,6 +14,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; + @RequiredArgsConstructor @Service public class ScoreVerificationAdminService { @@ -24,4 +30,12 @@ public Page searchGpaScores(ScoreSearchCondition scoreSe ); return gpaScoreRepository.searchGpaScores(scoreSearchCondition, sortedPageable); } + + @Transactional + public GpaScoreVerificationResponse verifyGpaScore(Long gpaScoreId, GpaScoreVerifyRequest request) { + GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) + .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); + gpaScore.updateGpaScore(request.verifyStatus(), request.rejectedReason()); + return GpaScoreVerificationResponse.of(gpaScore); + } } 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 54df13759..3cf83745d 100644 --- a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java +++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java @@ -55,4 +55,9 @@ public void setSiteUser(SiteUser siteUser) { this.siteUser = siteUser; siteUser.getGpaScoreList().add(this); } + + public void updateGpaScore(VerifyStatus verifyStatus, String rejectedReason) { + this.verifyStatus = verifyStatus; + this.rejectedReason = rejectedReason; + } } From a6f624c75f42263ec72d12a04a36e45456ab08a2 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:07:32 +0900 Subject: [PATCH 09/22] =?UTF-8?q?feat:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20GPA=20=EC=88=98=EC=A0=95=20api=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminController.java | 11 ++++ .../admin/dto/GpaUpdateRequest.java | 21 +++++++ .../admin/dto/GpaUpdateResponse.java | 20 +++++++ .../ScoreVerificationAdminService.java | 15 +++++ .../score/domain/GpaScore.java | 4 ++ .../ScoreVerificationAdminServiceTest.java | 60 +++++++++++++++++++ 6 files changed, 131 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index d6e52bc4d..6d67eebdb 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -3,6 +3,8 @@ import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.admin.dto.GpaUpdateRequest; +import com.example.solidconnection.admin.dto.GpaUpdateResponse; import com.example.solidconnection.admin.dto.ScoreSearchCondition; import com.example.solidconnection.admin.service.ScoreVerificationAdminService; import com.example.solidconnection.custom.response.PageResponse; @@ -37,6 +39,15 @@ public ResponseEntity> searchGpaScores( return ResponseEntity.ok(PageResponse.of(page)); } + @PatchMapping("/gpas/{gpa_score_id}") + public ResponseEntity updateGpaScore( + @PathVariable("gpa_score_id") Long gpaScoreId, + @Valid @RequestBody GpaUpdateRequest gpaUpdateRequest + ) { + GpaUpdateResponse response = scoreVerificationAdminService.updateGpaScore(gpaScoreId, gpaUpdateRequest); + return ResponseEntity.ok(response); + } + @PatchMapping("/gpas/{gpa_score_id}/verify") public ResponseEntity verifyGpaScore( @PathVariable("gpa_score_id") Long gpaScoreId, diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java b/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java new file mode 100644 index 000000000..095cb5a74 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java @@ -0,0 +1,21 @@ +package com.example.solidconnection.admin.dto; + +import com.example.solidconnection.score.domain.GpaScore; +import jakarta.validation.constraints.NotNull; + +public record GpaUpdateRequest( + @NotNull(message = "GPA를 입력해주세요.") + Double gpa, + + @NotNull(message = "GPA 기준을 입력해주세요.") + Double gpaCriteria +) { + public static GpaUpdateResponse of(GpaScore gpaScore) { + return new GpaUpdateResponse( + gpaScore.getId(), + gpaScore.getGpa().getGpa(), + gpaScore.getGpa().getGpaCriteria(), + gpaScore.getVerifyStatus() + ); + } +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java new file mode 100644 index 000000000..ceacc5da4 --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java @@ -0,0 +1,20 @@ +package com.example.solidconnection.admin.dto; + +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.type.VerifyStatus; + +public record GpaUpdateResponse( + Long id, + Double gpa, + Double gpaCriteria, + VerifyStatus verifyStatus +) { + public static GpaUpdateResponse of(GpaScore gpaScore) { + return new GpaUpdateResponse( + gpaScore.getId(), + gpaScore.getGpa().getGpa(), + gpaScore.getGpa().getGpaCriteria(), + gpaScore.getVerifyStatus() + ); + } +} diff --git a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java index 878b16030..80ed9c8f4 100644 --- a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java @@ -3,7 +3,10 @@ import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.admin.dto.GpaUpdateRequest; +import com.example.solidconnection.admin.dto.GpaUpdateResponse; 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.score.domain.GpaScore; import com.example.solidconnection.score.repository.GpaScoreRepository; @@ -31,6 +34,18 @@ public Page searchGpaScores(ScoreSearchCondition scoreSe return gpaScoreRepository.searchGpaScores(scoreSearchCondition, sortedPageable); } + @Transactional + public GpaUpdateResponse updateGpaScore(Long gpaScoreId, GpaUpdateRequest request) { + GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) + .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); + gpaScore.updateGpa(new Gpa( + request.gpa(), + request.gpaCriteria(), + gpaScore.getGpa().getGpaReportUrl() + )); + return GpaUpdateResponse.of(gpaScore); + } + @Transactional public GpaScoreVerificationResponse verifyGpaScore(Long gpaScoreId, GpaScoreVerifyRequest request) { GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) 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 3cf83745d..bf286ed77 100644 --- a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java +++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java @@ -60,4 +60,8 @@ public void updateGpaScore(VerifyStatus verifyStatus, String rejectedReason) { this.verifyStatus = verifyStatus; this.rejectedReason = rejectedReason; } + + public void updateGpa(Gpa gpa) { + this.gpa = gpa; + } } diff --git a/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java index 3c360cc81..7da543c44 100644 --- a/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java @@ -1,8 +1,11 @@ package com.example.solidconnection.admin.service; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; +import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; +import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; 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.score.domain.GpaScore; import com.example.solidconnection.score.repository.GpaScoreRepository; import com.example.solidconnection.siteuser.domain.SiteUser; @@ -24,7 +27,9 @@ import java.time.LocalDate; import java.util.List; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.junit.jupiter.api.Assertions.assertAll; @DisplayName("성적 검증 관리자 서비스 테스트") @@ -138,6 +143,61 @@ class 지원한_GPA_목록_조회 { } } + @Nested + class GPA_점수_검증 { + + @Test + void GPA_점수를_정상적으로_승인한다() { + // given + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest( + VerifyStatus.APPROVED, + null + ); + + // when + GpaScoreVerificationResponse response = scoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); + + // then + assertAll( + () -> assertThat(response.id()).isEqualTo(gpaScore1.getId()), + () -> assertThat(response.verifyStatus()).isEqualTo(VerifyStatus.APPROVED) + ); + } + + @Test + void GPA_점수를_정상적으로_거절한다() { + // given + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest( + VerifyStatus.REJECTED, + "잘못된 성적입니다." + ); + + // when + GpaScoreVerificationResponse response = scoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); + + // then + assertAll( + () -> assertThat(response.id()).isEqualTo(gpaScore1.getId()), + () -> assertThat(response.verifyStatus()).isEqualTo(VerifyStatus.REJECTED) + ); + } + + @Test + void 존재하지_않는_GPA_성적을_검증하면_예외_응답을_반환한다() { + // given + long invalidGpaScoreId = 9999L; + GpaScoreVerifyRequest request = new GpaScoreVerifyRequest( + VerifyStatus.APPROVED, + null + ); + + // when & then + assertThatCode(() -> scoreVerificationAdminService.verifyGpaScore(invalidGpaScoreId, request)) + .isInstanceOf(CustomException.class) + .hasMessage(INVALID_GPA_SCORE.getMessage()); + } + } + private SiteUser createSiteUser(int index, String nickname) { SiteUser siteUser = new SiteUser( "test" + index + " @example.com", From bf729a72cde826cf2d34f660f86a76834e10773f Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:25:14 +0900 Subject: [PATCH 10/22] =?UTF-8?q?refactor:=20updateGpaScore=20=E2=86=92=20?= =?UTF-8?q?updateGpa=20=EB=A9=94=EC=84=9C=EB=93=9C=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/ScoreVerificationAdminController.java | 4 ++-- .../admin/service/ScoreVerificationAdminService.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 6d67eebdb..58716e8a3 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -40,11 +40,11 @@ public ResponseEntity> searchGpaScores( } @PatchMapping("/gpas/{gpa_score_id}") - public ResponseEntity updateGpaScore( + public ResponseEntity updateGpa( @PathVariable("gpa_score_id") Long gpaScoreId, @Valid @RequestBody GpaUpdateRequest gpaUpdateRequest ) { - GpaUpdateResponse response = scoreVerificationAdminService.updateGpaScore(gpaScoreId, gpaUpdateRequest); + GpaUpdateResponse response = scoreVerificationAdminService.updateGpa(gpaScoreId, gpaUpdateRequest); return ResponseEntity.ok(response); } diff --git a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java index 80ed9c8f4..9069cfba6 100644 --- a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java @@ -35,7 +35,7 @@ public Page searchGpaScores(ScoreSearchCondition scoreSe } @Transactional - public GpaUpdateResponse updateGpaScore(Long gpaScoreId, GpaUpdateRequest request) { + public GpaUpdateResponse updateGpa(Long gpaScoreId, GpaUpdateRequest request) { GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); gpaScore.updateGpa(new Gpa( From d96d4753b8c35fe3522d687adc971be4d4c3772b Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:26:00 +0900 Subject: [PATCH 11/22] =?UTF-8?q?refactor:=20ScoreVerificationAdminService?= =?UTF-8?q?=20=E2=86=92=20GpaScoreVerificationAdminService=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminController.java | 10 +++++----- ...ava => GpaScoreVerificationAdminService.java} | 2 +- ...=> GpaScoreVerificationAdminServiceTest.java} | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) rename src/main/java/com/example/solidconnection/admin/service/{ScoreVerificationAdminService.java => GpaScoreVerificationAdminService.java} (98%) rename src/test/java/com/example/solidconnection/admin/service/{ScoreVerificationAdminServiceTest.java => GpaScoreVerificationAdminServiceTest.java} (91%) diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 58716e8a3..91d0a33d5 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -6,7 +6,7 @@ import com.example.solidconnection.admin.dto.GpaUpdateRequest; import com.example.solidconnection.admin.dto.GpaUpdateResponse; import com.example.solidconnection.admin.dto.ScoreSearchCondition; -import com.example.solidconnection.admin.service.ScoreVerificationAdminService; +import com.example.solidconnection.admin.service.GpaScoreVerificationAdminService; import com.example.solidconnection.custom.response.PageResponse; import com.example.solidconnection.util.PagingUtils; import jakarta.validation.Valid; @@ -27,7 +27,7 @@ @RestController public class ScoreVerificationAdminController { - private final ScoreVerificationAdminService scoreVerificationAdminService; + private final GpaScoreVerificationAdminService gpaScoreVerificationAdminService; @GetMapping("/gpas") public ResponseEntity> searchGpaScores( @@ -35,7 +35,7 @@ public ResponseEntity> searchGpaScores( Pageable pageable ) { PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); - Page page = scoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); + Page page = gpaScoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); return ResponseEntity.ok(PageResponse.of(page)); } @@ -44,7 +44,7 @@ public ResponseEntity updateGpa( @PathVariable("gpa_score_id") Long gpaScoreId, @Valid @RequestBody GpaUpdateRequest gpaUpdateRequest ) { - GpaUpdateResponse response = scoreVerificationAdminService.updateGpa(gpaScoreId, gpaUpdateRequest); + GpaUpdateResponse response = gpaScoreVerificationAdminService.updateGpa(gpaScoreId, gpaUpdateRequest); return ResponseEntity.ok(response); } @@ -53,7 +53,7 @@ public ResponseEntity verifyGpaScore( @PathVariable("gpa_score_id") Long gpaScoreId, @Valid @RequestBody GpaScoreVerifyRequest gpaScoreVerifyRequest ) { - GpaScoreVerificationResponse response = scoreVerificationAdminService.verifyGpaScore(gpaScoreId, gpaScoreVerifyRequest); + GpaScoreVerificationResponse response = gpaScoreVerificationAdminService.verifyGpaScore(gpaScoreId, gpaScoreVerifyRequest); return ResponseEntity.ok(response); } } diff --git a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java similarity index 98% rename from src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java rename to src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java index 9069cfba6..a5f3424e9 100644 --- a/src/main/java/com/example/solidconnection/admin/service/ScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java @@ -21,7 +21,7 @@ @RequiredArgsConstructor @Service -public class ScoreVerificationAdminService { +public class GpaScoreVerificationAdminService { private final GpaScoreRepository gpaScoreRepository; diff --git a/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java similarity index 91% rename from src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java rename to src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java index 7da543c44..d603b81ee 100644 --- a/src/test/java/com/example/solidconnection/admin/service/ScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java @@ -33,10 +33,10 @@ import static org.junit.jupiter.api.Assertions.assertAll; @DisplayName("성적 검증 관리자 서비스 테스트") -class ScoreVerificationAdminServiceTest extends BaseIntegrationTest { +class GpaScoreVerificationAdminServiceTest extends BaseIntegrationTest { @Autowired - private ScoreVerificationAdminService scoreVerificationAdminService; + private GpaScoreVerificationAdminService gpaScoreVerificationAdminService; @Autowired private SiteUserRepository siteUserRepository; @@ -72,7 +72,7 @@ class 지원한_GPA_목록_조회 { List expectedGpaScores = List.of(gpaScore1, gpaScore2); // when - Page response = scoreVerificationAdminService.searchGpaScores(condition, pageable); + Page response = gpaScoreVerificationAdminService.searchGpaScores(condition, pageable); // then assertThat(response.getContent()) @@ -98,7 +98,7 @@ class 지원한_GPA_목록_조회 { List expectedGpaScores = List.of(gpaScore1, gpaScore2, gpaScore3); // when - Page response = scoreVerificationAdminService.searchGpaScores(condition, pageable); + Page response = gpaScoreVerificationAdminService.searchGpaScores(condition, pageable); // then assertThat(response.getContent()) @@ -124,7 +124,7 @@ class 지원한_GPA_목록_조회 { List expectedGpaScores = List.of(gpaScore1); // when - Page response = scoreVerificationAdminService.searchGpaScores(condition, pageable); + Page response = gpaScoreVerificationAdminService.searchGpaScores(condition, pageable); // then assertThat(response.getContent()) @@ -155,7 +155,7 @@ class GPA_점수_검증 { ); // when - GpaScoreVerificationResponse response = scoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); + GpaScoreVerificationResponse response = gpaScoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); // then assertAll( @@ -173,7 +173,7 @@ class GPA_점수_검증 { ); // when - GpaScoreVerificationResponse response = scoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); + GpaScoreVerificationResponse response = gpaScoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); // then assertAll( @@ -192,7 +192,7 @@ class GPA_점수_검증 { ); // when & then - assertThatCode(() -> scoreVerificationAdminService.verifyGpaScore(invalidGpaScoreId, request)) + assertThatCode(() -> gpaScoreVerificationAdminService.verifyGpaScore(invalidGpaScoreId, request)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_GPA_SCORE.getMessage()); } From c1e2fadcd38f104efe40835386cc0476887530a0 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:31:30 +0900 Subject: [PATCH 12/22] =?UTF-8?q?test:=20=EA=B4=80=EB=A6=AC=EC=9E=90=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20GPA=20=EC=88=98=EC=A0=95=20api=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GpaScoreVerificationAdminServiceTest.java | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java index d603b81ee..2d18ff279 100644 --- a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java @@ -3,6 +3,8 @@ import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.admin.dto.GpaUpdateRequest; +import com.example.solidconnection.admin.dto.GpaUpdateResponse; import com.example.solidconnection.admin.dto.ScoreSearchCondition; import com.example.solidconnection.application.domain.Gpa; import com.example.solidconnection.custom.exception.CustomException; @@ -32,7 +34,7 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.junit.jupiter.api.Assertions.assertAll; -@DisplayName("성적 검증 관리자 서비스 테스트") +@DisplayName("학점 검증 관리자 서비스 테스트") class GpaScoreVerificationAdminServiceTest extends BaseIntegrationTest { @Autowired @@ -198,6 +200,30 @@ class GPA_점수_검증 { } } + @Nested + class GPA_수정 { + + @Test + void GPA와_GPA_기준을_정상적으로_수정한다() { + // given + GpaUpdateRequest request = new GpaUpdateRequest( + 3.8, + 4.3 + ); + + // when + GpaUpdateResponse response = gpaScoreVerificationAdminService.updateGpa(gpaScore1.getId(), request); + + // then + assertAll( + () -> assertThat(response.id()).isEqualTo(gpaScore1.getId()), + () -> assertThat(response.gpa()).isEqualTo(request.gpa()), + () -> assertThat(response.gpaCriteria()).isEqualTo(request.gpaCriteria()), + () -> assertThat(response.verifyStatus()).isEqualTo(gpaScore1.getVerifyStatus()) + ); + } + } + private SiteUser createSiteUser(int index, String nickname) { SiteUser siteUser = new SiteUser( "test" + index + " @example.com", From fb22382c26c629ca3b764bf11c36c9473dd321fd Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Fri, 14 Feb 2025 23:33:17 +0900 Subject: [PATCH 13/22] =?UTF-8?q?test:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20GPA=20=EA=B2=80=EC=A6=9D=20=EC=8B=A4=ED=8C=A8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GpaScoreVerificationAdminServiceTest.java | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java index 2d18ff279..d6f35eeac 100644 --- a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java @@ -7,7 +7,6 @@ import com.example.solidconnection.admin.dto.GpaUpdateResponse; 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.score.domain.GpaScore; import com.example.solidconnection.score.repository.GpaScoreRepository; import com.example.solidconnection.siteuser.domain.SiteUser; @@ -29,9 +28,7 @@ import java.time.LocalDate; import java.util.List; -import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.junit.jupiter.api.Assertions.assertAll; @DisplayName("학점 검증 관리자 서비스 테스트") @@ -183,21 +180,6 @@ class GPA_점수_검증 { () -> assertThat(response.verifyStatus()).isEqualTo(VerifyStatus.REJECTED) ); } - - @Test - void 존재하지_않는_GPA_성적을_검증하면_예외_응답을_반환한다() { - // given - long invalidGpaScoreId = 9999L; - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest( - VerifyStatus.APPROVED, - null - ); - - // when & then - assertThatCode(() -> gpaScoreVerificationAdminService.verifyGpaScore(invalidGpaScoreId, request)) - .isInstanceOf(CustomException.class) - .hasMessage(INVALID_GPA_SCORE.getMessage()); - } } @Nested From 28eef3b4793d5df855e095e89b2fd8bcabdb2273 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Sat, 15 Feb 2025 14:37:19 +0900 Subject: [PATCH 14/22] =?UTF-8?q?refactor:=20=ED=8E=98=EC=9D=B4=EC=A7=95?= =?UTF-8?q?=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20=EB=B0=8F=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../admin/controller/ScoreVerificationAdminController.java | 7 +++++-- .../admin/service/GpaScoreVerificationAdminService.java | 7 +------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index 91d0a33d5..e01da0abe 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -12,7 +12,9 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; @@ -32,10 +34,11 @@ public class ScoreVerificationAdminController { @GetMapping("/gpas") public ResponseEntity> searchGpaScores( @Valid @ModelAttribute ScoreSearchCondition scoreSearchCondition, - Pageable pageable + @PageableDefault(page = 1) Pageable pageable ) { PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); - Page page = gpaScoreVerificationAdminService.searchGpaScores(scoreSearchCondition, pageable); + Pageable internalPageable = PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize()); + Page page = gpaScoreVerificationAdminService.searchGpaScores(scoreSearchCondition, internalPageable); return ResponseEntity.ok(PageResponse.of(page)); } diff --git a/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java index a5f3424e9..581ca97d3 100644 --- a/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java @@ -12,7 +12,6 @@ import com.example.solidconnection.score.repository.GpaScoreRepository; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -27,11 +26,7 @@ public class GpaScoreVerificationAdminService { @Transactional(readOnly = true) public Page searchGpaScores(ScoreSearchCondition scoreSearchCondition, Pageable pageable) { - Pageable sortedPageable = PageRequest.of( - pageable.getPageNumber() - 1, - pageable.getPageSize() - ); - return gpaScoreRepository.searchGpaScores(scoreSearchCondition, sortedPageable); + return gpaScoreRepository.searchGpaScores(scoreSearchCondition, pageable); } @Transactional From f7ebafe587d103a564f8cf2089ef69f7ef762216 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Sat, 15 Feb 2025 14:57:59 +0900 Subject: [PATCH 15/22] =?UTF-8?q?refactor:=20GPA=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B2=80=EC=A6=9D=20=ED=95=98=EB=82=98=EC=9D=98=20?= =?UTF-8?q?api=EB=A1=9C=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ScoreVerificationAdminController.java | 21 +++--------- ...ateResponse.java => GpaScoreResponse.java} | 14 ++++---- ...equest.java => GpaScoreUpdateRequest.java} | 8 ++++- .../dto/GpaScoreVerificationResponse.java | 15 --------- .../admin/dto/GpaUpdateRequest.java | 21 ------------ .../GpaScoreVerificationAdminService.java | 33 ++++++++----------- .../custom/exception/ErrorCode.java | 3 +- .../validator/RejectedReasonValidator.java | 23 +++---------- .../score/domain/GpaScore.java | 3 +- 9 files changed, 41 insertions(+), 100 deletions(-) rename src/main/java/com/example/solidconnection/admin/dto/{GpaUpdateResponse.java => GpaScoreResponse.java} (57%) rename src/main/java/com/example/solidconnection/admin/dto/{GpaScoreVerifyRequest.java => GpaScoreUpdateRequest.java} (65%) delete mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java delete mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java index e01da0abe..7239888e6 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java @@ -1,10 +1,8 @@ package com.example.solidconnection.admin.controller; +import com.example.solidconnection.admin.dto.GpaScoreResponse; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; -import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; -import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; -import com.example.solidconnection.admin.dto.GpaUpdateRequest; -import com.example.solidconnection.admin.dto.GpaUpdateResponse; +import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest; import com.example.solidconnection.admin.dto.ScoreSearchCondition; import com.example.solidconnection.admin.service.GpaScoreVerificationAdminService; import com.example.solidconnection.custom.response.PageResponse; @@ -43,20 +41,11 @@ public ResponseEntity> searchGpaScores( } @PatchMapping("/gpas/{gpa_score_id}") - public ResponseEntity updateGpa( + public ResponseEntity updateGpaScore( @PathVariable("gpa_score_id") Long gpaScoreId, - @Valid @RequestBody GpaUpdateRequest gpaUpdateRequest + @Valid @RequestBody GpaScoreUpdateRequest request ) { - GpaUpdateResponse response = gpaScoreVerificationAdminService.updateGpa(gpaScoreId, gpaUpdateRequest); - return ResponseEntity.ok(response); - } - - @PatchMapping("/gpas/{gpa_score_id}/verify") - public ResponseEntity verifyGpaScore( - @PathVariable("gpa_score_id") Long gpaScoreId, - @Valid @RequestBody GpaScoreVerifyRequest gpaScoreVerifyRequest - ) { - GpaScoreVerificationResponse response = gpaScoreVerificationAdminService.verifyGpaScore(gpaScoreId, gpaScoreVerifyRequest); + GpaScoreResponse response = gpaScoreVerificationAdminService.updateGpaScore(gpaScoreId, request); return ResponseEntity.ok(response); } } diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java similarity index 57% rename from src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java rename to src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java index ceacc5da4..e89be1708 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateResponse.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java @@ -3,18 +3,20 @@ import com.example.solidconnection.score.domain.GpaScore; import com.example.solidconnection.type.VerifyStatus; -public record GpaUpdateResponse( +public record GpaScoreResponse( Long id, Double gpa, Double gpaCriteria, - VerifyStatus verifyStatus + VerifyStatus verifyStatus, + String rejectedReason ) { - public static GpaUpdateResponse of(GpaScore gpaScore) { - return new GpaUpdateResponse( + public static GpaScoreResponse of(GpaScore gpaScore) { + return new GpaScoreResponse( gpaScore.getId(), gpaScore.getGpa().getGpa(), gpaScore.getGpa().getGpaCriteria(), - gpaScore.getVerifyStatus() + gpaScore.getVerifyStatus(), + gpaScore.getRejectedReason() ); } -} +} \ No newline at end of file diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java similarity index 65% rename from src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java rename to src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java index 55d3ad69b..8d14039bd 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerifyRequest.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java @@ -5,7 +5,13 @@ import jakarta.validation.constraints.NotNull; @RejectedReasonRequired -public record GpaScoreVerifyRequest( +public record GpaScoreUpdateRequest( + @NotNull(message = "GPA를 입력해주세요.") + Double gpa, + + @NotNull(message = "GPA 기준을 입력해주세요.") + Double gpaCriteria, + @NotNull(message = "승인 여부를 설정해주세요.") VerifyStatus verifyStatus, diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java deleted file mode 100644 index 35535db4f..000000000 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreVerificationResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.example.solidconnection.admin.dto; - -import com.example.solidconnection.score.domain.GpaScore; -import com.example.solidconnection.type.VerifyStatus; - -public record GpaScoreVerificationResponse( - Long id, - VerifyStatus verifyStatus -) { - public static GpaScoreVerificationResponse of(GpaScore gpaScore) { - return new GpaScoreVerificationResponse( - gpaScore.getId(), - gpaScore.getVerifyStatus()); - } -} diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java b/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java deleted file mode 100644 index 095cb5a74..000000000 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaUpdateRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.example.solidconnection.admin.dto; - -import com.example.solidconnection.score.domain.GpaScore; -import jakarta.validation.constraints.NotNull; - -public record GpaUpdateRequest( - @NotNull(message = "GPA를 입력해주세요.") - Double gpa, - - @NotNull(message = "GPA 기준을 입력해주세요.") - Double gpaCriteria -) { - public static GpaUpdateResponse of(GpaScore gpaScore) { - return new GpaUpdateResponse( - gpaScore.getId(), - gpaScore.getGpa().getGpa(), - gpaScore.getGpa().getGpaCriteria(), - gpaScore.getVerifyStatus() - ); - } -} diff --git a/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java index 581ca97d3..484b14ad7 100644 --- a/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java @@ -1,15 +1,14 @@ package com.example.solidconnection.admin.service; +import com.example.solidconnection.admin.dto.GpaScoreResponse; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; -import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; -import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; -import com.example.solidconnection.admin.dto.GpaUpdateRequest; -import com.example.solidconnection.admin.dto.GpaUpdateResponse; +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.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; @@ -30,22 +29,18 @@ public Page searchGpaScores(ScoreSearchCondition scoreSe } @Transactional - public GpaUpdateResponse updateGpa(Long gpaScoreId, GpaUpdateRequest request) { + public GpaScoreResponse updateGpaScore(Long gpaScoreId, GpaScoreUpdateRequest request) { GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); - gpaScore.updateGpa(new Gpa( - request.gpa(), - request.gpaCriteria(), - gpaScore.getGpa().getGpaReportUrl() - )); - return GpaUpdateResponse.of(gpaScore); - } - - @Transactional - public GpaScoreVerificationResponse verifyGpaScore(Long gpaScoreId, GpaScoreVerifyRequest request) { - GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) - .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); - gpaScore.updateGpaScore(request.verifyStatus(), request.rejectedReason()); - return GpaScoreVerificationResponse.of(gpaScore); + gpaScore.updateGpaScore( + new Gpa( + request.gpa(), + request.gpaCriteria(), + gpaScore.getGpa().getGpaReportUrl() + ), + request.verifyStatus(), + request.verifyStatus() == VerifyStatus.REJECTED ? request.rejectedReason() : null + ); + return GpaScoreResponse.of(gpaScore); } } diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 93e224174..d4aa8cb80 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -91,8 +91,7 @@ public enum ErrorCode { INVALID_LANGUAGE_TEST_SCORE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 어학성적입니다."), INVALID_LANGUAGE_TEST_SCORE_STATUS(HttpStatus.BAD_REQUEST.value(), "어학성적이 승인되지 않았습니다."), USER_DO_NOT_HAVE_GPA(HttpStatus.BAD_REQUEST.value(), "해당 유저의 학점을 찾을 수 없음"), - REJECTED_REASON_REQUIRED(HttpStatus.BAD_REQUEST.value(), "거절 상태일 경우에만 거절 사유가 필요합니다."), - REJECTED_REASON_NOT_ALLOWED(HttpStatus.BAD_REQUEST.value(), "거절 상태가 아닐 경우 거절 사유를 입력할 수 없습니다."), + REJECTED_REASON_REQUIRED(HttpStatus.BAD_REQUEST.value(), "거절 사유가 필요합니다."), // page INVALID_PAGE(HttpStatus.BAD_REQUEST.value(), "페이지 번호가 최소값보다 작습니다."), diff --git a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java b/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java index 77914589e..9a0ff1635 100644 --- a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java +++ b/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java @@ -1,46 +1,31 @@ package com.example.solidconnection.custom.validation.validator; -import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest; import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired; import com.example.solidconnection.type.VerifyStatus; import jakarta.validation.ConstraintValidator; import jakarta.validation.ConstraintValidatorContext; -import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_NOT_ALLOWED; import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_REQUIRED; -public class RejectedReasonValidator implements ConstraintValidator { - +public class RejectedReasonValidator implements ConstraintValidator { private static final String REJECTED_REASON = "rejectedReason"; @Override - public boolean isValid(GpaScoreVerifyRequest request, ConstraintValidatorContext context) { + public boolean isValid(GpaScoreUpdateRequest request, ConstraintValidatorContext context) { context.disableDefaultConstraintViolation(); - if (isRejectedWithoutReason(request)) { addValidationError(context, REJECTED_REASON_REQUIRED.getMessage()); return false; } - - if (hasReasonWhenNotRejected(request)) { - addValidationError(context, REJECTED_REASON_NOT_ALLOWED.getMessage()); - return false; - } - return true; } - private boolean isRejectedWithoutReason(GpaScoreVerifyRequest request) { + private boolean isRejectedWithoutReason(GpaScoreUpdateRequest request) { return request.verifyStatus().equals(VerifyStatus.REJECTED) && (request.rejectedReason() == null || request.rejectedReason().trim().isEmpty()); } - private boolean hasReasonWhenNotRejected(GpaScoreVerifyRequest request) { - return !request.verifyStatus().equals(VerifyStatus.REJECTED) - && request.rejectedReason() != null - && !request.rejectedReason().trim().isEmpty(); - } - private void addValidationError(ConstraintValidatorContext context, String message) { context.buildConstraintViolationWithTemplate(message) .addPropertyNode(REJECTED_REASON) 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 bf286ed77..ddc583aa7 100644 --- a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java +++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java @@ -56,7 +56,8 @@ public void setSiteUser(SiteUser siteUser) { siteUser.getGpaScoreList().add(this); } - public void updateGpaScore(VerifyStatus verifyStatus, String rejectedReason) { + public void updateGpaScore(Gpa gpa, VerifyStatus verifyStatus, String rejectedReason) { + this.gpa = gpa; this.verifyStatus = verifyStatus; this.rejectedReason = rejectedReason; } From 72d629c2ea8e159db77de9cb08ad84c9584836ef Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Sat, 15 Feb 2025 15:20:46 +0900 Subject: [PATCH 16/22] =?UTF-8?q?test:=20=ED=86=B5=ED=95=A9=EB=90=9C=20api?= =?UTF-8?q?=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GpaScoreVerificationAdminServiceTest.java | 74 ++++++++++--------- .../RejectedReasonValidatorTest.java | 51 +++++-------- .../solidconnection/util/PagingUtilsTest.java | 5 +- 3 files changed, 58 insertions(+), 72 deletions(-) diff --git a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java index d6f35eeac..6f59e7787 100644 --- a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java @@ -1,12 +1,11 @@ package com.example.solidconnection.admin.service; +import com.example.solidconnection.admin.dto.GpaScoreResponse; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; -import com.example.solidconnection.admin.dto.GpaScoreVerificationResponse; -import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; -import com.example.solidconnection.admin.dto.GpaUpdateRequest; -import com.example.solidconnection.admin.dto.GpaUpdateResponse; +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.score.domain.GpaScore; import com.example.solidconnection.score.repository.GpaScoreRepository; import com.example.solidconnection.siteuser.domain.SiteUser; @@ -28,7 +27,9 @@ import java.time.LocalDate; import java.util.List; +import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.junit.jupiter.api.Assertions.assertAll; @DisplayName("학점 검증 관리자 서비스 테스트") @@ -67,7 +68,7 @@ class 지원한_GPA_목록_조회 { void 검증_상태를_조건으로_페이징하여_조회한다() { // given ScoreSearchCondition condition = new ScoreSearchCondition(VerifyStatus.PENDING, null, null); - Pageable pageable = PageRequest.of(1, 10); + Pageable pageable = PageRequest.of(0, 10); List expectedGpaScores = List.of(gpaScore1, gpaScore2); // when @@ -93,7 +94,7 @@ class 지원한_GPA_목록_조회 { void 닉네임으로_페이징하여_조회한다() { // given ScoreSearchCondition condition = new ScoreSearchCondition(null, "test", null); - Pageable pageable = PageRequest.of(1, 10); + Pageable pageable = PageRequest.of(0, 10); List expectedGpaScores = List.of(gpaScore1, gpaScore2, gpaScore3); // when @@ -119,7 +120,7 @@ class 지원한_GPA_목록_조회 { void 모든_조건으로_페이징하여_조회한다() { // given ScoreSearchCondition condition = new ScoreSearchCondition(VerifyStatus.PENDING, "test1", LocalDate.now()); - Pageable pageable = PageRequest.of(1, 10); + Pageable pageable = PageRequest.of(0, 10); List expectedGpaScores = List.of(gpaScore1); // when @@ -143,66 +144,69 @@ class 지원한_GPA_목록_조회 { } @Nested - class GPA_점수_검증 { + class GPA_점수_검증_및_수정 { @Test - void GPA_점수를_정상적으로_승인한다() { + void GPA와_검증상태를_정상적으로_수정한다() { // given - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest( + GpaScoreUpdateRequest request = new GpaScoreUpdateRequest( + 3.8, + 4.3, VerifyStatus.APPROVED, null ); // when - GpaScoreVerificationResponse response = gpaScoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); + GpaScoreResponse response = gpaScoreVerificationAdminService.updateGpaScore(gpaScore1.getId(), request); // then assertAll( () -> assertThat(response.id()).isEqualTo(gpaScore1.getId()), - () -> assertThat(response.verifyStatus()).isEqualTo(VerifyStatus.APPROVED) + () -> assertThat(response.gpa()).isEqualTo(request.gpa()), + () -> assertThat(response.gpaCriteria()).isEqualTo(request.gpaCriteria()), + () -> assertThat(response.verifyStatus()).isEqualTo(request.verifyStatus()), + () -> assertThat(response.rejectedReason()).isNull() ); } @Test - void GPA_점수를_정상적으로_거절한다() { + void 승인상태로_변경_시_거절사유가_입력되어도_null로_저장된다() { // given - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest( - VerifyStatus.REJECTED, - "잘못된 성적입니다." + GpaScoreUpdateRequest request = new GpaScoreUpdateRequest( + 3.8, + 4.3, + VerifyStatus.APPROVED, + "이 거절사유는 무시되어야 함" ); // when - GpaScoreVerificationResponse response = gpaScoreVerificationAdminService.verifyGpaScore(gpaScore1.getId(), request); + GpaScoreResponse response = gpaScoreVerificationAdminService.updateGpaScore(gpaScore1.getId(), request); // then assertAll( () -> assertThat(response.id()).isEqualTo(gpaScore1.getId()), - () -> assertThat(response.verifyStatus()).isEqualTo(VerifyStatus.REJECTED) + () -> assertThat(response.gpa()).isEqualTo(request.gpa()), + () -> assertThat(response.gpaCriteria()).isEqualTo(request.gpaCriteria()), + () -> assertThat(response.verifyStatus()).isEqualTo(VerifyStatus.APPROVED), + () -> assertThat(response.rejectedReason()).isNull() ); } - } - - @Nested - class GPA_수정 { @Test - void GPA와_GPA_기준을_정상적으로_수정한다() { + void 존재하지_않는_GPA_수정_시_예외_응답을_반환한다() { // given - GpaUpdateRequest request = new GpaUpdateRequest( + long invalidGpaScoreId = 9999L; + GpaScoreUpdateRequest request = new GpaScoreUpdateRequest( 3.8, - 4.3 + 4.3, + VerifyStatus.APPROVED, + null ); - // when - GpaUpdateResponse response = gpaScoreVerificationAdminService.updateGpa(gpaScore1.getId(), request); - - // then - assertAll( - () -> assertThat(response.id()).isEqualTo(gpaScore1.getId()), - () -> assertThat(response.gpa()).isEqualTo(request.gpa()), - () -> assertThat(response.gpaCriteria()).isEqualTo(request.gpaCriteria()), - () -> assertThat(response.verifyStatus()).isEqualTo(gpaScore1.getVerifyStatus()) - ); + // when & then + assertThatCode(() -> gpaScoreVerificationAdminService.updateGpaScore(invalidGpaScoreId, request)) + .isInstanceOf(CustomException.class) + .hasMessage(INVALID_GPA_SCORE.getMessage()); } } diff --git a/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java b/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java index 7702167c5..ecadd8aff 100644 --- a/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java +++ b/src/test/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidatorTest.java @@ -1,6 +1,6 @@ package com.example.solidconnection.custom.validation.validator; -import com.example.solidconnection.admin.dto.GpaScoreVerifyRequest; +import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest; import com.example.solidconnection.type.VerifyStatus; import jakarta.validation.ConstraintViolation; import jakarta.validation.Validation; @@ -12,7 +12,6 @@ import java.util.Set; -import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_NOT_ALLOWED; import static com.example.solidconnection.custom.exception.ErrorCode.REJECTED_REASON_REQUIRED; import static org.assertj.core.api.Assertions.assertThat; @@ -30,54 +29,38 @@ void setUp() { } @Test - void 거절상태일때_거절사유가_있으면_유효하다() { + void 거절_상태일_때_거절사유가_있으면_유효하다() { // given - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.REJECTED, "부적합"); + GpaScoreUpdateRequest request = new GpaScoreUpdateRequest( + 3.0, + 4.5, + VerifyStatus.REJECTED, + "부적합" + ); // when - Set> violations = validator.validate(request); + Set> violations = validator.validate(request); // then assertThat(violations).isEmpty(); } @Test - void 승인상태일때_거절사유가_없으면_유효하다() { + void 거절_상태일_때_거절사유가_없으면_예외_응답을_반환한다() { // given - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.APPROVED, null); + GpaScoreUpdateRequest request = new GpaScoreUpdateRequest( + 3.0, + 4.5, + VerifyStatus.REJECTED, + null + ); // when - Set> violations = validator.validate(request); - - // then - assertThat(violations).isEmpty(); - } - - @Test - void 거절상태일때_거절사유_없으면_예외_응답을_반환한다() { - // given - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.REJECTED, null); - - // when - Set> violations = validator.validate(request); + Set> violations = validator.validate(request); // then assertThat(violations) .extracting(MESSAGE) .contains(REJECTED_REASON_REQUIRED.getMessage()); } - - @Test - void 거절상태아닐때_거절사유_입력하면_예외_응답을_반환한다() { - // given - GpaScoreVerifyRequest request = new GpaScoreVerifyRequest(VerifyStatus.APPROVED, "사유"); - - // when - Set> violations = validator.validate(request); - - // then - assertThat(violations) - .extracting(MESSAGE) - .contains(REJECTED_REASON_NOT_ALLOWED.getMessage()); - } } diff --git a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java index 1557898a8..7e71911d7 100644 --- a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java +++ b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java @@ -7,7 +7,6 @@ import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_PAGE; import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SIZE; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; @DisplayName("PagingUtils 테스트") class PagingUtilsTest { @@ -31,7 +30,7 @@ void validateValidPageAndSize() { int validSize = 10; // when & then - assertThatThrownBy(() -> PagingUtils.validatePage(invalidPage, validSize)) + assertThatCode(() -> PagingUtils.validatePage(invalidPage, validSize)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_PAGE.getMessage()); } @@ -43,7 +42,7 @@ void validateValidPageAndSize() { int invalidSize = 0; // when & then - assertThatThrownBy(() -> PagingUtils.validatePage(validPage, invalidSize)) + assertThatCode(() -> PagingUtils.validatePage(validPage, invalidSize)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_SIZE.getMessage()); } From c74d396eb38801bf4a1ab7a5a63d1462c69fecff Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Mon, 17 Feb 2025 13:09:55 +0900 Subject: [PATCH 17/22] =?UTF-8?q?style:=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81=ED=95=98=EC=97=AC=20=EB=84=A4?= =?UTF-8?q?=EC=9D=B4=EB=B0=8D=20=EB=B0=8F=20=EA=B0=9C=ED=96=89=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/domain/QApplication.java | 7 ++ .../siteuser/domain/QSiteUser.java | 15 ++++ .../domain/QUniversityInfoForApply.java | 2 + ...troller.java => AdminScoreController.java} | 10 +-- .../admin/dto/GpaScoreResponse.java | 10 +-- .../admin/dto/GpaScoreSearchResponse.java | 4 +- ...tatus.java => GpaScoreStatusResponse.java} | 4 +- .../admin/dto/GpaScoreUpdateRequest.java | 2 +- ...SiteUserDto.java => SiteUserResponse.java} | 4 +- ...Service.java => AdminGpaScoreService.java} | 8 +-- .../service/ApplicationSubmissionService.java | 9 +-- .../custom/exception/ErrorCode.java | 2 +- .../custom/response/PageResponse.java | 3 + .../validator/RejectedReasonValidator.java | 4 +- .../custom/GpaScoreFilterRepositoryImpl.java | 9 +-- .../GpaScoreVerificationAdminServiceTest.java | 72 +++++++++---------- 16 files changed, 95 insertions(+), 70 deletions(-) rename src/main/java/com/example/solidconnection/admin/controller/{ScoreVerificationAdminController.java => AdminScoreController.java} (81%) rename src/main/java/com/example/solidconnection/admin/dto/{GpaScoreStatus.java => GpaScoreStatusResponse.java} (86%) rename src/main/java/com/example/solidconnection/admin/dto/{SiteUserDto.java => SiteUserResponse.java} (69%) rename src/main/java/com/example/solidconnection/admin/service/{GpaScoreVerificationAdminService.java => AdminGpaScoreService.java} (90%) diff --git a/src/main/generated/com/example/solidconnection/application/domain/QApplication.java b/src/main/generated/com/example/solidconnection/application/domain/QApplication.java index 742603411..764baa7cf 100644 --- a/src/main/generated/com/example/solidconnection/application/domain/QApplication.java +++ b/src/main/generated/com/example/solidconnection/application/domain/QApplication.java @@ -28,6 +28,8 @@ public class QApplication extends EntityPathBase { public final NumberPath id = createNumber("id", Long.class); + public final BooleanPath isDelete = createBoolean("isDelete"); + public final QLanguageTest languageTest; public final StringPath nicknameForApply = createString("nicknameForApply"); @@ -36,6 +38,10 @@ public class QApplication extends EntityPathBase { public final com.example.solidconnection.siteuser.domain.QSiteUser siteUser; + public final StringPath term = createString("term"); + + public final com.example.solidconnection.university.domain.QUniversityInfoForApply thirdChoiceUniversity; + public final NumberPath updateCount = createNumber("updateCount", Integer.class); public final EnumPath verifyStatus = createEnum("verifyStatus", com.example.solidconnection.type.VerifyStatus.class); @@ -63,6 +69,7 @@ public QApplication(Class type, PathMetadata metadata, Pa this.languageTest = inits.isInitialized("languageTest") ? new QLanguageTest(forProperty("languageTest")) : null; this.secondChoiceUniversity = inits.isInitialized("secondChoiceUniversity") ? new com.example.solidconnection.university.domain.QUniversityInfoForApply(forProperty("secondChoiceUniversity"), inits.get("secondChoiceUniversity")) : null; this.siteUser = inits.isInitialized("siteUser") ? new com.example.solidconnection.siteuser.domain.QSiteUser(forProperty("siteUser")) : null; + this.thirdChoiceUniversity = inits.isInitialized("thirdChoiceUniversity") ? new com.example.solidconnection.university.domain.QUniversityInfoForApply(forProperty("thirdChoiceUniversity"), inits.get("thirdChoiceUniversity")) : null; } } diff --git a/src/main/generated/com/example/solidconnection/siteuser/domain/QSiteUser.java b/src/main/generated/com/example/solidconnection/siteuser/domain/QSiteUser.java index a1879a555..ac4af0986 100644 --- a/src/main/generated/com/example/solidconnection/siteuser/domain/QSiteUser.java +++ b/src/main/generated/com/example/solidconnection/siteuser/domain/QSiteUser.java @@ -7,6 +7,7 @@ import com.querydsl.core.types.PathMetadata; import javax.annotation.processing.Generated; import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; /** @@ -19,18 +20,32 @@ public class QSiteUser extends EntityPathBase { public static final QSiteUser siteUser = new QSiteUser("siteUser"); + public final EnumPath authType = createEnum("authType", AuthType.class); + public final StringPath birth = createString("birth"); + public final ListPath commentList = this.createList("commentList", com.example.solidconnection.community.comment.domain.Comment.class, com.example.solidconnection.community.comment.domain.QComment.class, PathInits.DIRECT2); + public final StringPath email = createString("email"); public final EnumPath gender = createEnum("gender", com.example.solidconnection.type.Gender.class); + public final ListPath gpaScoreList = this.createList("gpaScoreList", com.example.solidconnection.score.domain.GpaScore.class, com.example.solidconnection.score.domain.QGpaScore.class, PathInits.DIRECT2); + public final NumberPath id = createNumber("id", Long.class); + public final ListPath languageTestScoreList = this.createList("languageTestScoreList", com.example.solidconnection.score.domain.LanguageTestScore.class, com.example.solidconnection.score.domain.QLanguageTestScore.class, PathInits.DIRECT2); + public final StringPath nickname = createString("nickname"); public final DateTimePath nicknameModifiedAt = createDateTime("nicknameModifiedAt", java.time.LocalDateTime.class); + public final StringPath password = createString("password"); + + public final ListPath postLikeList = this.createList("postLikeList", com.example.solidconnection.community.post.domain.PostLike.class, com.example.solidconnection.community.post.domain.QPostLike.class, PathInits.DIRECT2); + + public final ListPath postList = this.createList("postList", com.example.solidconnection.community.post.domain.Post.class, com.example.solidconnection.community.post.domain.QPost.class, PathInits.DIRECT2); + public final EnumPath preparationStage = createEnum("preparationStage", com.example.solidconnection.type.PreparationStatus.class); public final StringPath profileImageUrl = createString("profileImageUrl"); diff --git a/src/main/generated/com/example/solidconnection/university/domain/QUniversityInfoForApply.java b/src/main/generated/com/example/solidconnection/university/domain/QUniversityInfoForApply.java index 5ad64cfd7..4b4c55546 100644 --- a/src/main/generated/com/example/solidconnection/university/domain/QUniversityInfoForApply.java +++ b/src/main/generated/com/example/solidconnection/university/domain/QUniversityInfoForApply.java @@ -40,6 +40,8 @@ public class QUniversityInfoForApply extends EntityPathBase id = createNumber("id", Long.class); + public final StringPath koreanName = createString("koreanName"); + public final SetPath languageRequirements = this.createSet("languageRequirements", LanguageRequirement.class, QLanguageRequirement.class, PathInits.DIRECT2); public final EnumPath semesterAvailableForDispatch = createEnum("semesterAvailableForDispatch", com.example.solidconnection.type.SemesterAvailableForDispatch.class); diff --git a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java b/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java similarity index 81% rename from src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java rename to src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java index 7239888e6..80e223690 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/ScoreVerificationAdminController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java @@ -4,7 +4,7 @@ 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.admin.service.GpaScoreVerificationAdminService; +import com.example.solidconnection.admin.service.AdminGpaScoreService; import com.example.solidconnection.custom.response.PageResponse; import com.example.solidconnection.util.PagingUtils; import jakarta.validation.Valid; @@ -25,9 +25,9 @@ @RequiredArgsConstructor @RequestMapping("/admin/scores") @RestController -public class ScoreVerificationAdminController { +public class AdminScoreController { - private final GpaScoreVerificationAdminService gpaScoreVerificationAdminService; + private final AdminGpaScoreService adminGpaScoreService; @GetMapping("/gpas") public ResponseEntity> searchGpaScores( @@ -36,7 +36,7 @@ public ResponseEntity> searchGpaScores( ) { PagingUtils.validatePage(pageable.getPageNumber(), pageable.getPageSize()); Pageable internalPageable = PageRequest.of(pageable.getPageNumber() - 1, pageable.getPageSize()); - Page page = gpaScoreVerificationAdminService.searchGpaScores(scoreSearchCondition, internalPageable); + Page page = adminGpaScoreService.searchGpaScores(scoreSearchCondition, internalPageable); return ResponseEntity.ok(PageResponse.of(page)); } @@ -45,7 +45,7 @@ public ResponseEntity updateGpaScore( @PathVariable("gpa_score_id") Long gpaScoreId, @Valid @RequestBody GpaScoreUpdateRequest request ) { - GpaScoreResponse response = gpaScoreVerificationAdminService.updateGpaScore(gpaScoreId, request); + GpaScoreResponse response = adminGpaScoreService.updateGpaScore(gpaScoreId, request); return ResponseEntity.ok(response); } } 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 e89be1708..5f37e823b 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreResponse.java @@ -4,13 +4,13 @@ import com.example.solidconnection.type.VerifyStatus; public record GpaScoreResponse( - Long id, - Double gpa, - Double gpaCriteria, + long id, + double gpa, + double gpaCriteria, VerifyStatus verifyStatus, String rejectedReason ) { - public static GpaScoreResponse of(GpaScore gpaScore) { + public static GpaScoreResponse from(GpaScore gpaScore) { return new GpaScoreResponse( gpaScore.getId(), gpaScore.getGpa().getGpa(), @@ -19,4 +19,4 @@ public static GpaScoreResponse of(GpaScore gpaScore) { gpaScore.getRejectedReason() ); } -} \ No newline at end of file +} diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java index 14fc60af9..2da39fb88 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreSearchResponse.java @@ -1,7 +1,7 @@ package com.example.solidconnection.admin.dto; public record GpaScoreSearchResponse( - GpaScoreStatus gpaScoreStatus, - SiteUserDto siteUserDto + GpaScoreStatusResponse gpaScoreStatusResponse, + SiteUserResponse siteUserResponse ) { } diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java similarity index 86% rename from src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java rename to src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java index e16206290..295a8f758 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatus.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java @@ -5,8 +5,8 @@ import java.time.ZonedDateTime; -public record GpaScoreStatus( - Long id, +public record GpaScoreStatusResponse( + long id, Gpa gpa, VerifyStatus verifyStatus, String rejectedReason, 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 8d14039bd..d247200a3 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java @@ -12,7 +12,7 @@ public record GpaScoreUpdateRequest( @NotNull(message = "GPA 기준을 입력해주세요.") Double gpaCriteria, - @NotNull(message = "승인 여부를 설정해주세요.") + @NotNull(message = "승인 상태를 설정해주세요.") VerifyStatus verifyStatus, String rejectedReason diff --git a/src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java b/src/main/java/com/example/solidconnection/admin/dto/SiteUserResponse.java similarity index 69% rename from src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java rename to src/main/java/com/example/solidconnection/admin/dto/SiteUserResponse.java index dbbb8cbd8..1b62f262f 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/SiteUserDto.java +++ b/src/main/java/com/example/solidconnection/admin/dto/SiteUserResponse.java @@ -1,7 +1,7 @@ package com.example.solidconnection.admin.dto; -public record SiteUserDto( - Long id, +public record SiteUserResponse( + long id, String nickname, String profileImageUrl ) { diff --git a/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java b/src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java similarity index 90% rename from src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java rename to src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java index 484b14ad7..c761ff485 100644 --- a/src/main/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminService.java +++ b/src/main/java/com/example/solidconnection/admin/service/AdminGpaScoreService.java @@ -15,11 +15,11 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; +import static com.example.solidconnection.custom.exception.ErrorCode.GPA_SCORE_NOT_FOUND; @RequiredArgsConstructor @Service -public class GpaScoreVerificationAdminService { +public class AdminGpaScoreService { private final GpaScoreRepository gpaScoreRepository; @@ -31,7 +31,7 @@ public Page searchGpaScores(ScoreSearchCondition scoreSe @Transactional public GpaScoreResponse updateGpaScore(Long gpaScoreId, GpaScoreUpdateRequest request) { GpaScore gpaScore = gpaScoreRepository.findById(gpaScoreId) - .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); + .orElseThrow(() -> new CustomException(GPA_SCORE_NOT_FOUND)); gpaScore.updateGpaScore( new Gpa( request.gpa(), @@ -41,6 +41,6 @@ public GpaScoreResponse updateGpaScore(Long gpaScoreId, GpaScoreUpdateRequest re request.verifyStatus(), request.verifyStatus() == VerifyStatus.REJECTED ? request.rejectedReason() : null ); - return GpaScoreResponse.of(gpaScore); + return GpaScoreResponse.from(gpaScore); } } 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 dec092f5e..b493e197d 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java @@ -18,15 +18,10 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; import java.util.Optional; -import java.util.Set; import static com.example.solidconnection.custom.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED; -import static com.example.solidconnection.custom.exception.ErrorCode.CANT_APPLY_FOR_SAME_UNIVERSITY; -import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; +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; @@ -87,7 +82,7 @@ public boolean apply(SiteUser siteUser, ApplyRequest applyRequest) { private GpaScore getValidGpaScore(SiteUser siteUser, Long gpaScoreId) { GpaScore gpaScore = gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId) - .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); + .orElseThrow(() -> new CustomException(GPA_SCORE_NOT_FOUND)); if (gpaScore.getVerifyStatus() != VerifyStatus.APPROVED) { throw new CustomException(INVALID_GPA_SCORE_STATUS); } diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index d4aa8cb80..b7dc314d8 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -40,6 +40,7 @@ public enum ErrorCode { UNIVERSITY_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "대학교를 찾을 수 없습니다."), REGION_NOT_FOUND_BY_KOREAN_NAME(HttpStatus.NOT_FOUND.value(), "이름에 해당하는 지역을 찾을 수 없습니다."), COUNTRY_NOT_FOUND_BY_KOREAN_NAME(HttpStatus.NOT_FOUND.value(), "이름에 해당하는 국가를 찾을 수 없습니다."), + GPA_SCORE_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "존재하지 않는 학점입니다."), // auth USER_ALREADY_SIGN_OUT(HttpStatus.UNAUTHORIZED.value(), "로그아웃 되었습니다."), @@ -86,7 +87,6 @@ public enum ErrorCode { DUPLICATE_POST_LIKE(HttpStatus.BAD_REQUEST.value(), "이미 좋아요한 게시글입니다."), // score - INVALID_GPA_SCORE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 학점입니다."), INVALID_GPA_SCORE_STATUS(HttpStatus.BAD_REQUEST.value(), "학점이 승인되지 않았습니다."), INVALID_LANGUAGE_TEST_SCORE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 어학성적입니다."), INVALID_LANGUAGE_TEST_SCORE_STATUS(HttpStatus.BAD_REQUEST.value(), "어학성적이 승인되지 않았습니다."), diff --git a/src/main/java/com/example/solidconnection/custom/response/PageResponse.java b/src/main/java/com/example/solidconnection/custom/response/PageResponse.java index de128aea3..d1e3479d6 100644 --- a/src/main/java/com/example/solidconnection/custom/response/PageResponse.java +++ b/src/main/java/com/example/solidconnection/custom/response/PageResponse.java @@ -11,6 +11,9 @@ public record PageResponse( long totalElements, int totalPages ) { + /* + * 페이지 번호는 1부터 시작하는 것이 사용자 입장에서 더 직관적이기 때문에 1을 더해줌 + */ public static PageResponse of(Page page) { return new PageResponse<>( page.getContent(), diff --git a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java b/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java index 9a0ff1635..549c36ac5 100644 --- a/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java +++ b/src/main/java/com/example/solidconnection/custom/validation/validator/RejectedReasonValidator.java @@ -3,12 +3,14 @@ import com.example.solidconnection.admin.dto.GpaScoreUpdateRequest; import com.example.solidconnection.custom.validation.annotation.RejectedReasonRequired; import com.example.solidconnection.type.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; public class RejectedReasonValidator implements ConstraintValidator { + private static final String REJECTED_REASON = "rejectedReason"; @Override @@ -23,7 +25,7 @@ public boolean isValid(GpaScoreUpdateRequest request, ConstraintValidatorContext private boolean isRejectedWithoutReason(GpaScoreUpdateRequest request) { return request.verifyStatus().equals(VerifyStatus.REJECTED) - && (request.rejectedReason() == null || request.rejectedReason().trim().isEmpty()); + && StringUtils.isBlank(request.rejectedReason()); } private void addValidationError(ConstraintValidatorContext context, String message) { 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 56226c058..d3dc88342 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 @@ -1,9 +1,9 @@ package com.example.solidconnection.score.repository.custom; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; -import com.example.solidconnection.admin.dto.GpaScoreStatus; +import com.example.solidconnection.admin.dto.GpaScoreStatusResponse; import com.example.solidconnection.admin.dto.ScoreSearchCondition; -import com.example.solidconnection.admin.dto.SiteUserDto; +import com.example.solidconnection.admin.dto.SiteUserResponse; import com.example.solidconnection.type.VerifyStatus; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; @@ -26,6 +26,7 @@ @Repository public class GpaScoreFilterRepositoryImpl implements GpaScoreFilterRepository { + private final JPAQueryFactory queryFactory; @Autowired @@ -37,7 +38,7 @@ public GpaScoreFilterRepositoryImpl(EntityManager em) { public Page searchGpaScores(ScoreSearchCondition condition, Pageable pageable) { List content = queryFactory .select(Projections.constructor(GpaScoreSearchResponse.class, - Projections.constructor(GpaScoreStatus.class, + Projections.constructor(GpaScoreStatusResponse.class, gpaScore.id, gpaScore.gpa, gpaScore.verifyStatus, @@ -45,7 +46,7 @@ public Page searchGpaScores(ScoreSearchCondition conditi gpaScore.createdAt, gpaScore.updatedAt ), - Projections.constructor(SiteUserDto.class, + Projections.constructor(SiteUserResponse.class, siteUser.id, siteUser.nickname, siteUser.profileImageUrl diff --git a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java index 6f59e7787..4237551fe 100644 --- a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java @@ -27,7 +27,7 @@ import java.time.LocalDate; import java.util.List; -import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_GPA_SCORE; +import static com.example.solidconnection.custom.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; @@ -36,7 +36,7 @@ class GpaScoreVerificationAdminServiceTest extends BaseIntegrationTest { @Autowired - private GpaScoreVerificationAdminService gpaScoreVerificationAdminService; + private AdminGpaScoreService adminGpaScoreService; @Autowired private SiteUserRepository siteUserRepository; @@ -72,21 +72,21 @@ class 지원한_GPA_목록_조회 { List expectedGpaScores = List.of(gpaScore1, gpaScore2); // when - Page response = gpaScoreVerificationAdminService.searchGpaScores(condition, pageable); + Page response = adminGpaScoreService.searchGpaScores(condition, pageable); // then assertThat(response.getContent()) .hasSize(expectedGpaScores.size()) .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( - () -> assertThat(actual.gpaScoreStatus().id()).isEqualTo(expected.getId()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), - () -> assertThat(actual.gpaScoreStatus().verifyStatus()).isEqualTo(expected.getVerifyStatus()), - - () -> assertThat(actual.siteUserDto().id()).isEqualTo(expected.getSiteUser().getId()), - () -> assertThat(actual.siteUserDto().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()), - () -> assertThat(actual.siteUserDto().nickname()).isEqualTo(expected.getSiteUser().getNickname()) + () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaReportUrl()).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()) )); } @@ -98,21 +98,21 @@ class 지원한_GPA_목록_조회 { List expectedGpaScores = List.of(gpaScore1, gpaScore2, gpaScore3); // when - Page response = gpaScoreVerificationAdminService.searchGpaScores(condition, pageable); + Page response = adminGpaScoreService.searchGpaScores(condition, pageable); // then assertThat(response.getContent()) .hasSize(expectedGpaScores.size()) .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( - () -> assertThat(actual.gpaScoreStatus().id()).isEqualTo(expected.getId()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), - () -> assertThat(actual.gpaScoreStatus().verifyStatus()).isEqualTo(expected.getVerifyStatus()), - - () -> assertThat(actual.siteUserDto().id()).isEqualTo(expected.getSiteUser().getId()), - () -> assertThat(actual.siteUserDto().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()), - () -> assertThat(actual.siteUserDto().nickname()).isEqualTo(expected.getSiteUser().getNickname()) + () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaReportUrl()).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()) )); } @@ -124,21 +124,21 @@ class 지원한_GPA_목록_조회 { List expectedGpaScores = List.of(gpaScore1); // when - Page response = gpaScoreVerificationAdminService.searchGpaScores(condition, pageable); + Page response = adminGpaScoreService.searchGpaScores(condition, pageable); // then assertThat(response.getContent()) .hasSize(expectedGpaScores.size()) .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( - () -> assertThat(actual.gpaScoreStatus().id()).isEqualTo(expected.getId()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), - () -> assertThat(actual.gpaScoreStatus().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), - () -> assertThat(actual.gpaScoreStatus().verifyStatus()).isEqualTo(expected.getVerifyStatus()), - - () -> assertThat(actual.siteUserDto().id()).isEqualTo(expected.getSiteUser().getId()), - () -> assertThat(actual.siteUserDto().profileImageUrl()).isEqualTo(expected.getSiteUser().getProfileImageUrl()), - () -> assertThat(actual.siteUserDto().nickname()).isEqualTo(expected.getSiteUser().getNickname()) + () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), + () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaReportUrl()).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()) )); } } @@ -157,7 +157,7 @@ class GPA_점수_검증_및_수정 { ); // when - GpaScoreResponse response = gpaScoreVerificationAdminService.updateGpaScore(gpaScore1.getId(), request); + GpaScoreResponse response = adminGpaScoreService.updateGpaScore(gpaScore1.getId(), request); // then assertAll( @@ -180,7 +180,7 @@ class GPA_점수_검증_및_수정 { ); // when - GpaScoreResponse response = gpaScoreVerificationAdminService.updateGpaScore(gpaScore1.getId(), request); + GpaScoreResponse response = adminGpaScoreService.updateGpaScore(gpaScore1.getId(), request); // then assertAll( @@ -204,9 +204,9 @@ class GPA_점수_검증_및_수정 { ); // when & then - assertThatCode(() -> gpaScoreVerificationAdminService.updateGpaScore(invalidGpaScoreId, request)) + assertThatCode(() -> adminGpaScoreService.updateGpaScore(invalidGpaScoreId, request)) .isInstanceOf(CustomException.class) - .hasMessage(INVALID_GPA_SCORE.getMessage()); + .hasMessage(GPA_SCORE_NOT_FOUND.getMessage()); } } From a0d4d5b770edd4e4c2b6654f0c7c0db505f2ebcf Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Mon, 17 Feb 2025 13:17:55 +0900 Subject: [PATCH 18/22] =?UTF-8?q?refactor:=20=EC=9E=84=EB=B2=A0=EB=94=94?= =?UTF-8?q?=EB=93=9C=20=EC=97=94=ED=8B=B0=ED=8B=B0=20DTO=20=EB=B3=80?= =?UTF-8?q?=ED=99=98=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/admin/dto/GpaResponse.java | 8 ++++++++ .../admin/dto/GpaScoreStatusResponse.java | 3 +-- .../custom/GpaScoreFilterRepositoryImpl.java | 6 +++++- .../GpaScoreVerificationAdminServiceTest.java | 18 +++++++++--------- 4 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 src/main/java/com/example/solidconnection/admin/dto/GpaResponse.java diff --git a/src/main/java/com/example/solidconnection/admin/dto/GpaResponse.java b/src/main/java/com/example/solidconnection/admin/dto/GpaResponse.java new file mode 100644 index 000000000..564bc724b --- /dev/null +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaResponse.java @@ -0,0 +1,8 @@ +package com.example.solidconnection.admin.dto; + +public record GpaResponse( + double gpa, + double gpaCriteria, + String gpaReportUrl +) { +} 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 295a8f758..49afbd4ed 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreStatusResponse.java @@ -1,13 +1,12 @@ package com.example.solidconnection.admin.dto; -import com.example.solidconnection.application.domain.Gpa; import com.example.solidconnection.type.VerifyStatus; import java.time.ZonedDateTime; public record GpaScoreStatusResponse( long id, - Gpa gpa, + GpaResponse gpaResponse, VerifyStatus verifyStatus, String rejectedReason, ZonedDateTime createdAt, 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 d3dc88342..371119858 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 @@ -1,5 +1,6 @@ package com.example.solidconnection.score.repository.custom; +import com.example.solidconnection.admin.dto.GpaResponse; import com.example.solidconnection.admin.dto.GpaScoreSearchResponse; import com.example.solidconnection.admin.dto.GpaScoreStatusResponse; import com.example.solidconnection.admin.dto.ScoreSearchCondition; @@ -40,7 +41,10 @@ public Page searchGpaScores(ScoreSearchCondition conditi .select(Projections.constructor(GpaScoreSearchResponse.class, Projections.constructor(GpaScoreStatusResponse.class, gpaScore.id, - gpaScore.gpa, + Projections.constructor(GpaResponse.class, + gpaScore.gpa.gpa, + gpaScore.gpa.gpaCriteria, + gpaScore.gpa.gpaReportUrl), gpaScore.verifyStatus, gpaScore.rejectedReason, gpaScore.createdAt, diff --git a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java index 4237551fe..abfd226de 100644 --- a/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/service/GpaScoreVerificationAdminServiceTest.java @@ -79,9 +79,9 @@ class 지원한_GPA_목록_조회 { .hasSize(expectedGpaScores.size()) .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), + () -> 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()), @@ -105,9 +105,9 @@ class 지원한_GPA_목록_조회 { .hasSize(expectedGpaScores.size()) .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), + () -> 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()), @@ -131,9 +131,9 @@ class 지원한_GPA_목록_조회 { .hasSize(expectedGpaScores.size()) .zipSatisfy(expectedGpaScores, (actual, expected) -> assertAll( () -> assertThat(actual.gpaScoreStatusResponse().id()).isEqualTo(expected.getId()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpa()).isEqualTo(expected.getGpa().getGpa()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaCriteria()).isEqualTo(expected.getGpa().getGpaCriteria()), - () -> assertThat(actual.gpaScoreStatusResponse().gpa().getGpaReportUrl()).isEqualTo(expected.getGpa().getGpaReportUrl()), + () -> 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()), From fdb426e319c6f4879b2dc8f2672cca23771a37ce Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Mon, 17 Feb 2025 13:36:38 +0900 Subject: [PATCH 19/22] =?UTF-8?q?refactor:=20GpaScore=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=EC=A0=9D=EC=85=98=20=EB=B0=8F=20ZoneId=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/GpaScoreFilterRepositoryImpl.java | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-) 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 371119858..2138ed38d 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 @@ -6,6 +6,7 @@ import com.example.solidconnection.admin.dto.ScoreSearchCondition; import com.example.solidconnection.admin.dto.SiteUserResponse; import com.example.solidconnection.type.VerifyStatus; +import com.querydsl.core.types.ConstructorExpression; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -28,6 +29,35 @@ @Repository public class GpaScoreFilterRepositoryImpl implements GpaScoreFilterRepository { + private static final ZoneId systemZoneId = ZoneId.systemDefault(); + + private static final ConstructorExpression gpaResponseProjection = Projections.constructor( + GpaResponse.class, + gpaScore.gpa.gpa, + gpaScore.gpa.gpaCriteria, + gpaScore.gpa.gpaReportUrl + ); + private static final ConstructorExpression siteUserResponseProjection = Projections.constructor( + SiteUserResponse.class, + siteUser.id, + siteUser.nickname, + siteUser.profileImageUrl + ); + private static final ConstructorExpression gpaScoreStatusResponseProjection = Projections.constructor( + GpaScoreStatusResponse.class, + gpaScore.id, + gpaResponseProjection, + gpaScore.verifyStatus, + gpaScore.rejectedReason, + gpaScore.createdAt, + gpaScore.updatedAt + ); + private static final ConstructorExpression gpaScoreSearchResponseProjection = Projections.constructor( + GpaScoreSearchResponse.class, + gpaScoreStatusResponseProjection, + siteUserResponseProjection + ); + private final JPAQueryFactory queryFactory; @Autowired @@ -38,24 +68,7 @@ public GpaScoreFilterRepositoryImpl(EntityManager em) { @Override public Page searchGpaScores(ScoreSearchCondition condition, Pageable pageable) { List content = queryFactory - .select(Projections.constructor(GpaScoreSearchResponse.class, - Projections.constructor(GpaScoreStatusResponse.class, - gpaScore.id, - Projections.constructor(GpaResponse.class, - gpaScore.gpa.gpa, - gpaScore.gpa.gpaCriteria, - gpaScore.gpa.gpaReportUrl), - gpaScore.verifyStatus, - gpaScore.rejectedReason, - gpaScore.createdAt, - gpaScore.updatedAt - ), - Projections.constructor(SiteUserResponse.class, - siteUser.id, - siteUser.nickname, - siteUser.profileImageUrl - ) - )) + .select(gpaScoreSearchResponseProjection) .from(gpaScore) .join(gpaScore.siteUser, siteUser) .where( @@ -99,8 +112,8 @@ private BooleanExpression createdAtEq(LocalDate createdAt) { LocalDateTime endOfDay = createdAt.plusDays(1).atStartOfDay().minusNanos(1); return gpaScore.createdAt.between( - startOfDay.atZone(ZoneId.systemDefault()), - endOfDay.atZone(ZoneId.systemDefault()) + startOfDay.atZone(systemZoneId), + endOfDay.atZone(systemZoneId) ); } } From 1435fb046ed97a08ade93853bfec9d10bfffec83 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Mon, 17 Feb 2025 23:20:38 +0900 Subject: [PATCH 20/22] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EC=85=98=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=EC=97=90=20=EC=B5=9C=EB=8C=80=EA=B0=92=20=EC=A1=B0?= =?UTF-8?q?=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../custom/exception/ErrorCode.java | 4 +- .../solidconnection/util/PagingUtils.java | 6 ++- .../solidconnection/util/PagingUtilsTest.java | 47 +++++++++++++------ 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java index 3fa1fb409..e99d43f4a 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -96,8 +96,8 @@ public enum ErrorCode { REJECTED_REASON_REQUIRED(HttpStatus.BAD_REQUEST.value(), "거절 사유가 필요합니다."), // page - INVALID_PAGE(HttpStatus.BAD_REQUEST.value(), "페이지 번호가 최소값보다 작습니다."), - INVALID_SIZE(HttpStatus.BAD_REQUEST.value(), "페이지 크기가 최소값보다 작습니다."), + INVALID_PAGE(HttpStatus.BAD_REQUEST.value(), "페이지 번호는 1 이상 50 이하만 가능합니다."), + INVALID_SIZE(HttpStatus.BAD_REQUEST.value(), "페이지 크기는 1 이상 50 이하만 가능합니다."), // general JSON_PARSING_FAILED(HttpStatus.BAD_REQUEST.value(), "JSON 파싱을 할 수 없습니다."), diff --git a/src/main/java/com/example/solidconnection/util/PagingUtils.java b/src/main/java/com/example/solidconnection/util/PagingUtils.java index b98d65426..5b4547410 100644 --- a/src/main/java/com/example/solidconnection/util/PagingUtils.java +++ b/src/main/java/com/example/solidconnection/util/PagingUtils.java @@ -9,15 +9,17 @@ public class PagingUtils { private static final int MIN_PAGE = 1; private static final int MIN_SIZE = 1; + private static final int MAX_SIZE = 50; + private static final int MAX_PAGE = 50; private PagingUtils() { } public static void validatePage(int page, int size) { - if (page < MIN_PAGE) { + if (page < MIN_PAGE || page > MAX_PAGE) { throw new CustomException(INVALID_PAGE); } - if (size < MIN_SIZE) { + if (size < MIN_SIZE || size > MAX_SIZE) { throw new CustomException(INVALID_SIZE); } } diff --git a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java index 7e71911d7..7134050ba 100644 --- a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java +++ b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java @@ -11,39 +11,56 @@ @DisplayName("PagingUtils 테스트") class PagingUtilsTest { + private static final int VALID_PAGE = 1; + private static final int VALID_SIZE = 10; + + private static final int MIN_PAGE = 1; + private static final int MAX_PAGE = 50; + private static final int MIN_SIZE = 1; + private static final int MAX_SIZE = 50; + + private static final int INVALID_PAGE_BELOW_MIN = MIN_PAGE - 1; + private static final int INVALID_PAGE_ABOVE_MAX = MAX_PAGE + 1; + private static final int INVALID_SIZE_BELOW_MIN = MIN_SIZE - 1; + private static final int INVALID_SIZE_ABOVE_MAX = MAX_SIZE + 1; + @Test @DisplayName("유효한 페이지 번호와 크기가 주어지면 예외가 발생하지 않는다") void validateValidPageAndSize() { - // given - int validPage = 1; - int validSize = 10; - // when & then - assertThatCode(() -> PagingUtils.validatePage(validPage, validSize)) + assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, VALID_SIZE)) .doesNotThrowAnyException(); } @Test void 페이지_번호가_1보다_작으면_예외_응답을_반환한다() { - // given - int invalidPage = 0; - int validSize = 10; - // when & then - assertThatCode(() -> PagingUtils.validatePage(invalidPage, validSize)) + assertThatCode(() -> PagingUtils.validatePage(INVALID_PAGE_BELOW_MIN, VALID_SIZE)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_PAGE.getMessage()); } @Test - void 페이지_크기가_1보다_작으면_예외_응답을_반환한다() { - // given - int validPage = 1; - int invalidSize = 0; + void 페이지_크기가_50보다_크면_예외_응답을_반환한다() { + // when & then + assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, INVALID_SIZE_ABOVE_MAX)) + .isInstanceOf(CustomException.class) + .hasMessage(INVALID_SIZE.getMessage()); + } + @Test + void 페이지_크기가_1보다_작으면_예외_응답을_반환한다() { // when & then - assertThatCode(() -> PagingUtils.validatePage(validPage, invalidSize)) + assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, INVALID_SIZE_BELOW_MIN)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_SIZE.getMessage()); } + + @Test + void 페이지_번호가_50보다_크면_예외_응답을_반환한다() { + // when & then + assertThatCode(() -> PagingUtils.validatePage(INVALID_PAGE_ABOVE_MAX, VALID_SIZE)) + .isInstanceOf(CustomException.class) + .hasMessage(INVALID_PAGE.getMessage()); + } } From ba5a0274f5a69d13b01c1324bc3fad2c9694b75b Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Tue, 18 Feb 2025 09:40:12 +0900 Subject: [PATCH 21/22] =?UTF-8?q?style:=202=EC=B0=A8=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81=ED=95=98=EC=97=AC=20?= =?UTF-8?q?=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B0=8F=20=EA=B0=9C=ED=96=89=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AdminScoreController.java | 4 +-- .../custom/GpaScoreFilterRepositoryImpl.java | 32 +++++++++---------- .../solidconnection/util/PagingUtilsTest.java | 25 ++++++--------- 3 files changed, 28 insertions(+), 33 deletions(-) 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 80e223690..ab5bed64b 100644 --- a/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java +++ b/src/main/java/com/example/solidconnection/admin/controller/AdminScoreController.java @@ -40,9 +40,9 @@ public ResponseEntity> searchGpaScores( return ResponseEntity.ok(PageResponse.of(page)); } - @PatchMapping("/gpas/{gpa_score_id}") + @PatchMapping("/gpas/{gpa-score-id}") public ResponseEntity updateGpaScore( - @PathVariable("gpa_score_id") Long gpaScoreId, + @PathVariable("gpa-score-id") Long gpaScoreId, @Valid @RequestBody GpaScoreUpdateRequest request ) { GpaScoreResponse response = adminGpaScoreService.updateGpaScore(gpaScoreId, request); 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 2138ed38d..a02e62b49 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 @@ -29,33 +29,33 @@ @Repository public class GpaScoreFilterRepositoryImpl implements GpaScoreFilterRepository { - private static final ZoneId systemZoneId = ZoneId.systemDefault(); + private static final ZoneId SYSTEM_ZONE_ID = ZoneId.systemDefault(); - private static final ConstructorExpression gpaResponseProjection = Projections.constructor( + private static final ConstructorExpression GPA_RESPONSE_PROJECTION = Projections.constructor( GpaResponse.class, gpaScore.gpa.gpa, gpaScore.gpa.gpaCriteria, gpaScore.gpa.gpaReportUrl ); - private static final ConstructorExpression siteUserResponseProjection = Projections.constructor( - SiteUserResponse.class, - siteUser.id, - siteUser.nickname, - siteUser.profileImageUrl - ); - private static final ConstructorExpression gpaScoreStatusResponseProjection = Projections.constructor( + private static final ConstructorExpression GPA_SCORE_STATUS_RESPONSE_PROJECTION = Projections.constructor( GpaScoreStatusResponse.class, gpaScore.id, - gpaResponseProjection, + GPA_RESPONSE_PROJECTION, gpaScore.verifyStatus, gpaScore.rejectedReason, gpaScore.createdAt, gpaScore.updatedAt ); - private static final ConstructorExpression gpaScoreSearchResponseProjection = Projections.constructor( + private static final ConstructorExpression SITE_USER_RESPONSE_PROJECTION = Projections.constructor( + SiteUserResponse.class, + siteUser.id, + siteUser.nickname, + siteUser.profileImageUrl + ); + private static final ConstructorExpression GPA_SCORE_SEARCH_RESPONSE_PROJECTION = Projections.constructor( GpaScoreSearchResponse.class, - gpaScoreStatusResponseProjection, - siteUserResponseProjection + GPA_SCORE_STATUS_RESPONSE_PROJECTION, + SITE_USER_RESPONSE_PROJECTION ); private final JPAQueryFactory queryFactory; @@ -68,7 +68,7 @@ public GpaScoreFilterRepositoryImpl(EntityManager em) { @Override public Page searchGpaScores(ScoreSearchCondition condition, Pageable pageable) { List content = queryFactory - .select(gpaScoreSearchResponseProjection) + .select(GPA_SCORE_SEARCH_RESPONSE_PROJECTION) .from(gpaScore) .join(gpaScore.siteUser, siteUser) .where( @@ -112,8 +112,8 @@ private BooleanExpression createdAtEq(LocalDate createdAt) { LocalDateTime endOfDay = createdAt.plusDays(1).atStartOfDay().minusNanos(1); return gpaScore.createdAt.between( - startOfDay.atZone(systemZoneId), - endOfDay.atZone(systemZoneId) + startOfDay.atZone(SYSTEM_ZONE_ID), + endOfDay.atZone(SYSTEM_ZONE_ID) ); } } diff --git a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java index 7134050ba..f8a10a473 100644 --- a/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java +++ b/src/test/java/com/example/solidconnection/util/PagingUtilsTest.java @@ -19,11 +19,6 @@ class PagingUtilsTest { private static final int MIN_SIZE = 1; private static final int MAX_SIZE = 50; - private static final int INVALID_PAGE_BELOW_MIN = MIN_PAGE - 1; - private static final int INVALID_PAGE_ABOVE_MAX = MAX_PAGE + 1; - private static final int INVALID_SIZE_BELOW_MIN = MIN_SIZE - 1; - private static final int INVALID_SIZE_ABOVE_MAX = MAX_SIZE + 1; - @Test @DisplayName("유효한 페이지 번호와 크기가 주어지면 예외가 발생하지 않는다") void validateValidPageAndSize() { @@ -33,34 +28,34 @@ void validateValidPageAndSize() { } @Test - void 페이지_번호가_1보다_작으면_예외_응답을_반환한다() { + void 최소_페이지_번호보다_작으면_예외_응답을_반환한다() { // when & then - assertThatCode(() -> PagingUtils.validatePage(INVALID_PAGE_BELOW_MIN, VALID_SIZE)) + assertThatCode(() -> PagingUtils.validatePage(MIN_PAGE - 1, VALID_SIZE)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_PAGE.getMessage()); } @Test - void 페이지_크기가_50보다_크면_예외_응답을_반환한다() { + void 최대_페이지_번호보다_크면_예외_응답을_반환한다() { // when & then - assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, INVALID_SIZE_ABOVE_MAX)) + assertThatCode(() -> PagingUtils.validatePage(MAX_PAGE + 1, VALID_SIZE)) .isInstanceOf(CustomException.class) - .hasMessage(INVALID_SIZE.getMessage()); + .hasMessage(INVALID_PAGE.getMessage()); } @Test - void 페이지_크기가_1보다_작으면_예외_응답을_반환한다() { + void 최소_페이지_크기보다_작으면_예외_응답을_반환한다() { // when & then - assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, INVALID_SIZE_BELOW_MIN)) + assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, MIN_SIZE - 1)) .isInstanceOf(CustomException.class) .hasMessage(INVALID_SIZE.getMessage()); } @Test - void 페이지_번호가_50보다_크면_예외_응답을_반환한다() { + void 최대_페이지_크기보다_크면_예외_응답을_반환한다() { // when & then - assertThatCode(() -> PagingUtils.validatePage(INVALID_PAGE_ABOVE_MAX, VALID_SIZE)) + assertThatCode(() -> PagingUtils.validatePage(VALID_PAGE, MAX_SIZE + 1)) .isInstanceOf(CustomException.class) - .hasMessage(INVALID_PAGE.getMessage()); + .hasMessage(INVALID_SIZE.getMessage()); } } From abb963a7c2aae35a482d4d0b5a77993e55680089 Mon Sep 17 00:00:00 2001 From: Gyuhyeok99 <126947828+Gyuhyeok99@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:38:04 +0900 Subject: [PATCH 22/22] =?UTF-8?q?style:=20=EA=B0=9C=ED=96=89=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../example/solidconnection/admin/dto/GpaScoreUpdateRequest.java | 1 + 1 file changed, 1 insertion(+) 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 d247200a3..bc0b1aa42 100644 --- a/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java +++ b/src/main/java/com/example/solidconnection/admin/dto/GpaScoreUpdateRequest.java @@ -6,6 +6,7 @@ @RejectedReasonRequired public record GpaScoreUpdateRequest( + @NotNull(message = "GPA를 입력해주세요.") Double gpa,