From ea76a1726fe4340c24196011c92e778c217acf93 Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 02:21:12 +0900 Subject: [PATCH 01/13] =?UTF-8?q?[#78]=20Response=20=ED=98=95=EC=8B=9D=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advice/ExceptionAdvice.java | 2 +- .../memetory/global/response/ErrorCode.java | 13 ++++ .../global/response/ErrorResponse.java | 68 +++++++++++++++++++ .../memetory/global/response/ResultCode.java | 12 ++++ .../global/response/ResultResponse.java | 23 +++++++ 5 files changed, 117 insertions(+), 1 deletion(-) rename backend/memetory/src/main/java/com/example/memetory/global/{ => exception}/advice/ExceptionAdvice.java (96%) create mode 100644 backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java create mode 100644 backend/memetory/src/main/java/com/example/memetory/global/response/ErrorResponse.java create mode 100644 backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java create mode 100644 backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java diff --git a/backend/memetory/src/main/java/com/example/memetory/global/advice/ExceptionAdvice.java b/backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java similarity index 96% rename from backend/memetory/src/main/java/com/example/memetory/global/advice/ExceptionAdvice.java rename to backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java index 5f619915..428f5407 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/advice/ExceptionAdvice.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java @@ -1,4 +1,4 @@ -package com.example.memetory.global.advice; +package com.example.memetory.global.exception.advice; import org.springframework.http.HttpEntity; import org.springframework.http.HttpStatus; diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java new file mode 100644 index 00000000..4657cf80 --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java @@ -0,0 +1,13 @@ +package com.example.memetory.global.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** Enum Naming Format : {주체}_{이유} message format: 동사 명사형으로 마무리 */ +@Getter +@AllArgsConstructor +public enum ErrorCode { + ; + private final int status; + private final String message; +} \ No newline at end of file diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorResponse.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorResponse.java new file mode 100644 index 00000000..77c97fd4 --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorResponse.java @@ -0,0 +1,68 @@ +package com.example.memetory.global.response; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.validation.BindingResult; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class ErrorResponse { + private String errorMessage; + private List errors; + + public ErrorResponse(ErrorCode code, List fieldErrors) { + this.errorMessage = code.getMessage(); + this.errors = fieldErrors; + } + + private ErrorResponse(ErrorCode code) { + this.errorMessage = code.getMessage(); + this.errors = new ArrayList<>(); + } + + public static ErrorResponse of(final ErrorCode code, final BindingResult bindingResult) { + return new ErrorResponse(code, FieldError.of(bindingResult)); + } + + public static ErrorResponse of(ErrorCode code) { + return new ErrorResponse(code); + } + + @Getter + @NoArgsConstructor(access = AccessLevel.PROTECTED) + public static class FieldError { + private String field; + private String value; + private String reason; + + public FieldError(final String field, final String value, final String reason) { + this.field = field; + this.value = value; + this.reason = reason; + } + + private static List of(final BindingResult bindingResult) { + final List fieldErrors = + bindingResult.getFieldErrors(); + return fieldErrors.stream() + .map( + error -> + new FieldError( + error.getField(), + error.getRejectedValue() == null ? "" : error.getRejectedValue().toString(), + error.getDefaultMessage())) + .collect(Collectors.toList()); + } + } +} + diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java new file mode 100644 index 00000000..b3a31000 --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java @@ -0,0 +1,12 @@ +package com.example.memetory.global.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** Enum Naming Format : {행위}_{목적어}_{성공여부} message format: 동사 명사형으로 마무리 */ +@Getter +@AllArgsConstructor +public enum ResultCode { + ; + private final String message; +} diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java new file mode 100644 index 00000000..01a97098 --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java @@ -0,0 +1,23 @@ +package com.example.memetory.global.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class ResultResponse { + private int status; + private String message; + private Object data; + + public static ResultResponse of(ResultCode resultCode, Object data) { + return new ResultResponse(resultCode, data); + } + + public ResultResponse(ResultCode resultCode, Object data) { + this.message = resultCode.getMessage(); + this.data = data; + } +} \ No newline at end of file From 4125365395e6e7449133d6cd4661f69e9aa2e050 Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 02:24:04 +0900 Subject: [PATCH 02/13] =?UTF-8?q?[#78]=20BuisnessException=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/exception/BusinessException.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 backend/memetory/src/main/java/com/example/memetory/global/exception/BusinessException.java diff --git a/backend/memetory/src/main/java/com/example/memetory/global/exception/BusinessException.java b/backend/memetory/src/main/java/com/example/memetory/global/exception/BusinessException.java new file mode 100644 index 00000000..6d5612de --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/global/exception/BusinessException.java @@ -0,0 +1,15 @@ +package com.example.memetory.global.exception; + +import com.example.memetory.global.response.ErrorCode; + +import lombok.Getter; + +@Getter +public class BusinessException extends RuntimeException { + private final ErrorCode errorCode; + + public BusinessException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } +} From ad6c631c09ceba42ed15fba07ec538443014579a Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 02:35:32 +0900 Subject: [PATCH 03/13] =?UTF-8?q?[#78]=20ErrorCode=EC=97=90=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=EC=83=81=ED=99=A9=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memetory/global/response/ErrorCode.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java index 4657cf80..679b6e27 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java @@ -7,7 +7,34 @@ @Getter @AllArgsConstructor public enum ErrorCode { + // Global + INTERNAL_SERVER_ERROR(500, "서버 오류"), + INPUT_INVALID_VALUE(400, "잘못된 입력"), + + // Auth + LOGIN_FORBIDDEN(403, "토큰 인증 실패"), + TOKEN_NOT_FOUND(403, "토큰 추출 실패"), + EMAIL_NOT_FOUND(403, "이메일 추출 실패"), + + // Member + MEMBER_NOT_FOUND(400, "멤버를 찾기 실패"), + + // Meme + MEME_NOT_FOUND(400, "밈을 찾기 실패"), + + // Memes + MEMES_NOT_FOUND(400, "밈스를 찾기 실패"), + + // Like + LIKE_NOT_FOUND(400, "좋아요 찾기 실패"), + + // Complain + COMPLAIN_NOT_FOUND(400, "신고 찾기 실패"), + + // Comment + COMMENT_NOT_FOUND(400, "댓글 찾기 실패"), ; + private final int status; private final String message; } \ No newline at end of file From ad4b1b86be31a4d145e88c072385f64a6453ed7b Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 02:45:05 +0900 Subject: [PATCH 04/13] =?UTF-8?q?[#78]=20=EA=B8=B0=EC=A1=B4=20=EC=BB=A4?= =?UTF-8?q?=EC=8A=A4=ED=85=80=20=EC=98=88=EC=99=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?BusinessException=EC=9D=84=20=EC=83=81=EC=86=8D=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/NotFoundCommentException.java | 14 +++++--------- .../exception/NotFoundComplainException.java | 13 +++++-------- .../like/exception/NotFoundLikeException.java | 15 ++++++--------- .../member/exception/NotFoundMemberException.java | 14 +++++--------- .../meme/exception/NotFoundMemeException.java | 14 +++++--------- .../memes/exception/NotFoundMemesException.java | 11 ++++------- .../memetory/global/response/ErrorCode.java | 2 +- .../jwt/exception/InvalidTokenException.java | 14 +++++--------- .../jwt/exception/NotFoundEmailException.java | 14 +++++--------- .../jwt/exception/NotFoundTokenException.java | 14 +++++--------- .../filter/JwtAuthenticationProcessingFilter.java | 2 +- 11 files changed, 47 insertions(+), 80 deletions(-) diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/comment/exception/NotFoundCommentException.java b/backend/memetory/src/main/java/com/example/memetory/domain/comment/exception/NotFoundCommentException.java index 8ad40d76..8fd93a53 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/comment/exception/NotFoundCommentException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/comment/exception/NotFoundCommentException.java @@ -1,14 +1,10 @@ package com.example.memetory.domain.comment.exception; +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; -public class NotFoundCommentException extends RuntimeException { - public NotFoundCommentException() {} - - public NotFoundCommentException(String message) { - super(message); - } - - public NotFoundCommentException(String message, Throwable cause) { - super(message, cause); +public class NotFoundCommentException extends BusinessException { + public NotFoundCommentException() { + super(ErrorCode.COMMENT_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/complain/exception/NotFoundComplainException.java b/backend/memetory/src/main/java/com/example/memetory/domain/complain/exception/NotFoundComplainException.java index b8365740..a12684e2 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/complain/exception/NotFoundComplainException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/complain/exception/NotFoundComplainException.java @@ -1,13 +1,10 @@ package com.example.memetory.domain.complain.exception; -public class NotFoundComplainException extends RuntimeException{ - public NotFoundComplainException() {} +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public NotFoundComplainException(String message) { - super(message); - } - - public NotFoundComplainException(String message, Throwable cause) { - super(message, cause); +public class NotFoundComplainException extends BusinessException { + public NotFoundComplainException() { + super(ErrorCode.COMPLAIN_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/like/exception/NotFoundLikeException.java b/backend/memetory/src/main/java/com/example/memetory/domain/like/exception/NotFoundLikeException.java index d8bcc858..ea592bdd 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/like/exception/NotFoundLikeException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/like/exception/NotFoundLikeException.java @@ -1,13 +1,10 @@ package com.example.memetory.domain.like.exception; -public class NotFoundLikeException extends RuntimeException { - public NotFoundLikeException(){} +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public NotFoundLikeException(String message) { - super(message); - } - - public NotFoundLikeException(String message, Throwable cause) { - super(message, cause); - } +public class NotFoundLikeException extends BusinessException { + public NotFoundLikeException() { + super(ErrorCode.LIKE_NOT_FOUND); + } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/NotFoundMemberException.java b/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/NotFoundMemberException.java index 7e57d80f..1c59bc3d 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/NotFoundMemberException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/NotFoundMemberException.java @@ -1,14 +1,10 @@ package com.example.memetory.domain.member.exception; -public class NotFoundMemberException extends RuntimeException{ - public NotFoundMemberException() { - } +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public NotFoundMemberException(String message) { - super(message); - } - - public NotFoundMemberException(String message, Throwable cause) { - super(message, cause); +public class NotFoundMemberException extends BusinessException { + public NotFoundMemberException() { + super(ErrorCode.MEMBER_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/NotFoundMemeException.java b/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/NotFoundMemeException.java index 377458c0..7e3887f3 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/NotFoundMemeException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/NotFoundMemeException.java @@ -1,14 +1,10 @@ package com.example.memetory.domain.meme.exception; -public class NotFoundMemeException extends RuntimeException{ - public NotFoundMemeException() { - } +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public NotFoundMemeException(String message) { - super(message); - } - - public NotFoundMemeException(String message, Throwable cause) { - super(message, cause); +public class NotFoundMemeException extends BusinessException { + public NotFoundMemeException() { + super(ErrorCode.MEME_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java index 41ec354f..bd46483a 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java @@ -1,13 +1,10 @@ package com.example.memetory.domain.memes.exception; -public class NotFoundMemesException extends RuntimeException { - public NotFoundMemesException() {} +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; +public class NotFoundMemesException extends BusinessException { public NotFoundMemesException(String message) { - super(message); - } - - public NotFoundMemesException(String message, Throwable cause) { - super(message, cause); + super(ErrorCode.MEMES_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java index 679b6e27..c9a69f75 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java @@ -12,7 +12,7 @@ public enum ErrorCode { INPUT_INVALID_VALUE(400, "잘못된 입력"), // Auth - LOGIN_FORBIDDEN(403, "토큰 인증 실패"), + TOKEN_IS_INVALID(403, "토큰 인증 실패"), TOKEN_NOT_FOUND(403, "토큰 추출 실패"), EMAIL_NOT_FOUND(403, "이메일 추출 실패"), diff --git a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/InvalidTokenException.java b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/InvalidTokenException.java index 02e654e2..5a67f657 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/InvalidTokenException.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/InvalidTokenException.java @@ -1,14 +1,10 @@ package com.example.memetory.global.security.jwt.exception; -public class InvalidTokenException extends RuntimeException { - public InvalidTokenException() { - } +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public InvalidTokenException(String message) { - super(message); - } - - public InvalidTokenException(String message, Throwable cause) { - super(message, cause); +public class InvalidTokenException extends BusinessException { + public InvalidTokenException() { + super(ErrorCode.TOKEN_IS_INVALID); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundEmailException.java b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundEmailException.java index ef428d29..0f25bccf 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundEmailException.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundEmailException.java @@ -1,14 +1,10 @@ package com.example.memetory.global.security.jwt.exception; -public class NotFoundEmailException extends RuntimeException{ - public NotFoundEmailException() { - } +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public NotFoundEmailException(String message) { - super(message); - } - - public NotFoundEmailException(String message, Throwable cause) { - super(message, cause); +public class NotFoundEmailException extends BusinessException { + public NotFoundEmailException() { + super(ErrorCode.EMAIL_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundTokenException.java b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundTokenException.java index 5cba6646..d21ef147 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundTokenException.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/exception/NotFoundTokenException.java @@ -1,14 +1,10 @@ package com.example.memetory.global.security.jwt.exception; -public class NotFoundTokenException extends RuntimeException { - public NotFoundTokenException() { - } +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; - public NotFoundTokenException(String message) { - super(message); - } - - public NotFoundTokenException(String message, Throwable cause) { - super(message, cause); +public class NotFoundTokenException extends BusinessException { + public NotFoundTokenException() { + super(ErrorCode.TOKEN_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java index ab00d1fc..4b8aa59a 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java @@ -73,7 +73,7 @@ public void checkAccessTokenAndAuthentication(HttpServletRequest request, HttpSe .ifPresent(accessToken -> jwtService.extractEmail(accessToken) .ifPresentOrElse(email -> memberRepository.findByEmail(email).ifPresent(this::saveAuthentication), () -> { - throw new InvalidTokenException("Invalid access token"); + throw new InvalidTokenException(); } ) ); From 0d596e985cfd005d07567c36d2bb67e99bb54375 Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 02:50:54 +0900 Subject: [PATCH 05/13] =?UTF-8?q?[#78]=20ExceptionAdvice=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/advice/ExceptionAdvice.java | 49 ++++++++++++------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java b/backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java index 428f5407..4a4be1d1 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/exception/advice/ExceptionAdvice.java @@ -1,35 +1,46 @@ package com.example.memetory.global.exception.advice; -import org.springframework.http.HttpEntity; +import static com.example.memetory.global.response.ErrorCode.*; +import static org.springframework.http.HttpStatus.*; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; -import com.example.memetory.domain.member.exception.NotFoundMemberException; -import com.example.memetory.domain.meme.exception.NotFoundMemeException; -import com.example.memetory.global.security.jwt.exception.NotFoundEmailException; -import com.example.memetory.global.security.jwt.exception.NotFoundTokenException; +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; +import com.example.memetory.global.response.ErrorResponse; + +import lombok.extern.slf4j.Slf4j; +@Slf4j @RestControllerAdvice public class ExceptionAdvice { - @ExceptionHandler(NotFoundTokenException.class) - ResponseEntity notFoundTokenException() { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); - } - - @ExceptionHandler(NotFoundEmailException.class) - ResponseEntity notFoundEmailException() { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + @ExceptionHandler(Exception.class) + protected ResponseEntity handleException(Exception e) { + log.error(e.getMessage(), e); + ErrorResponse response = ErrorResponse.of(ErrorCode.INTERNAL_SERVER_ERROR); + return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR); } - @ExceptionHandler(NotFoundMemberException.class) - ResponseEntity notFoundMemberException() { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + @ExceptionHandler + protected ResponseEntity handleRuntimeException(BusinessException e) { + final ErrorCode errorCode = e.getErrorCode(); + final ErrorResponse response = + ErrorResponse.builder() + .errorMessage(errorCode.getMessage()) + .build(); + log.warn(e.getMessage()); + return ResponseEntity.status(errorCode.getStatus()).body(response); } - @ExceptionHandler(NotFoundMemeException.class) - ResponseEntity notFoundMemeException() { - return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); + @ExceptionHandler + protected ResponseEntity handleMethodArgumentNotValidException( + MethodArgumentNotValidException e) { + final ErrorResponse response = ErrorResponse.of(INPUT_INVALID_VALUE, e.getBindingResult()); + log.warn(e.getMessage()); + return new ResponseEntity<>(response, BAD_REQUEST); } } From 420baedd1f98e7c3673177c82f3c02c2c774e6d5 Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 03:25:54 +0900 Subject: [PATCH 06/13] =?UTF-8?q?[#78]=20Member=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 3 --- .../exception/DuplicatedMemberException.java | 10 +++++++ .../domain/member/service/MemberService.java | 9 +++---- .../exception/NotFoundMemesException.java | 2 +- .../domain/memes/service/MemesService.java | 6 ++--- .../memetory/global/response/ErrorCode.java | 1 + .../controller/MemberControllerTest.java | 21 ++++++--------- .../member/service/MemberServiceTest.java | 27 ++++++++++--------- 8 files changed, 42 insertions(+), 37 deletions(-) create mode 100644 backend/memetory/src/main/java/com/example/memetory/domain/member/exception/DuplicatedMemberException.java diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java b/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java index 1771918f..65d26904 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java @@ -25,9 +25,6 @@ public ResponseEntity updateMember(@LoginMemberEmail String email, @RequestBody MemberUpdateDto memberUpdateDto) { MemberServiceDto memberServiceDto = memberUpdateDto.toServiceDto(email); - if (memberService.isDuplicatedNickname(memberServiceDto)) { - return ResponseEntity.status(HttpStatus.CONFLICT).build(); - } memberService.update(memberServiceDto); return ResponseEntity.status(HttpStatus.OK).build(); diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/DuplicatedMemberException.java b/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/DuplicatedMemberException.java new file mode 100644 index 00000000..cad61d1c --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/domain/member/exception/DuplicatedMemberException.java @@ -0,0 +1,10 @@ +package com.example.memetory.domain.member.exception; + +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; + +public class DuplicatedMemberException extends BusinessException { + public DuplicatedMemberException() { + super(ErrorCode.NICKNAME_IS_DUPLICATED); + } +} diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/member/service/MemberService.java b/backend/memetory/src/main/java/com/example/memetory/domain/member/service/MemberService.java index a4adba39..7ef65c86 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/member/service/MemberService.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/member/service/MemberService.java @@ -5,6 +5,7 @@ import com.example.memetory.domain.member.dto.MemberServiceDto; import com.example.memetory.domain.member.entity.Member; +import com.example.memetory.domain.member.exception.DuplicatedMemberException; import com.example.memetory.domain.member.exception.NotFoundMemberException; import com.example.memetory.domain.member.repository.MemberRepository; @@ -19,6 +20,9 @@ public class MemberService { @Transactional public void update(MemberServiceDto memberServiceDto) { + if (memberRepository.existsMemberByNickname(memberServiceDto.getNickname())) { + throw new DuplicatedMemberException(); + } findByEmail(memberServiceDto.getEmail()).update(memberServiceDto); } @@ -31,9 +35,4 @@ public Member findByEmail(String email) { public Member findById(Long id) { return memberRepository.findById(id).orElseThrow(NotFoundMemberException::new); } - - @Transactional(readOnly = true) - public boolean isDuplicatedNickname(MemberServiceDto memberServiceDto) { - return memberRepository.existsMemberByNickname(memberServiceDto.getNickname()); - } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java index bd46483a..905545d4 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/exception/NotFoundMemesException.java @@ -4,7 +4,7 @@ import com.example.memetory.global.response.ErrorCode; public class NotFoundMemesException extends BusinessException { - public NotFoundMemesException(String message) { + public NotFoundMemesException() { super(ErrorCode.MEMES_NOT_FOUND); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java index d3dfee5c..e2b5e090 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java @@ -23,10 +23,10 @@ public class MemesService { @Transactional public void register(MemesServiceDto memesServiceDto) { - Member findMember = memberService.findByEmail(memesServiceDto.getEmail()); - Meme findMeme = memeService.getMemeBetweenService(memesServiceDto.getMemeId()); + Member member = memberService.findByEmail(memesServiceDto.getEmail()); + Meme meme = memeService.getMemeBetweenService(memesServiceDto.getMemeId()); - Memes newMemes = memesServiceDto.toEntity(findMember, findMeme); + Memes newMemes = memesServiceDto.toEntity(member, meme); memesRepository.save(newMemes); } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java index c9a69f75..8184452f 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java @@ -18,6 +18,7 @@ public enum ErrorCode { // Member MEMBER_NOT_FOUND(400, "멤버를 찾기 실패"), + NICKNAME_IS_DUPLICATED(409, "닉네임 중복"), // Meme MEME_NOT_FOUND(400, "밈을 찾기 실패"), diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java index a5360faf..da5b6946 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.ResultActions; import com.example.memetory.domain.member.dto.MemberUpdateDto; +import com.example.memetory.domain.member.exception.DuplicatedMemberException; import com.example.memetory.domain.member.service.MemberService; import com.example.memetory.global.LoginTest; @@ -26,12 +27,9 @@ public class MemberControllerTest extends LoginTest { @DisplayName("멤버 업데이트 성공") public void 멤버_업데이트_성공() throws Exception { // when - final ResultActions perform = mockMvc.perform( - post("/member") - .contentType(MediaType.APPLICATION_JSON) - .content(toRequestBody(new MemberUpdateDto("junrain2", "imageUrl2"))) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + final ResultActions perform = mockMvc.perform(post("/member").contentType(MediaType.APPLICATION_JSON) + .content(toRequestBody(new MemberUpdateDto("junrain2", "imageUrl2"))) + .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then perform.andExpect(status().isOk()); @@ -41,15 +39,12 @@ public class MemberControllerTest extends LoginTest { @DisplayName("멤버 업데이트 실패(닉네임 중복)") public void 멤버_업데이트_실패_닉네임_중복() throws Exception { // given -> 결과에 대한 객체, Member 객체 저장할 필요 존재 - given(memberService.isDuplicatedNickname(any())).willReturn(true); + doThrow(new DuplicatedMemberException()).when(memberService).update(any()); // when - final ResultActions perform = mockMvc.perform( - post("/member") - .contentType(MediaType.APPLICATION_JSON) - .content(toRequestBody(new MemberUpdateDto("junrain", "imageUrl"))) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + final ResultActions perform = mockMvc.perform(post("/member").contentType(MediaType.APPLICATION_JSON) + .content(toRequestBody(new MemberUpdateDto("junrain", "imageUrl"))) + .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then perform.andExpect(status().isConflict()); diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/member/service/MemberServiceTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/member/service/MemberServiceTest.java index c2c1853e..f2e6a054 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/member/service/MemberServiceTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/member/service/MemberServiceTest.java @@ -17,6 +17,7 @@ import com.example.memetory.domain.member.dto.MemberServiceDto; import com.example.memetory.domain.member.entity.Member; +import com.example.memetory.domain.member.exception.DuplicatedMemberException; import com.example.memetory.domain.member.exception.NotFoundMemberException; import com.example.memetory.domain.member.repository.MemberRepository; @@ -86,26 +87,28 @@ void setUp() { } @Test - @DisplayName("Member의 nickname 중복 여부 검사 true 반환") - void nickname_중복검사_True() { - // given - final MemberServiceDto memberServiceDto = MEMBER_SERVICE_DTO(); - given(memberRepository.existsMemberByNickname(memberServiceDto.getNickname())).willReturn(true); - - // then 실행 - assertTrue(memberService.isDuplicatedNickname(MEMBER_SERVICE_DTO())); - } - - @Test - @DisplayName("Member의 업데이트가 잘 이루어지는가") + @DisplayName("Member의 업데이트 성공") void member_업데이트() { MemberServiceDto memberServiceDto = UPDATE_MEMBER_SERVICE_DTO(); // when 멤버 업데이트 + when(memberRepository.existsMemberByNickname(anyString())).thenReturn(false); when(memberRepository.findByEmail(memberServiceDto.getEmail())).thenReturn(Optional.ofNullable(member)); memberService.update(memberServiceDto); // then assertThat(member.getNickname()).isEqualTo(memberServiceDto.getNickname()); } + + @Test + @DisplayName("Member의 업데이트 실패") + void member_업데이트_실패() { + MemberServiceDto memberServiceDto = UPDATE_MEMBER_SERVICE_DTO(); + + // when 멤버 업데이트 + when(memberRepository.existsMemberByNickname(anyString())).thenReturn(true); + + // then + assertThrows(DuplicatedMemberException.class, () -> memberService.update(memberServiceDto)); + } } From 3d76daf46bd6bbf56886f5f1f8a205645da21fe5 Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 10:47:28 +0900 Subject: [PATCH 07/13] =?UTF-8?q?[#78]=20likeControllerTest=EC=97=90=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=83=81=ED=99=A9=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memetory/global/response/ErrorCode.java | 12 +++++------ .../like/controller/LikeControllerTest.java | 21 +++++++++++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java index 8184452f..f9651852 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java @@ -17,23 +17,23 @@ public enum ErrorCode { EMAIL_NOT_FOUND(403, "이메일 추출 실패"), // Member - MEMBER_NOT_FOUND(400, "멤버를 찾기 실패"), + MEMBER_NOT_FOUND(404, "멤버를 찾기 실패"), NICKNAME_IS_DUPLICATED(409, "닉네임 중복"), // Meme - MEME_NOT_FOUND(400, "밈을 찾기 실패"), + MEME_NOT_FOUND(404, "밈을 찾기 실패"), // Memes - MEMES_NOT_FOUND(400, "밈스를 찾기 실패"), + MEMES_NOT_FOUND(404, "밈스를 찾기 실패"), // Like - LIKE_NOT_FOUND(400, "좋아요 찾기 실패"), + LIKE_NOT_FOUND(404, "좋아요 찾기 실패"), // Complain - COMPLAIN_NOT_FOUND(400, "신고 찾기 실패"), + COMPLAIN_NOT_FOUND(404, "신고 찾기 실패"), // Comment - COMMENT_NOT_FOUND(400, "댓글 찾기 실패"), + COMMENT_NOT_FOUND(404, "댓글 찾기 실패"), ; private final int status; diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java index bcbd264c..68576062 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java @@ -13,6 +13,7 @@ import org.springframework.test.web.servlet.ResultActions; import com.example.memetory.domain.like.dto.LikeServiceDto; +import com.example.memetory.domain.like.exception.NotFoundLikeException; import com.example.memetory.domain.like.service.LikeService; import com.example.memetory.domain.memes.exception.NotFoundMemesException; import com.example.memetory.global.LoginTest; @@ -38,9 +39,9 @@ public class LikeControllerTest extends LoginTest { perform.andExpect(status().isCreated()); } - @DisplayName("좋아요 제거 성공") + @DisplayName("좋아요 취소 성공") @Test - void 좋아요_제거() throws Exception { + void 좋아요_취소() throws Exception { // when final ResultActions perform = mockMvc.perform( delete("/memes/-1/like") @@ -52,4 +53,20 @@ public class LikeControllerTest extends LoginTest { verify(likeService).cancel(any(LikeServiceDto.class)); perform.andExpect(status().isOk()); } + + @DisplayName("좋아요 취소 실패") + @Test + void 좋아요_취소_실패() throws Exception { + // when + doThrow(new NotFoundLikeException()).when(likeService).cancel(any(LikeServiceDto.class)); + + final ResultActions perform = mockMvc.perform( + delete("/memes/-1/like") + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken) + ).andDo(print()); + + // then + perform.andExpect(status().isNotFound()); + } } From 9127e2526418149eef644125af38e699973c105f Mon Sep 17 00:00:00 2001 From: JunRain Date: Sat, 4 May 2024 11:21:06 +0900 Subject: [PATCH 08/13] =?UTF-8?q?[#78]=20Meme=20=EC=BB=A8=ED=8A=B8?= =?UTF-8?q?=EB=A1=A4=EB=9F=AC=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../meme/controller/MemeController.java | 94 +++++++++---------- .../exception/AccessDeniedMemeException.java | 10 ++ .../domain/meme/service/MemeService.java | 14 ++- .../memetory/global/response/ErrorCode.java | 1 + .../JwtAuthenticationProcessingFilter.java | 2 +- .../meme/controller/MemeControllerTest.java | 8 +- .../domain/meme/service/MemeServiceTest.java | 1 + 7 files changed, 68 insertions(+), 62 deletions(-) create mode 100644 backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/AccessDeniedMemeException.java diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java b/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java index d3c8262a..137af760 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java @@ -27,67 +27,63 @@ @RestController @RequiredArgsConstructor @RequestMapping("/meme") -public class MemeController implements MemeApi{ - private final MemeService memeService; +public class MemeController implements MemeApi { + private final MemeService memeService; - @Value("${spring.ai-server.url}") - private String AI_SERVER_URL; + @Value("${spring.ai-server.url}") + private String AI_SERVER_URL; - @PostMapping("/create/{memberId}") - @Override - public ResponseEntity callBackMeme(@PathVariable Long memberId, - @RequestBody ShotStackCallBackRequest shotStackCallBackRequest) { + @PostMapping("/create/{memberId}") + @Override + public ResponseEntity callBackMeme(@PathVariable Long memberId, + @RequestBody ShotStackCallBackRequest shotStackCallBackRequest) { - MemeServiceDto memeServiceDto = shotStackCallBackRequest.toServiceDto(memberId); + MemeServiceDto memeServiceDto = shotStackCallBackRequest.toServiceDto(memberId); - memeService.register(memeServiceDto); + memeService.register(memeServiceDto); - return ResponseEntity.status(HttpStatus.OK).build(); - } + return ResponseEntity.status(HttpStatus.OK).build(); + } - @PostMapping - @Override - public ResponseEntity register(@LoginMemberEmail String email, - @RequestBody GenerateMemeListRequest generateMemeListRequest) { + @PostMapping + @Override + public ResponseEntity register(@LoginMemberEmail String email, + @RequestBody GenerateMemeListRequest generateMemeListRequest) { - MemeServiceDto memeServiceDto = generateMemeListRequest.toServiceDto(email); - String aiServerSendJson = memeService.getAIServerSendJson(memeServiceDto); + MemeServiceDto memeServiceDto = generateMemeListRequest.toServiceDto(email); + String aiServerSendJson = memeService.getAIServerSendJson(memeServiceDto); - WebClient - .create(AI_SERVER_URL) - .post() - .contentType(MediaType.APPLICATION_JSON) - .body(BodyInserters.fromValue(aiServerSendJson)) - .retrieve() - .bodyToMono(Void.class) - .subscribe(); + WebClient + .create(AI_SERVER_URL) + .post() + .contentType(MediaType.APPLICATION_JSON) + .body(BodyInserters.fromValue(aiServerSendJson)) + .retrieve() + .bodyToMono(Void.class) + .subscribe(); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } + return ResponseEntity.status(HttpStatus.CREATED).build(); + } - @GetMapping("/{memeId}") - @Override - public ResponseEntity findMeme(@LoginMemberEmail String email, @PathVariable Long memeId) { - MemeServiceDto memeServiceDto = MemeServiceDto.create(email, memeId); + @GetMapping("/{memeId}") + @Override + public ResponseEntity findMeme(@LoginMemberEmail String email, @PathVariable Long memeId) { + MemeServiceDto memeServiceDto = MemeServiceDto.create(email, memeId); - if (memeService.checkMember(memeServiceDto)) { - return ResponseEntity.status(HttpStatus.FORBIDDEN).build(); - } + return ResponseEntity + .status(HttpStatus.OK) + .body(memeService.getMeme(memeServiceDto)); + } - return ResponseEntity - .status(HttpStatus.OK) - .body(memeService.getMeme(memeServiceDto)); - } + @GetMapping + @Override + public ResponseEntity findMemeList(@LoginMemberEmail String email, Pageable pageable) { + MemeServiceDto memeServiceDto = MemeServiceDto.create(email); - @GetMapping - @Override - public ResponseEntity findMemeList(@LoginMemberEmail String email, Pageable pageable) { - MemeServiceDto memeServiceDto = MemeServiceDto.create(email); + MemePageResponse memePageResponse = memeService.getAllMeme(memeServiceDto, pageable); - MemePageResponse memePageResponse = memeService.getAllMeme(memeServiceDto, pageable); - - return ResponseEntity - .status(HttpStatus.OK) - .body(memePageResponse); - } + return ResponseEntity + .status(HttpStatus.OK) + .body(memePageResponse); + } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/AccessDeniedMemeException.java b/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/AccessDeniedMemeException.java new file mode 100644 index 00000000..29af4e10 --- /dev/null +++ b/backend/memetory/src/main/java/com/example/memetory/domain/meme/exception/AccessDeniedMemeException.java @@ -0,0 +1,10 @@ +package com.example.memetory.domain.meme.exception; + +import com.example.memetory.global.exception.BusinessException; +import com.example.memetory.global.response.ErrorCode; + +public class AccessDeniedMemeException extends BusinessException { + public AccessDeniedMemeException() { + super(ErrorCode.MEME_ACCESS_DENY); + } +} diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/meme/service/MemeService.java b/backend/memetory/src/main/java/com/example/memetory/domain/meme/service/MemeService.java index 3d4acd26..e712a13c 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/meme/service/MemeService.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/meme/service/MemeService.java @@ -12,6 +12,7 @@ import com.example.memetory.domain.meme.dto.MemeResponse; import com.example.memetory.domain.meme.dto.MemeServiceDto; import com.example.memetory.domain.meme.entity.Meme; +import com.example.memetory.domain.meme.exception.AccessDeniedMemeException; import com.example.memetory.domain.meme.exception.NotFoundMemeException; import com.example.memetory.domain.meme.repository.MemeRepository; import com.google.gson.Gson; @@ -48,17 +49,14 @@ public String getAIServerSendJson(MemeServiceDto memeServiceDto) { @Transactional(readOnly = true) public MemeResponse getMeme(MemeServiceDto memeServiceDto) { + Member member = memberService.findById(memeServiceDto.getMemberId()); Meme meme = memeRepository.findById(memeServiceDto.getMemeId()).orElseThrow(NotFoundMemeException::new); - return MemeResponse.of(meme); - } - - @Transactional(readOnly = true) - public boolean checkMember(MemeServiceDto memeServiceDto) { - Meme meme = memeRepository.findById(memeServiceDto.getMemeId()).orElseThrow(NotFoundMemeException::new); - Member member = memberService.findById(memeServiceDto.getMemberId()); + if (meme.getMember() != member) { + throw new AccessDeniedMemeException(); + } - return meme.getMember() != member; + return MemeResponse.of(meme); } @Transactional diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java index f9651852..b7d2c239 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ErrorCode.java @@ -22,6 +22,7 @@ public enum ErrorCode { // Meme MEME_NOT_FOUND(404, "밈을 찾기 실패"), + MEME_ACCESS_DENY(403, "밈 접근 실패"), // Memes MEMES_NOT_FOUND(404, "밈스를 찾기 실패"), diff --git a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java index 4b8aa59a..38c28dac 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/filter/JwtAuthenticationProcessingFilter.java @@ -50,7 +50,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse if (refreshToken != null) { checkRefreshTokenAndReIssueAccessToken(response, refreshToken); - response.sendError(HttpServletResponse.SC_FORBIDDEN); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } if (refreshToken == null) { diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java index 9c156be0..1d009e22 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java @@ -17,7 +17,9 @@ import com.example.memetory.domain.meme.dto.MemePageResponse; import com.example.memetory.domain.meme.dto.MemeResponse; +import com.example.memetory.domain.meme.dto.MemeServiceDto; import com.example.memetory.domain.meme.entity.Meme; +import com.example.memetory.domain.meme.exception.AccessDeniedMemeException; import com.example.memetory.domain.meme.exception.NotFoundMemeException; import com.example.memetory.domain.meme.service.MemeService; import com.example.memetory.global.LoginTest; @@ -38,7 +40,6 @@ public class MemeControllerTest extends LoginTest { void 단일_밈_조회_성공() throws Exception { // given 예상될 MemeResponse 구현 Meme meme = MEME(loginMember); - given(memeService.checkMember(any())).willReturn(false); given(memeService.getMeme(any())).willReturn(MemeResponse.of(meme)); // when @@ -57,7 +58,7 @@ public class MemeControllerTest extends LoginTest { @DisplayName("단일 밈 조회 실패, 로그인한 유저의 밈이 아닐 경우") void 단일_밈_조회_실패_유저인증_실패() throws Exception { // given 예상될 MemeResponse 구현 - given(memeService.checkMember(any())).willReturn(true); + given(memeService.getMeme(any(MemeServiceDto.class))).willThrow(new AccessDeniedMemeException()); // when final ResultActions perform = mockMvc.perform( @@ -75,8 +76,7 @@ public class MemeControllerTest extends LoginTest { void 단일_밈_조회_실패_존재하지_않는_밈() throws Exception { // given 예상될 MemeResponse 구현 Meme meme = MEME(loginMember); - given(memeService.checkMember(any())).willReturn(false); - given(memeService.getMeme(any())).willThrow(NotFoundMemeException.class); + given(memeService.getMeme(any())).willThrow(new NotFoundMemeException()); // when final ResultActions perform = mockMvc.perform( diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/meme/service/MemeServiceTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/meme/service/MemeServiceTest.java index 9a0912c2..21f6c3b3 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/meme/service/MemeServiceTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/meme/service/MemeServiceTest.java @@ -75,6 +75,7 @@ void setUp() { // when when(memeRepository.findById(memeServiceDto.getMemeId())).thenReturn(Optional.ofNullable(meme)); + when(memberService.findById(memeServiceDto.getMemberId())).thenReturn(member); MemeResponse result = memeService.getMeme(memeServiceDto); // given From cdd4245810ce2e4c823f80e87cd39a7c42127d67 Mon Sep 17 00:00:00 2001 From: JunRain Date: Tue, 7 May 2024 11:34:25 +0900 Subject: [PATCH 09/13] =?UTF-8?q?[#78]=20Controller=20=EB=B0=98=ED=99=98?= =?UTF-8?q?=ED=98=95=EC=8B=9D=20=ED=86=B5=EC=9D=BC=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/comment/controller/CommentApi.java | 8 ++- .../comment/controller/CommentController.java | 49 +++++++++------- .../complain/controller/ComplainApi.java | 8 ++- .../controller/ComplainController.java | 57 +++++++++++-------- .../domain/like/controller/LikeApi.java | 6 +- .../like/controller/LikeController.java | 45 +++++++++------ .../domain/member/controller/MemberApi.java | 4 +- .../member/controller/MemberController.java | 8 ++- .../domain/meme/controller/MemeApi.java | 9 ++- .../meme/controller/MemeController.java | 28 ++++----- .../domain/memes/controller/MemesApi.java | 6 +- .../memes/controller/MemesController.java | 8 ++- .../memetory/global/response/ResultCode.java | 24 ++++++++ .../global/response/ResultResponse.java | 7 +++ 14 files changed, 169 insertions(+), 98 deletions(-) diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentApi.java index 363dab9d..487ea5e8 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentApi.java @@ -1,6 +1,8 @@ package com.example.memetory.domain.comment.controller; import com.example.memetory.domain.comment.dto.request.GenerateCommentRequest; +import com.example.memetory.global.response.ResultResponse; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -8,7 +10,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; + import org.springframework.http.ResponseEntity; @Tag(name = "Comment") @@ -25,7 +27,7 @@ public interface CommentApi { description = "댓글 생성!" ) }) - ResponseEntity register( + ResponseEntity register( @Parameter(hidden = true) String email, GenerateCommentRequest generateCommentRequest ); @@ -41,7 +43,7 @@ ResponseEntity register( description = "댓글 삭제!" ) }) - ResponseEntity delete( + ResponseEntity delete( @Parameter(in = ParameterIn.PATH, description = "댓글 아이디", required = true) Long commentId ); } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentController.java b/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentController.java index 6ee07043..a14e1bdf 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/comment/controller/CommentController.java @@ -1,36 +1,47 @@ package com.example.memetory.domain.comment.controller; +import static com.example.memetory.global.response.ResultCode.*; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import com.example.memetory.domain.comment.dto.CommentServiceDto; import com.example.memetory.domain.comment.dto.request.GenerateCommentRequest; import com.example.memetory.domain.comment.service.CommentService; import com.example.memetory.global.annotation.LoginMemberEmail; +import com.example.memetory.global.response.ResultResponse; + import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/comments") @RequiredArgsConstructor -public class CommentController implements CommentApi{ +public class CommentController implements CommentApi { - private final CommentService commentService; + private final CommentService commentService; - @PostMapping - @Override - public ResponseEntity register(@LoginMemberEmail String email, @RequestBody GenerateCommentRequest generateCommentRequest) { - CommentServiceDto newCommentServiceDto = generateCommentRequest.toServiceDto(email); - commentService.register(newCommentServiceDto); + @PostMapping + @Override + public ResponseEntity register(@LoginMemberEmail String email, + @RequestBody GenerateCommentRequest generateCommentRequest) { + CommentServiceDto newCommentServiceDto = generateCommentRequest.toServiceDto(email); + commentService.register(newCommentServiceDto); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } + return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_COMMENT_SUCCESS)); + } - @DeleteMapping("/{commentId}") - @Override - public ResponseEntity delete(@PathVariable Long commentId) { - CommentServiceDto newCommentServiceDto = CommentServiceDto.create(commentId); - commentService.delete(newCommentServiceDto); + @DeleteMapping("/{commentId}") + @Override + public ResponseEntity delete(@PathVariable Long commentId) { + CommentServiceDto newCommentServiceDto = CommentServiceDto.create(commentId); + commentService.delete(newCommentServiceDto); - return ResponseEntity.status(HttpStatus.OK).build(); - } + return ResponseEntity.ok(ResultResponse.of(DELETE_COMMENT_SUCCESS)); + } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainApi.java index 934e98fc..dda06df1 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainApi.java @@ -1,6 +1,8 @@ package com.example.memetory.domain.complain.controller; import com.example.memetory.domain.complain.dto.request.GenerateComplainRequest; +import com.example.memetory.global.response.ResultResponse; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; @@ -8,7 +10,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; + import org.springframework.http.ResponseEntity; @Tag(name = "Complain") @@ -24,7 +26,7 @@ public interface ComplainApi { description = "신고 생성!" ) }) - ResponseEntity register( + ResponseEntity register( @Parameter(hidden = true) String email, GenerateComplainRequest generateComplainRequest ); @@ -40,7 +42,7 @@ ResponseEntity register( description = "신고 삭제!" ) }) - ResponseEntity delete( + ResponseEntity delete( @Parameter(in = ParameterIn.PATH, description = "신고 아이디", required = true) Long complainId ); } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainController.java b/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainController.java index 8c424ccd..c0220472 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/complain/controller/ComplainController.java @@ -1,35 +1,46 @@ package com.example.memetory.domain.complain.controller; +import static com.example.memetory.global.response.ResultCode.*; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import com.example.memetory.domain.complain.dto.ComplainServiceDto; import com.example.memetory.domain.complain.dto.request.GenerateComplainRequest; import com.example.memetory.domain.complain.service.ComplainService; import com.example.memetory.global.annotation.LoginMemberEmail; +import com.example.memetory.global.response.ResultResponse; + import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor @RequestMapping("/complains") -public class ComplainController implements ComplainApi{ - private final ComplainService complainService; - - @PostMapping - @Override - public ResponseEntity register(@LoginMemberEmail String email, @RequestBody GenerateComplainRequest generateComplainRequest) { - ComplainServiceDto newComplainServiceDto = generateComplainRequest.toServiceDto(email); - complainService.register(newComplainServiceDto); - - return ResponseEntity.status(HttpStatus.CREATED).build(); - } - - @DeleteMapping("/{complainId}") - @Override - public ResponseEntity delete(@PathVariable Long complainId) { - ComplainServiceDto newComplainServiceDto = ComplainServiceDto.create(complainId); - complainService.delete(newComplainServiceDto); - - return ResponseEntity.status(HttpStatus.OK).build(); - } +public class ComplainController implements ComplainApi { + private final ComplainService complainService; + + @PostMapping + @Override + public ResponseEntity register(@LoginMemberEmail String email, + @RequestBody GenerateComplainRequest generateComplainRequest) { + ComplainServiceDto newComplainServiceDto = generateComplainRequest.toServiceDto(email); + complainService.register(newComplainServiceDto); + + return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_COMPLAIN_SUCCESS)); + } + + @DeleteMapping("/{complainId}") + @Override + public ResponseEntity delete(@PathVariable Long complainId) { + ComplainServiceDto newComplainServiceDto = ComplainServiceDto.create(complainId); + complainService.delete(newComplainServiceDto); + + return ResponseEntity.ok(ResultResponse.of(DELETE_COMMENT_SUCCESS)); + } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeApi.java index 0efdd2cc..96791c39 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeApi.java @@ -9,6 +9,8 @@ import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.http.ResponseEntity; +import com.example.memetory.global.response.ResultResponse; + @Tag(name = "Like") public interface LikeApi { @@ -23,7 +25,7 @@ public interface LikeApi { description = "좋아요 등록!" ) }) - ResponseEntity register( + ResponseEntity register( @Parameter(hidden = true) String email, @Parameter(in = ParameterIn.PATH, description = "밈스 아이디", required = true) Long memesId @@ -40,7 +42,7 @@ ResponseEntity register( description = "좋아요 취소!" ) }) - ResponseEntity cancel( + ResponseEntity cancel( @Parameter(hidden = true) String email, @Parameter(in = ParameterIn.PATH, description = "밈스 아이디", required = true) Long memesId diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeController.java b/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeController.java index 445fb259..006172f6 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/like/controller/LikeController.java @@ -1,34 +1,43 @@ package com.example.memetory.domain.like.controller; +import static com.example.memetory.global.response.ResultCode.*; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import com.example.memetory.domain.like.dto.LikeServiceDto; import com.example.memetory.domain.like.service.LikeService; import com.example.memetory.global.annotation.LoginMemberEmail; +import com.example.memetory.global.response.ResultResponse; + import lombok.RequiredArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor @RequestMapping("/memes") public class LikeController implements LikeApi { - private final LikeService likeService; + private final LikeService likeService; - @PostMapping("/{memesId}/like") - @Override - public ResponseEntity register(@LoginMemberEmail String email, @PathVariable Long memesId) { - LikeServiceDto likeServiceDto = LikeServiceDto.create(email, memesId); - likeService.register(likeServiceDto); + @PostMapping("/{memesId}/like") + @Override + public ResponseEntity register(@LoginMemberEmail String email, @PathVariable Long memesId) { + LikeServiceDto likeServiceDto = LikeServiceDto.create(email, memesId); + likeService.register(likeServiceDto); - return ResponseEntity.status(HttpStatus.CREATED).build(); - } + return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_LIKE_SUCCESS)); + } - @DeleteMapping("/{memesId}/like") - @Override - public ResponseEntity cancel(@LoginMemberEmail String email, @PathVariable Long memesId) { - LikeServiceDto likeServiceDto = LikeServiceDto.create(email, memesId); - likeService.cancel(likeServiceDto); + @DeleteMapping("/{memesId}/like") + @Override + public ResponseEntity cancel(@LoginMemberEmail String email, @PathVariable Long memesId) { + LikeServiceDto likeServiceDto = LikeServiceDto.create(email, memesId); + likeService.cancel(likeServiceDto); - return ResponseEntity.status(HttpStatus.OK).build(); - } + return ResponseEntity.ok(ResultResponse.of(DELETE_LIKE_SUCCESS)); + } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberApi.java index ee23a4c1..ac9d8f45 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberApi.java @@ -1,9 +1,9 @@ package com.example.memetory.domain.member.controller; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import com.example.memetory.domain.member.dto.MemberUpdateDto; +import com.example.memetory.global.response.ResultResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -30,5 +30,5 @@ public interface MemberApi { description = "닉네임 중복" )} ) - ResponseEntity updateMember(@Parameter(hidden = true) String email, MemberUpdateDto memberUpdateDto); + ResponseEntity updateMember(@Parameter(hidden = true) String email, MemberUpdateDto memberUpdateDto); } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java b/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java index 65d26904..21781973 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/member/controller/MemberController.java @@ -1,6 +1,7 @@ package com.example.memetory.domain.member.controller; -import org.springframework.http.HttpStatus; +import static com.example.memetory.global.response.ResultCode.*; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -11,6 +12,7 @@ import com.example.memetory.domain.member.dto.MemberUpdateDto; import com.example.memetory.domain.member.service.MemberService; import com.example.memetory.global.annotation.LoginMemberEmail; +import com.example.memetory.global.response.ResultResponse; import lombok.RequiredArgsConstructor; @@ -21,12 +23,12 @@ public class MemberController implements MemberApi { private final MemberService memberService; @PostMapping - public ResponseEntity updateMember(@LoginMemberEmail String email, + public ResponseEntity updateMember(@LoginMemberEmail String email, @RequestBody MemberUpdateDto memberUpdateDto) { MemberServiceDto memberServiceDto = memberUpdateDto.toServiceDto(email); memberService.update(memberServiceDto); - return ResponseEntity.status(HttpStatus.OK).build(); + return ResponseEntity.ok(ResultResponse.of(UPDATE_MEMBER_SUCCESS)); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeApi.java index d1e21c65..6c5cd27c 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeApi.java @@ -5,9 +5,8 @@ import org.springframework.http.ResponseEntity; import com.example.memetory.domain.meme.dto.GenerateMemeListRequest; -import com.example.memetory.domain.meme.dto.MemePageResponse; -import com.example.memetory.domain.meme.dto.MemeResponse; import com.example.memetory.domain.meme.dto.ShotStackCallBackRequest; +import com.example.memetory.global.response.ResultResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -46,7 +45,7 @@ ResponseEntity callBackMeme( description = "밈 생성" ) }) - ResponseEntity register( + ResponseEntity register( @Parameter(hidden = true) String email, GenerateMemeListRequest generateMemeListRequest ); @@ -62,7 +61,7 @@ ResponseEntity register( description = "밈 단일 조회" ) }) - ResponseEntity findMeme( + ResponseEntity findMeme( @Parameter(hidden = true) String email, @Parameter(in = ParameterIn.PATH, description = "밈 아이디", required = true) Long memeId ); @@ -78,7 +77,7 @@ ResponseEntity findMeme( description = "밈 전체 조회" ) }) - ResponseEntity findMemeList( + ResponseEntity findMemePage( @Parameter(hidden = true) String email, @Parameter Pageable pageable ); diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java b/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java index 137af760..dbaa4047 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/meme/controller/MemeController.java @@ -1,5 +1,7 @@ package com.example.memetory.domain.meme.controller; +import static com.example.memetory.global.response.ResultCode.*; + import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; @@ -15,12 +17,11 @@ import org.springframework.web.reactive.function.client.WebClient; import com.example.memetory.domain.meme.dto.GenerateMemeListRequest; -import com.example.memetory.domain.meme.dto.MemePageResponse; -import com.example.memetory.domain.meme.dto.MemeResponse; import com.example.memetory.domain.meme.dto.MemeServiceDto; import com.example.memetory.domain.meme.dto.ShotStackCallBackRequest; import com.example.memetory.domain.meme.service.MemeService; import com.example.memetory.global.annotation.LoginMemberEmail; +import com.example.memetory.global.response.ResultResponse; import lombok.RequiredArgsConstructor; @@ -47,14 +48,13 @@ public ResponseEntity callBackMeme(@PathVariable Long memberId, @PostMapping @Override - public ResponseEntity register(@LoginMemberEmail String email, + public ResponseEntity register(@LoginMemberEmail String email, @RequestBody GenerateMemeListRequest generateMemeListRequest) { MemeServiceDto memeServiceDto = generateMemeListRequest.toServiceDto(email); String aiServerSendJson = memeService.getAIServerSendJson(memeServiceDto); - WebClient - .create(AI_SERVER_URL) + WebClient.create(AI_SERVER_URL) .post() .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue(aiServerSendJson)) @@ -62,28 +62,24 @@ public ResponseEntity register(@LoginMemberEmail String email, .bodyToMono(Void.class) .subscribe(); - return ResponseEntity.status(HttpStatus.CREATED).build(); + return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_MEME_SUCCESS)); } @GetMapping("/{memeId}") @Override - public ResponseEntity findMeme(@LoginMemberEmail String email, @PathVariable Long memeId) { + public ResponseEntity findMeme(@LoginMemberEmail String email, @PathVariable Long memeId) { MemeServiceDto memeServiceDto = MemeServiceDto.create(email, memeId); - return ResponseEntity - .status(HttpStatus.OK) - .body(memeService.getMeme(memeServiceDto)); + return ResponseEntity.ok( + ResultResponse.of(GET_ONE_MEME_SUCCESS, memeService.getMeme(memeServiceDto))); } @GetMapping @Override - public ResponseEntity findMemeList(@LoginMemberEmail String email, Pageable pageable) { + public ResponseEntity findMemePage(@LoginMemberEmail String email, Pageable pageable) { MemeServiceDto memeServiceDto = MemeServiceDto.create(email); - MemePageResponse memePageResponse = memeService.getAllMeme(memeServiceDto, pageable); - - return ResponseEntity - .status(HttpStatus.OK) - .body(memePageResponse); + return ResponseEntity.ok( + ResultResponse.of(GET_MEMBER_MEME_SUCCESS, memeService.getAllMeme(memeServiceDto, pageable))); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java index abe57720..652f2019 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java @@ -1,13 +1,15 @@ package com.example.memetory.domain.memes.controller; import com.example.memetory.domain.memes.dto.request.GenerateMemesRequest; +import com.example.memetory.global.response.ResultResponse; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; + import org.springframework.http.ResponseEntity; @Tag(name = "Meme`s") @@ -24,7 +26,7 @@ public interface MemesApi { description = "밈스 생성!" ) }) - ResponseEntity register( + ResponseEntity register( @Parameter(hidden = true) String email, GenerateMemesRequest generateMemesRequest ); diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java index fb03bb16..510973ab 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java @@ -1,9 +1,13 @@ package com.example.memetory.domain.memes.controller; +import static com.example.memetory.global.response.ResultCode.*; + import com.example.memetory.domain.memes.dto.MemesServiceDto; import com.example.memetory.domain.memes.dto.request.GenerateMemesRequest; import com.example.memetory.domain.memes.service.MemesService; import com.example.memetory.global.annotation.LoginMemberEmail; +import com.example.memetory.global.response.ResultResponse; + import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -21,9 +25,9 @@ public class MemesController implements MemesApi{ @PostMapping @Override - public ResponseEntity register(@LoginMemberEmail String email, @RequestBody GenerateMemesRequest generateMemesRequest) { + public ResponseEntity register(@LoginMemberEmail String email, @RequestBody GenerateMemesRequest generateMemesRequest) { MemesServiceDto memesServiceDto = generateMemesRequest.toServiceDto(email); memesService.register(memesServiceDto); - return ResponseEntity.status(HttpStatus.CREATED).build(); + return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_MEMES_SUCCESS)); } } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java index b3a31000..635feffe 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java @@ -7,6 +7,30 @@ @Getter @AllArgsConstructor public enum ResultCode { + // member + UPDATE_MEMBER_SUCCESS(200,"멤버 업데이트 성공"), + + // meme + CREATE_MEME_SUCCESS(201, "밈 생성 성공"), + GET_ONE_MEME_SUCCESS(200, "단일 밈 조회 성공"), + GET_MEMBER_MEME_SUCCESS(200, "멤버별 밈 조회 성공"), + + // memes + CREATE_MEMES_SUCCESS(201, "밈스 생성 성공"), + + // like + CREATE_LIKE_SUCCESS(201, "좋아요 생성 성공"), + DELETE_LIKE_SUCCESS(200, "좋아요 삭제 성공"), + + // comment + CREATE_COMMENT_SUCCESS(201, "댓글 생성 성공"), + DELETE_COMMENT_SUCCESS(200, "댓글 삭제 성공"), + + //complain + CREATE_COMPLAIN_SUCCESS(201, "신고 생성 성공"), + DELETE_COMPLAIN_SUCCESS(201, "신고 삭제 성공"), + ; + private final int status; private final String message; } diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java index 01a97098..7fa76402 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultResponse.java @@ -16,8 +16,15 @@ public static ResultResponse of(ResultCode resultCode, Object data) { return new ResultResponse(resultCode, data); } + public static ResultResponse of(ResultCode resultCode) { + return new ResultResponse(resultCode, ""); + } + public ResultResponse(ResultCode resultCode, Object data) { + this.status = resultCode.getStatus(); this.message = resultCode.getMessage(); this.data = data; } + + } \ No newline at end of file From 7dda6f410acc78615d7f093e9601cc8eb67020e3 Mon Sep 17 00:00:00 2001 From: JunRain Date: Tue, 7 May 2024 13:02:41 +0900 Subject: [PATCH 10/13] =?UTF-8?q?[#78]=20ResultResponse=EC=97=90=20?= =?UTF-8?q?=EB=A7=9E=EC=B6=B0=EC=84=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memetory/domain/auth/AuthTest.java | 4 +- .../like/controller/LikeControllerTest.java | 33 +++++++-------- .../controller/MemberControllerTest.java | 7 +++- .../meme/controller/MemeControllerTest.java | 41 +++++++++---------- .../memes/controller/MemesControllerTest.java | 5 ++- .../example/memetory/global/LoginTest.java | 3 ++ 6 files changed, 47 insertions(+), 46 deletions(-) diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/auth/AuthTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/auth/AuthTest.java index 6c19383d..530e03f9 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/auth/AuthTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/auth/AuthTest.java @@ -100,7 +100,7 @@ public class AuthTest extends LoginTest { .header("Authorization-refresh", refreshToken)).andDo(print()); // then - perform.andExpect(status().isForbidden()) + perform.andExpect(status().isUnauthorized()) .andExpect(jsonPath("accessToken", is(accessToken)).exists()) .andExpect(jsonPath("refreshToken", is(refreshToken)).exists()); } @@ -121,6 +121,6 @@ public class AuthTest extends LoginTest { .header("Authorization-refresh", refreshToken)).andDo(print()); // then - perform.andExpect(status().isForbidden()); + perform.andExpect(status().isUnauthorized()); } } diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java index 68576062..886503b3 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/like/controller/LikeControllerTest.java @@ -1,5 +1,7 @@ package com.example.memetory.domain.like.controller; +import static com.example.memetory.global.response.ErrorCode.*; +import static com.example.memetory.global.response.ResultCode.*; import static org.mockito.BDDMockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; @@ -15,7 +17,6 @@ import com.example.memetory.domain.like.dto.LikeServiceDto; import com.example.memetory.domain.like.exception.NotFoundLikeException; import com.example.memetory.domain.like.service.LikeService; -import com.example.memetory.domain.memes.exception.NotFoundMemesException; import com.example.memetory.global.LoginTest; @DisplayName("Like 컨트롤러 테스트의 ") @@ -28,30 +29,26 @@ public class LikeControllerTest extends LoginTest { @Test void 좋아요_등록() throws Exception { // when - final ResultActions perform = mockMvc.perform( - post("/memes/-1/like") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + final ResultActions perform = mockMvc.perform(post("/memes/-1/like").contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then verify(likeService).register(any(LikeServiceDto.class)); - perform.andExpect(status().isCreated()); + perform.andExpect(status().isCreated()) + .andExpect(jsonPath(MESSAGE).value(CREATE_LIKE_SUCCESS.getMessage())); } @DisplayName("좋아요 취소 성공") @Test void 좋아요_취소() throws Exception { // when - final ResultActions perform = mockMvc.perform( - delete("/memes/-1/like") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + final ResultActions perform = mockMvc.perform(delete("/memes/-1/like").contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then verify(likeService).cancel(any(LikeServiceDto.class)); - perform.andExpect(status().isOk()); + perform.andExpect(status().isOk()) + .andExpect(jsonPath(MESSAGE).value(DELETE_LIKE_SUCCESS.getMessage())); } @DisplayName("좋아요 취소 실패") @@ -60,13 +57,11 @@ public class LikeControllerTest extends LoginTest { // when doThrow(new NotFoundLikeException()).when(likeService).cancel(any(LikeServiceDto.class)); - final ResultActions perform = mockMvc.perform( - delete("/memes/-1/like") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + final ResultActions perform = mockMvc.perform(delete("/memes/-1/like").contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then - perform.andExpect(status().isNotFound()); + perform.andExpect(status().isNotFound()) + .andExpect(jsonPath(ERROR_MESSAGE).value(LIKE_NOT_FOUND.getMessage())); } } diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java index da5b6946..86b7bfdc 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/member/controller/MemberControllerTest.java @@ -1,5 +1,7 @@ package com.example.memetory.domain.member.controller; +import static com.example.memetory.global.response.ErrorCode.*; +import static com.example.memetory.global.response.ResultCode.*; import static org.mockito.BDDMockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; @@ -32,7 +34,7 @@ public class MemberControllerTest extends LoginTest { .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then - perform.andExpect(status().isOk()); + perform.andExpect(status().isOk()).andExpect(jsonPath(MESSAGE).value(UPDATE_MEMBER_SUCCESS.getMessage())); } @Test @@ -47,6 +49,7 @@ public class MemberControllerTest extends LoginTest { .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then - perform.andExpect(status().isConflict()); + perform.andExpect(status().isConflict()) + .andExpect(jsonPath(ERROR_MESSAGE).value(NICKNAME_IS_DUPLICATED.getMessage())); } } diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java index 1d009e22..5dc45c88 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/meme/controller/MemeControllerTest.java @@ -1,6 +1,8 @@ package com.example.memetory.domain.meme.controller; import static com.example.memetory.domain.meme.MemeFixture.*; +import static com.example.memetory.global.response.ErrorCode.*; +import static com.example.memetory.global.response.ResultCode.*; import static org.mockito.BDDMockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; @@ -44,14 +46,13 @@ public class MemeControllerTest extends LoginTest { // when final ResultActions perform = mockMvc.perform( - get("/meme/-1") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + get("/meme/-1").contentType(MediaType.APPLICATION_JSON).header("Authorization", "Bearer " + accessToken)) + .andDo(print()); // then perform.andExpect(status().isOk()) - .andExpect(jsonPath("$.s3Url").exists()); + .andExpect(jsonPath(MESSAGE, GET_ONE_MEME_SUCCESS.getMessage()).exists()) + .andExpect(jsonPath("$.data.s3Url").exists()); } @Test @@ -62,13 +63,12 @@ public class MemeControllerTest extends LoginTest { // when final ResultActions perform = mockMvc.perform( - get("/meme/-1") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + get("/meme/-1").contentType(MediaType.APPLICATION_JSON).header("Authorization", "Bearer " + accessToken)) + .andDo(print()); // then - perform.andExpect(status().isForbidden()); + perform.andExpect(status().isForbidden()) + .andExpect(jsonPath(ERROR_MESSAGE, MEME_ACCESS_DENY.getMessage()).exists()); } @Test @@ -80,20 +80,20 @@ public class MemeControllerTest extends LoginTest { // when final ResultActions perform = mockMvc.perform( - get("/meme/-1") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + get("/meme/-1").contentType(MediaType.APPLICATION_JSON).header("Authorization", "Bearer " + accessToken)) + .andDo(print()); // then - perform.andExpect(status().isNotFound()); + perform.andExpect(status().isNotFound()) + .andExpect(jsonPath(ERROR_MESSAGE, MEME_NOT_FOUND.getMessage()).exists()); } @Test @DisplayName("전체 밈 조회 성공") void 전체_밈_조회_성공() throws Exception { // given 예상될 MemeResponse 구현 - List memeList = List.of(MEME(loginMember), SECOND_MEME(loginMember)).stream() + List memeList = List.of(MEME(loginMember), SECOND_MEME(loginMember)) + .stream() .map(MemeResponse::of) .toList(); MemePageResponse memePageResponse = MemePageResponse.builder().memeList(memeList).build(); @@ -102,13 +102,12 @@ public class MemeControllerTest extends LoginTest { // when final ResultActions perform = mockMvc.perform( - get("/meme?page=0&size=10") - .contentType(MediaType.APPLICATION_JSON) - .header("Authorization", "Bearer " + accessToken) - ).andDo(print()); + get("/meme?page=0&size=10").contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + accessToken)).andDo(print()); // then perform.andExpect(status().isOk()) - .andExpect(jsonPath("$.memeList").isArray()); + .andExpect(jsonPath(MESSAGE).value(GET_MEMBER_MEME_SUCCESS.getMessage())) + .andExpect(jsonPath("$.data.memeList").isArray()); } } diff --git a/backend/memetory/src/test/java/com/example/memetory/domain/memes/controller/MemesControllerTest.java b/backend/memetory/src/test/java/com/example/memetory/domain/memes/controller/MemesControllerTest.java index d9cdca1d..319d7ac2 100644 --- a/backend/memetory/src/test/java/com/example/memetory/domain/memes/controller/MemesControllerTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/domain/memes/controller/MemesControllerTest.java @@ -1,6 +1,7 @@ package com.example.memetory.domain.memes.controller; import static com.example.memetory.domain.meme.MemeFixture.*; +import static com.example.memetory.global.response.ResultCode.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; @@ -38,7 +39,7 @@ public class MemesControllerTest extends LoginTest { ).andDo(print()); // then - perform.andExpect(status().isCreated()); - + perform.andExpect(status().isCreated()) + .andExpect(jsonPath(MESSAGE).value(CREATE_MEMES_SUCCESS.getMessage())); } } diff --git a/backend/memetory/src/test/java/com/example/memetory/global/LoginTest.java b/backend/memetory/src/test/java/com/example/memetory/global/LoginTest.java index 8d60da9d..4aba4a0c 100644 --- a/backend/memetory/src/test/java/com/example/memetory/global/LoginTest.java +++ b/backend/memetory/src/test/java/com/example/memetory/global/LoginTest.java @@ -27,6 +27,9 @@ @WebMvcTest public abstract class LoginTest { + protected final String MESSAGE = "message"; + protected final String ERROR_MESSAGE = "errorMessage"; + @Value("${jwt.secretKey}") protected String secretKey; protected MockMvc mockMvc; From cf7cd3e03e95d169426c9af6abef4b874925432b Mon Sep 17 00:00:00 2001 From: JunRain Date: Tue, 7 May 2024 13:37:52 +0900 Subject: [PATCH 11/13] =?UTF-8?q?[#78]=20JwtService=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=20=ED=95=B8=EB=93=A4=EB=A7=81=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memetory/global/security/jwt/service/JwtService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/service/JwtService.java b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/service/JwtService.java index ea60dd92..a960a516 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/service/JwtService.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/security/jwt/service/JwtService.java @@ -61,7 +61,7 @@ public void sendAccessAndRefreshToken(HttpServletResponse response, String email response.getWriter().write(token); refreshTokenService.updateToken(email, refreshToken); } catch (IOException e) { - // 해당 에러처리 부분에 대해서 고민 필요 + log.error("sendAccessAndRefreshToken 오류 발생 : {}", e.getMessage()); throw new RuntimeException(e); } From cf34c209e6106209f3618bd8c3b69e7da0f09efe Mon Sep 17 00:00:00 2001 From: JunRain Date: Tue, 7 May 2024 14:09:29 +0900 Subject: [PATCH 12/13] =?UTF-8?q?[#78]=20memesController=20URL=20=EC=84=A4?= =?UTF-8?q?=EA=B3=84=20=EC=B9=B4=EB=A9=9C=EC=BC=80=EC=9D=B4=EC=8A=A4=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../memetory/domain/memes/controller/MemesApi.java | 6 +++--- .../domain/memes/controller/MemesController.java | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java index 470bd675..e56455f7 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java @@ -87,7 +87,7 @@ ResponseEntity register( description = "밈스 삭제" ) }) - ResponseEntity delete( + ResponseEntity deleteMemes( @Parameter(in = ParameterIn.PATH, description = "밈스 아이디", required = true) Long memesId ); @@ -102,7 +102,7 @@ ResponseEntity delete( description = "밈스 단일 조회" ) }) - ResponseEntity findOne( + ResponseEntity findMemes( @Parameter(in = ParameterIn.PATH, description = "밈스 아이디", required = true) Long memesId ); @@ -117,5 +117,5 @@ ResponseEntity findOne( description = "밈스 전체 조회" ) }) - ResponseEntity findAll(Pageable pageable); + ResponseEntity findAllMemes(Pageable pageable); } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java index ff683325..00e1a634 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java @@ -34,7 +34,7 @@ public ResponseEntity register(@LoginMemberEmail String email, @ } // 밈스 좋아요 순으로 상위 10개 조회 - @GetMapping("/likeAll") + @GetMapping("/like/all") @Override public ResponseEntity findTopMemesByLike() { MemesInfoListResponse newMemesInfoListResponse = memesService.findTopMemesByLike(); @@ -43,7 +43,7 @@ public ResponseEntity findTopMemesByLike() { } // 최근 한 달 동안 생성된 밈스 중 좋아요 순으로 상위 10개 조회 - @GetMapping("/likeMonth") + @GetMapping("/like/month") @Override public ResponseEntity findTopMemesByLikeForMonth() { MemesInfoListResponse newMemesInfoListResponse = memesService.findTopMemesByLikeForMonth(); @@ -52,7 +52,7 @@ public ResponseEntity findTopMemesByLikeForMonth() { } // 최근 한 주 동안 생성된 밈스 중 좋아요 순으로 상위 10개 조회 - @GetMapping("/likeWeek") + @GetMapping("/like/week") @Override public ResponseEntity findTopMemesByLikeForWeek() { MemesInfoListResponse newMemesInfoListResponse = memesService.findTopMemesByLikeForWeek(); @@ -63,7 +63,7 @@ public ResponseEntity findTopMemesByLikeForWeek() { // 밈스 삭제 @DeleteMapping("/{memesId}") @Override - public ResponseEntity delete(@PathVariable Long memesId) { + public ResponseEntity deleteMemes(@PathVariable Long memesId) { MemesServiceDto newMemesServiceDto = MemesServiceDto.create(memesId); memesService.delete(newMemesServiceDto); @@ -73,7 +73,7 @@ public ResponseEntity delete(@PathVariable Long memesId) { // 밈스 단일 조회 @GetMapping("/{memesId}") @Override - public ResponseEntity findOne(@PathVariable Long memesId) { + public ResponseEntity findMemes(@PathVariable Long memesId) { MemesServiceDto newMemesServiceDto = MemesServiceDto.create(memesId); MemesResponse newMemesResponse = memesService.findOne(newMemesServiceDto); @@ -83,7 +83,7 @@ public ResponseEntity findOne(@PathVariable Long memesId) { // 밈스 전체 조회 @GetMapping @Override - public ResponseEntity findAll(Pageable pageable) { + public ResponseEntity findAllMemes(Pageable pageable) { MemesListResponse memesListResponse = memesService.findAll(pageable); return ResponseEntity.status(HttpStatus.OK).body(memesListResponse); From 903871ae52041980b39ae941128edf539fb44882 Mon Sep 17 00:00:00 2001 From: JunRain Date: Tue, 7 May 2024 23:12:37 +0900 Subject: [PATCH 13/13] =?UTF-8?q?[#78]=20=EC=B5=9C=EC=8B=A0=20Memes=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=98=95=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/memes/controller/MemesApi.java | 16 +- .../memes/controller/MemesController.java | 149 +++++++++--------- .../memes/dto/{ => response}/MemesInfo.java | 2 +- .../dto/response/MemesInfoListResponse.java | 1 - .../domain/memes/service/MemesService.java | 2 +- .../memetory/global/response/ResultCode.java | 6 + 6 files changed, 91 insertions(+), 85 deletions(-) rename backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/{ => response}/MemesInfo.java (96%) diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java index e56455f7..0fbec3e7 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesApi.java @@ -1,13 +1,9 @@ package com.example.memetory.domain.memes.controller; import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import com.example.memetory.domain.memes.dto.request.GenerateMemesRequest; -import com.example.memetory.domain.memes.dto.response.MemesInfoListResponse; -import com.example.memetory.domain.memes.dto.response.MemesListResponse; -import com.example.memetory.domain.memes.dto.response.MemesResponse; import com.example.memetory.global.response.ResultResponse; import io.swagger.v3.oas.annotations.Operation; @@ -48,7 +44,7 @@ ResponseEntity register( description = "인기차트 조회" ) }) - ResponseEntity findTopMemesByLike(); + ResponseEntity findTopMemesByLike(); @Operation( summary = "meme`s 이달의 인기차트 조회", @@ -61,7 +57,7 @@ ResponseEntity register( description = "이달의 인기차트 조회" ) }) - ResponseEntity findTopMemesByLikeForMonth(); + ResponseEntity findTopMemesByLikeForMonth(); @Operation( summary = "meme`s 이주의 인기차트 조회", @@ -74,7 +70,7 @@ ResponseEntity register( description = "이주의 인기차트 조회" ) }) - ResponseEntity findTopMemesByLikeForWeek(); + ResponseEntity findTopMemesByLikeForWeek(); @Operation( summary = "meme`s 삭제", @@ -87,7 +83,7 @@ ResponseEntity register( description = "밈스 삭제" ) }) - ResponseEntity deleteMemes( + ResponseEntity deleteMemes( @Parameter(in = ParameterIn.PATH, description = "밈스 아이디", required = true) Long memesId ); @@ -102,7 +98,7 @@ ResponseEntity deleteMemes( description = "밈스 단일 조회" ) }) - ResponseEntity findMemes( + ResponseEntity findMemes( @Parameter(in = ParameterIn.PATH, description = "밈스 아이디", required = true) Long memesId ); @@ -117,5 +113,5 @@ ResponseEntity findMemes( description = "밈스 전체 조회" ) }) - ResponseEntity findAllMemes(Pageable pageable); + ResponseEntity findAllMemes(Pageable pageable); } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java index 00e1a634..8f2fd5b8 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/controller/MemesController.java @@ -2,6 +2,17 @@ import static com.example.memetory.global.response.ResultCode.*; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import com.example.memetory.domain.memes.dto.MemesServiceDto; import com.example.memetory.domain.memes.dto.request.GenerateMemesRequest; import com.example.memetory.domain.memes.dto.response.MemesInfoListResponse; @@ -12,80 +23,74 @@ import com.example.memetory.global.response.ResultResponse; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Pageable; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - @RestController @RequiredArgsConstructor @RequestMapping("/memes") -public class MemesController implements MemesApi{ - private final MemesService memesService; - - // 밈스 생성 - @PostMapping - @Override - public ResponseEntity register(@LoginMemberEmail String email, @RequestBody GenerateMemesRequest generateMemesRequest) { - MemesServiceDto memesServiceDto = generateMemesRequest.toServiceDto(email); - memesService.register(memesServiceDto); - return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_MEMES_SUCCESS)); - } - - // 밈스 좋아요 순으로 상위 10개 조회 - @GetMapping("/like/all") - @Override - public ResponseEntity findTopMemesByLike() { - MemesInfoListResponse newMemesInfoListResponse = memesService.findTopMemesByLike(); - - return ResponseEntity.status(HttpStatus.OK).body(newMemesInfoListResponse); - } - - // 최근 한 달 동안 생성된 밈스 중 좋아요 순으로 상위 10개 조회 - @GetMapping("/like/month") - @Override - public ResponseEntity findTopMemesByLikeForMonth() { - MemesInfoListResponse newMemesInfoListResponse = memesService.findTopMemesByLikeForMonth(); - - return ResponseEntity.status(HttpStatus.OK).body(newMemesInfoListResponse); - } - - // 최근 한 주 동안 생성된 밈스 중 좋아요 순으로 상위 10개 조회 - @GetMapping("/like/week") - @Override - public ResponseEntity findTopMemesByLikeForWeek() { - MemesInfoListResponse newMemesInfoListResponse = memesService.findTopMemesByLikeForWeek(); - - return ResponseEntity.status(HttpStatus.OK).body(newMemesInfoListResponse); - } - - // 밈스 삭제 - @DeleteMapping("/{memesId}") - @Override - public ResponseEntity deleteMemes(@PathVariable Long memesId) { - MemesServiceDto newMemesServiceDto = MemesServiceDto.create(memesId); - memesService.delete(newMemesServiceDto); - - return ResponseEntity.status(HttpStatus.OK).build(); - } - - // 밈스 단일 조회 - @GetMapping("/{memesId}") - @Override - public ResponseEntity findMemes(@PathVariable Long memesId) { - MemesServiceDto newMemesServiceDto = MemesServiceDto.create(memesId); - MemesResponse newMemesResponse = memesService.findOne(newMemesServiceDto); - - return ResponseEntity.status(HttpStatus.OK).body(newMemesResponse); - } - - // 밈스 전체 조회 - @GetMapping - @Override - public ResponseEntity findAllMemes(Pageable pageable) { - MemesListResponse memesListResponse = memesService.findAll(pageable); - - return ResponseEntity.status(HttpStatus.OK).body(memesListResponse); - } +public class MemesController implements MemesApi { + private final MemesService memesService; + + // 밈스 생성 + @PostMapping + @Override + public ResponseEntity register(@LoginMemberEmail String email, + @RequestBody GenerateMemesRequest generateMemesRequest) { + memesService.register(generateMemesRequest.toServiceDto(email)); + + return ResponseEntity.status(HttpStatus.CREATED).body(ResultResponse.of(CREATE_MEMES_SUCCESS)); + } + + // 밈스 좋아요 순으로 상위 10개 조회 + @GetMapping("/like/all") + @Override + public ResponseEntity findTopMemesByLike() { + MemesInfoListResponse response = memesService.findTopMemesByLike(); + + return ResponseEntity.ok(ResultResponse.of(GET_TOP_TEN_MEMES_SUCCESS, response)); + } + + // 최근 한 달 동안 생성된 밈스 중 좋아요 순으로 상위 10개 조회 + @GetMapping("/like/month") + @Override + public ResponseEntity findTopMemesByLikeForMonth() { + MemesInfoListResponse response = memesService.findTopMemesByLikeForMonth(); + + return ResponseEntity.ok(ResultResponse.of(GET_MONTH_TOP_TEN_MEMES_SUCCESS, response)); + } + + // 최근 한 주 동안 생성된 밈스 중 좋아요 순으로 상위 10개 조회 + @GetMapping("/like/week") + @Override + public ResponseEntity findTopMemesByLikeForWeek() { + MemesInfoListResponse response = memesService.findTopMemesByLikeForWeek(); + + return ResponseEntity.ok(ResultResponse.of(GET_WEEK_TOP_TEN_MEMES_SUCCESS, response)); + } + + // 밈스 삭제 -> 다른 유저가 삭제할 수 있음 + @DeleteMapping("/{memesId}") + @Override + public ResponseEntity deleteMemes(@PathVariable Long memesId) { + memesService.delete(MemesServiceDto.create(memesId)); + + return ResponseEntity.ok(ResultResponse.of(DELETE_MEMES_SUCCESS)); + } + + // 밈스 단일 조회? 밈스 상세 조회? + @GetMapping("/{memesId}") + @Override + public ResponseEntity findMemes(@PathVariable Long memesId) { + MemesResponse response = memesService.findOne(MemesServiceDto.create(memesId)); + + return ResponseEntity.ok(ResultResponse.of(GET_ONE_MEMES_SUCCESS, response)); + } + + // 밈스 전체 조회 + @GetMapping + @Override + public ResponseEntity findAllMemes(Pageable pageable) { + MemesListResponse response = memesService.findAll(pageable); + + return ResponseEntity.ok(ResultResponse.of(GET_ALL_MEMES_SUCCESS, response)); + } } diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/MemesInfo.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfo.java similarity index 96% rename from backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/MemesInfo.java rename to backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfo.java index 29ec755f..9d35bb1f 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/MemesInfo.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfo.java @@ -1,4 +1,4 @@ -package com.example.memetory.domain.memes.dto; +package com.example.memetory.domain.memes.dto.response; import java.time.LocalDateTime; diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfoListResponse.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfoListResponse.java index 33a49ff6..619a4d60 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfoListResponse.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/dto/response/MemesInfoListResponse.java @@ -1,6 +1,5 @@ package com.example.memetory.domain.memes.dto.response; -import com.example.memetory.domain.memes.dto.MemesInfo; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Builder; import lombok.Getter; diff --git a/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java b/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java index ece02970..75b3a4df 100644 --- a/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java +++ b/backend/memetory/src/main/java/com/example/memetory/domain/memes/service/MemesService.java @@ -14,7 +14,7 @@ import com.example.memetory.domain.member.service.MemberService; import com.example.memetory.domain.meme.entity.Meme; import com.example.memetory.domain.meme.service.MemeService; -import com.example.memetory.domain.memes.dto.MemesInfo; +import com.example.memetory.domain.memes.dto.response.MemesInfo; import com.example.memetory.domain.memes.dto.MemesServiceDto; import com.example.memetory.domain.memes.dto.response.MemesInfoListResponse; import com.example.memetory.domain.memes.dto.response.MemesListResponse; diff --git a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java index 635feffe..59525dc6 100644 --- a/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java +++ b/backend/memetory/src/main/java/com/example/memetory/global/response/ResultCode.java @@ -17,6 +17,12 @@ public enum ResultCode { // memes CREATE_MEMES_SUCCESS(201, "밈스 생성 성공"), + GET_ONE_MEMES_SUCCESS(200, "단일 밈스 조회 성공"), + GET_TOP_TEN_MEMES_SUCCESS(200, "Top 10 밈스 조회 성공"), + GET_MONTH_TOP_TEN_MEMES_SUCCESS(200, "월별 Top 10 밈스 조회 성공"), + GET_WEEK_TOP_TEN_MEMES_SUCCESS(200, "주별 Top 10 밈스 조회 성공"), + GET_ALL_MEMES_SUCCESS(200, "전체 밈스 조회 성공"), + DELETE_MEMES_SUCCESS(200, "밈스 삭제 성공"), // like CREATE_LIKE_SUCCESS(201, "좋아요 생성 성공"),