Compare commits
2 Commits
feature/lo
...
feature/ex
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ead7a450db | ||
|
|
d7c17cdfa6 |
@@ -1,9 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception;
|
|
||||||
|
|
||||||
public class AlreadyDeletedException extends RuntimeException {
|
|
||||||
|
|
||||||
public AlreadyDeletedException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception;
|
|
||||||
|
|
||||||
public class EmailNotFoundException extends IllegalArgumentException {
|
|
||||||
|
|
||||||
private static final String MESSAGE = "존재하지 않는 이메일 입니다.";
|
|
||||||
|
|
||||||
public EmailNotFoundException() {
|
|
||||||
super(MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.ticketing.server.global.exception;
|
||||||
|
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
import static org.springframework.http.HttpStatus.CONFLICT;
|
||||||
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ErrorCode {
|
||||||
|
|
||||||
|
/* 400 BAD_REQUEST : 잘못된 요청 */
|
||||||
|
MISMATCH_PASSWORD(BAD_REQUEST, "비밀번호가 일치하지 않습니다."),
|
||||||
|
TOKEN_TYPE(BAD_REQUEST, "토큰 타입이 올바르지 않습니다."),
|
||||||
|
UNAVAILABLE_REFRESH_TOKEN(BAD_REQUEST, "사용할 수 없는 토큰 입니다."),
|
||||||
|
|
||||||
|
/* 404 NOT_FOUND : Resource 를 찾을 수 없음 */
|
||||||
|
EMAIL_NOT_FOUND(NOT_FOUND, "해당 이메일을 찾을 수 없습니다."),
|
||||||
|
REFRESH_TOKEN_NOT_FOUND(NOT_FOUND, "리프레쉬 토큰을 찾을 수 없습니다."),
|
||||||
|
|
||||||
|
/* 409 CONFLICT : Resource 의 현재 상태와 충돌. 보통 중복된 데이터 존재 */
|
||||||
|
DUPLICATE_EMAIL(CONFLICT, "이메일이 이미 존재합니다."),
|
||||||
|
DELETED_EMAIL(CONFLICT, "이미 삭제된 이메일 입니다.");
|
||||||
|
|
||||||
|
private final HttpStatus httpStatus;
|
||||||
|
private final String detail;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.ticketing.server.global.exception;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@EqualsAndHashCode
|
||||||
|
public class ErrorResponse {
|
||||||
|
|
||||||
|
private final HttpStatus status;
|
||||||
|
private final String message;
|
||||||
|
private final List<String> errors;
|
||||||
|
|
||||||
|
public ErrorResponse(HttpStatus status, String message, List<String> errors) {
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
this.errors = errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ErrorResponse(HttpStatus status, String message, String error) {
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
this.errors = List.of(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ErrorResponse toErrorResponse(ErrorCode errorCode) {
|
||||||
|
return new ErrorResponse(
|
||||||
|
errorCode.getHttpStatus(),
|
||||||
|
errorCode.name(),
|
||||||
|
errorCode.getDetail());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,246 @@
|
|||||||
|
package com.ticketing.server.global.exception;
|
||||||
|
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
|
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;
|
||||||
|
import static org.springframework.http.HttpStatus.METHOD_NOT_ALLOWED;
|
||||||
|
import static org.springframework.http.HttpStatus.NOT_FOUND;
|
||||||
|
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
|
||||||
|
import static org.springframework.http.HttpStatus.UNSUPPORTED_MEDIA_TYPE;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.validation.ConstraintViolation;
|
||||||
|
import javax.validation.ConstraintViolationException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.TypeMismatchException;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.validation.FieldError;
|
||||||
|
import org.springframework.validation.ObjectError;
|
||||||
|
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||||
|
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
import org.springframework.web.context.request.WebRequest;
|
||||||
|
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
|
||||||
|
import org.springframework.web.multipart.support.MissingServletRequestPartException;
|
||||||
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
|
||||||
|
|
||||||
|
/* 400 START */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Valid 유효성 검사 실패
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleMethodArgumentNotValid(
|
||||||
|
MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("MethodArgumentNotValidException :: ", ex);
|
||||||
|
|
||||||
|
List<String> errors = generateErrors(ex);
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), errors);
|
||||||
|
return handleExceptionInternal(ex, response, headers, response.getStatus(), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* ModelAttribute 으로 binding error 발생
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleBindException(
|
||||||
|
BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("BindException :: ", ex);
|
||||||
|
|
||||||
|
List<String> errors = generateErrors(ex);
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), errors);
|
||||||
|
return handleExceptionInternal(ex, response, headers, response.getStatus(), request);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 잘못된 유형으로 Bean 속성 설정
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleTypeMismatch(
|
||||||
|
TypeMismatchException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("TypeMismatchException :: ", ex);
|
||||||
|
|
||||||
|
String error = ex.getValue() + " value for " + ex.getPropertyName() + " should be of type " + ex.getRequiredType();
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), error);
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(headers).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* multipart/form-data 요청 실패
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleMissingServletRequestPart(
|
||||||
|
MissingServletRequestPartException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("MissingServletRequestPartException :: ", ex);
|
||||||
|
|
||||||
|
String error = ex.getRequestPartName() + " part is missing";
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), error);
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(headers).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 필수 인수 누락
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleMissingServletRequestParameter(
|
||||||
|
MissingServletRequestParameterException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("MissingServletRequestParameterException :: ", ex);
|
||||||
|
|
||||||
|
String error = ex.getParameterName() + " parameter is missing";
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), error);
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(headers).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 인수가 예상한 형식이 아닐 시
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
|
||||||
|
protected ResponseEntity<Object> handleMethodArgumentTypeMismatch(MethodArgumentTypeMismatchException ex) {
|
||||||
|
log.error("MethodArgumentTypeMismatchException :: ", ex);
|
||||||
|
|
||||||
|
String error = ex.getName() + " should be of type " + Objects.requireNonNull(ex.getRequiredType()).getName();
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), error);
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 제약 조건 위반
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = ConstraintViolationException.class)
|
||||||
|
protected ResponseEntity<Object> handleConstraintViolation(ConstraintViolationException ex) {
|
||||||
|
log.error("ConstraintViolationException :: ", ex);
|
||||||
|
|
||||||
|
List<String> errors = new ArrayList<>();
|
||||||
|
for (ConstraintViolation<?> violation : ex.getConstraintViolations()) {
|
||||||
|
errors.add(violation.getRootBeanClass().getName() + " " + violation.getPropertyPath() + ": " + violation.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResponse response = new ErrorResponse(BAD_REQUEST, ex.getLocalizedMessage(), errors);
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 400 END */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 404 발생
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleNoHandlerFoundException(
|
||||||
|
NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("NoHandlerFoundException :: ", ex);
|
||||||
|
|
||||||
|
String error = "No handler found for " + ex.getHttpMethod() + " " + ex.getRequestURL();
|
||||||
|
ErrorResponse response = new ErrorResponse(NOT_FOUND, ex.getLocalizedMessage(), error);
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(headers).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 지원하지 않는 HTTP 메서드로 요청 405
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleHttpRequestMethodNotSupported(
|
||||||
|
HttpRequestMethodNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("HttpRequestMethodNotSupportedException :: ", ex);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(ex.getMethod());
|
||||||
|
builder.append(" method is not supported for this request. Supported methods are ");
|
||||||
|
|
||||||
|
Set<HttpMethod> supportedHttpMethods = ex.getSupportedHttpMethods();
|
||||||
|
if (supportedHttpMethods != null) {
|
||||||
|
supportedHttpMethods.forEach(t -> builder.append(t).append(" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorResponse response = new ErrorResponse(METHOD_NOT_ALLOWED, ex.getLocalizedMessage(), builder.toString());
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 지원되지 않는 미디어 유형으로 요청 415
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected ResponseEntity<Object> handleHttpMediaTypeNotSupported(
|
||||||
|
HttpMediaTypeNotSupportedException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
|
||||||
|
log.error("HttpMediaTypeNotSupportedException :: ", ex);
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
builder.append(ex.getContentType());
|
||||||
|
builder.append(" media type is not supported. Supported media types are ");
|
||||||
|
ex.getSupportedMediaTypes().forEach(t -> builder.append(t).append(" "));
|
||||||
|
|
||||||
|
ErrorResponse response = new ErrorResponse(UNSUPPORTED_MEDIA_TYPE, ex.getLocalizedMessage(), builder.substring(0, builder.length() - 2));
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 핸들러 없는 모든 예외 500
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = Exception.class)
|
||||||
|
protected ResponseEntity<Object> handleAll(Exception ex) {
|
||||||
|
log.error("Exception :: ", ex);
|
||||||
|
|
||||||
|
ErrorResponse response = new ErrorResponse(INTERNAL_SERVER_ERROR, ex.getLocalizedMessage(), "오류가 발생했습니다.");
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 접근 권한이 없을 때
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = AccessDeniedException.class)
|
||||||
|
protected ResponseEntity<ErrorResponse> handleAccessDeniedException(Exception ex) {
|
||||||
|
log.error("AccessDeniedException :: ", ex);
|
||||||
|
|
||||||
|
ErrorResponse response = new ErrorResponse(FORBIDDEN, ex.getLocalizedMessage(), "접근 권한이 없습니다.");
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 인증 정보가 없을 때
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = AuthenticationException.class)
|
||||||
|
protected ResponseEntity<ErrorResponse> handleAuthenticationException(Exception ex) {
|
||||||
|
log.error("AuthenticationException :: ", ex);
|
||||||
|
|
||||||
|
ErrorResponse response = new ErrorResponse(UNAUTHORIZED, ex.getLocalizedMessage(), "로그인 후 이용하실 수 있습니다.");
|
||||||
|
return ResponseEntity.status(response.getStatus()).headers(new HttpHeaders()).body(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 커스텀 예외 발생 시
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(value = TicketingException.class)
|
||||||
|
protected ResponseEntity<ErrorResponse> ticketingException(TicketingException ex) {
|
||||||
|
log.error("TicketingException :: ", ex);
|
||||||
|
|
||||||
|
ErrorCode errorCode = ex.getErrorCode();
|
||||||
|
return ResponseEntity.status(errorCode.getHttpStatus()).body(ErrorResponse.toErrorResponse(errorCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> generateErrors(BindException ex) {
|
||||||
|
List<String> errors = new ArrayList<>();
|
||||||
|
List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
|
||||||
|
|
||||||
|
for (ObjectError error : allErrors) {
|
||||||
|
errors.add(((FieldError) error).getField() + ": " + error.getDefaultMessage());
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception;
|
|
||||||
|
|
||||||
public class PasswordMismatchException extends RuntimeException {
|
|
||||||
|
|
||||||
private static final String MESSAGE = "패스워드가 일치하지 않습니다";
|
|
||||||
|
|
||||||
public PasswordMismatchException() {
|
|
||||||
super(MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ticketing.server.global.exception;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TicketingException extends RuntimeException {
|
||||||
|
|
||||||
|
private final ErrorCode errorCode;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception.token;
|
|
||||||
|
|
||||||
public class TokenException extends RuntimeException {
|
|
||||||
|
|
||||||
public TokenException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception.token;
|
|
||||||
|
|
||||||
public class TokenNotFindException extends TokenException {
|
|
||||||
|
|
||||||
private static final String MESSAGE = "일치하는 토큰을 찾지 못하였습니다.";
|
|
||||||
|
|
||||||
public TokenNotFindException() {
|
|
||||||
super(MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception.token;
|
|
||||||
|
|
||||||
public class TokenTypeException extends TokenException {
|
|
||||||
|
|
||||||
private static final String MESSAGE = "토큰 타입이 일치하지 않습니다.";
|
|
||||||
|
|
||||||
public TokenTypeException() {
|
|
||||||
super(MESSAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
package com.ticketing.server.global.exception.token;
|
|
||||||
|
|
||||||
public class UnavailableRefreshTokenException extends TokenException {
|
|
||||||
|
|
||||||
private static final String MESSAGE = "사용할 수 없는 refresh Token 입니다.";
|
|
||||||
|
|
||||||
public UnavailableRefreshTokenException() {
|
|
||||||
super(MESSAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,15 +3,24 @@ package com.ticketing.server.global.security.jwt.handle;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
|
||||||
@Component
|
@Component("JwtAccessDeniedHandler")
|
||||||
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
|
public class JwtAccessDeniedHandler implements AccessDeniedHandler {
|
||||||
|
|
||||||
|
private final HandlerExceptionResolver resolver;
|
||||||
|
|
||||||
|
public JwtAccessDeniedHandler(@Qualifier("handlerExceptionResolver") HandlerExceptionResolver resolver) {
|
||||||
|
this.resolver = resolver;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
|
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException {
|
||||||
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
response.sendError(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
resolver.resolveException(request, response, null, accessDeniedException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,15 +3,24 @@ package com.ticketing.server.global.security.jwt.handle;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
|
||||||
@Component
|
@Component("JwtAuthenticationEntryPoint")
|
||||||
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
|
private final HandlerExceptionResolver resolver;
|
||||||
|
|
||||||
|
public JwtAuthenticationEntryPoint(@Qualifier("handlerExceptionResolver") HandlerExceptionResolver resolver) {
|
||||||
|
this.resolver = resolver;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
|
resolver.resolveException(request, response, null, authException);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.ticketing.server.user.domain;
|
package com.ticketing.server.user.domain;
|
||||||
|
|
||||||
|
import static com.ticketing.server.global.exception.ErrorCode.DELETED_EMAIL;
|
||||||
|
import static com.ticketing.server.global.exception.ErrorCode.MISMATCH_PASSWORD;
|
||||||
|
|
||||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||||
import com.ticketing.server.global.exception.AlreadyDeletedException;
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
import com.ticketing.server.global.exception.PasswordMismatchException;
|
|
||||||
import com.ticketing.server.global.validator.constraints.Phone;
|
import com.ticketing.server.global.validator.constraints.Phone;
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||||
@@ -60,7 +62,7 @@ public class User extends AbstractEntity {
|
|||||||
|
|
||||||
public User delete(DeleteUserDTO deleteUser) {
|
public User delete(DeleteUserDTO deleteUser) {
|
||||||
if (isDeleted) {
|
if (isDeleted) {
|
||||||
throw new AlreadyDeletedException("이미 탈퇴된 회원 입니다.");
|
throw new TicketingException(DELETED_EMAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPassword(deleteUser);
|
checkPassword(deleteUser);
|
||||||
@@ -79,7 +81,7 @@ public class User extends AbstractEntity {
|
|||||||
|
|
||||||
public void checkPassword(PasswordMatches passwordMatches) {
|
public void checkPassword(PasswordMatches passwordMatches) {
|
||||||
if (!passwordMatches.passwordMatches(password)) {
|
if (!passwordMatches.passwordMatches(password)) {
|
||||||
throw new PasswordMismatchException();
|
throw new TicketingException(MISMATCH_PASSWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.token.TokenNotFindException;
|
import static com.ticketing.server.global.exception.ErrorCode.REFRESH_TOKEN_NOT_FOUND;
|
||||||
import com.ticketing.server.global.exception.token.TokenTypeException;
|
import static com.ticketing.server.global.exception.ErrorCode.TOKEN_TYPE;
|
||||||
import com.ticketing.server.global.exception.token.UnavailableRefreshTokenException;
|
import static com.ticketing.server.global.exception.ErrorCode.UNAVAILABLE_REFRESH_TOKEN;
|
||||||
|
|
||||||
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
import com.ticketing.server.global.redis.RefreshRedisRepository;
|
||||||
import com.ticketing.server.global.redis.RefreshToken;
|
import com.ticketing.server.global.redis.RefreshToken;
|
||||||
import com.ticketing.server.global.security.jwt.JwtProperties;
|
import com.ticketing.server.global.security.jwt.JwtProperties;
|
||||||
@@ -60,11 +62,11 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
|
|
||||||
// Redis 에 토큰이 있는지 검증
|
// Redis 에 토큰이 있는지 검증
|
||||||
RefreshToken findTokenEntity = refreshRedisRepository.findByEmail(authentication.getName())
|
RefreshToken findTokenEntity = refreshRedisRepository.findByEmail(authentication.getName())
|
||||||
.orElseThrow(TokenNotFindException::new);
|
.orElseThrow(() -> new TicketingException(REFRESH_TOKEN_NOT_FOUND));
|
||||||
|
|
||||||
// redis 토큰과 input 토큰이 일치한지 확인
|
// redis 토큰과 input 토큰이 일치한지 확인
|
||||||
if (!refreshToken.equals(findTokenEntity.getToken())) {
|
if (!refreshToken.equals(findTokenEntity.getToken())) {
|
||||||
throw new UnavailableRefreshTokenException();
|
throw new TicketingException(UNAVAILABLE_REFRESH_TOKEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 토큰 발급
|
// 토큰 발급
|
||||||
@@ -81,7 +83,7 @@ public class AuthenticationServiceImpl implements AuthenticationService {
|
|||||||
if (StringUtils.hasText(bearerToken) && jwtProperties.hasTokenStartsWith(bearerToken)) {
|
if (StringUtils.hasText(bearerToken) && jwtProperties.hasTokenStartsWith(bearerToken)) {
|
||||||
return bearerToken.substring(7);
|
return bearerToken.substring(7);
|
||||||
}
|
}
|
||||||
throw new TokenTypeException();
|
throw new TicketingException(TOKEN_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
|
import static com.ticketing.server.global.exception.ErrorCode.EMAIL_NOT_FOUND;
|
||||||
|
|
||||||
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -20,7 +23,7 @@ public class CustomUserDetailsService implements UserDetailsService {
|
|||||||
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
|
||||||
return userRepository.findByEmailAndIsDeletedFalse(email)
|
return userRepository.findByEmailAndIsDeletedFalse(email)
|
||||||
.map(this::createUserDetails)
|
.map(this::createUserDetails)
|
||||||
.orElseThrow(() -> new UsernameNotFoundException("존재하지 않는 email 입니다. :: " + email));
|
.orElseThrow(() -> new TicketingException(EMAIL_NOT_FOUND));
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserDetails createUserDetails(User user) {
|
private UserDetails createUserDetails(User user) {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package com.ticketing.server.user.service;
|
package com.ticketing.server.user.service;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.EmailNotFoundException;
|
import static com.ticketing.server.global.exception.ErrorCode.DUPLICATE_EMAIL;
|
||||||
|
import static com.ticketing.server.global.exception.ErrorCode.EMAIL_NOT_FOUND;
|
||||||
|
|
||||||
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
@@ -28,18 +31,17 @@ public class UserServiceImpl implements UserService {
|
|||||||
@Transactional
|
@Transactional
|
||||||
public User register(@Valid SignUpDTO signUpDto) {
|
public User register(@Valid SignUpDTO signUpDto) {
|
||||||
Optional<User> user = userRepository.findByEmail(signUpDto.getEmail());
|
Optional<User> user = userRepository.findByEmail(signUpDto.getEmail());
|
||||||
if (user.isPresent()) {
|
if (user.isEmpty()) {
|
||||||
log.error("이미 존재하는 이메일이기 때문에 신규 회원가입을 진행할 수 없습니다. :: {}", signUpDto);
|
return userRepository.save(signUpDto.toUser());
|
||||||
throw new IllegalArgumentException("이미 존재하는 이메일이기 때문에 신규 회원가입을 진행할 수 없습니다.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return userRepository.save(signUpDto.toUser());
|
throw new TicketingException(DUPLICATE_EMAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public User delete(@Valid DeleteUserDTO deleteUserDto) {
|
public User delete(@Valid DeleteUserDTO deleteUserDto) {
|
||||||
User user = findByEmail(deleteUserDto.getEmail());
|
User user = findNotDeletedUserByEmail(deleteUserDto.getEmail());
|
||||||
return user.delete(deleteUserDto);
|
return user.delete(deleteUserDto);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,19 +55,16 @@ public class UserServiceImpl implements UserService {
|
|||||||
@Override
|
@Override
|
||||||
public User findByEmail(String email) {
|
public User findByEmail(String email) {
|
||||||
return userRepository.findByEmail(email)
|
return userRepository.findByEmail(email)
|
||||||
.orElseThrow(() -> {
|
.orElseThrow(UserServiceImpl::throwEmailNotFound);
|
||||||
log.error("존재하지 않는 이메일 입니다. :: {}", email);
|
|
||||||
throw new EmailNotFoundException();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private User findNotDeletedUserByEmail(String email) {
|
private User findNotDeletedUserByEmail(String email) {
|
||||||
return userRepository.findByEmailAndIsDeletedFalse(email)
|
return userRepository.findByEmailAndIsDeletedFalse(email)
|
||||||
.orElseThrow(() -> {
|
.orElseThrow(UserServiceImpl::throwEmailNotFound);
|
||||||
log.error("존재하지 않는 이메일 입니다. :: {}", email);
|
}
|
||||||
throw new EmailNotFoundException();
|
|
||||||
});
|
private static RuntimeException throwEmailNotFound() {
|
||||||
|
throw new TicketingException(EMAIL_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ spring:
|
|||||||
mvc:
|
mvc:
|
||||||
pathmatch:
|
pathmatch:
|
||||||
matching-strategy: ant_path_matcher
|
matching-strategy: ant_path_matcher
|
||||||
|
throw-exception-if-no-handler-found: true
|
||||||
|
|
||||||
jasypt:
|
jasypt:
|
||||||
encryptor:
|
encryptor:
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
validation.not.empty.name="\uC774\uB984\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.name=\uC774\uB984\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.email="\uC774\uBA54\uC77C\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.email=\uC774\uBA54\uC77C\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.password="\uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.password=\uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.oldpassword="\uD604\uC7AC \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.oldpassword=\uD604\uC7AC \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.newpassword="\uBCC0\uACBD\uD560 \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.newpassword=\uBCC0\uACBD\uD560 \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.grade="\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.grade=\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.phone=\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.email=\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||||
validation.phone="\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.phone=\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||||
validation.password.not.change="\uB3D9\uC77C\uD55C \uD328\uC2A4\uC6CC\uB4DC\uB85C \uBCC0\uACBD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
validation.password.not.change=\uB3D9\uC77C\uD55C \uD328\uC2A4\uC6CC\uB4DC\uB85C \uBCC0\uACBD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
validation.not.empty.name="name is required."
|
validation.not.empty.name=name is required.
|
||||||
validation.not.empty.email="email is required."
|
validation.not.empty.email=email is required.
|
||||||
validation.not.empty.password="password is required."
|
validation.not.empty.password=password is required.
|
||||||
validation.not.empty.oldpassword="Old Password is required."
|
validation.not.empty.oldpassword=Old Password is required.
|
||||||
validation.not.empty.newpassword="New Password is required."
|
validation.not.empty.newpassword=New Password is required.
|
||||||
validation.not.empty.grade="user grade is required."
|
validation.not.empty.grade=user grade is required.
|
||||||
validation.not.empty.phone="phone is required."
|
validation.not.empty.phone=phone is required.
|
||||||
validation.email="email is not valid."
|
validation.email=email is not valid.
|
||||||
validation.phone="phone is not valid."
|
validation.phone=phone is not valid.
|
||||||
validation.password.not.change="password not change."
|
validation.password.not.change=password not change.
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
validation.not.empty.name="\uC774\uB984\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.name=\uC774\uB984\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.email="\uC774\uBA54\uC77C\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.email=\uC774\uBA54\uC77C\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.password="\uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.password=\uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.oldpassword="\uD604\uC7AC \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.oldpassword=\uD604\uC7AC \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.newpassword="\uBCC0\uACBD\uD560 \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.newpassword=\uBCC0\uACBD\uD560 \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.grade="\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.grade=\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
validation.not.empty.phone=\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4.
|
||||||
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.email=\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||||
validation.phone="\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
validation.phone=\uD734\uB300\uBC88\uD638\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
|
||||||
validation.password.not.change="\uB3D9\uC77C\uD55C \uD328\uC2A4\uC6CC\uB4DC\uB85C \uBCC0\uACBD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."
|
validation.password.not.change=\uB3D9\uC77C\uD55C \uD328\uC2A4\uC6CC\uB4DC\uB85C \uBCC0\uACBD\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.AlreadyDeletedException;
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
import com.ticketing.server.global.exception.PasswordMismatchException;
|
|
||||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||||
import com.ticketing.server.user.service.dto.DeleteUserDtoTest;
|
import com.ticketing.server.user.service.dto.DeleteUserDtoTest;
|
||||||
@@ -45,7 +44,7 @@ class UserTest {
|
|||||||
// when
|
// when
|
||||||
// then
|
// then
|
||||||
assertThatThrownBy(() -> user.delete(deleteUser))
|
assertThatThrownBy(() -> user.delete(deleteUser))
|
||||||
.isInstanceOf(PasswordMismatchException.class);
|
.isInstanceOf(TicketingException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@@ -60,7 +59,8 @@ class UserTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
assertThatThrownBy(() -> user.delete(deleteUserDto))
|
assertThatThrownBy(() -> user.delete(deleteUserDto))
|
||||||
.isInstanceOf(AlreadyDeletedException.class);
|
.isInstanceOf(TicketingException.class);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@@ -90,7 +90,7 @@ class UserTest {
|
|||||||
// when
|
// when
|
||||||
// then
|
// then
|
||||||
assertThatThrownBy(() -> user.changePassword(changePasswordDto))
|
assertThatThrownBy(() -> user.changePassword(changePasswordDto))
|
||||||
.isInstanceOf(PasswordMismatchException.class);
|
.isInstanceOf(TicketingException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import static org.junit.jupiter.api.Assertions.assertAll;
|
|||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import com.ticketing.server.global.exception.EmailNotFoundException;
|
import com.ticketing.server.global.exception.TicketingException;
|
||||||
import com.ticketing.server.user.domain.User;
|
import com.ticketing.server.user.domain.User;
|
||||||
import com.ticketing.server.user.domain.UserGrade;
|
import com.ticketing.server.user.domain.UserGrade;
|
||||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||||
@@ -54,7 +54,7 @@ class UserServiceImplTest {
|
|||||||
// when
|
// when
|
||||||
// then
|
// then
|
||||||
assertThatThrownBy(() -> userService.register(signUpDto))
|
assertThatThrownBy(() -> userService.register(signUpDto))
|
||||||
.isInstanceOf(IllegalArgumentException.class);
|
.isInstanceOf(TicketingException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -75,19 +75,19 @@ class UserServiceImplTest {
|
|||||||
@DisplayName("회원탈퇴 시 이메일이 존재하지 않을 경우")
|
@DisplayName("회원탈퇴 시 이메일이 존재하지 않을 경우")
|
||||||
void deleteFail() {
|
void deleteFail() {
|
||||||
// given
|
// given
|
||||||
when(userRepository.findByEmail("ticketing@gmail.com")).thenReturn(Optional.empty());
|
when(userRepository.findByEmailAndIsDeletedFalse("ticketing@gmail.com")).thenReturn(Optional.empty());
|
||||||
|
|
||||||
// when
|
// when
|
||||||
// then
|
// then
|
||||||
assertThatThrownBy(() -> userService.delete(deleteUserDto))
|
assertThatThrownBy(() -> userService.delete(deleteUserDto))
|
||||||
.isInstanceOf(EmailNotFoundException.class);
|
.isInstanceOf(TicketingException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("회원탈퇴 성공했을 경우")
|
@DisplayName("회원탈퇴 성공했을 경우")
|
||||||
void deleteSuccess() {
|
void deleteSuccess() {
|
||||||
// given
|
// given
|
||||||
when(userRepository.findByEmail("ticketing@gmail.com")).thenReturn(Optional.of(user));
|
when(userRepository.findByEmailAndIsDeletedFalse("ticketing@gmail.com")).thenReturn(Optional.of(user));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
User user = userService.delete(deleteUserDto);
|
User user = userService.delete(deleteUserDto);
|
||||||
@@ -108,7 +108,7 @@ class UserServiceImplTest {
|
|||||||
// when
|
// when
|
||||||
// then
|
// then
|
||||||
assertThatThrownBy(() -> userService.changePassword(changePasswordDto))
|
assertThatThrownBy(() -> userService.changePassword(changePasswordDto))
|
||||||
.isInstanceOf(EmailNotFoundException.class);
|
.isInstanceOf(TicketingException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user