From a28e917668b94a74cd67185fed2a79f1c37ea70d Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:48:51 +0900 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/domain/Gpa.java | 2 + .../application/domain/LanguageTest.java | 2 + .../score/domain/GpaScore.java | 59 +++++++++++++++++++ .../score/domain/LanguageTestScore.java | 59 +++++++++++++++++++ .../siteuser/domain/SiteUser.java | 16 +++++ 5 files changed, 138 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/score/domain/GpaScore.java create mode 100644 src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java diff --git a/src/main/java/com/example/solidconnection/application/domain/Gpa.java b/src/main/java/com/example/solidconnection/application/domain/Gpa.java index 82803dae9..85b12d047 100644 --- a/src/main/java/com/example/solidconnection/application/domain/Gpa.java +++ b/src/main/java/com/example/solidconnection/application/domain/Gpa.java @@ -3,6 +3,7 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -10,6 +11,7 @@ @AllArgsConstructor @NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) @Embeddable +@EqualsAndHashCode(of = {"gpa", "gpaCriteria", "gpaReportUrl"}) public class Gpa { @Column(nullable = false, name = "gpa") diff --git a/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java b/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java index a1e579ad8..4295372d4 100644 --- a/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java +++ b/src/main/java/com/example/solidconnection/application/domain/LanguageTest.java @@ -6,6 +6,7 @@ import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; @@ -13,6 +14,7 @@ @AllArgsConstructor @NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) @Embeddable +@EqualsAndHashCode(of = {"languageTestType", "languageTestScore", "languageTestReportUrl"}) public class LanguageTest { @Column(nullable = false, name = "language_test_type", length = 10) diff --git a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java new file mode 100644 index 000000000..b5829cdaa --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java @@ -0,0 +1,59 @@ +package com.example.solidconnection.score.domain; + +import com.example.solidconnection.application.domain.Gpa; +import com.example.solidconnection.entity.common.BaseEntity; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.type.VerifyStatus; +import jakarta.persistence.*; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDate; + +@Getter +@Entity +@NoArgsConstructor +@EqualsAndHashCode +public class GpaScore extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Embedded + private Gpa gpa; + + private LocalDate issueDate; + + @Setter + @Column(columnDefinition = "varchar(50) not null default 'PENDING'") + @Enumerated(EnumType.STRING) + private VerifyStatus verifyStatus; + + private String rejectedReason; + + @OneToOne + private SiteUser siteUser; + + public GpaScore(Gpa gpa, SiteUser siteUser, LocalDate issueDate) { + this.gpa = gpa; + this.siteUser = siteUser; + this.issueDate = issueDate; + this.verifyStatus = VerifyStatus.PENDING; + this.rejectedReason = null; + } + + public void setSiteUser(SiteUser siteUser) { + this.siteUser = siteUser; + if (siteUser != null && siteUser.getGpaScore() != this) { + siteUser.setGpaScore(this); + } + } + + public void update(Gpa gpa, LocalDate issueDate) { + this.gpa = gpa; + this.issueDate = issueDate; + this.verifyStatus = VerifyStatus.PENDING; + this.rejectedReason = null; + } +} diff --git a/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java b/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java new file mode 100644 index 000000000..78a75bcc5 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java @@ -0,0 +1,59 @@ +package com.example.solidconnection.score.domain; + +import com.example.solidconnection.application.domain.LanguageTest; +import com.example.solidconnection.entity.common.BaseEntity; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.type.VerifyStatus; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.LocalDate; + +@Getter +@Entity +@NoArgsConstructor +@AllArgsConstructor +public class LanguageTestScore extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Embedded + private LanguageTest languageTest; + + private LocalDate issueDate; + + @Setter + @Column(columnDefinition = "varchar(50) not null default 'PENDING'") + @Enumerated(EnumType.STRING) + private VerifyStatus verifyStatus; + + private String rejectedReason; + + @ManyToOne + private SiteUser siteUser; + + public LanguageTestScore(LanguageTest languageTest, LocalDate issueDate, SiteUser siteUser) { + this.languageTest = languageTest; + this.issueDate = issueDate; + this.verifyStatus = VerifyStatus.PENDING; + this.siteUser = siteUser; + } + + public void setSiteUser(SiteUser siteUser) { + if (this.siteUser != null) { + this.siteUser.getLanguageTestScoreList().remove(this); + } + this.siteUser = siteUser; + siteUser.getLanguageTestScoreList().add(this); + } + + public void update(LanguageTest languageTest, LocalDate issueDate) { + this.languageTest = languageTest; + this.issueDate = issueDate; + this.verifyStatus = VerifyStatus.PENDING; + this.rejectedReason = null; + } +} diff --git a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java index f3c870ceb..ed8d1650e 100644 --- a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java +++ b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java @@ -3,6 +3,8 @@ import com.example.solidconnection.comment.domain.Comment; import com.example.solidconnection.post.domain.Post; import com.example.solidconnection.post.domain.PostLike; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.score.domain.LanguageTestScore; import com.example.solidconnection.type.Gender; import com.example.solidconnection.type.PreparationStatus; import com.example.solidconnection.type.Role; @@ -65,6 +67,20 @@ public class SiteUser { @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) private List postLikeList = new ArrayList<>(); + @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) + private List languageTestScoreList = new ArrayList<>(); + + @OneToOne(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) + private GpaScore gpaScore; + + + public void setGpaScore(GpaScore gpaScore) { + this.gpaScore = gpaScore; + if (gpaScore != null && gpaScore.getSiteUser() != this) { + gpaScore.setSiteUser(this); + } + } + public SiteUser( String email, String nickname, From f45172009582ffc202ddc7bca487a780e6db9c12 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:49:32 +0900 Subject: [PATCH 02/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/repository/GpaScoreRepository.java | 15 +++++++++++++++ .../repository/LanguageTestScoreRepository.java | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java create mode 100644 src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java diff --git a/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java b/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java new file mode 100644 index 000000000..c5fbb2847 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/repository/GpaScoreRepository.java @@ -0,0 +1,15 @@ +package com.example.solidconnection.score.repository; + +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.siteuser.domain.SiteUser; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface GpaScoreRepository extends JpaRepository { + Optional findGpaScoreBySiteUser(SiteUser siteUser); + + Optional findGpaScoreBySiteUserAndId(SiteUser siteUser, Long id); +} diff --git a/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java b/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java new file mode 100644 index 000000000..8e6ca3967 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/repository/LanguageTestScoreRepository.java @@ -0,0 +1,17 @@ +package com.example.solidconnection.score.repository; + +import com.example.solidconnection.score.domain.LanguageTestScore; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.type.LanguageTestType; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface LanguageTestScoreRepository extends JpaRepository { + + Optional findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType(SiteUser siteUser, LanguageTestType languageTestType); + + Optional findLanguageTestScoreBySiteUserAndId(SiteUser siteUser, Long id); +} From 9382dc409f6447b906922728ff64624aac5bb2a3 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:50:08 +0900 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/VerifyStatusQueryService.java | 75 --------- .../score/service/ScoreService.java | 91 +++++++++++ .../e2e/VerifyStatusQueryTest.java | 150 ------------------ 3 files changed, 91 insertions(+), 225 deletions(-) delete mode 100644 src/main/java/com/example/solidconnection/application/service/VerifyStatusQueryService.java create mode 100644 src/main/java/com/example/solidconnection/score/service/ScoreService.java delete mode 100644 src/test/java/com/example/solidconnection/e2e/VerifyStatusQueryTest.java diff --git a/src/main/java/com/example/solidconnection/application/service/VerifyStatusQueryService.java b/src/main/java/com/example/solidconnection/application/service/VerifyStatusQueryService.java deleted file mode 100644 index 33bb340d9..000000000 --- a/src/main/java/com/example/solidconnection/application/service/VerifyStatusQueryService.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.example.solidconnection.application.service; - -import com.example.solidconnection.application.domain.Application; -import com.example.solidconnection.application.dto.VerifyStatusResponse; -import com.example.solidconnection.application.repository.ApplicationRepository; -import com.example.solidconnection.siteuser.domain.SiteUser; -import com.example.solidconnection.siteuser.repository.SiteUserRepository; -import com.example.solidconnection.type.VerifyStatus; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Optional; - -import static com.example.solidconnection.application.service.VerifyStatusQueryService.ApplicationStatusResponse.NOT_SUBMITTED; -import static com.example.solidconnection.application.service.VerifyStatusQueryService.ApplicationStatusResponse.SCORE_SUBMITTED; -import static com.example.solidconnection.application.service.VerifyStatusQueryService.ApplicationStatusResponse.SUBMITTED_APPROVED; -import static com.example.solidconnection.application.service.VerifyStatusQueryService.ApplicationStatusResponse.SUBMITTED_PENDING; -import static com.example.solidconnection.application.service.VerifyStatusQueryService.ApplicationStatusResponse.SUBMITTED_REJECTED; - -@RequiredArgsConstructor -@Service -public class VerifyStatusQueryService { - - private final ApplicationRepository applicationRepository; - private final SiteUserRepository siteUserRepository; - - @Value("${university.term}") - private String term; - - /* - * 지원 상태를 조회한다. - * 학기별로 상태가 관리된다. - * */ - @Transactional(readOnly = true) - public VerifyStatusResponse getVerifyStatus(String email) { - SiteUser siteUser = siteUserRepository.getByEmail(email); - Optional application = applicationRepository.findBySiteUserAndTerm(siteUser,term); - - // 아무것도 제출 안함 - if (application.isEmpty()) { - return new VerifyStatusResponse(NOT_SUBMITTED.name(), 0); - } - - int updateCount = application.get().getUpdateCount(); - - // 제출한 상태 - if (application.get().getVerifyStatus() == VerifyStatus.PENDING) { - // 성적만 제출 - if (application.get().getFirstChoiceUniversity() == null) { - return new VerifyStatusResponse(SCORE_SUBMITTED.name(), 0); - } - // 성적 승인 대기 중 - return new VerifyStatusResponse(SUBMITTED_PENDING.name(), updateCount); - } - - // 성적 승인 반려 - if (application.get().getVerifyStatus() == VerifyStatus.REJECTED) { - return new VerifyStatusResponse(SUBMITTED_REJECTED.name(), updateCount); - } - - // 성적 승인 완료 - return new VerifyStatusResponse(SUBMITTED_APPROVED.name(), updateCount); - } - - public enum ApplicationStatusResponse { - NOT_SUBMITTED, // 어떤 것도 제출하지 않음 - COLLEGE_SUBMITTED, // 지망 대학만 제출 - SCORE_SUBMITTED, // 성적만 제출 - SUBMITTED_PENDING, // 성적 인증 대기 중 - SUBMITTED_REJECTED, // 성적 인증 승인 완료 - SUBMITTED_APPROVED // 성적 인증 반려 - } -} diff --git a/src/main/java/com/example/solidconnection/score/service/ScoreService.java b/src/main/java/com/example/solidconnection/score/service/ScoreService.java new file mode 100644 index 000000000..4dc6031f5 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/service/ScoreService.java @@ -0,0 +1,91 @@ +package com.example.solidconnection.score.service; + +import com.example.solidconnection.application.domain.LanguageTest; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.score.domain.LanguageTestScore; +import com.example.solidconnection.score.dto.*; +import com.example.solidconnection.score.repository.GpaScoreRepository; +import com.example.solidconnection.score.repository.LanguageTestScoreRepository; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class ScoreService { + + private final GpaScoreRepository gpaScoreRepository; + private final LanguageTestScoreRepository languageTestScoreRepository; + private final SiteUserRepository siteUserRepository; + + @Transactional + public Long submitGpaScore(String email, GpaScoreRequest gpaScoreRequest) { + SiteUser siteUser = siteUserRepository.getByEmail(email); + + Optional gpaScoreBySiteUser = gpaScoreRepository.findGpaScoreBySiteUser(siteUser); + if (gpaScoreBySiteUser.isPresent()) { + GpaScore gpaScore = gpaScoreBySiteUser.get(); + gpaScore.update(gpaScoreRequest.toGpa(), gpaScoreRequest.issueDate()); + GpaScore savedGpaScore = gpaScoreRepository.save(gpaScore); // 저장 후 반환된 객체 + return savedGpaScore.getId(); // 저장된 GPA Score의 ID 반환 + } else { + GpaScore newGpaScore = new GpaScore(gpaScoreRequest.toGpa(), siteUser, gpaScoreRequest.issueDate()); + newGpaScore.setSiteUser(siteUser); + GpaScore savedNewGpaScore = gpaScoreRepository.save(newGpaScore); // 저장 후 반환된 객체 + return savedNewGpaScore.getId(); // 저장된 GPA Score의 ID 반환 + } + } + + @Transactional + public Long submitLanguageTestScore(String email, LanguageTestScoreRequest languageTestScoreRequest) { + SiteUser siteUser = siteUserRepository.getByEmail(email); + LanguageTest languageTest = languageTestScoreRequest.toLanguageTest(); + + Optional languageTestScore = + languageTestScoreRepository.findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType(siteUser, languageTest.getLanguageTestType()); + + if (languageTestScore.isPresent()) { + // 기존 이력이 있을 경우 업데이트 + LanguageTestScore existingScore = languageTestScore.get(); + existingScore.update(languageTest, languageTestScoreRequest.issueDate()); + languageTestScoreRepository.save(existingScore); + return existingScore.getId(); // 업데이트된 객체의 ID 반환 + } else { + // 기존 이력이 없을 경우 새로 생성 + LanguageTestScore newScore = new LanguageTestScore( + languageTest, languageTestScoreRequest.issueDate(), siteUser); + newScore.setSiteUser(siteUser); + LanguageTestScore savedNewScore = languageTestScoreRepository.save(newScore); // 새로 저장한 객체 + return savedNewScore.getId(); // 저장된 객체의 ID 반환 + } + } + + @Transactional(readOnly = true) + public GpaScoreStatusResponse getGpaScoreStatus(String email) { + SiteUser siteUser = siteUserRepository.getByEmail(email); + GpaScore gpaScore = siteUser.getGpaScore(); + if (gpaScore == null) { + return null; + } + return GpaScoreStatusResponse.from(gpaScore); + } + + @Transactional(readOnly = true) + public LanguageTestScoreStatusResponse getLanguageTestScoreStatus(String email) { + SiteUser siteUser = siteUserRepository.getByEmail(email); + List languageTestScoreStatusList = + Optional.ofNullable(siteUser.getLanguageTestScoreList()) + .map(scores -> scores.stream() + .map(LanguageTestScoreStatus::from) + .collect(Collectors.toList())) + .orElse(Collections.emptyList()); + return new LanguageTestScoreStatusResponse(languageTestScoreStatusList); + } +} diff --git a/src/test/java/com/example/solidconnection/e2e/VerifyStatusQueryTest.java b/src/test/java/com/example/solidconnection/e2e/VerifyStatusQueryTest.java deleted file mode 100644 index 856c4cdca..000000000 --- a/src/test/java/com/example/solidconnection/e2e/VerifyStatusQueryTest.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.example.solidconnection.e2e; - -import com.example.solidconnection.application.domain.Application; -import com.example.solidconnection.application.dto.VerifyStatusResponse; -import com.example.solidconnection.application.repository.ApplicationRepository; -import com.example.solidconnection.config.token.TokenService; -import com.example.solidconnection.config.token.TokenType; -import com.example.solidconnection.siteuser.domain.SiteUser; -import com.example.solidconnection.siteuser.repository.SiteUserRepository; -import com.example.solidconnection.type.VerifyStatus; -import io.restassured.RestAssured; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; - -import static com.example.solidconnection.e2e.DynamicFixture.createDummyGpa; -import static com.example.solidconnection.e2e.DynamicFixture.createDummyLanguageTest; -import static com.example.solidconnection.e2e.DynamicFixture.createSiteUserByEmail; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -@DisplayName("지원 상태 조회 테스트") -class VerifyStatusQueryTest extends UniversityDataSetUpEndToEndTest { - - @Autowired - private SiteUserRepository siteUserRepository; - - @Autowired - private TokenService tokenService; - - @Autowired - private ApplicationRepository applicationRepository; - - private String accessToken; - private SiteUser siteUser; - - @BeforeEach - public void setUpUserAndToken() { - // setUp - 회원 정보 저장 - String email = "email@email.com"; - siteUser = siteUserRepository.save(createSiteUserByEmail(email)); - - // setUp - 엑세스 토큰 생성과 리프레시 토큰 생성 및 저장 - accessToken = tokenService.generateToken(email, TokenType.ACCESS); - String refreshToken = tokenService.generateToken(email, TokenType.REFRESH); - tokenService.saveToken(refreshToken, TokenType.REFRESH); - } - - @Test - void 아무것도_제출하지_않은_상태를_반환한다() { - // request - 요청 - VerifyStatusResponse response = RestAssured.given().log().all() - .header("Authorization", "Bearer " + accessToken) - .when().get("/application/status") - .then().log().all() - .statusCode(200) - .extract().as(VerifyStatusResponse.class); - - assertAll( - () -> assertThat(response.status()).isEqualTo("NOT_SUBMITTED"), - () -> assertThat(response.updateCount()).isZero() - ); - } - - @Test - void 성적만_제출한_상태를_반환한다() { - // setUp - 성적만 제출한 상태 - Application application = new Application(siteUser, createDummyGpa(), createDummyLanguageTest(),term); - applicationRepository.save(application); - - // request - 요청 - VerifyStatusResponse response = RestAssured.given().log().all() - .header("Authorization", "Bearer " + accessToken) - .when().get("/application/status") - .then().log().all() - .statusCode(200) - .extract().as(VerifyStatusResponse.class); - - assertAll( - () -> assertThat(response.status()).isEqualTo("SCORE_SUBMITTED"), - () -> assertThat(response.updateCount()).isZero() - ); - } - - @Test - void 성적과_대학을_모두_제출하고_승인을_기대라는_상태를_반환한다() { - // setUp - 성적과 대학을 모두 제출한 상태 - Application application = new Application(siteUser, createDummyGpa(), createDummyLanguageTest(),term); - application.updateUniversityChoice(괌대학_B_지원_정보, 괌대학_A_지원_정보, 네바다주립대학_라스베이거스_지원_정보, "닉네임"); - applicationRepository.save(application); - - // request - 요청 - VerifyStatusResponse response = RestAssured.given().log().all() - .header("Authorization", "Bearer " + accessToken) - .when().get("/application/status") - .then().log().all() - .statusCode(200) - .extract().as(VerifyStatusResponse.class); - - assertAll( - () -> assertThat(response.status()).isEqualTo("SUBMITTED_PENDING"), - () -> assertThat(response.updateCount()).isZero() - ); - } - - @Test - void 성적과_대학을_모두_제출했지만_승인이_반려된_상태를_반환한다() { - // setUp - 성적과 대학을 모두 제출했지만, 승인 거절 - Application application = new Application(siteUser, createDummyGpa(), createDummyLanguageTest(),term); - application.updateUniversityChoice(괌대학_B_지원_정보, 괌대학_A_지원_정보, 네바다주립대학_라스베이거스_지원_정보,"닉네임"); - application.setVerifyStatus(VerifyStatus.REJECTED); - applicationRepository.save(application); - - // request - 요청 - VerifyStatusResponse response = RestAssured.given().log().all() - .header("Authorization", "Bearer " + accessToken) - .when().get("/application/status") - .then().log().all() - .statusCode(200) - .extract().as(VerifyStatusResponse.class); - - assertAll( - () -> assertThat(response.status()).isEqualTo("SUBMITTED_REJECTED"), - () -> assertThat(response.updateCount()).isZero() - ); - } - - @Test - void 성적과_대학을_모두_제출했으며_승인이_된_상태를_반환한다() { - // setUp - 성적과 대학을 모두 제출했으며, 승인이 된 상태 - Application application = new Application(siteUser, createDummyGpa(), createDummyLanguageTest(),term); - application.updateUniversityChoice(괌대학_B_지원_정보, 괌대학_A_지원_정보, 네바다주립대학_라스베이거스_지원_정보, "닉네임"); - application.setVerifyStatus(VerifyStatus.APPROVED); - applicationRepository.save(application); - - // request - 요청 - VerifyStatusResponse response = RestAssured.given().log().all() - .header("Authorization", "Bearer " + accessToken) - .when().get("/application/status") - .then().log().all() - .statusCode(200) - .extract().as(VerifyStatusResponse.class); - - assertAll( - () -> assertThat(response.status()).isEqualTo("SUBMITTED_APPROVED"), - () -> assertThat(response.updateCount()).isZero() - ); - } -} From 1e10e9ce857c7fc4db2809f853108252df6fc778 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:50:31 +0900 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/controller/ScoreController.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/score/controller/ScoreController.java diff --git a/src/main/java/com/example/solidconnection/score/controller/ScoreController.java b/src/main/java/com/example/solidconnection/score/controller/ScoreController.java new file mode 100644 index 000000000..6172e99c5 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/controller/ScoreController.java @@ -0,0 +1,56 @@ +package com.example.solidconnection.score.controller; + +import com.example.solidconnection.score.dto.*; +import com.example.solidconnection.score.service.ScoreService; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.security.Principal; + +import static com.example.solidconnection.config.swagger.SwaggerConfig.ACCESS_TOKEN; + +@RestController +@RequestMapping("/score") +@RequiredArgsConstructor +@SecurityRequirements +@SecurityRequirement(name = ACCESS_TOKEN) +public class ScoreController { + + private final ScoreService scoreService; + + // 학점을 등록하는 api + @PostMapping("/gpaScore") + public ResponseEntity submitGpaScore( + Principal principal, + @Valid @RequestBody GpaScoreRequest gpaScoreRequest) { + Long id = scoreService.submitGpaScore(principal.getName(), gpaScoreRequest); + return ResponseEntity.ok(id); + } + + // 어학성적을 등록하는 api + @PostMapping("/languageTestScore") + public ResponseEntity submitLanguageTestScore( + Principal principal, + @Valid @RequestBody LanguageTestScoreRequest languageTestScoreRequest) { + Long id = scoreService.submitLanguageTestScore(principal.getName(), languageTestScoreRequest); + return ResponseEntity.ok(id); + } + + // 학점 상태를 확인하는 api + @GetMapping("/gpaScore/status") + public ResponseEntity getGpaScoreStatus(Principal principal) { + GpaScoreStatusResponse gpaScoreStatus = scoreService.getGpaScoreStatus(principal.getName()); + return ResponseEntity.ok(gpaScoreStatus); + } + + // 어학 성적 상태를 확인하는 api + @GetMapping("/languageTestScore/status") + public ResponseEntity getLanguageTestScoreStatus(Principal principal) { + LanguageTestScoreStatusResponse languageTestScoreStatus = scoreService.getLanguageTestScoreStatus(principal.getName()); + return ResponseEntity.ok(languageTestScoreStatus); + } +} From 18c9cda3d6c432aad71b75dd67bdae857196e3ab Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:51:07 +0900 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EA=B4=80=EB=A0=A8=20DTO=20=EC=A0=95=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/dto/GpaScoreRequest.java | 34 +++++++++++++++++ .../score/dto/GpaScoreStatusResponse.java | 25 +++++++++++++ .../score/dto/LanguageTestScoreRequest.java | 37 +++++++++++++++++++ .../score/dto/LanguageTestScoreStatus.java | 25 +++++++++++++ .../dto/LanguageTestScoreStatusResponse.java | 9 +++++ 5 files changed, 130 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/score/dto/GpaScoreRequest.java create mode 100644 src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java create mode 100644 src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java create mode 100644 src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatus.java create mode 100644 src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java diff --git a/src/main/java/com/example/solidconnection/score/dto/GpaScoreRequest.java b/src/main/java/com/example/solidconnection/score/dto/GpaScoreRequest.java new file mode 100644 index 000000000..b655f6143 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/dto/GpaScoreRequest.java @@ -0,0 +1,34 @@ +package com.example.solidconnection.score.dto; + +import com.example.solidconnection.application.domain.Gpa; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDate; + +@Schema(description = "대학 성적과 어학 시험 성적") +public record GpaScoreRequest( + @NotNull(message = "학점을 입력해주세요.") + @Schema(description = "GPA", example = "3.5", required = true) + Double gpa, + + @NotNull(message = "학점 기준을 입력해주세요.") + @Schema(description = "GPA 계산 기준", example = "4.0", required = true) + Double gpaCriteria, + + @NotNull(message = "발급일자를 입력해주세요.") + @Schema(description = "발급일자", example = "2024-10-06", required = true) + LocalDate issueDate, + + @NotBlank(message = "대학 성적 증명서를 첨부해주세요.") + @Schema(description = "대학 성적 증명서 URL", example = "http://example.com/gpa-report.pdf", required = true) + String gpaReportUrl) { + + public Gpa toGpa() { + return new Gpa( + this.gpa, + this.gpaCriteria, + this.gpaReportUrl); + } +} diff --git a/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java new file mode 100644 index 000000000..eb9c38ea4 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java @@ -0,0 +1,25 @@ +package com.example.solidconnection.score.dto; + +import com.example.solidconnection.application.domain.Gpa; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.type.VerifyStatus; + +import java.time.LocalDate; + +public record GpaScoreStatusResponse( + Long id, + Gpa gpa, + LocalDate issueDate, + VerifyStatus verifyStatus, + String rejectedReason +) { + public static GpaScoreStatusResponse from(GpaScore gpaScore) { + return new GpaScoreStatusResponse( + gpaScore.getId(), + gpaScore.getGpa(), + gpaScore.getIssueDate(), + gpaScore.getVerifyStatus(), + gpaScore.getRejectedReason() + ); + } +} diff --git a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java new file mode 100644 index 000000000..36687b6c2 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreRequest.java @@ -0,0 +1,37 @@ +package com.example.solidconnection.score.dto; + + +import com.example.solidconnection.application.domain.LanguageTest; +import com.example.solidconnection.type.LanguageTestType; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDate; + +@Schema(description = "대학 성적과 어학 시험 성적") +public record LanguageTestScoreRequest( + @NotNull(message = "어학 종류를 입력해주세요.") + @Schema(description = "어학 시험 종류", example = "TOEFL", required = true) + LanguageTestType languageTestType, + + @NotBlank(message = "어학 점수를 입력해주세요.") + @Schema(description = "어학 시험 점수", example = "115", required = true) + String languageTestScore, + + @NotNull(message = "발급일자를 입력해주세요.") + @Schema(description = "발급일자", example = "2024-10-06", required = true) + LocalDate issueDate, + + @NotBlank(message = "어학 증명서를 첨부해주세요.") + @Schema(description = "어학 증명서 URL", example = "http://example.com/test-report.pdf", required = true) + String languageTestReportUrl) { + + public LanguageTest toLanguageTest() { + return new LanguageTest( + this.languageTestType, + this.languageTestScore, + this.languageTestReportUrl + ); + } +} diff --git a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatus.java b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatus.java new file mode 100644 index 000000000..2d1d8fcb1 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatus.java @@ -0,0 +1,25 @@ +package com.example.solidconnection.score.dto; + +import com.example.solidconnection.application.domain.LanguageTest; +import com.example.solidconnection.score.domain.LanguageTestScore; +import com.example.solidconnection.type.VerifyStatus; + +import java.time.LocalDate; + +public record LanguageTestScoreStatus( + Long id, + LanguageTest languageTest, + LocalDate issueDate, + VerifyStatus verifyStatus, + String rejectedReason +) { + public static LanguageTestScoreStatus from(LanguageTestScore languageTestScore) { + return new LanguageTestScoreStatus( + languageTestScore.getId(), + languageTestScore.getLanguageTest(), + languageTestScore.getIssueDate(), + languageTestScore.getVerifyStatus(), + languageTestScore.getRejectedReason() + ); + } +} diff --git a/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java new file mode 100644 index 000000000..3d4f74894 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/dto/LanguageTestScoreStatusResponse.java @@ -0,0 +1,9 @@ +package com.example.solidconnection.score.dto; + + +import java.util.List; + +public record LanguageTestScoreStatusResponse( + List languageTestScoreStatusList +) { +} From d067ba4d746df82edbef77192c6a44fd997ddfc8 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:51:31 +0900 Subject: [PATCH 06/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EA=B4=80=EB=A0=A8=20=EC=98=88=EC=99=B8=20=EC=A0=95?= =?UTF-8?q?=EC=9D=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solidconnection/custom/exception/ErrorCode.java | 7 +++++++ 1 file changed, 7 insertions(+) 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 f9e1e45b1..1a3aa8df7 100644 --- a/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/custom/exception/ErrorCode.java @@ -66,6 +66,13 @@ public enum ErrorCode { INVALID_POST_LIKE(HttpStatus.BAD_REQUEST.value(), "존재하지 않는 게시글 좋아요입니다."), 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(), "어학성적이 승인되지 않았습니다."), + USER_DO_NOT_HAVE_GPA(HttpStatus.BAD_REQUEST.value(), "해당 유저의 학점을 찾을 수 없음"), + // general JSON_PARSING_FAILED(HttpStatus.BAD_REQUEST.value(), "JSON 파싱을 할 수 없습니다."), JWT_EXCEPTION(HttpStatus.BAD_REQUEST.value(), "JWT 토큰을 처리할 수 없습니다."), From 23be4d7c3d395cf090ed1dd9e4ab6fcea6ea6828 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:52:25 +0900 Subject: [PATCH 07/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EB=A0=88=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=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 --- .../repository/GpaScoreRepositoryTest.java | 93 ++++++++++++++++++ .../LanguageTestScoreRepositoryTest.java | 98 +++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 src/test/java/com/example/solidconnection/unit/repository/GpaScoreRepositoryTest.java create mode 100644 src/test/java/com/example/solidconnection/unit/repository/LanguageTestScoreRepositoryTest.java diff --git a/src/test/java/com/example/solidconnection/unit/repository/GpaScoreRepositoryTest.java b/src/test/java/com/example/solidconnection/unit/repository/GpaScoreRepositoryTest.java new file mode 100644 index 000000000..e3fa680c2 --- /dev/null +++ b/src/test/java/com/example/solidconnection/unit/repository/GpaScoreRepositoryTest.java @@ -0,0 +1,93 @@ +package com.example.solidconnection.unit.repository; + +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.type.Gender; +import com.example.solidconnection.type.PreparationStatus; +import com.example.solidconnection.type.Role; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@DisplayName("학점 레포지토리 테스트") +@Transactional +public class GpaScoreRepositoryTest { + @Autowired + private SiteUserRepository siteUserRepository; + @Autowired + private GpaScoreRepository gpaScoreRepository; + + private SiteUser siteUser; + + @BeforeEach + public void setUp() { + siteUser = createSiteUser(); + siteUserRepository.save(siteUser); + } + + private SiteUser createSiteUser() { + return new SiteUser( + "test@example.com", + "nickname", + "profileImageUrl", + "1999-01-01", + PreparationStatus.CONSIDERING, + Role.MENTEE, + Gender.MALE + ); + } + + @Test + public void 사용자의_학점을_조회한다_기존이력_없을_때() { + Optional gpaScoreBySiteUser = gpaScoreRepository.findGpaScoreBySiteUser(siteUser); + assertThat(gpaScoreBySiteUser).isEqualTo(Optional.empty()); + } + + @Test + public void 사용자의_학점을_조회한다_기존이력_있을_때() { + GpaScore gpaScore = new GpaScore( + new Gpa(4.5, 4.5, "http://example.com/gpa-report.pdf"), + siteUser, + LocalDate.of(2024, 10, 10) + ); + gpaScore.setSiteUser(siteUser); + gpaScoreRepository.save(gpaScore); + + Optional gpaScoreBySiteUser = gpaScoreRepository.findGpaScoreBySiteUser(siteUser); + assertThat(gpaScoreBySiteUser).isEqualTo(Optional.of(gpaScore)); + } + + @Test + public void 아이디와_사용자정보로_사용자의_학점을_조회한다_기존이력_없을_때() { + Optional gpaScoreBySiteUser = gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, 1L); + assertThat(gpaScoreBySiteUser).isEqualTo(Optional.empty()); + } + + @Test + public void 아이디와_사용자정보로_사용자의_학점을_조회한다_기존이력_있을_때() { + GpaScore gpaScore = new GpaScore( + new Gpa(4.5, 4.5, "http://example.com/gpa-report.pdf"), + siteUser, + LocalDate.of(2024, 10, 10) + ); + gpaScore.setSiteUser(siteUser); + gpaScoreRepository.save(gpaScore); + + Optional gpaScoreBySiteUser = gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScore.getId()); + assertThat(gpaScoreBySiteUser).isEqualTo(Optional.of(gpaScore)); + } +} diff --git a/src/test/java/com/example/solidconnection/unit/repository/LanguageTestScoreRepositoryTest.java b/src/test/java/com/example/solidconnection/unit/repository/LanguageTestScoreRepositoryTest.java new file mode 100644 index 000000000..7369f20fa --- /dev/null +++ b/src/test/java/com/example/solidconnection/unit/repository/LanguageTestScoreRepositoryTest.java @@ -0,0 +1,98 @@ +package com.example.solidconnection.unit.repository; + +import com.example.solidconnection.application.domain.LanguageTest; +import com.example.solidconnection.score.domain.LanguageTestScore; +import com.example.solidconnection.score.repository.LanguageTestScoreRepository; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.type.Gender; +import com.example.solidconnection.type.LanguageTestType; +import com.example.solidconnection.type.PreparationStatus; +import com.example.solidconnection.type.Role; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +@DataJpaTest +@ActiveProfiles("test") +@DisplayName("어학성적 레포지토리 테스트") +@Transactional +public class LanguageTestScoreRepositoryTest { + @Autowired + private SiteUserRepository siteUserRepository; + @Autowired + private LanguageTestScoreRepository languageTestScoreRepository; + + private SiteUser siteUser; + + @BeforeEach + public void setUp() { + siteUser = createSiteUser(); + siteUserRepository.save(siteUser); + } + + private SiteUser createSiteUser() { + return new SiteUser( + "test@example.com", + "nickname", + "profileImageUrl", + "1999-01-01", + PreparationStatus.CONSIDERING, + Role.MENTEE, + Gender.MALE + ); + } + + @Test + public void 사용자의_어학성적을_조회한다_기존이력_없을_때() { + Optional languageTestScore = languageTestScoreRepository + .findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType(siteUser, LanguageTestType.TOEIC); + assertThat(languageTestScore).isEqualTo(Optional.empty()); + } + + @Test + public void 사용자의_어학성적을_조회한다_기존이력_있을_때() { + LanguageTestScore languageTestScore = new LanguageTestScore( + new LanguageTest(LanguageTestType.TOEIC, "990", "http://example.com/gpa-report.pdf"), + LocalDate.of(2024, 10, 10), + siteUser + ); + languageTestScore.setSiteUser(siteUser); + languageTestScoreRepository.save(languageTestScore); + + Optional languageTestScore1 = languageTestScoreRepository + .findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType(siteUser, LanguageTestType.TOEIC); + assertThat(languageTestScore1).isEqualTo(Optional.of(languageTestScore)); + } + + @Test + public void 아이디와_사용자정보로_사용자의_어학성적을_조회한다_기존이력_없을_때() { + Optional languageTestScore = languageTestScoreRepository + .findLanguageTestScoreBySiteUserAndId(siteUser, 1L); + assertThat(languageTestScore).isEqualTo(Optional.empty()); + } + + @Test + public void 아이디와_사용자정보로_사용자의_어학성적을_조회한다_기존이력_있을_때() { + LanguageTestScore languageTestScore = new LanguageTestScore( + new LanguageTest(LanguageTestType.TOEIC, "990", "http://example.com/gpa-report.pdf"), + LocalDate.of(2024, 10, 10), + siteUser + ); + languageTestScore.setSiteUser(siteUser); + languageTestScoreRepository.save(languageTestScore); + + Optional languageTestScore1 = languageTestScoreRepository + .findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScore.getId()); + assertThat(languageTestScore1).isEqualTo(Optional.of(languageTestScore)); + } +} From 802475bfd146c41a982d9b35b5b5e0ab6f28e80f Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:52:40 +0900 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=ED=95=99=EC=A0=90,=20=EC=96=B4?= =?UTF-8?q?=ED=95=99=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../unit/service/ScoreServiceTest.java | 244 ++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java diff --git a/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java new file mode 100644 index 000000000..e60093fde --- /dev/null +++ b/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java @@ -0,0 +1,244 @@ +package com.example.solidconnection.unit.service; + +import com.example.solidconnection.application.domain.Gpa; +import com.example.solidconnection.application.domain.LanguageTest; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.score.domain.LanguageTestScore; +import com.example.solidconnection.score.dto.*; +import com.example.solidconnection.score.repository.GpaScoreRepository; +import com.example.solidconnection.score.repository.LanguageTestScoreRepository; +import com.example.solidconnection.score.service.ScoreService; +import com.example.solidconnection.siteuser.domain.SiteUser; +import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.type.Gender; +import com.example.solidconnection.type.LanguageTestType; +import com.example.solidconnection.type.PreparationStatus; +import com.example.solidconnection.type.Role; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.time.LocalDate; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +@DisplayName("점수 서비스 테스트") +public class ScoreServiceTest { + @InjectMocks + ScoreService scoreService; + @Mock + GpaScoreRepository gpaScoreRepository; + @Mock + LanguageTestScoreRepository languageTestScoreRepository; + @Mock + SiteUserRepository siteUserRepository; + + private SiteUser siteUser; + private GpaScore beforeGpaScore; + private LanguageTestScore beforeLanguageTestScore; + private LanguageTestScore beforeLanguageTestScore2; + + @BeforeEach + void setUp() { + siteUser = createSiteUser(); + beforeGpaScore = createBeforeGpaScore(siteUser); + beforeLanguageTestScore = createBeforeLanguageTestScore(siteUser); + beforeLanguageTestScore2 = createBeforeLanguageTestScore2(siteUser); + } + + private SiteUser createSiteUser() { + return new SiteUser( + "test@example.com", + "nickname", + "profileImageUrl", + "1999-01-01", + PreparationStatus.CONSIDERING, + Role.MENTEE, + Gender.MALE + ); + } + + private GpaScore createBeforeGpaScore(SiteUser siteUser) { + return new GpaScore( + new Gpa(4.5, 4.5, "http://example.com/gpa-report.pdf"), + siteUser, + LocalDate.of(2024, 10, 20) + ); + } + + private LanguageTestScore createBeforeLanguageTestScore(SiteUser siteUser) { + return new LanguageTestScore( + new LanguageTest(LanguageTestType.TOEIC, "900", "http://example.com/gpa-report.pdf"), + LocalDate.of(2024, 10, 30), + siteUser + ); + } + + private LanguageTestScore createBeforeLanguageTestScore2(SiteUser siteUser) { + return new LanguageTestScore( + new LanguageTest(LanguageTestType.TOEFL_IBT, "100", "http://example.com/gpa-report.pdf"), + LocalDate.of(2024, 10, 30), + siteUser + ); + } + + @Test + void 학점을_등록한다_기존이력이_없을_때() { + // Given + GpaScoreRequest gpaScoreRequest = new GpaScoreRequest( + 4.5, 4.5, LocalDate.of(2024, 10, 20), "http://example.com/gpa-report.pdf" + ); + GpaScore newGpaScore = new GpaScore(gpaScoreRequest.toGpa(), siteUser, gpaScoreRequest.issueDate()); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(gpaScoreRepository.findGpaScoreBySiteUser(siteUser)).thenReturn(Optional.empty()); + when(gpaScoreRepository.save(newGpaScore)).thenReturn(newGpaScore); + + // 새로운 gpa 저장하게된다. + scoreService.submitGpaScore(siteUser.getEmail(), gpaScoreRequest); + + // Then + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + verify(gpaScoreRepository, times(1)).save(any(GpaScore.class)); + } + + @Test + void 학점을_등록한다_기존이력이_있을_때() { + // Given + GpaScoreRequest gpaScoreRequest = new GpaScoreRequest( + 4.5, 4.5, LocalDate.of(2024, 10, 30), "http://example.com/gpa-report.pdf" + ); + GpaScore afterGpaScore = new GpaScore( + new Gpa(4.3, 4.5, "http://example.com/gpa-report.pdf"), + siteUser, + LocalDate.of(2024, 10, 30) + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(gpaScoreRepository.findGpaScoreBySiteUser(siteUser)).thenReturn(Optional.of(beforeGpaScore)); + when(gpaScoreRepository.save(any(GpaScore.class))).thenReturn(afterGpaScore); + + // GPA 저장 + scoreService.submitGpaScore(siteUser.getEmail(), gpaScoreRequest); + + // Then + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + verify(gpaScoreRepository, times(1)).save(any(GpaScore.class)); + } + + @Test + void 어학성적을_등록한다_기존이력이_없을_때() { + // Given + LanguageTestScoreRequest languageTestScoreRequest = new LanguageTestScoreRequest( + LanguageTestType.TOEIC, "900", + LocalDate.of(2024, 10, 30), "http://example.com/gpa-report.pdf" + ); + LanguageTest languageTest = languageTestScoreRequest.toLanguageTest(); + LanguageTestScore languageTestScore = new LanguageTestScore(languageTest, LocalDate.of(2024, 10, 30), siteUser); + + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType( + siteUser, languageTest.getLanguageTestType())).thenReturn(Optional.empty()); + when(languageTestScoreRepository.save(any(LanguageTestScore.class))).thenReturn(languageTestScore); + + //when + scoreService.submitLanguageTestScore(siteUser.getEmail(), languageTestScoreRequest); + + // Then + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + verify(languageTestScoreRepository, times(1)).save(any(LanguageTestScore.class)); + } + + @Test + void 어학성적을_등록한다_기존이력이_있을_때() { + // Given + LanguageTestScoreRequest languageTestScoreRequest = new LanguageTestScoreRequest( + LanguageTestType.TOEIC, "990", + LocalDate.of(2024, 10, 30), "http://example.com/gpa-report.pdf" + ); + LanguageTest languageTest = languageTestScoreRequest.toLanguageTest(); + + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType( + siteUser, languageTest.getLanguageTestType())).thenReturn(Optional.of(beforeLanguageTestScore)); + beforeLanguageTestScore.update(languageTest, languageTestScoreRequest.issueDate()); + when(languageTestScoreRepository.save(any(LanguageTestScore.class))).thenReturn(beforeLanguageTestScore); + + //when + scoreService.submitLanguageTestScore(siteUser.getEmail(), languageTestScoreRequest); + + // Then + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + verify(languageTestScoreRepository, times(1)).save(any(LanguageTestScore.class)); + } + + @Test + void 학점이력을_조회한다_제출이력이_있을_때() { + // Given + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + beforeGpaScore.setSiteUser(siteUser); + + // when + GpaScoreStatusResponse gpaScoreStatus = scoreService.getGpaScoreStatus(siteUser.getEmail()); + + // Then + assertThat(gpaScoreStatus) + .isEqualTo(GpaScoreStatusResponse.from(siteUser.getGpaScore())); + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + } + + @Test + void 학점이력을_조회한다_제출이력이_없을_때() { + // Given + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + + // when + GpaScoreStatusResponse gpaScoreStatus = scoreService.getGpaScoreStatus(siteUser.getEmail()); + + // Then + assertThat(gpaScoreStatus) + .isEqualTo(null); + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + } + + + @Test + void 어학이력을_조회한다_제출이력이_있을_때() { + // Given + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + beforeLanguageTestScore.setSiteUser(siteUser); + beforeLanguageTestScore2.setSiteUser(siteUser); + + // when + LanguageTestScoreStatusResponse languageTestScoreStatus = scoreService.getLanguageTestScoreStatus(siteUser.getEmail()); + + // Then + List expectedStatusList = List.of( + LanguageTestScoreStatus.from(beforeLanguageTestScore), + LanguageTestScoreStatus.from(beforeLanguageTestScore2) + ); + assertThat(languageTestScoreStatus.languageTestScoreStatusList()) + .hasSize(2) + .containsExactlyElementsOf(expectedStatusList); + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + } + + @Test + void 어학이력을_조회한다_제출이력이_없을_때() { + // Given + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + + // when + LanguageTestScoreStatusResponse languageTestScoreStatus = scoreService.getLanguageTestScoreStatus(siteUser.getEmail()); + + // Then + assertThat(languageTestScoreStatus.languageTestScoreStatusList()).isEmpty(); + verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + } +} From feb7109e6e7593f6a9e47822e534d5db39da6ab7 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:54:34 +0900 Subject: [PATCH 09/16] =?UTF-8?q?refactor:=20=EC=88=98=EC=A0=95=EC=95=88?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=A7=80=EC=9B=90=20=EC=A0=88?= =?UTF-8?q?=EC=B0=A8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ApplicationController.java | 34 +---- .../ApplicationControllerSwagger.java | 68 ---------- .../application/domain/Application.java | 18 ++- .../application/dto/ApplyRequest.java | 18 +++ .../service/ApplicationSubmissionService.java | 117 ++++++++---------- 5 files changed, 93 insertions(+), 162 deletions(-) create mode 100644 src/main/java/com/example/solidconnection/application/dto/ApplyRequest.java diff --git a/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java b/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java index d6695df28..8baf7255f 100644 --- a/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java +++ b/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java @@ -1,13 +1,8 @@ package com.example.solidconnection.application.controller; -import com.example.solidconnection.application.dto.ApplicationSubmissionResponse; -import com.example.solidconnection.application.dto.ApplicationsResponse; -import com.example.solidconnection.application.dto.ScoreRequest; -import com.example.solidconnection.application.dto.UniversityChoiceRequest; -import com.example.solidconnection.application.dto.VerifyStatusResponse; +import com.example.solidconnection.application.dto.*; import com.example.solidconnection.application.service.ApplicationQueryService; import com.example.solidconnection.application.service.ApplicationSubmissionService; -import com.example.solidconnection.application.service.VerifyStatusQueryService; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -28,28 +23,18 @@ public class ApplicationController implements ApplicationControllerSwagger { private final ApplicationSubmissionService applicationSubmissionService; private final ApplicationQueryService applicationQueryService; - private final VerifyStatusQueryService verifyStatusQueryService; - @PostMapping("/score") - public ResponseEntity submitScore( + // 지원서 제출하기 api + @PostMapping() + public ResponseEntity apply( Principal principal, - @Valid @RequestBody ScoreRequest scoreRequest) { - boolean result = applicationSubmissionService.submitScore(principal.getName(), scoreRequest); + @Valid @RequestBody ApplyRequest applyRequest) { + boolean result = applicationSubmissionService.apply(principal.getName(), applyRequest); return ResponseEntity .status(HttpStatus.OK) .body(new ApplicationSubmissionResponse(result)); } - @PostMapping("/university") - public ResponseEntity submitUniversityChoice( - Principal principal, - @Valid @RequestBody UniversityChoiceRequest universityChoiceRequest) { - boolean result = applicationSubmissionService.submitUniversityChoice(principal.getName(), universityChoiceRequest); - return ResponseEntity - .status(HttpStatus.OK) - .body(new ApplicationSubmissionResponse(result)); - } - @GetMapping public ResponseEntity getApplicants( Principal principal, @@ -69,11 +54,4 @@ public ResponseEntity getApplicantsForUserCompetitors( return ResponseEntity .ok(result); } - - @GetMapping("/status") - public ResponseEntity getApplicationVerifyStatus(Principal principal) { - VerifyStatusResponse result = verifyStatusQueryService.getVerifyStatus(principal.getName()); - return ResponseEntity - .ok(result); - } } diff --git a/src/main/java/com/example/solidconnection/application/controller/ApplicationControllerSwagger.java b/src/main/java/com/example/solidconnection/application/controller/ApplicationControllerSwagger.java index f531923ac..3b93dea4c 100644 --- a/src/main/java/com/example/solidconnection/application/controller/ApplicationControllerSwagger.java +++ b/src/main/java/com/example/solidconnection/application/controller/ApplicationControllerSwagger.java @@ -1,10 +1,6 @@ package com.example.solidconnection.application.controller; -import com.example.solidconnection.application.dto.ApplicationSubmissionResponse; import com.example.solidconnection.application.dto.ApplicationsResponse; -import com.example.solidconnection.application.dto.ScoreRequest; -import com.example.solidconnection.application.dto.UniversityChoiceRequest; -import com.example.solidconnection.application.dto.VerifyStatusResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; @@ -12,10 +8,8 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.security.SecurityRequirements; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestParam; -import io.swagger.v3.oas.annotations.parameters.RequestBody; import java.security.Principal; @@ -25,53 +19,6 @@ @SecurityRequirements @SecurityRequirement(name = ACCESS_TOKEN) public interface ApplicationControllerSwagger { - - @Operation( - summary = "대학 성적과 어학 성적 제출", - requestBody = @RequestBody( - description = "대학 성적과 어학 성적", - required = true, - content = @Content( - mediaType = "application/json", - schema = @Schema(implementation = ScoreRequest.class) - ) - ), - responses = { - @ApiResponse( - responseCode = "200", - description = "대학 성적과 어학 성적 제출 성공", - content = @Content( - mediaType = "application/json", - schema = @Schema(implementation = ApplicationSubmissionResponse.class) - ) - ) - } - ) - ResponseEntity submitScore(Principal principal, @Valid @RequestBody ScoreRequest scoreRequest); - - @Operation( - summary = "지망 대학 제출", - requestBody = @RequestBody( - description = "지망 대학", - required = true, - content = @Content( - mediaType = "application/json", - schema = @Schema(implementation = UniversityChoiceRequest.class) - ) - ), - responses = { - @ApiResponse( - responseCode = "200", - description = "지망 대학 제출 성공", - content = @Content( - mediaType = "application/json", - schema = @Schema(implementation = ApplicationSubmissionResponse.class) - ) - ) - } - ) - ResponseEntity submitUniversityChoice(Principal principal, @Valid @RequestBody UniversityChoiceRequest universityChoiceRequest); - @Operation( summary = "지원자 목록 조회", responses = { @@ -86,19 +33,4 @@ public interface ApplicationControllerSwagger { } ) ResponseEntity getApplicants(Principal principal, @RequestParam(required = false) String region, @RequestParam(required = false) String keyword); - - @Operation( - summary = "성적 승인 상태 확인", - responses = { - @ApiResponse( - responseCode = "200", - description = "성적 승인 상태 반환", - content = @Content( - mediaType = "application/json", - schema = @Schema(implementation = VerifyStatusResponse.class) - ) - ) - } - ) - ResponseEntity getApplicationVerifyStatus(Principal principal); } diff --git a/src/main/java/com/example/solidconnection/application/domain/Application.java b/src/main/java/com/example/solidconnection/application/domain/Application.java index 085141f22..8dc4f129e 100644 --- a/src/main/java/com/example/solidconnection/application/domain/Application.java +++ b/src/main/java/com/example/solidconnection/application/domain/Application.java @@ -76,12 +76,24 @@ public Application( this.verifyStatus = PENDING; } - public void updateGpaAndLanguageTest( + public void updateApplication( Gpa gpa, - LanguageTest languageTest) { + LanguageTest languageTest, + UniversityInfoForApply firstChoiceUniversity, + UniversityInfoForApply secondChoiceUniversity, + UniversityInfoForApply thirdChoiceUniversity, + String nicknameForApply + ) { this.gpa = gpa; this.languageTest = languageTest; - this.verifyStatus = PENDING; + if (this.firstChoiceUniversity != null) { + this.updateCount++; + } + this.firstChoiceUniversity = firstChoiceUniversity; + this.secondChoiceUniversity = secondChoiceUniversity; + this.thirdChoiceUniversity = thirdChoiceUniversity; + this.nicknameForApply = nicknameForApply; + this.verifyStatus = VerifyStatus.APPROVED; } public void updateUniversityChoice( diff --git a/src/main/java/com/example/solidconnection/application/dto/ApplyRequest.java b/src/main/java/com/example/solidconnection/application/dto/ApplyRequest.java new file mode 100644 index 000000000..3a5d7f2f5 --- /dev/null +++ b/src/main/java/com/example/solidconnection/application/dto/ApplyRequest.java @@ -0,0 +1,18 @@ +package com.example.solidconnection.application.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; + +@Schema(description = "지원서 제출") +public record ApplyRequest( + @NotNull(message = "gpa score id를 입력해주세요.") + @Schema(description = "지원하는 유저의 gpa score id", example = "1") + Long gpaScoreId, + + @NotNull(message = "language test score id를 입력해주세요.") + @Schema(description = "지원하는 유저의 language test score id", example = "1") + Long languageTestScoreId, + + UniversityChoiceRequest universityChoiceRequest +) { +} 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 b23b876c7..0d8334a7b 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java @@ -1,15 +1,17 @@ package com.example.solidconnection.application.service; -import com.example.solidconnection.application.domain.Application; -import com.example.solidconnection.application.domain.Gpa; -import com.example.solidconnection.application.domain.LanguageTest; -import com.example.solidconnection.application.dto.ScoreRequest; +import com.example.solidconnection.application.domain.*; +import com.example.solidconnection.application.dto.ApplyRequest; import com.example.solidconnection.application.dto.UniversityChoiceRequest; import com.example.solidconnection.application.repository.ApplicationRepository; -import com.example.solidconnection.cache.annotation.DefaultCacheOut; +import com.example.solidconnection.score.repository.GpaScoreRepository; +import com.example.solidconnection.score.repository.LanguageTestScoreRepository; import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.score.domain.LanguageTestScore; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; +import com.example.solidconnection.type.VerifyStatus; import com.example.solidconnection.university.domain.UniversityInfoForApply; import com.example.solidconnection.university.repository.UniversityInfoForApplyRepository; import lombok.RequiredArgsConstructor; @@ -30,74 +32,63 @@ public class ApplicationSubmissionService { private final ApplicationRepository applicationRepository; private final UniversityInfoForApplyRepository universityInfoForApplyRepository; private final SiteUserRepository siteUserRepository; + private final GpaScoreRepository gpaScoreRepository; + private final LanguageTestScoreRepository languageTestScoreRepository; @Value("${university.term}") private String term; - /* - * 학점과 영어 성적을 제출한다. - * - 금학기에 제출한 적이 있다면, 수정한다. - * - 성적을 제출한적이 한번도 없거나 제출한적이 있지만 금학기에 제출한 적이 없다면 새로 등록한다. - * - 수정을 하고 나면, 성적 승인 상태(verifyStatus)를 PENDING 상태로 변경한다. - * */ + // 학점 및 어학성적이 모두 유효한 경우에만 지원서 등록이 가능하다. + // 기존에 있던 status field 우선 APRROVED로 입력시킨다. @Transactional - @DefaultCacheOut(key = "application:query", cacheManager = "customCacheManager", prefix = true) - public boolean submitScore(String email, ScoreRequest scoreRequest) { + public boolean apply(String email, ApplyRequest applyRequest) { SiteUser siteUser = siteUserRepository.getByEmail(email); - Gpa gpa = scoreRequest.toGpa(); - LanguageTest languageTest = scoreRequest.toLanguageTest(); - - applicationRepository.findBySiteUserAndTerm(siteUser, term) - .ifPresentOrElse( - // 금학기에 성적 제출 이력이 있는 경우 - application -> application.updateGpaAndLanguageTest(gpa, languageTest), - () -> { - // 성적 제출한적이 한번도 없는 경우 && 성적 제출한적이 있지만 금학기에 없는 경우 - applicationRepository.save(new Application(siteUser, gpa, languageTest, term)); - } - ); + UniversityChoiceRequest universityChoiceRequest = applyRequest.universityChoiceRequest(); + validateUniversityChoices(universityChoiceRequest); + + Long gpaScoreId = applyRequest.gpaScoreId(); + Long languageTestScoreId = applyRequest.languageTestScoreId(); + GpaScore gpaScore = validateGpaScore(siteUser, gpaScoreId); + LanguageTestScore languageTestScore = validateLanguageTestScore(siteUser, languageTestScoreId); + + Optional application = applicationRepository.findBySiteUserAndTerm(siteUser, term); + application.ifPresentOrElse(before -> { + validateUpdateLimitNotExceed(before); + UniversityInfoForApply firstChoiceUniversity = universityInfoForApplyRepository + .getUniversityInfoForApplyByIdAndTerm(universityChoiceRequest.firstChoiceUniversityId(), term); + UniversityInfoForApply secondChoiceUniversity = Optional.ofNullable(universityChoiceRequest.secondChoiceUniversityId()) + .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) + .orElse(null); + UniversityInfoForApply thirdChoiceUniversity = Optional.ofNullable(universityChoiceRequest.thirdChoiceUniversityId()) + .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) + .orElse(null); + before.updateApplication(gpaScore.getGpa(), languageTestScore.getLanguageTest(), firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname()); + applicationRepository.save(before); + }, () -> { + Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(), term); + newApplication.setVerifyStatus(VerifyStatus.APPROVED); + applicationRepository.save(newApplication); + }); return true; } - /* - * 지망 대학교를 제출한다. - * - 지망 대학중 중복된 대학교가 있는지 검증한다. - * - 지원 정보 제출 내역이 없다면, 지금의 프로세스(성적 제출 후 지망대학 제출)에 벗어나는 요청이므로 예외를 응답한다. - * - 기존에 제출한 적이 있다면, 수정한다. - * - 수정 횟수 제한을 초과하지 않았는지 검증한다. - * - 새로운 '제출 닉네임'을 부여한다. (악의적으로 타인의 변경 기록을 추적하는 것을 막기 위해) - * - 성적 승인 상태(verifyStatus) 는 변경하지 않는다. - * */ - @Transactional - @DefaultCacheOut(key = "application:query", cacheManager = "customCacheManager", prefix = true) - public boolean submitUniversityChoice(String email, UniversityChoiceRequest universityChoiceRequest) { - validateUniversityChoices(universityChoiceRequest); + private GpaScore validateGpaScore(SiteUser siteUser, Long gpaScoreId) { + GpaScore gpaScore = gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId) + .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); + if (gpaScore.getVerifyStatus() != VerifyStatus.APPROVED) { + throw new CustomException(INVALID_GPA_SCORE_STATUS); + } + return gpaScore; + } - // 성적 제출한 적이 한번도 없는 경우 - Application existingApplication = applicationRepository.findTop1BySiteUser_EmailOrderByTermDesc(email) - .orElseThrow(() -> new CustomException(SCORE_SHOULD_SUBMITTED_FIRST)); - - Application application = Optional.of(existingApplication) - .filter(app -> !app.getTerm().equals(term)) - .map(app -> { - // 성적 제출한 적이 있지만 금학기에 없는 경우, 이전 성적으로 새 Application 객체를 등록 - SiteUser siteUser = siteUserRepository.getByEmail(email); - return applicationRepository.save(new Application(siteUser, app.getGpa(), app.getLanguageTest(), term)); - }) - .orElse(existingApplication); // 금학기에 이미 성적 제출한 경우 기존 객체 사용 - - validateUpdateLimitNotExceed(application); - - UniversityInfoForApply firstChoiceUniversity = universityInfoForApplyRepository - .getUniversityInfoForApplyByIdAndTerm(universityChoiceRequest.firstChoiceUniversityId(), term); - UniversityInfoForApply secondChoiceUniversity = Optional.ofNullable(universityChoiceRequest.secondChoiceUniversityId()) - .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) - .orElse(null); - UniversityInfoForApply thirdChoiceUniversity = Optional.ofNullable(universityChoiceRequest.thirdChoiceUniversityId()) - .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) - .orElse(null); - application.updateUniversityChoice(firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname()); - return true; + private LanguageTestScore validateLanguageTestScore(SiteUser siteUser, Long languageTestScoreId) { + LanguageTestScore languageTestScore = languageTestScoreRepository + .findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId) + .orElseThrow(() -> new CustomException(INVALID_LANGUAGE_TEST_SCORE)); + if (languageTestScore.getVerifyStatus() != VerifyStatus.APPROVED) { + throw new CustomException(INVALID_LANGUAGE_TEST_SCORE_STATUS); + } + return languageTestScore; } private String getRandomNickname() { From 5f2f33085d623520c4014292cfb49827555acb62 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 12 Nov 2024 18:55:35 +0900 Subject: [PATCH 10/16] =?UTF-8?q?refactor:=20=EC=88=98=EC=A0=95=EC=95=88?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=A7=80=EC=9B=90=20=EC=A0=88?= =?UTF-8?q?=EC=B0=A8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=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 --- .../e2e/ApplicationSubmissionTest.java | 254 ----------------- .../unit/service/ApplicationServiceTest.java | 256 ++++++++++-------- 2 files changed, 146 insertions(+), 364 deletions(-) delete mode 100644 src/test/java/com/example/solidconnection/e2e/ApplicationSubmissionTest.java diff --git a/src/test/java/com/example/solidconnection/e2e/ApplicationSubmissionTest.java b/src/test/java/com/example/solidconnection/e2e/ApplicationSubmissionTest.java deleted file mode 100644 index a12612071..000000000 --- a/src/test/java/com/example/solidconnection/e2e/ApplicationSubmissionTest.java +++ /dev/null @@ -1,254 +0,0 @@ -package com.example.solidconnection.e2e; - -import com.example.solidconnection.application.domain.Application; -import com.example.solidconnection.application.dto.ScoreRequest; -import com.example.solidconnection.application.dto.UniversityChoiceRequest; -import com.example.solidconnection.application.repository.ApplicationRepository; -import com.example.solidconnection.config.token.TokenService; -import com.example.solidconnection.config.token.TokenType; -import com.example.solidconnection.custom.response.ErrorResponse; -import com.example.solidconnection.siteuser.domain.SiteUser; -import com.example.solidconnection.siteuser.repository.SiteUserRepository; -import com.example.solidconnection.type.LanguageTestType; -import com.example.solidconnection.type.VerifyStatus; -import io.restassured.RestAssured; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; - -import static com.example.solidconnection.application.service.ApplicationSubmissionService.APPLICATION_UPDATE_COUNT_LIMIT; -import static com.example.solidconnection.custom.exception.ErrorCode.APPLY_UPDATE_LIMIT_EXCEED; -import static com.example.solidconnection.custom.exception.ErrorCode.CANT_APPLY_FOR_SAME_UNIVERSITY; -import static com.example.solidconnection.e2e.DynamicFixture.createSiteUserByEmail; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertAll; - -@DisplayName("지원 정보 제출 테스트") -class ApplicationSubmissionTest extends UniversityDataSetUpEndToEndTest { - - @Autowired - private ApplicationRepository applicationRepository; - - @Autowired - private SiteUserRepository siteUserRepository; - - @Autowired - private TokenService tokenService; - - private final String email = "email@email.com"; - private String accessToken; - private SiteUser siteUser; - - @BeforeEach - public void setUpUserAndToken() { - // setUp - 회원 정보 저장 - siteUser = siteUserRepository.save(createSiteUserByEmail(email)); - - // setUp - 엑세스 토큰 생성과 리프레시 토큰 생성 및 저장 - accessToken = tokenService.generateToken(email, TokenType.ACCESS); - String refreshToken = tokenService.generateToken(email, TokenType.REFRESH); - tokenService.saveToken(refreshToken, TokenType.REFRESH); - } - - @Test - void 대학교_성적과_어학성적을_처음으로_제출한다() { - // request - body 생성 및 요청 - ScoreRequest request = new ScoreRequest(LanguageTestType.TOEFL_IBT, "80", - "languageTestReportUrl", 4.0, 4.5, "gpaReportUrl"); - RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .log().all() - .post("/application/score") - .then().log().all() - .statusCode(HttpStatus.OK.value()); - - Application application = applicationRepository.getApplicationBySiteUserAndTerm(siteUser,term); - assertAll("대학교 성적과 어학 성적을 저장한다.", - () -> assertThat(application.getId()).isNotNull(), - () -> assertThat(application.getSiteUser().getId()).isEqualTo(siteUser.getId()), - () -> assertThat(application.getLanguageTest().getLanguageTestType()).isEqualTo(request.languageTestType()), - () -> assertThat(application.getLanguageTest().getLanguageTestScore()).isEqualTo(request.languageTestScore()), - () -> assertThat(application.getLanguageTest().getLanguageTestReportUrl()).isEqualTo(request.languageTestReportUrl()), - () -> assertThat(application.getGpa().getGpa()).isEqualTo(request.gpa()), - () -> assertThat(application.getGpa().getGpaReportUrl()).isEqualTo(request.gpaReportUrl()), - () -> assertThat(application.getVerifyStatus()).isEqualTo(VerifyStatus.PENDING), - () -> assertThat(application.getUpdateCount()).isZero()); - } - - @Test - void 대학교_성적과_어학성적을_다시_제출한다() { - // setUp - 성적 정보 저장 - ScoreRequest firstRequest = new ScoreRequest(LanguageTestType.TOEFL_IBT, "80", - "languageTestReportUrl", 4.0, 4.5, "gpaReportUrl"); - applicationRepository.save(new Application(siteUser, firstRequest.toGpa(), firstRequest.toLanguageTest(),term)); - - // request - body 생성 및 요청 - ScoreRequest secondRequest = new ScoreRequest(LanguageTestType.TOEFL_IBT, "90", - "languageTestReportUrl", 4.1, 4.5, "gpaReportUrl"); - RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(secondRequest) - .contentType("application/json") - .log().all() - .post("/application/score") - .then().log().all() - .statusCode(HttpStatus.OK.value()); - - Application updatedApplication = applicationRepository.getApplicationBySiteUserAndTerm(siteUser,term); - assertAll("대학교 성적과 어학 성적을 수정한다. 이때 수정 횟수는 증가하지 않고, 성적 승인 상태는 PENDING 으로 바뀐다.", - () -> assertThat(updatedApplication.getId()).isNotNull(), - () -> assertThat(updatedApplication.getSiteUser().getId()).isEqualTo(siteUser.getId()), - () -> assertThat(updatedApplication.getLanguageTest().getLanguageTestType()).isEqualTo(secondRequest.languageTestType()), - () -> assertThat(updatedApplication.getLanguageTest().getLanguageTestScore()).isEqualTo(secondRequest.languageTestScore()), - () -> assertThat(updatedApplication.getLanguageTest().getLanguageTestReportUrl()).isEqualTo(secondRequest.languageTestReportUrl()), - () -> assertThat(updatedApplication.getGpa().getGpa()).isEqualTo(secondRequest.gpa()), - () -> assertThat(updatedApplication.getGpa().getGpaReportUrl()).isEqualTo(secondRequest.gpaReportUrl()), - () -> assertThat(updatedApplication.getVerifyStatus()).isEqualTo(VerifyStatus.PENDING), - () -> assertThat(updatedApplication.getUpdateCount()).isZero()); - } - - @Test - void 성적_제출_후_지망_대학을_제출한다() { - // setUp - 성적 정보 저장 - ScoreRequest firstRequest = new ScoreRequest(LanguageTestType.TOEFL_IBT, "80", - "languageTestReportUrl", 4.0, 4.5, "gpaReportUrl"); - applicationRepository.save(new Application(siteUser, firstRequest.toGpa(), firstRequest.toLanguageTest(),term)); - - // request - body 생성 및 요청 - UniversityChoiceRequest request = new UniversityChoiceRequest(그라츠대학_지원_정보.getId(), 코펜하겐IT대학_지원_정보.getId(), 메이지대학_지원_정보.getId()); - RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .log().all() - .post("/application/university") - .then().log().all() - .statusCode(HttpStatus.OK.value()); - - Application application = applicationRepository.getApplicationBySiteUserAndTerm(siteUser,term); - assertAll("지망 대학교를 저장한다.", - () -> assertThat(application.getId()).isNotNull(), - () -> assertThat(application.getSiteUser().getId()).isEqualTo(siteUser.getId()), - () -> assertThat(application.getFirstChoiceUniversity().getId()).isEqualTo(request.firstChoiceUniversityId()), - () -> assertThat(application.getSecondChoiceUniversity().getId()).isEqualTo(request.secondChoiceUniversityId()), - () -> assertThat(application.getThirdChoiceUniversity().getId()).isEqualTo(request.thirdChoiceUniversityId()), - () -> assertThat(application.getNicknameForApply()).isNotNull(), - () -> assertThat(application.getVerifyStatus()).isEqualTo(VerifyStatus.PENDING), - () -> assertThat(application.getUpdateCount()).isZero()); - } - - @Test - void 지망_대학을_수정한다() { - // setUp - 성적 정보와 지망 대학 저장 - ScoreRequest firstRequest = new ScoreRequest(LanguageTestType.TOEFL_IBT, "80", - "languageTestReportUrl", 4.0, 4.5, "gpaReportUrl"); - applicationRepository.save(new Application(siteUser, firstRequest.toGpa(), firstRequest.toLanguageTest(),term)) - .updateUniversityChoice(괌대학_A_지원_정보, 괌대학_B_지원_정보, 네바다주립대학_라스베이거스_지원_정보, "nickname"); - Application initialApplication = applicationRepository.getApplicationBySiteUserAndTerm(siteUser,term); - - // request - body 생성 및 요청 - UniversityChoiceRequest request = new UniversityChoiceRequest(그라츠대학_지원_정보.getId(), 코펜하겐IT대학_지원_정보.getId(), 메이지대학_지원_정보.getId()); - RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .log().all() - .post("/application/university") - .then().log().all() - .statusCode(HttpStatus.OK.value()); - - Application updatedApplication = applicationRepository.getApplicationBySiteUserAndTerm(siteUser,term); - assertAll("지망 대학교를 수정한다. 이때 수정 횟수는 증가하고, 성적 승인 상태는 바뀌지 않는다.", - () -> assertThat(updatedApplication.getId()).isNotNull(), - () -> assertThat(updatedApplication.getSiteUser().getId()).isEqualTo(siteUser.getId()), - () -> assertThat(updatedApplication.getFirstChoiceUniversity().getId()).isEqualTo(request.firstChoiceUniversityId()), - () -> assertThat(updatedApplication.getSecondChoiceUniversity().getId()).isEqualTo(request.secondChoiceUniversityId()), - () -> assertThat(updatedApplication.getThirdChoiceUniversity().getId()).isEqualTo(request.thirdChoiceUniversityId()), - () -> assertThat(updatedApplication.getNicknameForApply()).isNotNull(), - () -> assertThat(updatedApplication.getVerifyStatus()).isEqualTo(initialApplication.getVerifyStatus()), - () -> assertThat(updatedApplication.getUpdateCount()).isEqualTo(initialApplication.getUpdateCount())); - } - - @Test - void 지망_대학을_최대_수정_가능_횟수보다_더_수정하려고하면_예외_응답을_반환한다() { - // setUp - 성적 정보와 지망 대학 저장 - ScoreRequest firstRequest = new ScoreRequest(LanguageTestType.TOEFL_IBT, "80", - "languageTestReportUrl", 4.0, 4.5, "gpaReportUrl"); - applicationRepository.save(new Application(siteUser, firstRequest.toGpa(), firstRequest.toLanguageTest(),term)); - Application initialApplication = applicationRepository.getApplicationBySiteUserAndTerm(siteUser,term); - - // setUp - 지망 대학을 한계까지 수정 - for (int i = 0; i <= APPLICATION_UPDATE_COUNT_LIMIT; i++) { - initialApplication.updateUniversityChoice(괌대학_A_지원_정보, 괌대학_B_지원_정보, 네바다주립대학_라스베이거스_지원_정보, "nickname"); - applicationRepository.save(initialApplication); - } - - // request - body 생성 및 요청 - UniversityChoiceRequest request = new UniversityChoiceRequest(그라츠대학_지원_정보.getId(), 코펜하겐IT대학_지원_정보.getId(), 메이지대학_지원_정보.getId()); - ErrorResponse errorResponse = RestAssured.given().log().all() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .post("/application/university") - .then().log().all() - .statusCode(HttpStatus.BAD_REQUEST.value()) - .extract().as(ErrorResponse.class); - - assertThat(errorResponse.message()).isEqualTo(APPLY_UPDATE_LIMIT_EXCEED.getMessage()); - } - - @Test - void 일지망_대학과_이지망_대학이_같으면_예외_응답을_반환한다() { - // request - body 생성 및 요청 - UniversityChoiceRequest request = new UniversityChoiceRequest(그라츠대학_지원_정보.getId(), 그라츠대학_지원_정보.getId(), 메이지대학_지원_정보.getId()); - ErrorResponse errorResponse = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .log().all() - .post("/application/university") - .then().log().all() - .statusCode(HttpStatus.BAD_REQUEST.value()) - .extract().as(ErrorResponse.class); - - assertThat(errorResponse.message()).isEqualTo(CANT_APPLY_FOR_SAME_UNIVERSITY.getMessage()); - } - - @Test - void 일지망_대학과_삼지망_대학이_같으면_예외_응답을_반환한다() { - // request - body 생성 및 요청 - UniversityChoiceRequest request = new UniversityChoiceRequest(그라츠대학_지원_정보.getId(), 코펜하겐IT대학_지원_정보.getId(), 그라츠대학_지원_정보.getId()); - ErrorResponse errorResponse = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .log().all() - .post("/application/university") - .then().log().all() - .statusCode(HttpStatus.BAD_REQUEST.value()) - .extract().as(ErrorResponse.class); - - assertThat(errorResponse.message()).isEqualTo(CANT_APPLY_FOR_SAME_UNIVERSITY.getMessage()); - } - - @Test - void 이지망_대학과_삼지망_대학이_같으면_예외_응답을_반환한다() { - // request - body 생성 및 요청 - UniversityChoiceRequest request = new UniversityChoiceRequest(그라츠대학_지원_정보.getId(), 코펜하겐IT대학_지원_정보.getId(), 코펜하겐IT대학_지원_정보.getId()); - ErrorResponse errorResponse = RestAssured.given() - .header("Authorization", "Bearer " + accessToken) - .body(request) - .contentType("application/json") - .log().all() - .post("/application/university") - .then().log().all() - .statusCode(HttpStatus.BAD_REQUEST.value()) - .extract().as(ErrorResponse.class); - - assertThat(errorResponse.message()).isEqualTo(CANT_APPLY_FOR_SAME_UNIVERSITY.getMessage()); - } -} diff --git a/src/test/java/com/example/solidconnection/unit/service/ApplicationServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/ApplicationServiceTest.java index 7688478fc..dd87a383f 100644 --- a/src/test/java/com/example/solidconnection/unit/service/ApplicationServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/ApplicationServiceTest.java @@ -3,11 +3,16 @@ import com.example.solidconnection.application.domain.Application; import com.example.solidconnection.application.domain.Gpa; import com.example.solidconnection.application.domain.LanguageTest; -import com.example.solidconnection.application.dto.ScoreRequest; +import com.example.solidconnection.application.dto.ApplyRequest; import com.example.solidconnection.application.dto.UniversityChoiceRequest; import com.example.solidconnection.application.repository.ApplicationRepository; import com.example.solidconnection.application.service.ApplicationSubmissionService; import com.example.solidconnection.custom.exception.CustomException; +import com.example.solidconnection.custom.exception.ErrorCode; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.score.domain.LanguageTestScore; +import com.example.solidconnection.score.repository.GpaScoreRepository; +import com.example.solidconnection.score.repository.LanguageTestScoreRepository; import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.siteuser.repository.SiteUserRepository; import com.example.solidconnection.type.*; @@ -16,19 +21,15 @@ import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.beans.factory.annotation.Value; +import java.time.LocalDate; import java.util.Optional; -import static com.example.solidconnection.custom.exception.ErrorCode.CANT_APPLY_FOR_SAME_UNIVERSITY; -import static com.example.solidconnection.custom.exception.ErrorCode.SCORE_SHOULD_SUBMITTED_FIRST; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; @@ -41,27 +42,28 @@ public class ApplicationServiceTest { @Mock ApplicationRepository applicationRepository; @Mock + UniversityInfoForApplyRepository universityInfoForApplyRepository; + @Mock SiteUserRepository siteUserRepository; @Mock - UniversityInfoForApplyRepository universityInfoForApplyRepository; + GpaScoreRepository gpaScoreRepository; + @Mock + LanguageTestScoreRepository languageTestScoreRepository; + @Value("${university.term}") + private String term; private SiteUser siteUser; - private Application application; - private Application applicationBeforeTerm; - - private String term = "2024-1"; - private String beforeTerm = "1999-1"; + private GpaScore gpaScore; + private LanguageTestScore languageTestScore; + private final long gpaScoreId = 1L; + private final long languageTestScoreId = 1L; + private final long firstChoiceUniversityId = 1L; + private final long secondChoiceUniversityId = 2L; + private final long thirdChoiceUniversityId = 3L; @BeforeEach void setUp() { - ReflectionTestUtils.setField(applicationSubmissionService, "term", term); // 테스트시 @value값 주입위함 - siteUser = createSiteUser(); - application = createApplication(term); - applicationBeforeTerm = createApplication(beforeTerm); - } - - private SiteUser createSiteUser() { - return new SiteUser( + siteUser = new SiteUser( "test@example.com", "nickname", "profileImageUrl", @@ -70,154 +72,188 @@ private SiteUser createSiteUser() { Role.MENTEE, Gender.MALE ); - } - - private Application createApplication(String term) { - return new Application( + gpaScore = new GpaScore( + new Gpa(4.3, 4.5, "gpaScoreUrl"), siteUser, - new Gpa(4.0, 4.5, "url"), - new LanguageTest(LanguageTestType.TOEIC, "900", "url"), - term + LocalDate.of(2024, 10, 30) + ); + languageTestScore = new LanguageTestScore( + new LanguageTest(LanguageTestType.TOEIC, "990", "languageTestScoreUrl"), + LocalDate.of(2024, 10, 30), + siteUser ); } @Test - void 성적을_제출한다_금학기_제출이력_없음() { + void 지원한다_기존_이력_없음() { // Given - ScoreRequest scoreRequest = new ScoreRequest( - LanguageTestType.TOEIC, "990", "url", 4.5, 4.5, "url" + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, secondChoiceUniversityId, thirdChoiceUniversityId) ); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + gpaScore.setVerifyStatus(VerifyStatus.APPROVED); + when(gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId)).thenReturn(Optional.of(gpaScore)); + languageTestScore.setVerifyStatus(VerifyStatus.APPROVED); + when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId)).thenReturn(Optional.of(languageTestScore)); when(applicationRepository.findBySiteUserAndTerm(siteUser, term)).thenReturn(Optional.empty()); // When - applicationSubmissionService.submitScore(siteUser.getEmail(), scoreRequest); + boolean result = applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); // Then + assertThat(result).isEqualTo(true); verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); - verify(applicationRepository, times(1)).findBySiteUserAndTerm(siteUser, term); + verify(gpaScoreRepository, times(1)).findGpaScoreBySiteUserAndId(siteUser, gpaScoreId); + verify(languageTestScoreRepository, times(1)).findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId); verify(applicationRepository, times(1)).save(any(Application.class)); } @Test - void 성적을_제출한다_금학기_제출이력_있음() { + void 지원한다_기존_이력_있음() { // Given - ScoreRequest scoreRequest = new ScoreRequest( - LanguageTestType.TOEIC, "990", "url", 4.5, 4.5, "url" + Application beforeApplication = new Application( + siteUser, + new Gpa(4.5, 4.5, "beforeGpaScoreUrl"), + new LanguageTest(LanguageTestType.TOEIC, "900", "beforeLanguageTestUrl"), + term + ); + beforeApplication.setVerifyStatus(VerifyStatus.APPROVED); + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, secondChoiceUniversityId, thirdChoiceUniversityId) ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); - when(applicationRepository.findBySiteUserAndTerm(siteUser, term)).thenReturn(Optional.of(application)); + gpaScore.setVerifyStatus(VerifyStatus.APPROVED); + when(gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, 1L)).thenReturn(Optional.of(gpaScore)); + languageTestScore.setVerifyStatus(VerifyStatus.APPROVED); + when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndId(siteUser, 1L)).thenReturn(Optional.of(languageTestScore)); + when(applicationRepository.findBySiteUserAndTerm(siteUser, term)).thenReturn(Optional.of(beforeApplication)); // When - applicationSubmissionService.submitScore(siteUser.getEmail(), scoreRequest); + boolean result = applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); // Then - assertEquals(application.getGpa().getGpa(), scoreRequest.gpa()); - assertEquals(application.getLanguageTest().getLanguageTestScore(), scoreRequest.languageTestScore()); + assertThat(result).isEqualTo(true); verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); + verify(gpaScoreRepository, times(1)).findGpaScoreBySiteUserAndId(siteUser, gpaScoreId); + verify(languageTestScoreRepository, times(1)).findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId); verify(applicationRepository, times(1)).findBySiteUserAndTerm(siteUser, term); - verify(applicationRepository, times(0)).save(any(Application.class)); + verify(universityInfoForApplyRepository, times(1)).getUniversityInfoForApplyByIdAndTerm(firstChoiceUniversityId, term); + verify(universityInfoForApplyRepository, times(1)).getUniversityInfoForApplyByIdAndTerm(secondChoiceUniversityId, term); + verify(universityInfoForApplyRepository, times(1)).getUniversityInfoForApplyByIdAndTerm(thirdChoiceUniversityId, term); + verify(applicationRepository, times(1)).save(any(Application.class)); } - /** - * 지망대학 제출 - */ @Test - void 지망대학_제출할_때_성적_제출이력이_없다면_예외_응답을_반환한다() { + void 지원할_때_존재하지_않는_학점이라면_예외_응답을_반환한다() { // given - UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest( - 1L, 2L, 3L + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, secondChoiceUniversityId, thirdChoiceUniversityId) ); - when(applicationRepository.findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail())) - .thenReturn(Optional.empty()); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + when(gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId)).thenReturn(Optional.empty()); // when, then CustomException exception = assertThrows(CustomException.class, () -> { - applicationSubmissionService.submitUniversityChoice(siteUser.getEmail(), universityChoiceRequest); + applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); }); assertThat(exception.getMessage()) - .isEqualTo(SCORE_SHOULD_SUBMITTED_FIRST.getMessage()); + .isEqualTo(ErrorCode.INVALID_GPA_SCORE.getMessage()); assertThat(exception.getCode()) - .isEqualTo(SCORE_SHOULD_SUBMITTED_FIRST.getCode()); + .isEqualTo(ErrorCode.INVALID_GPA_SCORE.getCode()); } @Test - void 지망대학_제출한다_이전학기_성적_제출이력_있음() { - // Given - UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest( - 1L, 2L, 3L + void 지원할_때_승인되지_않은_학점이라면_예외_응답을_반환한다() { + // given + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, secondChoiceUniversityId, thirdChoiceUniversityId) ); - when(applicationRepository.findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail())) - .thenReturn(Optional.of(applicationBeforeTerm)); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + gpaScore.setVerifyStatus(VerifyStatus.REJECTED); + when(gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId)).thenReturn(Optional.of(gpaScore)); - // When - applicationSubmissionService.submitUniversityChoice(siteUser.getEmail(), universityChoiceRequest); - - // Then - verify(applicationRepository, times(1)).findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail()); - verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); - verify(applicationRepository, times(1)).save(any(Application.class)); + // when, then + CustomException exception = assertThrows(CustomException.class, () -> { + applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); + }); + assertThat(exception.getMessage()) + .isEqualTo(ErrorCode.INVALID_GPA_SCORE_STATUS.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(ErrorCode.INVALID_GPA_SCORE_STATUS.getCode()); } @Test - void 지망대학_제출한다_금학기_성적_제출이력_있음() { - // Given - UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest( - 1L, 2L, 3L + void 지원할_때_존재하지_않는_어학성적이라면_예외_응답을_반환한다() { + // given + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, secondChoiceUniversityId, thirdChoiceUniversityId) ); - when(applicationRepository.findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail())) - .thenReturn(Optional.of(application)); - - // When - applicationSubmissionService.submitUniversityChoice(siteUser.getEmail(), universityChoiceRequest); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + gpaScore.setVerifyStatus(VerifyStatus.APPROVED); + when(gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId)).thenReturn(Optional.of(gpaScore)); + when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId)).thenReturn(Optional.empty()); - // Then - verify(applicationRepository, times(1)).findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail()); - verify(siteUserRepository, times(0)).getByEmail(siteUser.getEmail()); - verify(applicationRepository, times(0)).save(any(Application.class)); + // when, then + CustomException exception = assertThrows(CustomException.class, () -> { + applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); + }); + assertThat(exception.getMessage()) + .isEqualTo(ErrorCode.INVALID_LANGUAGE_TEST_SCORE.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(ErrorCode.INVALID_LANGUAGE_TEST_SCORE.getCode()); } - @ParameterizedTest - @CsvSource({ - "1, 2, 3", - "1, , 3", - "1, 2, ", - "1, , " - }) - void 지망대학_제출할_때_2지망과_3지망은_NULL_허용한다(Long firstChoice, Long secondChoice, Long thirdChoice) { - // Given - UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest(firstChoice, secondChoice, thirdChoice); - when(applicationRepository.findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail())) - .thenReturn(Optional.of(application)); - - // When - applicationSubmissionService.submitUniversityChoice(siteUser.getEmail(), universityChoiceRequest); + @Test + void 지원할_때_승인되지_않은_어학성적이라면_예외_응답을_반환한다() { + // given + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, secondChoiceUniversityId, thirdChoiceUniversityId) + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); + gpaScore.setVerifyStatus(VerifyStatus.APPROVED); + when(gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId)).thenReturn(Optional.of(gpaScore)); + languageTestScore.setVerifyStatus(VerifyStatus.REJECTED); + when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId)).thenReturn(Optional.of(languageTestScore)); - // Then - verify(applicationRepository, times(1)).findTop1BySiteUser_EmailOrderByTermDesc(siteUser.getEmail()); - verify(siteUserRepository, times(0)).getByEmail(siteUser.getEmail()); - verify(applicationRepository, times(0)).save(any(Application.class)); + // when, then + CustomException exception = assertThrows(CustomException.class, () -> { + applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); + }); + assertThat(exception.getMessage()) + .isEqualTo(ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS.getMessage()); + assertThat(exception.getCode()) + .isEqualTo(ErrorCode.INVALID_LANGUAGE_TEST_SCORE_STATUS.getCode()); } - @ParameterizedTest - @CsvSource({ - "1, 1, 1", - "1, 2, 1", - "1, 1, 2", - "1, , 1", - "1, 1, " - }) - void 지망대학_제출할_때_선택지가_중복된다면_예외_응답을_반환한다(Long firstChoice, Long secondChoice, Long thirdChoice) { + @Test + void 지원할_때_학교_선택이_중복되면_예외_응답을_반환한다() { // given - UniversityChoiceRequest universityChoiceRequest = new UniversityChoiceRequest(firstChoice, secondChoice, thirdChoice); + ApplyRequest applyRequest = new ApplyRequest( + gpaScoreId, + languageTestScoreId, + new UniversityChoiceRequest(firstChoiceUniversityId, firstChoiceUniversityId, firstChoiceUniversityId) + ); + when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); // when, then CustomException exception = assertThrows(CustomException.class, () -> { - applicationSubmissionService.submitUniversityChoice(siteUser.getEmail(), universityChoiceRequest); + applicationSubmissionService.apply(siteUser.getEmail(), applyRequest); }); assertThat(exception.getMessage()) - .isEqualTo(CANT_APPLY_FOR_SAME_UNIVERSITY.getMessage()); + .isEqualTo(ErrorCode.CANT_APPLY_FOR_SAME_UNIVERSITY.getMessage()); assertThat(exception.getCode()) - .isEqualTo(CANT_APPLY_FOR_SAME_UNIVERSITY.getCode()); + .isEqualTo(ErrorCode.CANT_APPLY_FOR_SAME_UNIVERSITY.getCode()); } } From e270e239b2ec9033e2b90db99beff4067a15e081 Mon Sep 17 00:00:00 2001 From: sewon Date: Thu, 14 Nov 2024 21:25:17 +0900 Subject: [PATCH 11/16] =?UTF-8?q?feat:=20api=20naming=20=ED=86=B5=EC=9D=BC?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EA=B2=BD=EB=A1=9C=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 --- .../solidconnection/score/controller/ScoreController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/solidconnection/score/controller/ScoreController.java b/src/main/java/com/example/solidconnection/score/controller/ScoreController.java index 6172e99c5..7bd0edaf2 100644 --- a/src/main/java/com/example/solidconnection/score/controller/ScoreController.java +++ b/src/main/java/com/example/solidconnection/score/controller/ScoreController.java @@ -23,7 +23,7 @@ public class ScoreController { private final ScoreService scoreService; // 학점을 등록하는 api - @PostMapping("/gpaScore") + @PostMapping("/gpa") public ResponseEntity submitGpaScore( Principal principal, @Valid @RequestBody GpaScoreRequest gpaScoreRequest) { @@ -32,7 +32,7 @@ public ResponseEntity submitGpaScore( } // 어학성적을 등록하는 api - @PostMapping("/languageTestScore") + @PostMapping("/languageTest") public ResponseEntity submitLanguageTestScore( Principal principal, @Valid @RequestBody LanguageTestScoreRequest languageTestScoreRequest) { @@ -41,14 +41,14 @@ public ResponseEntity submitLanguageTestScore( } // 학점 상태를 확인하는 api - @GetMapping("/gpaScore/status") + @GetMapping("/gpa") public ResponseEntity getGpaScoreStatus(Principal principal) { GpaScoreStatusResponse gpaScoreStatus = scoreService.getGpaScoreStatus(principal.getName()); return ResponseEntity.ok(gpaScoreStatus); } // 어학 성적 상태를 확인하는 api - @GetMapping("/languageTestScore/status") + @GetMapping("/languageTest") public ResponseEntity getLanguageTestScoreStatus(Principal principal) { LanguageTestScoreStatusResponse languageTestScoreStatus = scoreService.getLanguageTestScoreStatus(principal.getName()); return ResponseEntity.ok(languageTestScoreStatus); From 2faebcdaa8397ce8e6b4fd6bdb7c6572a6b88f05 Mon Sep 17 00:00:00 2001 From: sewon Date: Mon, 18 Nov 2024 16:49:42 +0900 Subject: [PATCH 12/16] =?UTF-8?q?refactor:=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?=EB=AA=A9=EC=A0=81=EC=97=90=20=EB=A7=9E=EA=B2=8C=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/service/ApplicationSubmissionService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 0d8334a7b..1d8e76898 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java @@ -48,8 +48,8 @@ public boolean apply(String email, ApplyRequest applyRequest) { Long gpaScoreId = applyRequest.gpaScoreId(); Long languageTestScoreId = applyRequest.languageTestScoreId(); - GpaScore gpaScore = validateGpaScore(siteUser, gpaScoreId); - LanguageTestScore languageTestScore = validateLanguageTestScore(siteUser, languageTestScoreId); + GpaScore gpaScore = getGpaScore(siteUser, gpaScoreId); + LanguageTestScore languageTestScore = getLanguageTestScore(siteUser, languageTestScoreId); Optional application = applicationRepository.findBySiteUserAndTerm(siteUser, term); application.ifPresentOrElse(before -> { @@ -72,7 +72,7 @@ public boolean apply(String email, ApplyRequest applyRequest) { return true; } - private GpaScore validateGpaScore(SiteUser siteUser, Long gpaScoreId) { + private GpaScore getGpaScore(SiteUser siteUser, Long gpaScoreId) { GpaScore gpaScore = gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId) .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); if (gpaScore.getVerifyStatus() != VerifyStatus.APPROVED) { @@ -81,7 +81,7 @@ private GpaScore validateGpaScore(SiteUser siteUser, Long gpaScoreId) { return gpaScore; } - private LanguageTestScore validateLanguageTestScore(SiteUser siteUser, Long languageTestScoreId) { + private LanguageTestScore getLanguageTestScore(SiteUser siteUser, Long languageTestScoreId) { LanguageTestScore languageTestScore = languageTestScoreRepository .findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId) .orElseThrow(() -> new CustomException(INVALID_LANGUAGE_TEST_SCORE)); From 1ccf4a5857fa319633cb2bba01825a0ff32421f2 Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 19 Nov 2024 11:45:02 +0900 Subject: [PATCH 13/16] =?UTF-8?q?refactor:=20=EC=A7=80=EC=9B=90=EC=84=9C?= =?UTF-8?q?=20=EC=A0=9C=EC=B6=9C=EC=97=90=EC=84=9C=20=EA=B8=B0=EC=A1=B4?= =?UTF-8?q?=EC=9D=B4=EB=A0=A5=EC=9D=84=20soft=20delete=20=EB=B0=A9?= =?UTF-8?q?=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/domain/Application.java | 62 +++++++++++++------ .../repository/ApplicationRepository.java | 7 ++- .../service/ApplicationSubmissionService.java | 44 +++++++------ 3 files changed, 72 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/example/solidconnection/application/domain/Application.java b/src/main/java/com/example/solidconnection/application/domain/Application.java index 8dc4f129e..0c56fd7f5 100644 --- a/src/main/java/com/example/solidconnection/application/domain/Application.java +++ b/src/main/java/com/example/solidconnection/application/domain/Application.java @@ -3,15 +3,7 @@ import com.example.solidconnection.siteuser.domain.SiteUser; import com.example.solidconnection.type.VerifyStatus; import com.example.solidconnection.university.domain.UniversityInfoForApply; -import jakarta.persistence.Column; -import jakarta.persistence.Embedded; -import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.ManyToOne; +import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -51,16 +43,19 @@ public class Application { @Column(length = 50, nullable = false) private String term; - @ManyToOne + @Column(columnDefinition = "TINYINT(1) NOT NULL DEFAULT 0") + private Boolean isDelete; + + @ManyToOne(fetch = FetchType.LAZY) private UniversityInfoForApply firstChoiceUniversity; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private UniversityInfoForApply secondChoiceUniversity; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private UniversityInfoForApply thirdChoiceUniversity; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private SiteUser siteUser; public Application( @@ -76,24 +71,51 @@ public Application( this.verifyStatus = PENDING; } - public void updateApplication( + public Application( + SiteUser siteUser, Gpa gpa, LanguageTest languageTest, + String term, + Integer updateCount, UniversityInfoForApply firstChoiceUniversity, UniversityInfoForApply secondChoiceUniversity, UniversityInfoForApply thirdChoiceUniversity, - String nicknameForApply - ) { + String nicknameForApply) { + this.siteUser = siteUser; this.gpa = gpa; this.languageTest = languageTest; - if (this.firstChoiceUniversity != null) { - this.updateCount++; - } + this.term = term; + this.updateCount = updateCount; + this.firstChoiceUniversity = firstChoiceUniversity; + this.secondChoiceUniversity = secondChoiceUniversity; + this.thirdChoiceUniversity = thirdChoiceUniversity; + this.nicknameForApply = nicknameForApply; + this.verifyStatus = PENDING; + } + + public Application( + SiteUser siteUser, + Gpa gpa, + LanguageTest languageTest, + String term, + UniversityInfoForApply firstChoiceUniversity, + UniversityInfoForApply secondChoiceUniversity, + UniversityInfoForApply thirdChoiceUniversity, + String nicknameForApply) { + this.siteUser = siteUser; + this.gpa = gpa; + this.languageTest = languageTest; + this.term = term; + this.updateCount = 0; this.firstChoiceUniversity = firstChoiceUniversity; this.secondChoiceUniversity = secondChoiceUniversity; this.thirdChoiceUniversity = thirdChoiceUniversity; this.nicknameForApply = nicknameForApply; - this.verifyStatus = VerifyStatus.APPROVED; + this.verifyStatus = PENDING; + } + + public void setIsDeleteTrue() { + this.isDelete = true; } public void updateUniversityChoice( diff --git a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java index 8f30c196c..a3bca9dc2 100644 --- a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java +++ b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java @@ -6,6 +6,8 @@ import com.example.solidconnection.type.VerifyStatus; import com.example.solidconnection.university.domain.UniversityInfoForApply; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -18,9 +20,8 @@ public interface ApplicationRepository extends JpaRepository boolean existsByNicknameForApply(String nicknameForApply); - Optional findTop1BySiteUser_EmailOrderByTermDesc(String email); - - Optional findBySiteUserAndTerm(SiteUser siteUser, String term); + @Query("SELECT a FROM Application a WHERE a.siteUser = :siteUser AND a.term = :term AND a.isDelete = false") + Optional findBySiteUserAndTerm(@Param("siteUser") SiteUser siteUser, @Param("term") String term); List findAllByFirstChoiceUniversityAndVerifyStatusAndTerm(UniversityInfoForApply firstChoiceUniversity, VerifyStatus verifyStatus, String term); 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 1d8e76898..6b263996e 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationSubmissionService.java @@ -48,31 +48,39 @@ public boolean apply(String email, ApplyRequest applyRequest) { Long gpaScoreId = applyRequest.gpaScoreId(); Long languageTestScoreId = applyRequest.languageTestScoreId(); - GpaScore gpaScore = getGpaScore(siteUser, gpaScoreId); - LanguageTestScore languageTestScore = getLanguageTestScore(siteUser, languageTestScoreId); + GpaScore gpaScore = getValidGpaScore(siteUser, gpaScoreId); + LanguageTestScore languageTestScore = getValidLanguageTestScore(siteUser, languageTestScoreId); Optional application = applicationRepository.findBySiteUserAndTerm(siteUser, term); - application.ifPresentOrElse(before -> { + + UniversityInfoForApply firstChoiceUniversity = universityInfoForApplyRepository + .getUniversityInfoForApplyByIdAndTerm(universityChoiceRequest.firstChoiceUniversityId(), term); + UniversityInfoForApply secondChoiceUniversity = Optional.ofNullable(universityChoiceRequest.secondChoiceUniversityId()) + .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) + .orElse(null); + UniversityInfoForApply thirdChoiceUniversity = Optional.ofNullable(universityChoiceRequest.thirdChoiceUniversityId()) + .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) + .orElse(null); + + if (application.isEmpty()) { + Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(), + term, firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname()); + newApplication.setVerifyStatus(VerifyStatus.APPROVED); + applicationRepository.save(newApplication); + } else { + Application before = application.get(); validateUpdateLimitNotExceed(before); - UniversityInfoForApply firstChoiceUniversity = universityInfoForApplyRepository - .getUniversityInfoForApplyByIdAndTerm(universityChoiceRequest.firstChoiceUniversityId(), term); - UniversityInfoForApply secondChoiceUniversity = Optional.ofNullable(universityChoiceRequest.secondChoiceUniversityId()) - .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) - .orElse(null); - UniversityInfoForApply thirdChoiceUniversity = Optional.ofNullable(universityChoiceRequest.thirdChoiceUniversityId()) - .map(id -> universityInfoForApplyRepository.getUniversityInfoForApplyByIdAndTerm(id, term)) - .orElse(null); - before.updateApplication(gpaScore.getGpa(), languageTestScore.getLanguageTest(), firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname()); - applicationRepository.save(before); - }, () -> { - Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(), term); + before.setIsDeleteTrue(); // 기존 이력 soft delete 수행한다. + + Application newApplication = new Application(siteUser, gpaScore.getGpa(), languageTestScore.getLanguageTest(), + term, before.getUpdateCount() + 1, firstChoiceUniversity, secondChoiceUniversity, thirdChoiceUniversity, getRandomNickname()); newApplication.setVerifyStatus(VerifyStatus.APPROVED); applicationRepository.save(newApplication); - }); + } return true; } - private GpaScore getGpaScore(SiteUser siteUser, Long gpaScoreId) { + private GpaScore getValidGpaScore(SiteUser siteUser, Long gpaScoreId) { GpaScore gpaScore = gpaScoreRepository.findGpaScoreBySiteUserAndId(siteUser, gpaScoreId) .orElseThrow(() -> new CustomException(INVALID_GPA_SCORE)); if (gpaScore.getVerifyStatus() != VerifyStatus.APPROVED) { @@ -81,7 +89,7 @@ private GpaScore getGpaScore(SiteUser siteUser, Long gpaScoreId) { return gpaScore; } - private LanguageTestScore getLanguageTestScore(SiteUser siteUser, Long languageTestScoreId) { + private LanguageTestScore getValidLanguageTestScore(SiteUser siteUser, Long languageTestScoreId) { LanguageTestScore languageTestScore = languageTestScoreRepository .findLanguageTestScoreBySiteUserAndId(siteUser, languageTestScoreId) .orElseThrow(() -> new CustomException(INVALID_LANGUAGE_TEST_SCORE)); From b9f470fbc995603102fe78379cf671b14102e3df Mon Sep 17 00:00:00 2001 From: sewon Date: Tue, 19 Nov 2024 11:50:53 +0900 Subject: [PATCH 14/16] =?UTF-8?q?refactor:=20=EC=98=88=EC=83=81=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EB=AA=BB=ED=95=9C=20=EC=BF=BC=EB=A6=AC=20=EC=8B=A4?= =?UTF-8?q?=ED=96=89=EC=9D=84=20=EB=B0=A9=EC=A7=80=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20=EC=A6=89=EC=8B=9C=EB=A1=9C=EB=94=A9=20?= =?UTF-8?q?=EC=A7=80=EC=97=B0=EB=A1=9C=EB=94=A9=EC=9C=BC=EB=A1=9C=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 --- .../solidconnection/score/domain/GpaScore.java | 2 +- .../solidconnection/university/domain/University.java | 11 +++-------- .../university/domain/UniversityInfoForApply.java | 4 ++-- 3 files changed, 6 insertions(+), 11 deletions(-) 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 b5829cdaa..3bd70c02e 100644 --- a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java +++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java @@ -32,7 +32,7 @@ public class GpaScore extends BaseEntity { private String rejectedReason; - @OneToOne + @OneToOne(fetch = FetchType.LAZY) private SiteUser siteUser; public GpaScore(Gpa gpa, SiteUser siteUser, LocalDate issueDate) { diff --git a/src/main/java/com/example/solidconnection/university/domain/University.java b/src/main/java/com/example/solidconnection/university/domain/University.java index c3021385e..1ebb7dd49 100644 --- a/src/main/java/com/example/solidconnection/university/domain/University.java +++ b/src/main/java/com/example/solidconnection/university/domain/University.java @@ -2,12 +2,7 @@ import com.example.solidconnection.entity.Country; import com.example.solidconnection.entity.Region; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; -import jakarta.persistence.ManyToOne; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; @@ -50,9 +45,9 @@ public class University { @Column(length = 1000) private String detailsForLocal; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private Country country; - @ManyToOne + @ManyToOne(fetch = FetchType.LAZY) private Region region; } diff --git a/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java b/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java index 6a1cdf4dd..bf489a6fa 100644 --- a/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java +++ b/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java @@ -76,10 +76,10 @@ public class UniversityInfoForApply { @Column(length = 500) private String details; - @OneToMany(mappedBy = "universityInfoForApply", fetch = FetchType.EAGER) + @OneToMany(mappedBy = "universityInfoForApply", fetch = FetchType.LAZY) private Set languageRequirements = new HashSet<>(); - @ManyToOne(fetch = FetchType.EAGER) + @ManyToOne(fetch = FetchType.LAZY) private University university; public void addLanguageRequirements(LanguageRequirement languageRequirements) { From 3f2e7197f34e3fdf2e02565175145e5c3740c502 Mon Sep 17 00:00:00 2001 From: sewon Date: Wed, 27 Nov 2024 15:32:16 +0900 Subject: [PATCH 15/16] =?UTF-8?q?refactor:=20GpaScore,=20LanguageTestScore?= =?UTF-8?q?=20=EC=9D=B4=EB=A0=A5=20=EC=88=98=EC=A0=95=20=EB=8C=80=EC=8B=A0?= =?UTF-8?q?=20=EC=83=88=EB=A1=9C=EC=9A=B4=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=98=EC=97=AC=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../score/domain/GpaScore.java | 16 ++-- .../score/domain/LanguageTestScore.java | 7 -- .../score/dto/GpaScoreStatus.java | 25 +++++++ .../score/dto/GpaScoreStatusResponse.java | 21 +----- .../score/service/ScoreService.java | 50 ++++--------- .../siteuser/domain/SiteUser.java | 11 +-- .../unit/service/ScoreServiceTest.java | 73 ++++--------------- 7 files changed, 65 insertions(+), 138 deletions(-) create mode 100644 src/main/java/com/example/solidconnection/score/dto/GpaScoreStatus.java 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 3bd70c02e..2747f8c88 100644 --- a/src/main/java/com/example/solidconnection/score/domain/GpaScore.java +++ b/src/main/java/com/example/solidconnection/score/domain/GpaScore.java @@ -32,7 +32,7 @@ public class GpaScore extends BaseEntity { private String rejectedReason; - @OneToOne(fetch = FetchType.LAZY) + @ManyToOne private SiteUser siteUser; public GpaScore(Gpa gpa, SiteUser siteUser, LocalDate issueDate) { @@ -44,16 +44,10 @@ public GpaScore(Gpa gpa, SiteUser siteUser, LocalDate issueDate) { } public void setSiteUser(SiteUser siteUser) { - this.siteUser = siteUser; - if (siteUser != null && siteUser.getGpaScore() != this) { - siteUser.setGpaScore(this); + if (this.siteUser != null) { + this.siteUser.getGpaScoreList().remove(this); } - } - - public void update(Gpa gpa, LocalDate issueDate) { - this.gpa = gpa; - this.issueDate = issueDate; - this.verifyStatus = VerifyStatus.PENDING; - this.rejectedReason = null; + this.siteUser = siteUser; + siteUser.getGpaScoreList().add(this); } } diff --git a/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java b/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java index 78a75bcc5..bc16bc4e4 100644 --- a/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java +++ b/src/main/java/com/example/solidconnection/score/domain/LanguageTestScore.java @@ -49,11 +49,4 @@ public void setSiteUser(SiteUser siteUser) { this.siteUser = siteUser; siteUser.getLanguageTestScoreList().add(this); } - - public void update(LanguageTest languageTest, LocalDate issueDate) { - this.languageTest = languageTest; - this.issueDate = issueDate; - this.verifyStatus = VerifyStatus.PENDING; - this.rejectedReason = null; - } } diff --git a/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatus.java b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatus.java new file mode 100644 index 000000000..0361cf0e7 --- /dev/null +++ b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatus.java @@ -0,0 +1,25 @@ +package com.example.solidconnection.score.dto; + +import com.example.solidconnection.application.domain.Gpa; +import com.example.solidconnection.score.domain.GpaScore; +import com.example.solidconnection.type.VerifyStatus; + +import java.time.LocalDate; + +public record GpaScoreStatus( + Long id, + Gpa gpa, + LocalDate issueDate, + VerifyStatus verifyStatus, + String rejectedReason +) { + public static GpaScoreStatus from(GpaScore gpaScore) { + return new GpaScoreStatus( + gpaScore.getId(), + gpaScore.getGpa(), + gpaScore.getIssueDate(), + gpaScore.getVerifyStatus(), + gpaScore.getRejectedReason() + ); + } +} diff --git a/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java index eb9c38ea4..06fdba0d3 100644 --- a/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java +++ b/src/main/java/com/example/solidconnection/score/dto/GpaScoreStatusResponse.java @@ -1,25 +1,8 @@ package com.example.solidconnection.score.dto; -import com.example.solidconnection.application.domain.Gpa; -import com.example.solidconnection.score.domain.GpaScore; -import com.example.solidconnection.type.VerifyStatus; - -import java.time.LocalDate; +import java.util.List; public record GpaScoreStatusResponse( - Long id, - Gpa gpa, - LocalDate issueDate, - VerifyStatus verifyStatus, - String rejectedReason + List gpaScoreStatusList ) { - public static GpaScoreStatusResponse from(GpaScore gpaScore) { - return new GpaScoreStatusResponse( - gpaScore.getId(), - gpaScore.getGpa(), - gpaScore.getIssueDate(), - gpaScore.getVerifyStatus(), - gpaScore.getRejectedReason() - ); - } } diff --git a/src/main/java/com/example/solidconnection/score/service/ScoreService.java b/src/main/java/com/example/solidconnection/score/service/ScoreService.java index 4dc6031f5..b2d9ad29e 100644 --- a/src/main/java/com/example/solidconnection/score/service/ScoreService.java +++ b/src/main/java/com/example/solidconnection/score/service/ScoreService.java @@ -29,18 +29,10 @@ public class ScoreService { public Long submitGpaScore(String email, GpaScoreRequest gpaScoreRequest) { SiteUser siteUser = siteUserRepository.getByEmail(email); - Optional gpaScoreBySiteUser = gpaScoreRepository.findGpaScoreBySiteUser(siteUser); - if (gpaScoreBySiteUser.isPresent()) { - GpaScore gpaScore = gpaScoreBySiteUser.get(); - gpaScore.update(gpaScoreRequest.toGpa(), gpaScoreRequest.issueDate()); - GpaScore savedGpaScore = gpaScoreRepository.save(gpaScore); // 저장 후 반환된 객체 - return savedGpaScore.getId(); // 저장된 GPA Score의 ID 반환 - } else { - GpaScore newGpaScore = new GpaScore(gpaScoreRequest.toGpa(), siteUser, gpaScoreRequest.issueDate()); - newGpaScore.setSiteUser(siteUser); - GpaScore savedNewGpaScore = gpaScoreRepository.save(newGpaScore); // 저장 후 반환된 객체 - return savedNewGpaScore.getId(); // 저장된 GPA Score의 ID 반환 - } + GpaScore newGpaScore = new GpaScore(gpaScoreRequest.toGpa(), siteUser, gpaScoreRequest.issueDate()); + newGpaScore.setSiteUser(siteUser); + GpaScore savedNewGpaScore = gpaScoreRepository.save(newGpaScore); // 저장 후 반환된 객체 + return savedNewGpaScore.getId(); // 저장된 GPA Score의 ID 반환 } @Transactional @@ -48,33 +40,23 @@ public Long submitLanguageTestScore(String email, LanguageTestScoreRequest langu SiteUser siteUser = siteUserRepository.getByEmail(email); LanguageTest languageTest = languageTestScoreRequest.toLanguageTest(); - Optional languageTestScore = - languageTestScoreRepository.findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType(siteUser, languageTest.getLanguageTestType()); - - if (languageTestScore.isPresent()) { - // 기존 이력이 있을 경우 업데이트 - LanguageTestScore existingScore = languageTestScore.get(); - existingScore.update(languageTest, languageTestScoreRequest.issueDate()); - languageTestScoreRepository.save(existingScore); - return existingScore.getId(); // 업데이트된 객체의 ID 반환 - } else { - // 기존 이력이 없을 경우 새로 생성 - LanguageTestScore newScore = new LanguageTestScore( - languageTest, languageTestScoreRequest.issueDate(), siteUser); - newScore.setSiteUser(siteUser); - LanguageTestScore savedNewScore = languageTestScoreRepository.save(newScore); // 새로 저장한 객체 - return savedNewScore.getId(); // 저장된 객체의 ID 반환 - } + LanguageTestScore newScore = new LanguageTestScore( + languageTest, languageTestScoreRequest.issueDate(), siteUser); + newScore.setSiteUser(siteUser); + LanguageTestScore savedNewScore = languageTestScoreRepository.save(newScore); // 새로 저장한 객체 + return savedNewScore.getId(); // 저장된 객체의 ID 반환 } @Transactional(readOnly = true) public GpaScoreStatusResponse getGpaScoreStatus(String email) { SiteUser siteUser = siteUserRepository.getByEmail(email); - GpaScore gpaScore = siteUser.getGpaScore(); - if (gpaScore == null) { - return null; - } - return GpaScoreStatusResponse.from(gpaScore); + List gpaScoreStatusList = + Optional.ofNullable(siteUser.getGpaScoreList()) + .map(scores -> scores.stream() + .map(GpaScoreStatus::from) + .collect(Collectors.toList())) + .orElse(Collections.emptyList()); + return new GpaScoreStatusResponse(gpaScoreStatusList); } @Transactional(readOnly = true) diff --git a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java index ed8d1650e..47a071b04 100644 --- a/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java +++ b/src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java @@ -70,16 +70,9 @@ public class SiteUser { @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) private List languageTestScoreList = new ArrayList<>(); - @OneToOne(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) - private GpaScore gpaScore; - + @OneToMany(mappedBy = "siteUser", cascade = CascadeType.ALL, orphanRemoval = true) + private List gpaScoreList = new ArrayList<>(); - public void setGpaScore(GpaScore gpaScore) { - this.gpaScore = gpaScore; - if (gpaScore != null && gpaScore.getSiteUser() != this) { - gpaScore.setSiteUser(this); - } - } public SiteUser( String email, diff --git a/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java b/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java index e60093fde..39deadb54 100644 --- a/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java +++ b/src/test/java/com/example/solidconnection/unit/service/ScoreServiceTest.java @@ -24,7 +24,6 @@ import java.time.LocalDate; import java.util.List; -import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; @@ -43,13 +42,15 @@ public class ScoreServiceTest { private SiteUser siteUser; private GpaScore beforeGpaScore; + private GpaScore beforeGpaScore2; private LanguageTestScore beforeLanguageTestScore; private LanguageTestScore beforeLanguageTestScore2; @BeforeEach void setUp() { siteUser = createSiteUser(); - beforeGpaScore = createBeforeGpaScore(siteUser); + beforeGpaScore = createBeforeGpaScore(siteUser, 4.5); + beforeGpaScore2 = createBeforeGpaScore(siteUser, 4.3); beforeLanguageTestScore = createBeforeLanguageTestScore(siteUser); beforeLanguageTestScore2 = createBeforeLanguageTestScore2(siteUser); } @@ -66,9 +67,9 @@ private SiteUser createSiteUser() { ); } - private GpaScore createBeforeGpaScore(SiteUser siteUser) { + private GpaScore createBeforeGpaScore(SiteUser siteUser, Double gpa) { return new GpaScore( - new Gpa(4.5, 4.5, "http://example.com/gpa-report.pdf"), + new Gpa(gpa, 4.5, "http://example.com/gpa-report.pdf"), siteUser, LocalDate.of(2024, 10, 20) ); @@ -98,7 +99,6 @@ private LanguageTestScore createBeforeLanguageTestScore2(SiteUser siteUser) { ); GpaScore newGpaScore = new GpaScore(gpaScoreRequest.toGpa(), siteUser, gpaScoreRequest.issueDate()); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); - when(gpaScoreRepository.findGpaScoreBySiteUser(siteUser)).thenReturn(Optional.empty()); when(gpaScoreRepository.save(newGpaScore)).thenReturn(newGpaScore); // 새로운 gpa 저장하게된다. @@ -109,29 +109,6 @@ private LanguageTestScore createBeforeLanguageTestScore2(SiteUser siteUser) { verify(gpaScoreRepository, times(1)).save(any(GpaScore.class)); } - @Test - void 학점을_등록한다_기존이력이_있을_때() { - // Given - GpaScoreRequest gpaScoreRequest = new GpaScoreRequest( - 4.5, 4.5, LocalDate.of(2024, 10, 30), "http://example.com/gpa-report.pdf" - ); - GpaScore afterGpaScore = new GpaScore( - new Gpa(4.3, 4.5, "http://example.com/gpa-report.pdf"), - siteUser, - LocalDate.of(2024, 10, 30) - ); - when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); - when(gpaScoreRepository.findGpaScoreBySiteUser(siteUser)).thenReturn(Optional.of(beforeGpaScore)); - when(gpaScoreRepository.save(any(GpaScore.class))).thenReturn(afterGpaScore); - - // GPA 저장 - scoreService.submitGpaScore(siteUser.getEmail(), gpaScoreRequest); - - // Then - verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); - verify(gpaScoreRepository, times(1)).save(any(GpaScore.class)); - } - @Test void 어학성적을_등록한다_기존이력이_없을_때() { // Given @@ -143,8 +120,6 @@ private LanguageTestScore createBeforeLanguageTestScore2(SiteUser siteUser) { LanguageTestScore languageTestScore = new LanguageTestScore(languageTest, LocalDate.of(2024, 10, 30), siteUser); when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); - when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType( - siteUser, languageTest.getLanguageTestType())).thenReturn(Optional.empty()); when(languageTestScoreRepository.save(any(LanguageTestScore.class))).thenReturn(languageTestScore); //when @@ -155,41 +130,24 @@ private LanguageTestScore createBeforeLanguageTestScore2(SiteUser siteUser) { verify(languageTestScoreRepository, times(1)).save(any(LanguageTestScore.class)); } - @Test - void 어학성적을_등록한다_기존이력이_있을_때() { - // Given - LanguageTestScoreRequest languageTestScoreRequest = new LanguageTestScoreRequest( - LanguageTestType.TOEIC, "990", - LocalDate.of(2024, 10, 30), "http://example.com/gpa-report.pdf" - ); - LanguageTest languageTest = languageTestScoreRequest.toLanguageTest(); - - when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); - when(languageTestScoreRepository.findLanguageTestScoreBySiteUserAndLanguageTest_LanguageTestType( - siteUser, languageTest.getLanguageTestType())).thenReturn(Optional.of(beforeLanguageTestScore)); - beforeLanguageTestScore.update(languageTest, languageTestScoreRequest.issueDate()); - when(languageTestScoreRepository.save(any(LanguageTestScore.class))).thenReturn(beforeLanguageTestScore); - - //when - scoreService.submitLanguageTestScore(siteUser.getEmail(), languageTestScoreRequest); - - // Then - verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); - verify(languageTestScoreRepository, times(1)).save(any(LanguageTestScore.class)); - } - @Test void 학점이력을_조회한다_제출이력이_있을_때() { // Given when(siteUserRepository.getByEmail(siteUser.getEmail())).thenReturn(siteUser); beforeGpaScore.setSiteUser(siteUser); + beforeGpaScore2.setSiteUser(siteUser); // when - GpaScoreStatusResponse gpaScoreStatus = scoreService.getGpaScoreStatus(siteUser.getEmail()); + GpaScoreStatusResponse gpaScoreStatusResponse = scoreService.getGpaScoreStatus(siteUser.getEmail()); // Then - assertThat(gpaScoreStatus) - .isEqualTo(GpaScoreStatusResponse.from(siteUser.getGpaScore())); + List expectedStatusList = List.of( + GpaScoreStatus.from(beforeGpaScore), + GpaScoreStatus.from(beforeGpaScore2) + ); + assertThat(gpaScoreStatusResponse.gpaScoreStatusList()) + .hasSize(2) + .containsExactlyElementsOf(expectedStatusList); verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); } @@ -202,8 +160,7 @@ private LanguageTestScore createBeforeLanguageTestScore2(SiteUser siteUser) { GpaScoreStatusResponse gpaScoreStatus = scoreService.getGpaScoreStatus(siteUser.getEmail()); // Then - assertThat(gpaScoreStatus) - .isEqualTo(null); + assertThat(gpaScoreStatus.gpaScoreStatusList()).isEmpty(); verify(siteUserRepository, times(1)).getByEmail(siteUser.getEmail()); } From 96d6ab3b2e5101661ad8af2c6a2fbdda8e3f2129 Mon Sep 17 00:00:00 2001 From: sewon Date: Sat, 30 Nov 2024 18:06:32 +0900 Subject: [PATCH 16/16] =?UTF-8?q?fix:=20=EC=B6=94=EC=B2=9C=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=8B=A4=ED=8C=A8=EB=A1=9C=20=EC=A6=89?= =?UTF-8?q?=EC=8B=9C=EB=A1=9C=EB=94=A9=EC=9C=BC=EB=A1=9C=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 --- .../example/solidconnection/university/domain/University.java | 4 ++-- .../university/domain/UniversityInfoForApply.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/example/solidconnection/university/domain/University.java b/src/main/java/com/example/solidconnection/university/domain/University.java index 1ebb7dd49..8e31dfa4a 100644 --- a/src/main/java/com/example/solidconnection/university/domain/University.java +++ b/src/main/java/com/example/solidconnection/university/domain/University.java @@ -45,9 +45,9 @@ public class University { @Column(length = 1000) private String detailsForLocal; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne private Country country; - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne private Region region; } diff --git a/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java b/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java index bf489a6fa..6a1cdf4dd 100644 --- a/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java +++ b/src/main/java/com/example/solidconnection/university/domain/UniversityInfoForApply.java @@ -76,10 +76,10 @@ public class UniversityInfoForApply { @Column(length = 500) private String details; - @OneToMany(mappedBy = "universityInfoForApply", fetch = FetchType.LAZY) + @OneToMany(mappedBy = "universityInfoForApply", fetch = FetchType.EAGER) private Set languageRequirements = new HashSet<>(); - @ManyToOne(fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.EAGER) private University university; public void addLanguageRequirements(LanguageRequirement languageRequirements) {