From f62d7cf48070244671b47faff2fa3e0ec14f431a Mon Sep 17 00:00:00 2001 From: sukangpunch Date: Wed, 20 May 2026 15:41:03 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=A9=98=ED=86=A0=20=EC=8A=B9=EA=B2=A9?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=20=ED=9A=9F=EC=88=98=20=EC=A0=9C=ED=95=9C?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20(#667)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 유저당 멘토 승격 요청을 최대 5회까지만 가능하도록 제한 --- .../common/exception/ErrorCode.java | 2 ++ .../service/MentorApplicationService.java | 10 ++++++++++ .../service/MentorApplicationServiceTest.java | 20 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java index 5f65329e..78b653da 100644 --- a/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java @@ -1,6 +1,7 @@ package com.example.solidconnection.common.exception; import static com.example.solidconnection.application.service.ApplicationSubmissionService.APPLICATION_UPDATE_COUNT_LIMIT; +import static com.example.solidconnection.mentor.service.MentorApplicationService.MENTOR_APPLICATION_COUNT_LIMIT; import static com.example.solidconnection.siteuser.service.MyPageService.MIN_DAYS_BETWEEN_NICKNAME_CHANGES; import lombok.AllArgsConstructor; @@ -133,6 +134,7 @@ public enum ErrorCode { UNAUTHORIZED_MENTORING(HttpStatus.FORBIDDEN.value(), "멘토링 권한이 없습니다."), MENTORING_ALREADY_CONFIRMED(HttpStatus.BAD_REQUEST.value(), "이미 승인 또는 거절된 멘토링입니다."), MENTOR_APPLICATION_ALREADY_EXISTED(HttpStatus.CONFLICT.value(), "멘토 승격 요청이 이미 존재합니다."), + MENTOR_APPLICATION_LIMIT_EXCEEDED(HttpStatus.BAD_REQUEST.value(), "멘토 승격 요청은 " + MENTOR_APPLICATION_COUNT_LIMIT + "회까지만 가능합니다."), INVALID_EXCHANGE_STATUS_FOR_MENTOR(HttpStatus.BAD_REQUEST.value(), "멘토 승격 지원 가능한 교환학생 상태가 아닙니다."), UNIVERSITY_ID_REQUIRED_FOR_CATALOG(HttpStatus.BAD_REQUEST.value(), "목록에서 학교를 선택한 경우 학교 정보가 필요합니다."), UNIVERSITY_ID_MUST_BE_NULL_FOR_OTHER(HttpStatus.BAD_REQUEST.value(), "기타 학교를 선택한 경우 학교 정보를 입력할 수 없습니다."), diff --git a/src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java b/src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java index 762dcc33..9a6f4c1b 100644 --- a/src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java +++ b/src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java @@ -1,6 +1,7 @@ package com.example.solidconnection.mentor.service; import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_APPLICATION_ALREADY_EXISTED; +import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_APPLICATION_LIMIT_EXCEEDED; import static com.example.solidconnection.common.exception.ErrorCode.TERM_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.USER_NOT_FOUND; @@ -28,6 +29,8 @@ @Slf4j public class MentorApplicationService { + public static final int MENTOR_APPLICATION_COUNT_LIMIT = 5; + private final MentorApplicationRepository mentorApplicationRepository; private final SiteUserRepository siteUserRepository; private final S3Service s3Service; @@ -40,6 +43,7 @@ public void submitMentorApplication( MultipartFile file ) { ensureNoPendingOrApprovedMentorApplication(siteUserId); + ensureApplicationCountNotExceeded(siteUserId); SiteUser siteUser = siteUserRepository.findById(siteUserId) .orElseThrow(() -> new CustomException(USER_NOT_FOUND)); @@ -66,4 +70,10 @@ private void ensureNoPendingOrApprovedMentorApplication(long siteUserId) { throw new CustomException(MENTOR_APPLICATION_ALREADY_EXISTED); } } + + private void ensureApplicationCountNotExceeded(long siteUserId) { + if (mentorApplicationRepository.countBySiteUserId(siteUserId) >= MENTOR_APPLICATION_COUNT_LIMIT) { + throw new CustomException(MENTOR_APPLICATION_LIMIT_EXCEEDED); + } + } } diff --git a/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java b/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java index 9c148291..31792e6a 100644 --- a/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java +++ b/src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java @@ -1,8 +1,10 @@ package com.example.solidconnection.mentor.service; import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_APPLICATION_ALREADY_EXISTED; +import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_APPLICATION_LIMIT_EXCEEDED; import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_ID_MUST_BE_NULL_FOR_OTHER; import static com.example.solidconnection.common.exception.ErrorCode.UNIVERSITY_ID_REQUIRED_FOR_CATALOG; +import static com.example.solidconnection.mentor.service.MentorApplicationService.MENTOR_APPLICATION_COUNT_LIMIT; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.mockito.BDDMockito.given; @@ -163,6 +165,24 @@ void setUp() { .hasMessage(MENTOR_APPLICATION_ALREADY_EXISTED.getMessage()); } + @Test + void 멘토_승격_신청_횟수가_최대_횟수에_도달하면_예외가_발생한다() { + // given + for (int i = 0; i < MENTOR_APPLICATION_COUNT_LIMIT; i++) { + mentorApplicationFixture.거절된_멘토신청(user.getId(), UniversitySelectType.CATALOG, 1L); + } + + UniversitySelectType universitySelectType = UniversitySelectType.CATALOG; + Long universityId = 1L; + MentorApplicationRequest request = createMentorApplicationRequest(universitySelectType, universityId); + MockMultipartFile file = createMentorProofFile(); + + // when & then + assertThatCode(() -> mentorApplicationService.submitMentorApplication(user.getId(), request, file)) + .isInstanceOf(CustomException.class) + .hasMessage(MENTOR_APPLICATION_LIMIT_EXCEEDED.getMessage()); + } + @Test void 이미_REJECTED_상태인_멘토_승격_요청이_존재할_때_멘토_신청이_등록된다() { // given