From ed4acc4bf32c8378514f17f31de19c39f9698ba1 Mon Sep 17 00:00:00 2001 From: 5uhwann <106325839+5uhwann@users.noreply.github.com> Date: Fri, 19 Jul 2024 21:39:01 +0900 Subject: [PATCH] =?UTF-8?q?[DEV-32]=20=EC=BB=A4=EC=8A=A4=ED=85=80=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=A0=81=EC=9A=A9=20(#2?= =?UTF-8?q?81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: custom errorCode 정의 * feat: ExceptionResponse 스펙 수정 * refactor: ErrorCode 추가 및 적용 * refactor: Auth - 로그인 요청 custom errorCode 적용 * refactor: 수강과목 등록 - pdf parsing text custom errorCode 적용 * feat: StudentCategory - 학생 이수구분 카테고리에 졸업 카테고리가 포함 여부 검증 로직 추가 * feat: 유저아이디 찾기 커스텀 에러코드 적용 * feat: 유저검증 커스텀 에러코드 적용 * feat: 비밀번호 재설정 커스텀 에러코드 적용 * feat: 아이디 중복 체크 커스텀 에러코드 적용 * feat: 학번 중복 체크정 커스텀 에러코드 적용 * feat: 회원 탈퇴 커스텀 에러코드 적용 * feat: 회원가입 요청 커스텀 에러코드 적용 * refactor: GlobalExceptionHandler response 스펙 수정 * refactor: 불필요 import 제거 --- .../api/signin/dto/request/SignInRequest.java | 2 +- .../auth/security/JwtAccessDeniedHandler.java | 7 +- .../security/JwtAuthenticationEntryPoint.java | 9 +- .../security/JwtAuthenticationProvider.java | 6 +- .../core/exception/ErrorCode.java | 25 +++++ .../core/exception/ExceptionResponse.java | 20 +--- .../exception/GlobalExceptionHandler.java | 24 ++--- ...alculateSingleDetailGraduationService.java | 1 + .../service/ParsingTextService.java | 6 +- ...aveTakenLectureFromParsingTextService.java | 19 ++-- .../findauthid/FindAuthIdApiPresentation.java | 5 +- .../api/findauthid/FindAuthIdController.java | 9 +- .../ResetPasswordApiPresentation.java | 3 +- .../ResetPasswordController.java | 7 +- .../dto/request/ResetPasswordRequest.java | 4 +- .../api/signup/SignUpApiPresentation.java | 7 +- .../user/api/signup/SignUpController.java | 9 +- .../api/signup/dto/request/SignUpRequest.java | 6 +- .../service/find/FindUserService.java | 7 +- .../resetpassword/ResetPasswordService.java | 3 +- .../service/signup/SignUpService.java | 9 +- .../service/withdraw/WithDrawUserService.java | 5 +- .../user/domain/model/StudentCategory.java | 38 ++++++-- .../user/domain/model/User.java | 12 +-- .../auth/api/signin/SignInControllerTest.java | 7 +- .../auth/api/token/TokenControllerTest.java | 2 +- .../FindDetailGraduationsControllerTest.java | 4 +- ...lateSingleDetailGraduationServiceTest.java | 93 ++++++++++++++++++- .../api/SearchLectureControllerTest.java | 2 +- .../api/ParsingTextControllerTest.java | 3 +- .../service/ParsingTextServiceTest.java | 3 +- ...akenLectureFromParsingTextServiceTest.java | 3 +- .../findauthid/FindAuthIdControllerTest.java | 6 +- .../ResetPasswordControllerTest.java | 7 +- .../user/api/signup/SignUpControllerTest.java | 11 +-- .../service/find/FindUserServiceTest.java | 8 +- .../ResetPasswordServiceTest.java | 3 +- .../service/signup/SignUpServiceTest.java | 21 +++-- .../withdraw/WithDrawUserServiceTest.java | 3 +- .../domain/model/StudentCategoryTest.java | 32 +++++++ .../user/domain/model/UserTest.java | 10 +- 41 files changed, 335 insertions(+), 126 deletions(-) create mode 100644 src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ErrorCode.java create mode 100644 src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategoryTest.java diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/dto/request/SignInRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/dto/request/SignInRequest.java index 5f597428..73ac31b8 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/dto/request/SignInRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/dto/request/SignInRequest.java @@ -11,7 +11,7 @@ @NoArgsConstructor public class SignInRequest { - @NotBlank(message = "아아디를 입력해주세요.") + @NotBlank(message = "아이디를 입력해주세요.") @Schema(name = "authId", example = "plzgraduate") private String authId; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAccessDeniedHandler.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAccessDeniedHandler.java index 58e66399..d34a1190 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAccessDeniedHandler.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAccessDeniedHandler.java @@ -1,5 +1,7 @@ package com.plzgraduate.myongjigraduatebe.auth.security; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; + import java.io.IOException; import javax.servlet.ServletException; @@ -12,6 +14,7 @@ import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.exception.ExceptionResponse; import lombok.RequiredArgsConstructor; @@ -20,13 +23,13 @@ @RequiredArgsConstructor public class JwtAccessDeniedHandler implements AccessDeniedHandler { - private static final ExceptionResponse E403 = ExceptionResponse.of(HttpStatus.FORBIDDEN, "Authentication error (cause: forbidden)"); + private static final ExceptionResponse E403 = ExceptionResponse.from(AUTHENTICATION_FAIL_FORBIDDEN.toString()); private final ObjectMapper om; @Override public void handle(HttpServletRequest request, HttpServletResponse response, - AccessDeniedException accessDeniedException) throws IOException, ServletException { + AccessDeniedException accessDeniedException) throws IOException { response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setHeader("content-type", "application/json"); response.getWriter().write(om.writeValueAsString(E403)); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationEntryPoint.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationEntryPoint.java index 1eb3ffde..b42ed4a6 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationEntryPoint.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationEntryPoint.java @@ -1,5 +1,7 @@ package com.plzgraduate.myongjigraduatebe.auth.security; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; + import java.io.IOException; import javax.servlet.ServletException; @@ -12,20 +14,21 @@ import org.springframework.stereotype.Component; import com.fasterxml.jackson.databind.ObjectMapper; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.exception.ExceptionResponse; import lombok.RequiredArgsConstructor; @Component @RequiredArgsConstructor -public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint{ - private static final ExceptionResponse E401 = ExceptionResponse.of(HttpStatus.UNAUTHORIZED, "Authentication error (cause: unauthorized)"); +public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint { + private static final ExceptionResponse E401 = ExceptionResponse.from(AUTHENTICATION_FAIL_UNAUTHORIZED.toString()); private final ObjectMapper om; @Override public void commence(HttpServletRequest request, HttpServletResponse response, - AuthenticationException authException) throws IOException, ServletException { + AuthenticationException authException) throws IOException { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setHeader("content-type", "application/json"); response.getWriter().write(om.writeValueAsString(E401)); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationProvider.java b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationProvider.java index b0a713e0..6fba9d33 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationProvider.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/auth/security/JwtAuthenticationProvider.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.auth.security; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; import static org.hibernate.validator.internal.util.TypeHelper.isAssignable; import java.util.Collections; @@ -10,6 +11,7 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.crypto.password.PasswordEncoder; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.exception.UnAuthorizedException; import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserUseCase; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; @@ -35,14 +37,14 @@ public Authentication authenticate(Authentication authentication) throws Authent } private Authentication processAuthentication(JwtAuthenticationToken authenticationToken) { + User user = findUserUseCase.findUserByAuthId(String.valueOf(authenticationToken.getPrincipal())); try { - User user = findUserUseCase.findUserByAuthId(String.valueOf(authenticationToken.getPrincipal())); user.matchPassword(passwordEncoder, String.valueOf(authenticationToken.getCredentials())); return new JwtAuthenticationToken( user.getId(), null, Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")) ); } catch (IllegalArgumentException e) { - throw new UnAuthorizedException("아이디 혹은 비밀번호가 일치하지 않습니다."); + throw new UnAuthorizedException(INCORRECT_PASSWORD.toString()); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ErrorCode.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ErrorCode.java new file mode 100644 index 00000000..22b65096 --- /dev/null +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ErrorCode.java @@ -0,0 +1,25 @@ +package com.plzgraduate.myongjigraduatebe.core.exception; + +public enum ErrorCode { + + INTERNAL_SEVER_ERROR, + INVALIDATED_GRADUATION_CATEGORY, + UNFITTED_GRADUATION_CATEGORY, + UNREGISTERED_USER, + INVALIDATED_STUDENT_NUMBER_TYPE, + INVALIDATED_PASSWORD_TYPE, + MISMATCHED_PASSWORD, + NOT_FOUND_AUTHID, + INVALIDATED_AUTHID_TYPE, + INCORRECT_PASSWORD, + DUPLICATED_STUDENT_NUMBER, + DUPLICATED_AUTHID, + NOT_FOUND_STUDENT_NUMBER, + INVALIDATED_AUTH_TOKEN, + INCORRECT_STUDENT_NUMBER, + NON_EXISTED_LECTURE, + UNSUPPORTED_STUDENT_CATEGORY, + UNSUPPORTED_STUDENT_NUMBER, + AUTHENTICATION_FAIL_FORBIDDEN, + AUTHENTICATION_FAIL_UNAUTHORIZED +} diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ExceptionResponse.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ExceptionResponse.java index beaa5c6d..1e9d09b1 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ExceptionResponse.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/ExceptionResponse.java @@ -1,27 +1,17 @@ package com.plzgraduate.myongjigraduatebe.core.exception; -import org.springframework.http.HttpStatus; - import lombok.Getter; @Getter public class ExceptionResponse { - private final int status; - private final String message; + private final String errorCode; - private ExceptionResponse( - int status, - String message - ) { - this.status = status; - this.message = message; + private ExceptionResponse(String errorCode) { + this.errorCode = errorCode; } - public static ExceptionResponse of( - HttpStatus httpStatus, - String message - ) { - return new ExceptionResponse(httpStatus.value(), message); + public static ExceptionResponse from(String errorCode) { + return new ExceptionResponse(errorCode); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/GlobalExceptionHandler.java b/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/GlobalExceptionHandler.java index 270a8eaf..c178fef9 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/GlobalExceptionHandler.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/core/exception/GlobalExceptionHandler.java @@ -31,62 +31,56 @@ public class GlobalExceptionHandler { @ResponseStatus(HttpStatus.BAD_REQUEST) public ExceptionResponse handleBadRequestException(Exception e) { log.debug("Bad request exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.BAD_REQUEST, getMessage(e)); + return ExceptionResponse.from(e.getMessage()); } @ExceptionHandler(NoSuchElementException.class) @ResponseStatus(HttpStatus.NOT_FOUND) public ExceptionResponse handleNotFoundException(Exception e) { log.debug("Not Found exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.NOT_FOUND, getMessage(e)); + return ExceptionResponse.from(e.getMessage()); } @ExceptionHandler(UnAuthorizedException.class) @ResponseStatus(HttpStatus.UNAUTHORIZED) public ExceptionResponse handleUnAuthorizedException(Exception e) { log.debug("unauthorized exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.UNAUTHORIZED, getMessage(e)); + return ExceptionResponse.from(e.getMessage()); } @ExceptionHandler(ConstraintViolationException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ExceptionResponse handleValidationException(ConstraintViolationException e) { log.info("validated exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.BAD_REQUEST, getViolationErrorMessage(e)); + return ExceptionResponse.from(getViolationErrorMessage(e)); } - - @ExceptionHandler(MethodArgumentNotValidException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ExceptionResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { log.debug("validation exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.BAD_REQUEST, getBindingErrorMessage(e)); + return ExceptionResponse.from(getBindingErrorMessage(e)); } @ExceptionHandler(MethodArgumentTypeMismatchException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ExceptionResponse handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { - log.debug("graduation category mismatch exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.BAD_REQUEST, getMethodArgumentTypeMismatchErrorMessage(e)); + log.debug("graduation category mismatch exception occurred: {}", getMethodArgumentTypeMismatchErrorMessage(e)); + return ExceptionResponse.from(ErrorCode.INVALIDATED_GRADUATION_CATEGORY.toString()); } @ExceptionHandler({PdfParsingException.class, InvalidPdfException.class}) @ResponseStatus(HttpStatus.BAD_REQUEST) public ExceptionResponse handlePdfException(Exception e) { log.warn("pdf exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.BAD_REQUEST, getMessage(e)); + return ExceptionResponse.from(e.getMessage()); } @ExceptionHandler({RuntimeException.class, Exception.class}) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ExceptionResponse handleRuntimeException(RuntimeException e) { log.error("Unexpected exception occurred: {}", e.getMessage(), e); - return ExceptionResponse.of(HttpStatus.INTERNAL_SERVER_ERROR, getMessage(e)); - } - - private String getMessage(Exception e) { - return Optional.ofNullable(e.getCause()).map(Throwable::getMessage).orElse(e.getMessage()); + return ExceptionResponse.from(ErrorCode.INTERNAL_SEVER_ERROR.toString()); } private String getViolationErrorMessage(ConstraintViolationException e) { diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationService.java index ea4fb083..cc976fb9 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationService.java @@ -31,6 +31,7 @@ public class CalculateSingleDetailGraduationService implements CalculateSingleDe @Override public DetailGraduationResult calculateSingleDetailGraduation(Long userId, GraduationCategory graduationCategory) { User user = findUserUseCase.findUserById(userId); + user.getStudentCategory().validateGraduationCategoryInclusion(graduationCategory); TakenLectureInventory takenLectures = findTakenLectureUseCase.findTakenLectures(userId); CalculateDetailGraduationUseCase calculateDetailGraduationUseCase = determineCalculateDetailGraduationUseCase( graduationCategory); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java index 0c5e26bc..6b1fa30b 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextService.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.parsing.application.service; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; import static com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory.ASSOCIATED_MAJOR; import static com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory.DOUBLE_SUB; @@ -9,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional; import com.plzgraduate.myongjigraduatebe.completedcredit.application.usecase.GenerateOrModifyCompletedCreditUseCase; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.exception.InvalidPdfException; import com.plzgraduate.myongjigraduatebe.core.exception.PdfParsingException; import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; @@ -81,7 +83,7 @@ private void validateParsingText(String parsingText) { private void validateStudentNumber(User user, ParsingInformation parsingInformation) { if (!user.compareStudentNumber(parsingInformation.getStudentNumber())) { - throw new InvalidPdfException("본인의 학번과 PDF 학번이 일치하지 않습니다."); + throw new InvalidPdfException(INCORRECT_STUDENT_NUMBER.toString()); } } @@ -100,7 +102,7 @@ private List getSaveTakenLectureCommand( private void checkUnSupportedUser(ParsingInformation parsingInformation) { if (parsingInformation.getStudentCategory() == ASSOCIATED_MAJOR || parsingInformation.getStudentCategory() == DOUBLE_SUB) { - throw new IllegalArgumentException("연계전공, 복수+부전공은 참여가 어렵습니다. 빠른 시일 내에 업데이트하도록 하겠습니다."); + throw new IllegalArgumentException(ErrorCode.UNSUPPORTED_STUDENT_CATEGORY.toString()); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextService.java index b4456c5e..e41532ed 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextService.java @@ -8,6 +8,7 @@ import org.springframework.transaction.annotation.Transactional; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; import com.plzgraduate.myongjigraduatebe.lecture.application.usecase.FindLecturesUseCase; import com.plzgraduate.myongjigraduatebe.lecture.domain.model.Lecture; @@ -18,10 +19,12 @@ import com.plzgraduate.myongjigraduatebe.user.domain.model.User; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; @UseCase @Transactional @RequiredArgsConstructor +@Slf4j class SaveTakenLectureFromParsingTextService implements SaveTakenLectureFromParsingTextUseCase { private final SaveTakenLecturePort saveTakenLecturePort; @@ -38,18 +41,20 @@ private List makeTakenLectures(User user, List lectureMap) { return takenLectureInformationList.stream() .map(takenLectureInformation -> { - Lecture lecture = getLectureFromLectureMap(lectureMap, takenLectureInformation); - return TakenLecture.of(user, lecture, takenLectureInformation.getYear(), - takenLectureInformation.getSemester()); - } - ).collect(Collectors.toList()); + Lecture lecture = getLectureFromLectureMap(lectureMap, takenLectureInformation); + return TakenLecture.of(user, lecture, takenLectureInformation.getYear(), + takenLectureInformation.getSemester()); + } + ).collect(Collectors.toList()); } private Lecture getLectureFromLectureMap(Map lectureMap, TakenLectureInformation takenLectureInformation) { return Optional.ofNullable(lectureMap.get(takenLectureInformation.getLectureCode())) - .orElseThrow( - () -> new IllegalArgumentException(takenLectureInformation.getLectureCode() + "이 데이터베이스에 존재하지 않습니다.")); + .orElseThrow(() -> { + log.warn("Not Found Lecture in Database: {}", takenLectureInformation.getLectureCode()); + return new IllegalArgumentException(ErrorCode.NON_EXISTED_LECTURE.toString()); + }); } private Map makeLectureMapByLectureCodes( diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdApiPresentation.java index fd8e89a0..35a43988 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdApiPresentation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdApiPresentation.java @@ -1,5 +1,8 @@ package com.plzgraduate.myongjigraduatebe.user.api.findauthid; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; + import org.springframework.web.bind.annotation.PathVariable; import com.plzgraduate.myongjigraduatebe.user.api.findauthid.dto.response.UserAuthIdResponse; @@ -12,5 +15,5 @@ public interface FindAuthIdApiPresentation { UserAuthIdResponse findUserAuthId( - @Parameter(name = "studentNumber", description = "학번", in = ParameterIn.PATH) @PathVariable String studentNumber); + @Parameter(name = "studentNumber", description = "학번", in = ParameterIn.PATH) @PathVariable @Pattern(regexp = "^60\\d{6}$", message = "INVALIDATED_STUDENT_NUMBER_TYPE") String studentNumber); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdController.java index 423d8253..bda63075 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdController.java @@ -1,24 +1,29 @@ package com.plzgraduate.myongjigraduatebe.user.api.findauthid; +import javax.validation.constraints.Pattern; + +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import com.plzgraduate.myongjigraduatebe.core.meta.WebAdapter; -import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserAuthIdUseCase; import com.plzgraduate.myongjigraduatebe.user.api.findauthid.dto.response.UserAuthIdResponse; +import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserAuthIdUseCase; import lombok.RequiredArgsConstructor; @WebAdapter @RequestMapping("/api/v1/users") @RequiredArgsConstructor +@Validated public class FindAuthIdController implements FindAuthIdApiPresentation { private final FindUserAuthIdUseCase findUserAuthIdUseCase; @GetMapping("/{studentNumber}/auth-id") - public UserAuthIdResponse findUserAuthId(@PathVariable String studentNumber) { + public UserAuthIdResponse findUserAuthId( + @PathVariable @Pattern(regexp = "^60\\d{6}$", message = "INVALIDATED_STUDENT_NUMBER_TYPE") String studentNumber) { String foundUserAuthId = findUserAuthIdUseCase.findUserAuthId(studentNumber); return UserAuthIdResponse.of(foundUserAuthId, studentNumber); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordApiPresentation.java index 888a50bf..9ae3b03c 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordApiPresentation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordApiPresentation.java @@ -1,6 +1,7 @@ package com.plzgraduate.myongjigraduatebe.user.api.resetpassword; import javax.validation.Valid; +import javax.validation.constraints.Pattern; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -22,7 +23,7 @@ public interface ResetPasswordApiPresentation { @Parameter(name = "auth-id", description = "아이디") ValidateUserResponse validateUser( @Parameter(name = "studentNumber", description = "학번", in = ParameterIn.PATH) - @PathVariable String studentNumber, + @PathVariable @Pattern(regexp = "^60\\d{6}$", message = "INVALIDATED_STUDENT_NUMBER_TYPE") String studentNumber, @RequestParam("auth-id") String authId); @PatchMapping("/password") diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordController.java index 83fd7f33..ebacbe8e 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordController.java @@ -1,7 +1,9 @@ package com.plzgraduate.myongjigraduatebe.user.api.resetpassword; import javax.validation.Valid; +import javax.validation.constraints.Pattern; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -11,8 +13,8 @@ import com.plzgraduate.myongjigraduatebe.core.meta.WebAdapter; import com.plzgraduate.myongjigraduatebe.user.api.resetpassword.dto.request.ResetPasswordRequest; -import com.plzgraduate.myongjigraduatebe.user.application.usecase.resetpassword.ResetPasswordUseCase; import com.plzgraduate.myongjigraduatebe.user.api.resetpassword.dto.response.ValidateUserResponse; +import com.plzgraduate.myongjigraduatebe.user.application.usecase.resetpassword.ResetPasswordUseCase; import com.plzgraduate.myongjigraduatebe.user.application.usecase.validate.ValidateUserUseCase; import lombok.RequiredArgsConstructor; @@ -20,6 +22,7 @@ @WebAdapter @RequestMapping("api/v1/users") @RequiredArgsConstructor +@Validated public class ResetPasswordController implements ResetPasswordApiPresentation { private final ValidateUserUseCase validateUserUseCase; @@ -27,7 +30,7 @@ public class ResetPasswordController implements ResetPasswordApiPresentation { @GetMapping("/{studentNumber}/validate") public ValidateUserResponse validateUser( - @PathVariable String studentNumber, + @PathVariable @Pattern(regexp = "^60\\d{6}$", message = "INVALIDATED_STUDENT_NUMBER_TYPE") String studentNumber, @RequestParam("auth-id") String authId) { boolean validated = validateUserUseCase.validateUser(studentNumber, authId); return ValidateUserResponse.builder().passedUserValidation(validated).build(); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/dto/request/ResetPasswordRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/dto/request/ResetPasswordRequest.java index 957eafb9..aac51d16 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/dto/request/ResetPasswordRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/dto/request/ResetPasswordRequest.java @@ -17,12 +17,12 @@ public class ResetPasswordRequest { private String authId; @NotBlank(message = "비밀번호를 입력해주세요.") - @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.") + @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "INVALIDATED_PASSWORD_TYPE") @Schema(name = "newPassword", example = "Plz1231343!?") private String newPassword; @NotBlank(message = "비밀번호 확인을 입력해주세요.") - @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.") + @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "INVALIDATED_PASSWORD_TYPE") @Schema(name = "passwordCheck", example = "Plz1231343!?") private String passwordCheck; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpApiPresentation.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpApiPresentation.java index ede116ee..e6b84116 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpApiPresentation.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpApiPresentation.java @@ -1,6 +1,8 @@ package com.plzgraduate.myongjigraduatebe.user.api.signup; import javax.validation.Valid; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -21,10 +23,11 @@ public interface SignUpApiPresentation { @Operation(description = "로그인 아이디 중복 여부를 체크한다.") @Parameter(name = "auth-id", description = "아이디") - AuthIdDuplicationResponse checkAuthIdDuplication(@RequestParam("auth-id") String authId); + AuthIdDuplicationResponse checkAuthIdDuplication( + @RequestParam("auth-id") @Size(min = 6, max = 20, message = "INVALIDATED_AUTHID_TYPE") String authId); @Operation(description = "학번 중복 여부를 체크한다.") @Parameter(name = "student-number", description = "학번") StudentNumberDuplicationResponse checkStudentNumberDuplication( - @RequestParam("student-number") String studentNumber); + @RequestParam("student-number") @Pattern(regexp = "^60\\d{6}$", message = "INVALIDATED_STUDENT_NUMBER_TYPE") String studentNumber); } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpController.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpController.java index 66c2b8cf..7280ffe8 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpController.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpController.java @@ -1,7 +1,10 @@ package com.plzgraduate.myongjigraduatebe.user.api.signup; import javax.validation.Valid; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -21,6 +24,7 @@ @WebAdapter @RequestMapping("/api/v1/users") @RequiredArgsConstructor +@Validated public class SignUpController implements SignUpApiPresentation { private final SignUpUseCase signUpUseCase; @@ -33,13 +37,14 @@ public void signUp(@Valid @RequestBody SignUpRequest signUpRequest) { } @GetMapping("/sign-up/check-duplicate-auth-id") - public AuthIdDuplicationResponse checkAuthIdDuplication(@RequestParam("auth-id") String authId) { + public AuthIdDuplicationResponse checkAuthIdDuplication( + @RequestParam("auth-id") @Size(min = 6, max = 20, message = "INVALIDATED_AUTHID_TYPE") String authId) { return checkAuthIdDuplicationUseCase.checkAuthIdDuplication(authId); } @GetMapping("/sign-up/check-duplicate-student-number") public StudentNumberDuplicationResponse checkStudentNumberDuplication( - @RequestParam("student-number") String studentNumber) { + @RequestParam("student-number") @Pattern(regexp = "^60\\d{6}$", message = "INVALIDATED_STUDENT_NUMBER_TYPE") String studentNumber) { return checkStudentNumberDuplicationUseCase.checkStudentNumberDuplication(studentNumber); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/dto/request/SignUpRequest.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/dto/request/SignUpRequest.java index e7943142..fad85c66 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/dto/request/SignUpRequest.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/api/signup/dto/request/SignUpRequest.java @@ -17,17 +17,17 @@ public class SignUpRequest { @NotBlank(message = "아이디를 입력해주세요.") - @Size(min = 6, max = 20, message = "아이디는 6자에서 20자 사이여야합니다.") + @Size(min = 6, max = 20, message = "INVALIDATED_AUTHID_TYPE") @Schema(name = "authId", example = "plzgraduate") private String authId; @NotBlank(message = "비밀번호를 입력해주세요.") - @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.") + @Pattern(regexp = "^(?=.*[!@#$%^&*])(?=.*[a-zA-Z0-9]).{8,20}$", message = "INVALIDATED_PASSWORD_TYPE") @Schema(name = "password", example = "Plz1231343!") private String password; @NotBlank(message = "비밀번호를 입력해주세요.") - @Pattern(regexp = "\\d{8}", message = "학번은 8자리 숫자여야 합니다.") + @Pattern(regexp = "\\d{8}", message = "INVALIDATED_STUDENT_NUMBER_TYPE") @Schema(name = "studentNumber", example = "60202000") private String studentNumber; diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserService.java index 1fed0c55..63736e5d 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserService.java @@ -1,7 +1,10 @@ package com.plzgraduate.myongjigraduatebe.user.application.service.find; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; + import org.springframework.transaction.annotation.Transactional; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserUseCase; import com.plzgraduate.myongjigraduatebe.user.application.port.FindUserPort; @@ -26,13 +29,13 @@ public User findUserById(Long id) { @Override public User findUserByAuthId(String authId) { return findUserPort.findUserByAuthId(authId) - .orElseThrow(() -> new IllegalArgumentException(NOT_FOUND_USER_ERROR_MESSAGE)); + .orElseThrow(() -> new IllegalArgumentException(NOT_FOUND_AUTHID.toString())); } @Override public User findUserByStudentNumber(String studentNumber) { return findUserPort.findUserByStudentNumber(studentNumber) - .orElseThrow(() -> new IllegalArgumentException(NOT_FOUND_USER_ERROR_MESSAGE)); + .orElseThrow(() -> new IllegalArgumentException(UNREGISTERED_USER.toString())); } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordService.java index 4c305487..7c3dbc71 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordService.java @@ -3,6 +3,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; import com.plzgraduate.myongjigraduatebe.user.application.port.UpdateUserPort; import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserUseCase; @@ -30,7 +31,7 @@ public void resetPassword(String authId, String newPassword, String passwordChec private void checkMatchPassword(String newPassword,String passwordCheck) { if (!newPassword.equals(passwordCheck)) { - throw new IllegalArgumentException("비밀번호와 비밀번호 확인이 일치하지 않습니다."); + throw new IllegalArgumentException(ErrorCode.MISMATCHED_PASSWORD.toString()); } } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpService.java index ee9b4427..f96e0f17 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpService.java @@ -1,8 +1,11 @@ package com.plzgraduate.myongjigraduatebe.user.application.service.signup; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; + import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.transaction.annotation.Transactional; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; import com.plzgraduate.myongjigraduatebe.user.application.usecase.signup.SignUpUseCase; import com.plzgraduate.myongjigraduatebe.user.application.usecase.signup.SignUpCommand; @@ -35,16 +38,16 @@ public void signUp(SignUpCommand signUpCommand) { private void checkStudentNumberOver16(User user) { if(user.checkBeforeEntryYear(CLASS_OF_2016)) { - throw new IllegalArgumentException("서비스 이용대상자는 16~23학번까지입니다."); + throw new IllegalArgumentException(UNSUPPORTED_STUDENT_NUMBER.toString()); } } private void checkDuplicateUser(SignUpCommand signUpCommand) { if(checkUserPort.checkDuplicateAuthId(signUpCommand.getAuthId())) { - throw new IllegalArgumentException("이미 존재하는 아이디입니다."); + throw new IllegalArgumentException(DUPLICATED_AUTHID.toString()); } if(checkUserPort.checkDuplicateStudentNumber(signUpCommand.getStudentNumber())) { - throw new IllegalArgumentException("이미 존재하는 학번입니다."); + throw new IllegalArgumentException(DUPLICATED_STUDENT_NUMBER.toString()); } } } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserService.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserService.java index 3b809c55..09430edb 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserService.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserService.java @@ -4,6 +4,7 @@ import org.springframework.transaction.annotation.Transactional; import com.plzgraduate.myongjigraduatebe.completedcredit.application.port.DeleteCompletedCreditPort; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.meta.UseCase; import com.plzgraduate.myongjigraduatebe.parsing.application.port.DeleteParsingTextHistoryPort; import com.plzgraduate.myongjigraduatebe.takenlecture.application.usecase.delete.DeleteTakenLectureUseCase; @@ -29,7 +30,9 @@ class WithDrawUserService implements WithDrawUserUseCase { @Override public void withDraw(Long userId, String password) { User user = findUserUseCase.findUserById(userId); - user.matchPassword(passwordEncoder, password); + if(!user.matchPassword(passwordEncoder, password)){ + throw new IllegalArgumentException(ErrorCode.INCORRECT_PASSWORD.toString()); + } deleteTakenLectureByUserUseCase.deleteAllTakenLecturesByUser(user); deleteParsingTextHistoryPort.deleteUserParsingTextHistory(user); deleteCompletedCreditPort.deleteAllCompletedCredits(user); diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java index 11c35874..7e6f048e 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategory.java @@ -1,10 +1,14 @@ package com.plzgraduate.myongjigraduatebe.user.domain.model; +import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.*; + import java.util.Arrays; import java.util.List; import java.util.Objects; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.core.exception.PdfParsingException; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -12,14 +16,30 @@ @Getter @RequiredArgsConstructor public enum StudentCategory { - NORMAL(List.of()), - CHANGE_MAJOR(List.of("전과")), - SUB_MAJOR(List.of("부전공")), - DUAL_MAJOR(List.of("복수전공")), - ASSOCIATED_MAJOR(List.of("연계전공")), - DOUBLE_SUB(List.of("복수전공", "부전공")); + NORMAL(List.of(), + List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)), + CHANGE_MAJOR(List.of("전과"), + List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)), + SUB_MAJOR(List.of("부전공"), + List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, + PRIMARY_ELECTIVE_MAJOR, GraduationCategory.SUB_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)), + DUAL_MAJOR(List.of("복수전공"), + List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, DUAL_BASIC_ACADEMICAL_CULTURE, + PRIMARY_MANDATORY_MAJOR, PRIMARY_ELECTIVE_MAJOR, DUAL_MANDATORY_MAJOR, DUAL_ELECTIVE_MAJOR, NORMAL_CULTURE, + FREE_ELECTIVE, CHAPEL)), + ASSOCIATED_MAJOR(List.of("연계전공"), + // 현재 미지원 + List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)), + DOUBLE_SUB(List.of("복수전공", "부전공"), + // 현재 미지원 + List.of(COMMON_CULTURE, CORE_CULTURE, PRIMARY_BASIC_ACADEMICAL_CULTURE, PRIMARY_MANDATORY_MAJOR, + PRIMARY_ELECTIVE_MAJOR, NORMAL_CULTURE, FREE_ELECTIVE, CHAPEL)); private final List categories; + private final List includedGraduationCategories; public static StudentCategory from(List categories) { return Arrays.stream(StudentCategory.values()) @@ -28,4 +48,10 @@ public static StudentCategory from(List categories) { .orElseThrow(() -> new PdfParsingException("PDF 정보 추출에 실패했습니다.")); } + public void validateGraduationCategoryInclusion(GraduationCategory graduationCategory) { + if (!includedGraduationCategories.contains(graduationCategory)) { + throw new IllegalArgumentException(ErrorCode.UNFITTED_GRADUATION_CATEGORY.toString()); + } + } + } diff --git a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java index c9ca5878..176aa136 100644 --- a/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java +++ b/src/main/java/com/plzgraduate/myongjigraduatebe/user/domain/model/User.java @@ -68,7 +68,7 @@ public static User create(String authId, String password, EnglishLevel englishLe .build(); } - public void updateStudentInformation(String name, String major, String dualMajor, String subMajor, + public void updateStudentInformation(String name, String major, String dualMajor, String subMajor, StudentCategory studentCategory, int totalCredit, double takenCredit, boolean graduate) { this.name = name; this.primaryMajor = major; @@ -92,10 +92,8 @@ public boolean compareStudentNumber(String studentNumber) { return this.studentNumber.equals(studentNumber); } - public void matchPassword(PasswordEncoder passwordEncoder, String password) { - if (!passwordEncoder.matches(password, this.password)) { - throw new IllegalArgumentException("비밀번호가 일치하지 않습니다."); - } + public boolean matchPassword(PasswordEncoder passwordEncoder, String password) { + return passwordEncoder.matches(password, this.password); } public String getEncryptedAuthId() { @@ -111,9 +109,9 @@ public boolean isMyAuthId(String authId) { } public String getMajorByMajorType(MajorType majorType) { - if(majorType == PRIMARY) { + if (majorType == PRIMARY) { return primaryMajor; - } else if(majorType == DUAL) { + } else if (majorType == DUAL) { return dualMajor; } return subMajor; diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/SignInControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/SignInControllerTest.java index a9a9e086..54648b12 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/SignInControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/signin/SignInControllerTest.java @@ -52,7 +52,7 @@ void blankAuthId() throws Exception { ) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message").value("아아디를 입력해주세요.")); + .andExpect(jsonPath("$.errorCode").value("아이디를 입력해주세요.")); } @DisplayName("비밀번호가 빈 문자열일 경우 에러를 반환한다.") @@ -71,7 +71,7 @@ void blankPassword() throws Exception { ) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message").value("비밀번호를 입력해주세요.")); + .andExpect(jsonPath("$.errorCode").value("비밀번호를 입력해주세요.")); } @DisplayName("아이디 및 비밀번호에 해당하는 사용자가 없을 경우 에러를 반환한다.") @@ -91,7 +91,6 @@ void invalidUser() throws Exception { ) .andDo(print()) .andExpect(status().isUnauthorized()) - .andExpect(jsonPath("$.status").value("401")) - .andExpect(jsonPath("$.message").value("아이디 혹은 비밀번호가 일치하지 않습니다.")); + .andExpect(jsonPath("$.errorCode").value("아이디 혹은 비밀번호가 일치하지 않습니다.")); } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/token/TokenControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/token/TokenControllerTest.java index 4ca57e14..f545e6a3 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/token/TokenControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/auth/api/token/TokenControllerTest.java @@ -65,6 +65,6 @@ void invalidRefreshToken() throws Exception { ) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", is("유효하지 않은 토큰입니다.")));; + .andExpect(jsonPath("$.errorCode", is("유효하지 않은 토큰입니다.")));; } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationsControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationsControllerTest.java index 48d59774..b3ca4d6e 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationsControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/api/FindDetailGraduationsControllerTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.graduation.api; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.INVALIDATED_GRADUATION_CATEGORY; import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.COMMON_CULTURE; import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.CORE_CULTURE; import static com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory.PRIMARY_BASIC_ACADEMICAL_CULTURE; @@ -202,8 +203,7 @@ void getDetailGraduationsWithInvalidGraduationCategory() throws Exception { .param("graduationCategory", invalidGraduationCategoryName)) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) - .andExpect(jsonPath("$.message").value("Failed to convert value: " + invalidGraduationCategoryName)); + .andExpect(jsonPath("$.errorCode").value(INVALIDATED_GRADUATION_CATEGORY.toString())); } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationServiceTest.java index b9086668..c961beff 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/graduation/application/service/CalculateSingleDetailGraduationServiceTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.graduation.application.service; +import static com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory.*; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; @@ -25,6 +26,7 @@ import com.plzgraduate.myongjigraduatebe.takenlecture.application.usecase.find.FindTakenLectureUseCase; import com.plzgraduate.myongjigraduatebe.takenlecture.domain.model.TakenLectureInventory; import com.plzgraduate.myongjigraduatebe.user.application.usecase.find.FindUserUseCase; +import com.plzgraduate.myongjigraduatebe.user.domain.model.StudentCategory; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; @ExtendWith(MockitoExtension.class) @@ -40,20 +42,103 @@ class CalculateSingleDetailGraduationServiceTest { @InjectMocks private CalculateSingleDetailGraduationService calculateSingleDetailGraduationService; - @DisplayName("단일 카테고리 졸업상세결과를 조회한다.") + @DisplayName("이수구분 NORMAL, CHANGE: 단일 카테고리 졸업상세결과를 조회한다.") + @ValueSource(strings = + {"COMMON_CULTURE", "CORE_CULTURE", "PRIMARY_MANDATORY_MAJOR", "PRIMARY_ELECTIVE_MAJOR", + "PRIMARY_BASIC_ACADEMICAL_CULTURE", "NORMAL_CULTURE", "FREE_ELECTIVE" + }) + @ParameterizedTest + void calculateSingleDetailGraduationForNormalAndChange(String graduationCategoryName) { + // given + User user = User.builder() + .id(1L) + .entryYear(19) + .studentCategory(NORMAL) + .primaryMajor("응용소프트웨어전공").build(); + GraduationCategory graduationCategory = GraduationCategory.valueOf(graduationCategoryName); + CalculateDetailGraduationUseCase calculateDetailGraduationUseCase = mock( + CalculateDetailGraduationUseCase.class); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(new HashSet<>()); + + given(findUserUseCase.findUserById(user.getId())).willReturn(user); + given(findTakenLectureUseCase.findTakenLectures(user.getId())).willReturn(takenLectureInventory); + given(calculateDetailGraduationUseCases.stream()).willReturn(Stream.of(calculateDetailGraduationUseCase)); + given(calculateDetailGraduationUseCase.supports(graduationCategory)).willReturn(true); + given(calculateDetailGraduationUseCase.calculateSingleDetailGraduation( + any(User.class), any(GraduationCategory.class), + any(TakenLectureInventory.class), any(GraduationRequirement.class))) + .willReturn(DetailGraduationResult.create(graduationCategory, 10, List.of())); + + // when + DetailGraduationResult result = + calculateSingleDetailGraduationService.calculateSingleDetailGraduation(1L, graduationCategory); + + // then + assertNotNull(result); + then(calculateDetailGraduationUseCase).should() + .calculateSingleDetailGraduation(any(User.class), any(GraduationCategory.class), + any(TakenLectureInventory.class), any(GraduationRequirement.class)); + + } + + @DisplayName("이수구분 DUAL: 단일 카테고리 졸업상세결과를 조회한다.") @ValueSource(strings = {"COMMON_CULTURE", "CORE_CULTURE", "PRIMARY_MANDATORY_MAJOR", "PRIMARY_ELECTIVE_MAJOR", "DUAL_MANDATORY_MAJOR", - "DUAL_ELECTIVE_MAJOR", "SUB_MAJOR", "PRIMARY_BASIC_ACADEMICAL_CULTURE", "DUAL_BASIC_ACADEMICAL_CULTURE" + "DUAL_ELECTIVE_MAJOR", "PRIMARY_BASIC_ACADEMICAL_CULTURE", "DUAL_BASIC_ACADEMICAL_CULTURE", + "NORMAL_CULTURE", "FREE_ELECTIVE" + }) + @ParameterizedTest + void calculateSingleDetailGraduationForDual(String graduationCategoryName) { + // given + User user = User.builder() + .id(1L) + .entryYear(19) + .studentCategory(DUAL_MAJOR) + .primaryMajor("응용소프트웨어전공") + .dualMajor("데이터테크놀로지전공") + .build(); + GraduationCategory graduationCategory = GraduationCategory.valueOf(graduationCategoryName); + CalculateDetailGraduationUseCase calculateDetailGraduationUseCase = mock( + CalculateDetailGraduationUseCase.class); + TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(new HashSet<>()); + + given(findUserUseCase.findUserById(user.getId())).willReturn(user); + given(findTakenLectureUseCase.findTakenLectures(user.getId())).willReturn(takenLectureInventory); + given(calculateDetailGraduationUseCases.stream()).willReturn(Stream.of(calculateDetailGraduationUseCase)); + given(calculateDetailGraduationUseCase.supports(graduationCategory)).willReturn(true); + given(calculateDetailGraduationUseCase.calculateSingleDetailGraduation( + any(User.class), any(GraduationCategory.class), + any(TakenLectureInventory.class), any(GraduationRequirement.class))) + .willReturn(DetailGraduationResult.create(graduationCategory, 10, List.of())); + + // when + DetailGraduationResult result = + calculateSingleDetailGraduationService.calculateSingleDetailGraduation(1L, graduationCategory); + + // then + assertNotNull(result); + then(calculateDetailGraduationUseCase).should() + .calculateSingleDetailGraduation(any(User.class), any(GraduationCategory.class), + any(TakenLectureInventory.class), any(GraduationRequirement.class)); + + } + + @DisplayName("이수구분 SUB: 단일 카테고리 졸업상세결과를 조회한다.") + @ValueSource(strings = + {"COMMON_CULTURE", "CORE_CULTURE", "PRIMARY_MANDATORY_MAJOR", "PRIMARY_ELECTIVE_MAJOR", "SUB_MAJOR", + "PRIMARY_BASIC_ACADEMICAL_CULTURE", "NORMAL_CULTURE", "FREE_ELECTIVE" }) @ParameterizedTest - void calculateSingleDetailGraduation(String graduationCategoryName) { + void calculateSingleDetailGraduationForSub(String graduationCategoryName) { // given User user = User.builder() .id(1L) .entryYear(19) + .studentCategory(SUB_MAJOR) .primaryMajor("응용소프트웨어전공").build(); GraduationCategory graduationCategory = GraduationCategory.valueOf(graduationCategoryName); - CalculateDetailGraduationUseCase calculateDetailGraduationUseCase = mock(CalculateDetailGraduationUseCase.class); + CalculateDetailGraduationUseCase calculateDetailGraduationUseCase = mock( + CalculateDetailGraduationUseCase.class); TakenLectureInventory takenLectureInventory = TakenLectureInventory.from(new HashSet<>()); given(findUserUseCase.findUserById(user.getId())).willReturn(user); diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/lecture/api/SearchLectureControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/lecture/api/SearchLectureControllerTest.java index 279bb55a..933d39e8 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/lecture/api/SearchLectureControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/lecture/api/SearchLectureControllerTest.java @@ -54,7 +54,7 @@ void searchWithKeywordSizeUnder2() throws Exception { .param("keyword", "")) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message").value("검색어를 2자리 이상 입력해주세요.")); + .andExpect(jsonPath("$.errorCode").value("검색어를 2자리 이상 입력해주세요.")); } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextControllerTest.java index 285fd0f6..f316d154 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/api/ParsingTextControllerTest.java @@ -73,8 +73,7 @@ void failToEnrollParsingText() throws Exception { actions .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.status").value(400)) - .andExpect(jsonPath("$.message").value("")); + .andExpect(jsonPath("$.errorCode").value("")); then(parsingTextHistoryUseCase).should().generateFailedParsingTextHistory(any(Long.class), any(String.class)); } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextServiceTest.java index 176edc93..05ac256b 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/parsing/application/service/ParsingTextServiceTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.parsing.application.service; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.INCORRECT_STUDENT_NUMBER; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.BDDMockito.any; import static org.mockito.BDDMockito.anyLong; @@ -102,7 +103,7 @@ class ParsingTextServiceTest{ assertThatThrownBy(() -> parsingTextService.enrollParsingText(1L, parsingText)) .isInstanceOf(InvalidPdfException.class) - .hasMessage("본인의 학번과 PDF 학번이 일치하지 않습니다."); + .hasMessage(INCORRECT_STUDENT_NUMBER.toString()); } @DisplayName("RuntimeException이 발생했을 경우 PdfParsingException을 반환한다.") diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextServiceTest.java index 9c2b8327..a934d1e0 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/takenlecture/application/service/save/SaveTakenLectureFromParsingTextServiceTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.takenlecture.application.service.save; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.NON_EXISTED_LECTURE; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.tuple; @@ -82,7 +83,7 @@ void lectureDoesNotExist() { assertThatThrownBy( () -> saveTakenLectureFromParsingTextService.saveTakenLectures(user, takenLectureInformationList)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("KMA02135이 데이터베이스에 존재하지 않습니다."); + .hasMessage(NON_EXISTED_LECTURE.toString()); } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdControllerTest.java index 0b9dfd74..8dec43c6 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/findauthid/FindAuthIdControllerTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.api.findauthid; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.UNREGISTERED_USER; import static org.hamcrest.Matchers.is; import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; @@ -37,14 +38,13 @@ void findUserAuthIdWithoutUser() throws Exception { //given String studentNumber = "60191111"; given(findUserAuthIdUseCase.findUserAuthId(any())).willThrow( - new IllegalArgumentException("해당 사용자를 찾을 수 없습니다.")); + new IllegalArgumentException(UNREGISTERED_USER.toString())); //when //then mockMvc.perform(get("/api/v1/users/{student-number}/auth-id", studentNumber)) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.status", is(400))) - .andExpect(jsonPath("$.message", is("해당 사용자를 찾을 수 없습니다."))); + .andExpect(jsonPath("$.errorCode", is(UNREGISTERED_USER.toString()))); } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordControllerTest.java index 981e6554..890555ab 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/resetpassword/ResetPasswordControllerTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.api.resetpassword; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.INVALIDATED_PASSWORD_TYPE; import static org.hamcrest.Matchers.is; import static org.mockito.BDDMockito.given; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; @@ -76,7 +77,7 @@ void resetPasswordWithNonAuthId() throws Exception { actions. andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", is("아이디를 입력해주세요."))); + .andExpect(jsonPath("$.errorCode", is("아이디를 입력해주세요."))); } @DisplayName("새로운 비밀번호가 비밀번호 형식에 맞지 않을 시 예외가 발생한다.") @@ -99,7 +100,7 @@ void resetPasswordWithUnSuitableNewPassword() throws Exception { actions. andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", is("비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다."))); + .andExpect(jsonPath("$.errorCode", is(INVALIDATED_PASSWORD_TYPE.toString()))); } @DisplayName("비밀번호 확인 비밀번호가 비밀번호 형식에 맞지 않을 시 예외가 발생한다.") @@ -122,7 +123,7 @@ void resetPasswordWithUnSuitableCheckPassword() throws Exception { actions. andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.message", is("비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다."))); + .andExpect(jsonPath("$.errorCode", is(INVALIDATED_PASSWORD_TYPE.toString()))); } } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpControllerTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpControllerTest.java index 631d5712..72110a8f 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpControllerTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/api/signup/SignUpControllerTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.api.signup; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.*; import static org.mockito.BDDMockito.given; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -13,6 +14,7 @@ import org.springframework.http.MediaType; import org.springframework.test.web.servlet.ResultActions; +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; import com.plzgraduate.myongjigraduatebe.support.WebAdaptorTestSupport; import com.plzgraduate.myongjigraduatebe.user.api.signup.dto.request.SignUpRequest; import com.plzgraduate.myongjigraduatebe.user.api.signup.dto.response.AuthIdDuplicationResponse; @@ -62,8 +64,7 @@ void signUp() throws Exception { ) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.status").value(400)) - .andExpect(jsonPath("$.message").value("아이디는 6자에서 20자 사이여야합니다.")); + .andExpect(jsonPath("$.errorCode").value(INVALIDATED_AUTHID_TYPE.toString())); } @DisplayName("비밀번호는 8자리 이상 20자리 미민이어야한다.") @@ -85,8 +86,7 @@ void signUp() throws Exception { ) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.status").value(400)) - .andExpect(jsonPath("$.message").value("비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.")); + .andExpect(jsonPath("$.errorCode").value(INVALIDATED_PASSWORD_TYPE.toString())); } @DisplayName("비밀번호는 하나 이상의 기호가 포함되어야한다.") @@ -107,8 +107,7 @@ void signUp() throws Exception { ) .andDo(print()) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.status").value(400)) - .andExpect(jsonPath("$.message").value("비밀번호는 특수문자를 포함한 8자에서 20자 사이여야합니다.")); + .andExpect(jsonPath("$.errorCode").value(INVALIDATED_PASSWORD_TYPE.toString())); } @DisplayName("로그인 아이디 중복 여부를 체크한다.") diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserServiceTest.java index c760bb82..eeb7082d 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/find/FindUserServiceTest.java @@ -1,7 +1,9 @@ package com.plzgraduate.myongjigraduatebe.user.application.service.find; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.BDDMockito.*; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.NOT_FOUND_AUTHID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.given; import java.util.Optional; @@ -87,7 +89,7 @@ void findUserByNotExistAuthId() { //when //test assertThatThrownBy(() -> findUserService.findUserByAuthId("tester00")) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("해당 사용자를 찾을 수 없습니다."); + .hasMessage(NOT_FOUND_AUTHID.toString()); } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordServiceTest.java index 40875d2a..5c3fd1a8 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/resetpassword/ResetPasswordServiceTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.application.service.resetpassword; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.MISMATCHED_PASSWORD; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.BDDMockito.given; import static org.mockito.BDDMockito.then; @@ -58,7 +59,7 @@ void resetPasswordWithDifferentPasswordCheck() { //when //then assertThatThrownBy(() -> resetPasswordService.resetPassword(authId, newPassword, passwordCheck)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("비밀번호와 비밀번호 확인이 일치하지 않습니다."); + .hasMessage(MISMATCHED_PASSWORD.toString()); } @DisplayName("해당 유저 아이디가 존재하지 않을 경우 예외가 발생한다.") diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpServiceTest.java index d4baa620..b6ac15b8 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/signup/SignUpServiceTest.java @@ -1,7 +1,14 @@ package com.plzgraduate.myongjigraduatebe.user.application.service.signup; -import static org.assertj.core.api.Assertions.*; -import static org.mockito.BDDMockito.*; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.DUPLICATED_AUTHID; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.DUPLICATED_STUDENT_NUMBER; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.BDDMockito.any; +import static org.mockito.BDDMockito.anyString; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.never; +import static org.mockito.BDDMockito.then; +import static org.mockito.BDDMockito.times; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -11,9 +18,9 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.security.crypto.password.PasswordEncoder; -import com.plzgraduate.myongjigraduatebe.user.application.usecase.signup.SignUpCommand; import com.plzgraduate.myongjigraduatebe.user.application.port.CheckUserPort; import com.plzgraduate.myongjigraduatebe.user.application.port.SaveUserPort; +import com.plzgraduate.myongjigraduatebe.user.application.usecase.signup.SignUpCommand; import com.plzgraduate.myongjigraduatebe.user.domain.model.EnglishLevel; import com.plzgraduate.myongjigraduatebe.user.domain.model.User; @@ -31,7 +38,7 @@ class SignUpServiceTest { @DisplayName("회원가입을 진행한다") @Test void signUp() { - //given + //given SignUpCommand command = SignUpCommand.builder() .authId("mju-graduate") .password("1q2w3e4r!") @@ -43,7 +50,7 @@ void signUp() { //when signUpService.signUp(command); - //then + //then then(passwordEncoder).should().encode("1q2w3e4r!"); then(saveUserPort).should().saveUser(any(User.class)); } @@ -64,7 +71,7 @@ void signUp() { //when //then assertThatThrownBy(() -> signUpService.signUp(command)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("이미 존재하는 아이디입니다."); + .hasMessage(DUPLICATED_AUTHID.toString()); then(checkUserPort).should(times(1)).checkDuplicateAuthId(authId); then(checkUserPort).should(never()).checkDuplicateStudentNumber(anyString()); @@ -88,7 +95,7 @@ void signUp() { //when //then assertThatThrownBy(() -> signUpService.signUp(command)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("이미 존재하는 학번입니다."); + .hasMessage(DUPLICATED_STUDENT_NUMBER.toString()); then(checkUserPort).should(times(1)).checkDuplicateAuthId(anyString()); then(checkUserPort).should(times(1)).checkDuplicateStudentNumber(studentNumber); diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserServiceTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserServiceTest.java index 0154bd10..0cc8d492 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserServiceTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/application/service/withdraw/WithDrawUserServiceTest.java @@ -1,5 +1,6 @@ package com.plzgraduate.myongjigraduatebe.user.application.service.withdraw; +import static com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode.INCORRECT_PASSWORD; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; @@ -75,7 +76,7 @@ void withDrawWithUnValidationPassword() { //when //then assertThatThrownBy(() -> withDrawUserService.withDraw(user.getId(), password)) .isInstanceOf(IllegalArgumentException.class) - .hasMessage("비밀번호가 일치하지 않습니다."); + .hasMessage(INCORRECT_PASSWORD.toString()); } diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategoryTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategoryTest.java new file mode 100644 index 00000000..ee39298e --- /dev/null +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/StudentCategoryTest.java @@ -0,0 +1,32 @@ +package com.plzgraduate.myongjigraduatebe.user.domain.model; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import com.plzgraduate.myongjigraduatebe.core.exception.ErrorCode; +import com.plzgraduate.myongjigraduatebe.graduation.domain.model.GraduationCategory; + +class StudentCategoryTest { + + @DisplayName("학생 이수구분 카테고리에 포함되는 졸업 카테고리인지 검증한다.") + @ParameterizedTest + @ValueSource(strings = {"DUAL_MANDATORY_MAJOR", "DUAL_ELECTIVE_MAJOR", "SUB_MAJOR", + "DUAL_BASIC_ACADEMICAL_CULTURE"}) + void validateGraduationCategoryInclusion(String graduationCategoryName) { + //given + User user = User.builder() + .studentCategory(StudentCategory.NORMAL).build(); + GraduationCategory graduationCategory = GraduationCategory.valueOf(graduationCategoryName); + + //when //then + assertThatThrownBy( + () -> user.getStudentCategory().validateGraduationCategoryInclusion(graduationCategory)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage(ErrorCode.UNFITTED_GRADUATION_CATEGORY.toString()); + + } + +} diff --git a/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/UserTest.java b/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/UserTest.java index 902fb143..163caafd 100644 --- a/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/UserTest.java +++ b/src/test/java/com/plzgraduate/myongjigraduatebe/user/domain/model/UserTest.java @@ -96,10 +96,12 @@ void matchPassword() { void matchWrongPassword() { //given given(passwordEncoder.matches("wrongPassword", "tester00!")).willReturn(false); - //when //then - assertThatThrownBy(() -> user.matchPassword(passwordEncoder, "wrongPassword")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage("비밀번호가 일치하지 않습니다."); + + //when + boolean result = user.matchPassword(passwordEncoder, "wrongPassword"); + + // then + assertThat(result).isFalse(); } @DisplayName("유저의 암호화된 로그인 아이디(뒷 세자리 *** 대체)를 반환한다.")