From dfbb08d524f0e78d6a83acbe5e7628d4d2890ea6 Mon Sep 17 00:00:00 2001 From: seonghyeok cho <65901319+whqtker@users.noreply.github.com> Date: Sat, 11 Jul 2026 13:27:08 +0900 Subject: [PATCH 1/4] =?UTF-8?q?chore:=20=EC=A0=84=EC=B2=B4=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EB=B0=98=EB=B3=B5=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#814)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/full-test-repeat.yml | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 .github/workflows/full-test-repeat.yml diff --git a/.github/workflows/full-test-repeat.yml b/.github/workflows/full-test-repeat.yml new file mode 100644 index 000000000..267b4da70 --- /dev/null +++ b/.github/workflows/full-test-repeat.yml @@ -0,0 +1,59 @@ +name: Full Test Suite Repeat + +on: + workflow_dispatch: + inputs: + repeat_count: + description: '전체 테스트를 반복할 횟수' + required: true + default: '10' + +jobs: + repeat-test: + runs-on: ubuntu-latest + permissions: + contents: read + checks: write + + steps: + - name: Checkout the code + uses: actions/checkout@v4 + + - name: Set up JDK 21 + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + - name: Run full test suite N times + run: | + set +e + REPEAT_COUNT="${{ github.event.inputs.repeat_count }}" + FAIL_COUNT=0 + for i in $(seq 1 "$REPEAT_COUNT"); do + echo "=== Run $i/$REPEAT_COUNT ===" + ./gradlew test --rerun-tasks + STATUS=$? + mkdir -p "build/repeat-test-results/run-$i" + cp -r build/test-results/test/. "build/repeat-test-results/run-$i/" 2>/dev/null || true + if [ $STATUS -ne 0 ]; then + FAIL_COUNT=$((FAIL_COUNT + 1)) + echo "Run $i FAILED" + fi + done + echo "Total failures: $FAIL_COUNT / $REPEAT_COUNT" + if [ "$FAIL_COUNT" -ne 0 ]; then + exit 1 + fi + + - name: Publish Test Report + uses: mikepenz/action-junit-report@v5 + if: success() || failure() + with: + report_paths: 'build/repeat-test-results/**/TEST-*.xml' From 065564c8fbab0647207cbb184099bd8cf23ba4c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=95=9C=EB=A7=8C=EC=9A=B1?= <98882987+manNomi@users.noreply.github.com> Date: Fri, 31 Jul 2026 20:49:34 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=20=ED=98=84?= =?UTF-8?q?=ED=99=A9=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20API=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#815)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 지원 현황 미리보기 API 추가 * fix: 지원 현황 미리보기를 모교별로 제한 * fix: 지원 현황 미리보기 리뷰 반영 --- .../controller/ApplicationController.java | 9 ++ .../dto/ApplicationPreviewResponse.java | 8 ++ .../ApplicationUniversityPreviewResponse.java | 25 ++++ .../repository/ApplicationRepository.java | 33 +++++ .../service/ApplicationQueryService.java | 23 ++++ .../repository/UnivApplyInfoRepository.java | 2 + .../service/ApplicationQueryServiceTest.java | 121 ++++++++++++++++++ 7 files changed, 221 insertions(+) create mode 100644 src/main/java/com/example/solidconnection/application/dto/ApplicationPreviewResponse.java create mode 100644 src/main/java/com/example/solidconnection/application/dto/ApplicationUniversityPreviewResponse.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 c388f8b25..97002f8b9 100644 --- a/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java +++ b/src/main/java/com/example/solidconnection/application/controller/ApplicationController.java @@ -1,5 +1,6 @@ package com.example.solidconnection.application.controller; +import com.example.solidconnection.application.dto.ApplicationPreviewResponse; import com.example.solidconnection.application.dto.ApplicationSubmissionResponse; import com.example.solidconnection.application.dto.ApplicationsResponse; import com.example.solidconnection.application.dto.ApplyRequest; @@ -37,6 +38,14 @@ public ResponseEntity apply( .body(applicationSubmissionResponse); } + @GetMapping("/preview") + public ResponseEntity getApplicationPreview( + @AuthorizedUser long siteUserId + ) { + ApplicationPreviewResponse result = applicationQueryService.getApplicantUniversityPreviews(siteUserId); + return ResponseEntity.ok(result); + } + // @RequireRoleAccess(roles = {Role.ADMIN}) // todo : 추후 어드민 페이지에서 권한 변경 기능 추가 필요 @GetMapping public ResponseEntity getApplicants( diff --git a/src/main/java/com/example/solidconnection/application/dto/ApplicationPreviewResponse.java b/src/main/java/com/example/solidconnection/application/dto/ApplicationPreviewResponse.java new file mode 100644 index 000000000..fc739808b --- /dev/null +++ b/src/main/java/com/example/solidconnection/application/dto/ApplicationPreviewResponse.java @@ -0,0 +1,8 @@ +package com.example.solidconnection.application.dto; + +import java.util.List; + +public record ApplicationPreviewResponse( + long totalUniversityCount, + List universities) { +} diff --git a/src/main/java/com/example/solidconnection/application/dto/ApplicationUniversityPreviewResponse.java b/src/main/java/com/example/solidconnection/application/dto/ApplicationUniversityPreviewResponse.java new file mode 100644 index 000000000..54fa56a32 --- /dev/null +++ b/src/main/java/com/example/solidconnection/application/dto/ApplicationUniversityPreviewResponse.java @@ -0,0 +1,25 @@ +package com.example.solidconnection.application.dto; + +import com.example.solidconnection.university.domain.UnivApplyInfo; + +public record ApplicationUniversityPreviewResponse( + long id, + String koreanName, + Integer studentCapacity, + String region, + String country, + String logoImageUrl, + String backgroundImageUrl) { + + public static ApplicationUniversityPreviewResponse from(UnivApplyInfo univApplyInfo) { + return new ApplicationUniversityPreviewResponse( + univApplyInfo.getId(), + univApplyInfo.getKoreanName(), + univApplyInfo.getStudentCapacity(), + univApplyInfo.getUniversity().getRegion().getKoreanName(), + univApplyInfo.getUniversity().getCountry().getKoreanName(), + univApplyInfo.getUniversity().getLogoImageUrl(), + univApplyInfo.getUniversity().getBackgroundImageUrl() + ); + } +} 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 306158fc2..f155b7e75 100644 --- a/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java +++ b/src/main/java/com/example/solidconnection/application/repository/ApplicationRepository.java @@ -3,6 +3,7 @@ import static com.example.solidconnection.common.exception.ErrorCode.APPLICATION_NOT_FOUND; import com.example.solidconnection.application.domain.Application; +import com.example.solidconnection.application.dto.ApplicationUniversityPreviewResponse; import com.example.solidconnection.common.VerifyStatus; import com.example.solidconnection.common.exception.CustomException; import java.util.List; @@ -29,6 +30,38 @@ List findAllByUnivApplyInfoIds( @Param("status") VerifyStatus status, @Param("termId") long termId); + @Query(""" + SELECT new com.example.solidconnection.application.dto.ApplicationUniversityPreviewResponse( + uai.id, + uai.koreanName, + uai.studentCapacity, + region.koreanName, + country.koreanName, + university.logoImageUrl, + university.backgroundImageUrl + ) + FROM UnivApplyInfo uai + JOIN uai.university university + JOIN university.region region + JOIN university.country country + WHERE uai.termId = :termId + AND uai.homeUniversity.id = :homeUniversityId + AND EXISTS ( + SELECT application.id + FROM Application application + JOIN application.choices choice + WHERE choice.univApplyInfoId = uai.id + AND application.verifyStatus = :status + AND application.termId = :termId + AND application.isDelete = false + ) + ORDER BY uai.koreanName + """) + List findApplicantUniversityPreviews( + @Param("status") VerifyStatus status, + @Param("termId") long termId, + @Param("homeUniversityId") long homeUniversityId); + Optional findTopBySiteUserIdAndTermIdAndIsDeleteFalseOrderByIdDesc(long siteUserId, long termId); default Application getApplicationBySiteUserIdAndTermId(long siteUserId, long termId) { diff --git a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java index d69d59395..a1d1a9661 100644 --- a/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java +++ b/src/main/java/com/example/solidconnection/application/service/ApplicationQueryService.java @@ -2,11 +2,13 @@ import static com.example.solidconnection.common.exception.ErrorCode.APPLICATION_NOT_APPROVED; import static com.example.solidconnection.common.exception.ErrorCode.CURRENT_TERM_NOT_FOUND; +import static com.example.solidconnection.common.exception.ErrorCode.SCHOOL_EMAIL_NOT_VERIFIED; import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND; import com.example.solidconnection.application.domain.Application; import com.example.solidconnection.application.domain.ApplicationChoice; import com.example.solidconnection.application.dto.ApplicantsResponse; +import com.example.solidconnection.application.dto.ApplicationPreviewResponse; import com.example.solidconnection.application.dto.ApplicationsResponse; import com.example.solidconnection.application.repository.ApplicationRepository; import com.example.solidconnection.common.VerifyStatus; @@ -41,6 +43,27 @@ public class ApplicationQueryService { private final TermRepository termRepository; private final HomeUniversityRepository homeUniversityRepository; + @Transactional(readOnly = true) + public ApplicationPreviewResponse getApplicantUniversityPreviews(long siteUserId) { + SiteUser siteUser = siteUserRepository.findById(siteUserId) + .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); + + if (siteUser.getHomeUniversityId() == null) { + throw new CustomException(SCHOOL_EMAIL_NOT_VERIFIED); + } + + Term term = termRepository.findByIsCurrentTrue() + .orElseThrow(() -> new CustomException(CURRENT_TERM_NOT_FOUND)); + + return new ApplicationPreviewResponse( + univApplyInfoRepository.countByTermIdAndHomeUniversityId(term.getId(), siteUser.getHomeUniversityId()), + applicationRepository.findApplicantUniversityPreviews( + VerifyStatus.APPROVED, + term.getId(), + siteUser.getHomeUniversityId()) + ); + } + @Transactional(readOnly = true) public ApplicationsResponse getApplicants(long siteUserId, String regionCode, String keyword) { SiteUser siteUser = siteUserRepository.findById(siteUserId) diff --git a/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java b/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java index 4c2b6578e..bd9911536 100644 --- a/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java +++ b/src/main/java/com/example/solidconnection/university/repository/UnivApplyInfoRepository.java @@ -71,6 +71,8 @@ default UnivApplyInfo getUnivApplyInfoById(Long id) { boolean existsByHomeUniversityId(Long homeUniversityId); + long countByTermIdAndHomeUniversityId(long termId, long homeUniversityId); + @Query(""" SELECT uai.id FROM UnivApplyInfo uai diff --git a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java index a897284cb..bee562261 100644 --- a/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java +++ b/src/test/java/com/example/solidconnection/application/service/ApplicationQueryServiceTest.java @@ -1,14 +1,19 @@ package com.example.solidconnection.application.service; +import static com.example.solidconnection.common.exception.ErrorCode.SCHOOL_EMAIL_NOT_VERIFIED; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import com.example.solidconnection.application.domain.Application; import com.example.solidconnection.application.dto.ApplicantResponse; import com.example.solidconnection.application.dto.ApplicantsResponse; +import com.example.solidconnection.application.dto.ApplicationPreviewResponse; +import com.example.solidconnection.application.dto.ApplicationUniversityPreviewResponse; import com.example.solidconnection.application.dto.ApplicationsResponse; import com.example.solidconnection.application.fixture.ApplicationFixture; import com.example.solidconnection.application.repository.ApplicationRepository; import com.example.solidconnection.common.VerifyStatus; +import com.example.solidconnection.common.exception.CustomException; import com.example.solidconnection.location.region.fixture.RegionFixture; import com.example.solidconnection.score.domain.GpaScore; import com.example.solidconnection.score.domain.LanguageTestScore; @@ -20,7 +25,9 @@ import com.example.solidconnection.term.domain.Term; import com.example.solidconnection.term.fixture.TermFixture; import com.example.solidconnection.university.domain.UnivApplyInfo; +import com.example.solidconnection.university.fixture.HomeUniversityFixture; import com.example.solidconnection.university.fixture.UnivApplyInfoFixture; +import com.example.solidconnection.university.fixture.UnivApplyInfoFixtureBuilder; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -47,6 +54,12 @@ class ApplicationQueryServiceTest { @Autowired private UnivApplyInfoFixture univApplyInfoFixture; + @Autowired + private UnivApplyInfoFixtureBuilder univApplyInfoFixtureBuilder; + + @Autowired + private HomeUniversityFixture homeUniversityFixture; + @Autowired private GpaScoreFixture gpaScoreFixture; @@ -98,6 +111,114 @@ void setUp() { 서던덴마크대학교_지원_정보 = univApplyInfoFixture.서던덴마크대학교_지원_정보(term.getId()); } + @Nested + @DisplayName("지원 현황 미리보기 조회") + class 지원_현황_미리보기_조회_테스트 { + + @Test + void 자신의_모교에_속한_지원_대학만_중복_없이_조회한다() { + // given + SiteUser inhaUniversityUser = siteUserFixture.국내_대학_정보_소지_사용자( + 괌대학_A_지원_정보.getHomeUniversity().getId()); + applicationFixture.지원서( + user1, "nickname1", term.getId(), + gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), + List.of(괌대학_A_지원_정보.getId(), 버지니아공과대학_지원_정보.getId()) + ); + applicationFixture.지원서( + user2, "nickname2", term.getId(), + gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), + List.of(괌대학_A_지원_정보.getId()) + ); + UnivApplyInfo 인천대학교_전용_지원_정보 = univApplyInfoFixtureBuilder.univApplyInfo() + .termId(term.getId()) + .koreanName("인천대학교 전용 교환 대학") + .university(서던덴마크대학교_지원_정보.getUniversity()) + .homeUniversity(homeUniversityFixture.인천대학교()) + .create(); + applicationFixture.지원서( + user3, "nickname3", term.getId(), + gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), + List.of(인천대학교_전용_지원_정보.getId()) + ); + Application deletedApplication = applicationFixture.지원서( + user3, "nickname3", term.getId(), + gpaScore3.getGpa(), languageTestScore3.getLanguageTest(), + List.of(서던덴마크대학교_지원_정보.getId()) + ); + deletedApplication.setIsDeleteTrue(); + applicationRepository.save(deletedApplication); + UnivApplyInfo 승인_대기_지원_정보 = univApplyInfoFixtureBuilder.univApplyInfo() + .termId(term.getId()) + .koreanName("승인 대기 교환 대학") + .university(서던덴마크대학교_지원_정보.getUniversity()) + .homeUniversity(괌대학_A_지원_정보.getHomeUniversity()) + .create(); + Application pendingApplication = applicationFixture.지원서( + user1, "pending-nickname", term.getId(), + gpaScore1.getGpa(), languageTestScore1.getLanguageTest(), + List.of(승인_대기_지원_정보.getId()) + ); + pendingApplication.setVerifyStatus(VerifyStatus.PENDING); + applicationRepository.save(pendingApplication); + UnivApplyInfo 승인_거절_지원_정보 = univApplyInfoFixtureBuilder.univApplyInfo() + .termId(term.getId()) + .koreanName("승인 거절 교환 대학") + .university(서던덴마크대학교_지원_정보.getUniversity()) + .homeUniversity(괌대학_A_지원_정보.getHomeUniversity()) + .create(); + Application rejectedApplication = applicationFixture.지원서( + user2, "rejected-nickname", term.getId(), + gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), + List.of(승인_거절_지원_정보.getId()) + ); + rejectedApplication.setVerifyStatus(VerifyStatus.REJECTED); + applicationRepository.save(rejectedApplication); + + // when + ApplicationPreviewResponse response = applicationQueryService.getApplicantUniversityPreviews( + inhaUniversityUser.getId()); + + // then + assertThat(response.totalUniversityCount()).isEqualTo(5); + assertThat(response.universities()).containsExactly( + ApplicationUniversityPreviewResponse.from(괌대학_A_지원_정보), + ApplicationUniversityPreviewResponse.from(버지니아공과대학_지원_정보) + ); + } + + @Test + void 성적과_지원서를_제출하지_않은_로그인_사용자도_미리보기를_조회할_수_있다() { + // given + SiteUser signedInUserWithoutScores = siteUserFixture.국내_대학_정보_소지_사용자( + 괌대학_A_지원_정보.getHomeUniversity().getId()); + applicationFixture.지원서( + user2, "nickname2", term.getId(), + gpaScore2.getGpa(), languageTestScore2.getLanguageTest(), + List.of(괌대학_A_지원_정보.getId()) + ); + + // when + ApplicationPreviewResponse response = applicationQueryService.getApplicantUniversityPreviews( + signedInUserWithoutScores.getId()); + + // then + assertThat(response.totalUniversityCount()).isEqualTo(3); + assertThat(response.universities()).containsExactly( + ApplicationUniversityPreviewResponse.from(괌대학_A_지원_정보) + ); + } + + @Test + void 모교가_등록되지_않은_사용자는_미리보기를_조회할_수_없다() { + // when + // then + assertThatThrownBy(() -> applicationQueryService.getApplicantUniversityPreviews(user1.getId())) + .isInstanceOf(CustomException.class) + .hasMessage(SCHOOL_EMAIL_NOT_VERIFIED.getMessage()); + } + } + @Nested class 지원자_목록_조회_테스트 { From a1490d46139951d4feb8b58a8383a7527e2b7ec9 Mon Sep 17 00:00:00 2001 From: seonghyeok cho <65901319+whqtker@users.noreply.github.com> Date: Sun, 2 Aug 2026 01:42:32 +0900 Subject: [PATCH 3/4] =?UTF-8?q?chore:=20CODEOWNERS=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?(#820)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f9840b68f..7657ae672 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @Gyuhyeok99 @wibaek @whqtker @lsy1307 @Hexeong @JAEHEE25 @sukangpunch +* @Gyuhyeok99 @wibaek @whqtker @lsy1307 @Hexeong @sukangpunch From 5e577bfa7a378114cb5f0379893676dd82270dcb Mon Sep 17 00:00:00 2001 From: seonghyeok cho <65901319+whqtker@users.noreply.github.com> Date: Sun, 2 Aug 2026 01:45:34 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=EC=A7=80=EC=9B=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=99=20=EB=8B=A8=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(#817)=20(#818)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 어드민 지원 대학 관리에서 수정 모달을 열 때 목록 조회(search/text) 응답만 사용하고 있어 정원 외 필드가 채워지지 않는 문제가 있었다. search/text가 반환하는 미리보기 응답에는 애초에 해당 필드들이 포함되어 있지 않아 프론트에서 해결할 수 없었다. GET /admin/univ-apply-infos/{id}를 추가해 전체 필드를 담은 AdminUnivApplyInfoResponse를 단건으로 조회할 수 있게 했다. Co-authored-by: Claude Sonnet 5 --- .../AdminUnivApplyInfoController.java | 7 ++++ .../service/AdminUnivApplyInfoService.java | 7 ++++ .../AdminUnivApplyInfoServiceTest.java | 37 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/main/java/com/example/solidconnection/admin/university/controller/AdminUnivApplyInfoController.java b/src/main/java/com/example/solidconnection/admin/university/controller/AdminUnivApplyInfoController.java index e0fdbcb70..79d46506b 100644 --- a/src/main/java/com/example/solidconnection/admin/university/controller/AdminUnivApplyInfoController.java +++ b/src/main/java/com/example/solidconnection/admin/university/controller/AdminUnivApplyInfoController.java @@ -38,6 +38,13 @@ public ResponseEntity importUnivApplyInfos( return ResponseEntity.ok(adminUnivApplyInfoService.importUnivApplyInfos(request)); } + @GetMapping("/{id}") + public ResponseEntity getUnivApplyInfo( + @PathVariable long id + ) { + return ResponseEntity.ok(adminUnivApplyInfoService.getUnivApplyInfo(id)); + } + @PostMapping public ResponseEntity createUnivApplyInfo( @Valid @RequestBody AdminUnivApplyInfoCreateRequest request diff --git a/src/main/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoService.java b/src/main/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoService.java index 389c09031..93122007e 100644 --- a/src/main/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoService.java +++ b/src/main/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoService.java @@ -141,6 +141,13 @@ private HostUniversity findHostUniversity(Long hostUniversityId) { .orElseThrow(() -> new CustomException(UNIVERSITY_NOT_FOUND)); } + @Transactional(readOnly = true) + public AdminUnivApplyInfoResponse getUnivApplyInfo(long id) { + UnivApplyInfo univApplyInfo = univApplyInfoRepository.findById(id) + .orElseThrow(() -> new CustomException(UNIV_APPLY_INFO_NOT_FOUND)); + return AdminUnivApplyInfoResponse.from(univApplyInfo); + } + @Transactional @DefaultCacheOut( key = {"univApplyInfoTextSearch", "university:recommend:general"}, diff --git a/src/test/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoServiceTest.java b/src/test/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoServiceTest.java index 9f8f2c6dd..5f2ef1fcd 100644 --- a/src/test/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoServiceTest.java +++ b/src/test/java/com/example/solidconnection/admin/university/service/AdminUnivApplyInfoServiceTest.java @@ -515,6 +515,43 @@ class 지원_정보_생성 { } } + @Nested + class 지원_정보_단건_조회 { + + @Test + void 존재하는_id로_조회하면_상세_정보를_반환한다() { + // given + UnivApplyInfo univApplyInfo = univApplyInfoFixtureBuilder.univApplyInfo() + .termId(term.getId()).koreanName("괌대학(A형)") + .university(hostUniversity).homeUniversity(homeUniversity).create(); + + // when + AdminUnivApplyInfoResponse response = adminUnivApplyInfoService.getUnivApplyInfo(univApplyInfo.getId()); + + // then + assertAll( + () -> assertThat(response.id()).isEqualTo(univApplyInfo.getId()), + () -> assertThat(response.termId()).isEqualTo(term.getId()), + () -> assertThat(response.homeUniversityId()).isEqualTo(homeUniversity.getId()), + () -> assertThat(response.hostUniversityId()).isEqualTo(hostUniversity.getId()), + () -> assertThat(response.studentCapacity()).isEqualTo(univApplyInfo.getStudentCapacity()), + () -> assertThat(response.semesterRequirement()).isEqualTo(univApplyInfo.getSemesterRequirement()), + () -> assertThat(response.detailsForLanguage()).isEqualTo(univApplyInfo.getDetailsForLanguage()), + () -> assertThat(response.gpaRequirement()).isEqualTo(univApplyInfo.getGpaRequirement()), + () -> assertThat(response.gpaRequirementCriteria()).isEqualTo(univApplyInfo.getGpaRequirementCriteria()), + () -> assertThat(response.detailsForAccommodation()).isEqualTo(univApplyInfo.getDetailsForAccommodation()) + ); + } + + @Test + void 존재하지_않는_id로_조회하면_예외가_발생한다() { + // when & then + assertThatCode(() -> adminUnivApplyInfoService.getUnivApplyInfo(invalidId)) + .isInstanceOf(CustomException.class) + .hasMessage(ErrorCode.UNIV_APPLY_INFO_NOT_FOUND.getMessage()); + } + } + @Nested class 지원_정보_수정 {