From 65ebd1b3b66e796496f66ffb3cfc4afab33e3737 Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 18:47:04 +0900 Subject: [PATCH 01/39] =?UTF-8?q?feat:=20(common)=20Mapstruct=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 8bf3f6c36..2a59c153d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,13 +47,17 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-core:2.11.3' implementation 'com.fasterxml.jackson.core:jackson-databind:2.11.3' - // Lombok + // Lombok: 보일러플레이트 코드를 어노테이션을 통해 줄여주는 라이브러리 compileOnly 'org.projectlombok:lombok:1.18.16' annotationProcessor 'org.projectlombok:lombok:1.18.16' // DozerMapper implementation 'com.github.dozermapper:dozer-core:6.4.0' + // Mapstruct: 어노테이션 프로세서를 사용하여 객체 간 Mapping을 도와주는 라이브러리 + implementation 'org.mapstruct:mapstruct:1.5.3.Final' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.3.Final' + // JWT implementation 'io.jsonwebtoken:jjwt-api:0.11.2' runtime 'io.jsonwebtoken:jjwt-impl:0.11.2' From 2f8740fbbc15b07ca3129c3d56228f5d7160022d Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 18:59:21 +0900 Subject: [PATCH 02/39] =?UTF-8?q?refactor:=20(common)=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=84=EB=A1=9C=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{controllers => }/HelloController.java | 2 +- .../{dto => common/exception}/ErrorResponse.java | 2 +- .../exception/GlobalExceptionHandler.java} | 11 +++++------ .../application/ProductService.java | 10 +++++----- .../assignment/{ => product}/domain/Product.java | 2 +- .../{ => product}/domain/ProductRepository.java | 2 +- .../exception}/ProductNotFoundException.java | 2 +- .../infra/JpaProductRepository.java | 6 +++--- .../presentation}/ProductController.java | 8 ++++---- .../presentation}/dto/ProductData.java | 2 +- .../{ => user}/application/UserService.java | 16 ++++++++-------- .../assignment/{ => user}/domain/User.java | 2 +- .../{ => user}/domain/UserRepository.java | 2 +- .../UserEmailDuplicationException.java | 2 +- .../exception}/UserNotFoundException.java | 2 +- .../{ => user}/infra/JpaUserRepository.java | 6 +++--- .../presentation}/UserController.java | 12 ++++++------ .../presentation}/dto/UserModificationData.java | 2 +- .../presentation}/dto/UserRegistrationData.java | 2 +- .../presentation}/dto/UserResultData.java | 2 +- .../{controllers => }/HelloControllerTest.java | 2 +- .../application/ProductServiceTest.java | 10 +++++----- .../{ => product}/domain/ProductTest.java | 2 +- .../presentation}/ProductControllerTest.java | 10 +++++----- .../{ => user}/application/UserServiceTest.java | 16 ++++++++-------- .../assignment/{ => user}/domain/UserTest.java | 2 +- .../presentation}/UserControllerTest.java | 12 ++++++------ 27 files changed, 74 insertions(+), 75 deletions(-) rename app/src/main/java/com/codesoom/assignment/{controllers => }/HelloController.java (85%) rename app/src/main/java/com/codesoom/assignment/{dto => common/exception}/ErrorResponse.java (80%) rename app/src/main/java/com/codesoom/assignment/{controllers/ControllerErrorAdvice.java => common/exception/GlobalExceptionHandler.java} (75%) rename app/src/main/java/com/codesoom/assignment/{ => product}/application/ProductService.java (81%) rename app/src/main/java/com/codesoom/assignment/{ => product}/domain/Product.java (95%) rename app/src/main/java/com/codesoom/assignment/{ => product}/domain/ProductRepository.java (82%) rename app/src/main/java/com/codesoom/assignment/{errors => product/exception}/ProductNotFoundException.java (76%) rename app/src/main/java/com/codesoom/assignment/{ => product}/infra/JpaProductRepository.java (68%) rename app/src/main/java/com/codesoom/assignment/{controllers => product/presentation}/ProductController.java (83%) rename app/src/main/java/com/codesoom/assignment/{ => product/presentation}/dto/ProductData.java (89%) rename app/src/main/java/com/codesoom/assignment/{ => user}/application/UserService.java (74%) rename app/src/main/java/com/codesoom/assignment/{ => user}/domain/User.java (94%) rename app/src/main/java/com/codesoom/assignment/{ => user}/domain/UserRepository.java (85%) rename app/src/main/java/com/codesoom/assignment/{errors => user/exception}/UserEmailDuplicationException.java (80%) rename app/src/main/java/com/codesoom/assignment/{errors => user/exception}/UserNotFoundException.java (76%) rename app/src/main/java/com/codesoom/assignment/{ => user}/infra/JpaUserRepository.java (72%) rename app/src/main/java/com/codesoom/assignment/{controllers => user/presentation}/UserController.java (77%) rename app/src/main/java/com/codesoom/assignment/{ => user/presentation}/dto/UserModificationData.java (90%) rename app/src/main/java/com/codesoom/assignment/{ => user/presentation}/dto/UserRegistrationData.java (91%) rename app/src/main/java/com/codesoom/assignment/{ => user/presentation}/dto/UserResultData.java (80%) rename app/src/test/java/com/codesoom/assignment/{controllers => }/HelloControllerTest.java (86%) rename app/src/test/java/com/codesoom/assignment/{ => product}/application/ProductServiceTest.java (92%) rename app/src/test/java/com/codesoom/assignment/{ => product}/domain/ProductTest.java (96%) rename app/src/test/java/com/codesoom/assignment/{controllers => product/presentation}/ProductControllerTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{ => user}/application/UserServiceTest.java (92%) rename app/src/test/java/com/codesoom/assignment/{ => user}/domain/UserTest.java (96%) rename app/src/test/java/com/codesoom/assignment/{controllers => user/presentation}/UserControllerTest.java (93%) diff --git a/app/src/main/java/com/codesoom/assignment/controllers/HelloController.java b/app/src/main/java/com/codesoom/assignment/HelloController.java similarity index 85% rename from app/src/main/java/com/codesoom/assignment/controllers/HelloController.java rename to app/src/main/java/com/codesoom/assignment/HelloController.java index 52d536c2d..42b03e93e 100644 --- a/app/src/main/java/com/codesoom/assignment/controllers/HelloController.java +++ b/app/src/main/java/com/codesoom/assignment/HelloController.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/app/src/main/java/com/codesoom/assignment/dto/ErrorResponse.java b/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java similarity index 80% rename from app/src/main/java/com/codesoom/assignment/dto/ErrorResponse.java rename to app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java index aa329697e..ac553c7cc 100644 --- a/app/src/main/java/com/codesoom/assignment/dto/ErrorResponse.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.dto; +package com.codesoom.assignment.common.exception; public class ErrorResponse { private String message; diff --git a/app/src/main/java/com/codesoom/assignment/controllers/ControllerErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java similarity index 75% rename from app/src/main/java/com/codesoom/assignment/controllers/ControllerErrorAdvice.java rename to app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java index 099939d4e..0976ed619 100644 --- a/app/src/main/java/com/codesoom/assignment/controllers/ControllerErrorAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java @@ -1,9 +1,8 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment.common.exception; -import com.codesoom.assignment.dto.ErrorResponse; -import com.codesoom.assignment.errors.ProductNotFoundException; -import com.codesoom.assignment.errors.UserEmailDuplicationException; -import com.codesoom.assignment.errors.UserNotFoundException; +import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.user.exception.UserNotFoundException; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -12,7 +11,7 @@ @ResponseBody @ControllerAdvice -public class ControllerErrorAdvice { +public class GlobalExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(ProductNotFoundException.class) public ErrorResponse handleProductNotFound() { diff --git a/app/src/main/java/com/codesoom/assignment/application/ProductService.java b/app/src/main/java/com/codesoom/assignment/product/application/ProductService.java similarity index 81% rename from app/src/main/java/com/codesoom/assignment/application/ProductService.java rename to app/src/main/java/com/codesoom/assignment/product/application/ProductService.java index 921337bdf..532bf88b1 100644 --- a/app/src/main/java/com/codesoom/assignment/application/ProductService.java +++ b/app/src/main/java/com/codesoom/assignment/product/application/ProductService.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.application; +package com.codesoom.assignment.product.application; -import com.codesoom.assignment.domain.Product; -import com.codesoom.assignment.domain.ProductRepository; -import com.codesoom.assignment.dto.ProductData; -import com.codesoom.assignment.errors.ProductNotFoundException; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.domain.ProductRepository; +import com.codesoom.assignment.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.exception.ProductNotFoundException; import com.github.dozermapper.core.Mapper; import org.springframework.stereotype.Service; diff --git a/app/src/main/java/com/codesoom/assignment/domain/Product.java b/app/src/main/java/com/codesoom/assignment/product/domain/Product.java similarity index 95% rename from app/src/main/java/com/codesoom/assignment/domain/Product.java rename to app/src/main/java/com/codesoom/assignment/product/domain/Product.java index 2a6c959ad..87fe9214c 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/Product.java +++ b/app/src/main/java/com/codesoom/assignment/product/domain/Product.java @@ -14,7 +14,7 @@ // 3. 가격 - 5,000원 (판매가) // 4. 이미지 - static, CDN => image URL -package com.codesoom.assignment.domain; +package com.codesoom.assignment.product.domain; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/domain/ProductRepository.java b/app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java similarity index 82% rename from app/src/main/java/com/codesoom/assignment/domain/ProductRepository.java rename to app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java index 15064c487..44082966e 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/ProductRepository.java +++ b/app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain; +package com.codesoom.assignment.product.domain; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/errors/ProductNotFoundException.java b/app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java similarity index 76% rename from app/src/main/java/com/codesoom/assignment/errors/ProductNotFoundException.java rename to app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java index 9ad39fa30..f962b0e4f 100644 --- a/app/src/main/java/com/codesoom/assignment/errors/ProductNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.errors; +package com.codesoom.assignment.product.exception; public class ProductNotFoundException extends RuntimeException { public ProductNotFoundException(Long id) { diff --git a/app/src/main/java/com/codesoom/assignment/infra/JpaProductRepository.java b/app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java similarity index 68% rename from app/src/main/java/com/codesoom/assignment/infra/JpaProductRepository.java rename to app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java index ebe972bf3..05b32a803 100644 --- a/app/src/main/java/com/codesoom/assignment/infra/JpaProductRepository.java +++ b/app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java @@ -1,7 +1,7 @@ -package com.codesoom.assignment.infra; +package com.codesoom.assignment.product.infra; -import com.codesoom.assignment.domain.Product; -import com.codesoom.assignment.domain.ProductRepository; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.domain.ProductRepository; import org.springframework.data.repository.CrudRepository; import java.util.List; diff --git a/app/src/main/java/com/codesoom/assignment/controllers/ProductController.java b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java similarity index 83% rename from app/src/main/java/com/codesoom/assignment/controllers/ProductController.java rename to app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java index 49c2a8ac7..c50e96236 100644 --- a/app/src/main/java/com/codesoom/assignment/controllers/ProductController.java +++ b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java @@ -1,8 +1,8 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment.product.presentation; -import com.codesoom.assignment.application.ProductService; -import com.codesoom.assignment.domain.Product; -import com.codesoom.assignment.dto.ProductData; +import com.codesoom.assignment.product.application.ProductService; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.presentation.dto.ProductData; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/app/src/main/java/com/codesoom/assignment/dto/ProductData.java b/app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java similarity index 89% rename from app/src/main/java/com/codesoom/assignment/dto/ProductData.java rename to app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java index eea73cb08..d9bd6d451 100644 --- a/app/src/main/java/com/codesoom/assignment/dto/ProductData.java +++ b/app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.dto; +package com.codesoom.assignment.product.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.*; diff --git a/app/src/main/java/com/codesoom/assignment/application/UserService.java b/app/src/main/java/com/codesoom/assignment/user/application/UserService.java similarity index 74% rename from app/src/main/java/com/codesoom/assignment/application/UserService.java rename to app/src/main/java/com/codesoom/assignment/user/application/UserService.java index 99eb0260e..e1c45f71a 100644 --- a/app/src/main/java/com/codesoom/assignment/application/UserService.java +++ b/app/src/main/java/com/codesoom/assignment/user/application/UserService.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.application; - -import com.codesoom.assignment.domain.User; -import com.codesoom.assignment.domain.UserRepository; -import com.codesoom.assignment.dto.UserModificationData; -import com.codesoom.assignment.dto.UserRegistrationData; -import com.codesoom.assignment.errors.UserEmailDuplicationException; -import com.codesoom.assignment.errors.UserNotFoundException; +package com.codesoom.assignment.user.application; + +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.user.exception.UserNotFoundException; import com.github.dozermapper.core.Mapper; import org.springframework.stereotype.Service; diff --git a/app/src/main/java/com/codesoom/assignment/domain/User.java b/app/src/main/java/com/codesoom/assignment/user/domain/User.java similarity index 94% rename from app/src/main/java/com/codesoom/assignment/domain/User.java rename to app/src/main/java/com/codesoom/assignment/user/domain/User.java index c2299bcf1..1c3b1562f 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/User.java +++ b/app/src/main/java/com/codesoom/assignment/user/domain/User.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain; +package com.codesoom.assignment.user.domain; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/domain/UserRepository.java b/app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java similarity index 85% rename from app/src/main/java/com/codesoom/assignment/domain/UserRepository.java rename to app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java index 995d6395a..dc5c096f3 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/UserRepository.java +++ b/app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain; +package com.codesoom.assignment.user.domain; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/errors/UserEmailDuplicationException.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java similarity index 80% rename from app/src/main/java/com/codesoom/assignment/errors/UserEmailDuplicationException.java rename to app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java index 7f0788b62..ed54c6ae2 100644 --- a/app/src/main/java/com/codesoom/assignment/errors/UserEmailDuplicationException.java +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.errors; +package com.codesoom.assignment.user.exception; public class UserEmailDuplicationException extends RuntimeException { public UserEmailDuplicationException(String email) { diff --git a/app/src/main/java/com/codesoom/assignment/errors/UserNotFoundException.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java similarity index 76% rename from app/src/main/java/com/codesoom/assignment/errors/UserNotFoundException.java rename to app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java index 870dfd123..26df1e09f 100644 --- a/app/src/main/java/com/codesoom/assignment/errors/UserNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.errors; +package com.codesoom.assignment.user.exception; public class UserNotFoundException extends RuntimeException { public UserNotFoundException(Long id) { diff --git a/app/src/main/java/com/codesoom/assignment/infra/JpaUserRepository.java b/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java similarity index 72% rename from app/src/main/java/com/codesoom/assignment/infra/JpaUserRepository.java rename to app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java index 7e8205836..2d13a9534 100644 --- a/app/src/main/java/com/codesoom/assignment/infra/JpaUserRepository.java +++ b/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java @@ -1,7 +1,7 @@ -package com.codesoom.assignment.infra; +package com.codesoom.assignment.user.infra; -import com.codesoom.assignment.domain.User; -import com.codesoom.assignment.domain.UserRepository; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; import org.springframework.data.repository.CrudRepository; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/controllers/UserController.java b/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java similarity index 77% rename from app/src/main/java/com/codesoom/assignment/controllers/UserController.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java index 0600bef45..687511d53 100644 --- a/app/src/main/java/com/codesoom/assignment/controllers/UserController.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java @@ -1,10 +1,10 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment.user.presentation; -import com.codesoom.assignment.application.UserService; -import com.codesoom.assignment.domain.User; -import com.codesoom.assignment.dto.UserModificationData; -import com.codesoom.assignment.dto.UserRegistrationData; -import com.codesoom.assignment.dto.UserResultData; +import com.codesoom.assignment.user.application.UserService; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.user.presentation.dto.UserResultData; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; diff --git a/app/src/main/java/com/codesoom/assignment/dto/UserModificationData.java b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java similarity index 90% rename from app/src/main/java/com/codesoom/assignment/dto/UserModificationData.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java index 3b1e8e76c..5fc387cff 100644 --- a/app/src/main/java/com/codesoom/assignment/dto/UserModificationData.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.dto; +package com.codesoom.assignment.user.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/com/codesoom/assignment/dto/UserRegistrationData.java b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java similarity index 91% rename from app/src/main/java/com/codesoom/assignment/dto/UserRegistrationData.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java index 2ed7eb699..428c32f77 100644 --- a/app/src/main/java/com/codesoom/assignment/dto/UserRegistrationData.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.dto; +package com.codesoom.assignment.user.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/com/codesoom/assignment/dto/UserResultData.java b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java similarity index 80% rename from app/src/main/java/com/codesoom/assignment/dto/UserResultData.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java index bde8acca3..f295e5046 100644 --- a/app/src/main/java/com/codesoom/assignment/dto/UserResultData.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.dto; +package com.codesoom.assignment.user.presentation.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/test/java/com/codesoom/assignment/controllers/HelloControllerTest.java b/app/src/test/java/com/codesoom/assignment/HelloControllerTest.java similarity index 86% rename from app/src/test/java/com/codesoom/assignment/controllers/HelloControllerTest.java rename to app/src/test/java/com/codesoom/assignment/HelloControllerTest.java index b0b8bc8ee..81fe6bf7b 100644 --- a/app/src/test/java/com/codesoom/assignment/controllers/HelloControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/HelloControllerTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/application/ProductServiceTest.java b/app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java similarity index 92% rename from app/src/test/java/com/codesoom/assignment/application/ProductServiceTest.java rename to app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java index fca677f4e..106a836d6 100644 --- a/app/src/test/java/com/codesoom/assignment/application/ProductServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.application; +package com.codesoom.assignment.product.application; -import com.codesoom.assignment.domain.Product; -import com.codesoom.assignment.domain.ProductRepository; -import com.codesoom.assignment.dto.ProductData; -import com.codesoom.assignment.errors.ProductNotFoundException; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.domain.ProductRepository; +import com.codesoom.assignment.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.exception.ProductNotFoundException; import com.github.dozermapper.core.DozerBeanMapperBuilder; import com.github.dozermapper.core.Mapper; import org.junit.jupiter.api.BeforeEach; diff --git a/app/src/test/java/com/codesoom/assignment/domain/ProductTest.java b/app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java similarity index 96% rename from app/src/test/java/com/codesoom/assignment/domain/ProductTest.java rename to app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java index 581f5c845..652060808 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/ProductTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain; +package com.codesoom.assignment.product.domain; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/controllers/ProductControllerTest.java b/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/controllers/ProductControllerTest.java rename to app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java index a387bea09..7074f6f80 100644 --- a/app/src/test/java/com/codesoom/assignment/controllers/ProductControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment.product.presentation; -import com.codesoom.assignment.application.ProductService; -import com.codesoom.assignment.domain.Product; -import com.codesoom.assignment.dto.ProductData; -import com.codesoom.assignment.errors.ProductNotFoundException; +import com.codesoom.assignment.product.application.ProductService; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.exception.ProductNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/app/src/test/java/com/codesoom/assignment/application/UserServiceTest.java b/app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java similarity index 92% rename from app/src/test/java/com/codesoom/assignment/application/UserServiceTest.java rename to app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java index 4b85229c0..d9794876e 100644 --- a/app/src/test/java/com/codesoom/assignment/application/UserServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.application; - -import com.codesoom.assignment.domain.User; -import com.codesoom.assignment.domain.UserRepository; -import com.codesoom.assignment.dto.UserModificationData; -import com.codesoom.assignment.dto.UserRegistrationData; -import com.codesoom.assignment.errors.UserEmailDuplicationException; -import com.codesoom.assignment.errors.UserNotFoundException; +package com.codesoom.assignment.user.application; + +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.user.exception.UserNotFoundException; import com.github.dozermapper.core.DozerBeanMapperBuilder; import com.github.dozermapper.core.Mapper; import org.junit.jupiter.api.BeforeEach; diff --git a/app/src/test/java/com/codesoom/assignment/domain/UserTest.java b/app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java similarity index 96% rename from app/src/test/java/com/codesoom/assignment/domain/UserTest.java rename to app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java index f9950e612..097cdae82 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/UserTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain; +package com.codesoom.assignment.user.domain; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/controllers/UserControllerTest.java b/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java similarity index 93% rename from app/src/test/java/com/codesoom/assignment/controllers/UserControllerTest.java rename to app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java index 0cd048cc5..d1ca7bf08 100644 --- a/app/src/test/java/com/codesoom/assignment/controllers/UserControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java @@ -1,10 +1,10 @@ -package com.codesoom.assignment.controllers; +package com.codesoom.assignment.user.presentation; -import com.codesoom.assignment.application.UserService; -import com.codesoom.assignment.domain.User; -import com.codesoom.assignment.dto.UserModificationData; -import com.codesoom.assignment.dto.UserRegistrationData; -import com.codesoom.assignment.errors.UserNotFoundException; +import com.codesoom.assignment.user.application.UserService; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; From 97afaf6a478d76c0dfe6cf87d886c0c5c142cb20 Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 19:17:03 +0900 Subject: [PATCH 03/39] =?UTF-8?q?refactor:=20(common)=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=B3=84=20=EC=98=88=EC=99=B8=20=ED=95=B8=EB=93=A4?= =?UTF-8?q?=EB=A7=81=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/ErrorResponse.java | 14 ++++++-- .../exception/GlobalExceptionHandler.java | 35 +++++++++---------- .../exception/ProductControllerAdvice.java | 20 +++++++++++ .../exception/ProductExceptionHandler.java | 16 +++++++++ .../presentation/ProductController.java | 6 +++- .../user/exception/UserControllerAdvice.java | 20 +++++++++++ .../user/exception/UserExceptionHandler.java | 22 ++++++++++++ 7 files changed, 112 insertions(+), 21 deletions(-) create mode 100644 app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java create mode 100644 app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java create mode 100644 app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java create mode 100644 app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java diff --git a/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java b/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java index ac553c7cc..a8eea17bf 100644 --- a/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java @@ -1,5 +1,12 @@ package com.codesoom.assignment.common.exception; +import lombok.Getter; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.web.bind.MethodArgumentNotValidException; + +import java.util.stream.Collectors; + +@Getter public class ErrorResponse { private String message; @@ -7,7 +14,10 @@ public ErrorResponse(String message) { this.message = message; } - public String getMessage() { - return message; + public static ErrorResponse from(final MethodArgumentNotValidException exception) { + return new ErrorResponse(exception.getBindingResult().getFieldErrors() + .stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage) + .collect(Collectors.toList()).toString()); } } diff --git a/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java index 0976ed619..7a9ee8d24 100644 --- a/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java @@ -1,32 +1,31 @@ package com.codesoom.assignment.common.exception; -import com.codesoom.assignment.product.exception.ProductNotFoundException; -import com.codesoom.assignment.user.exception.UserEmailDuplicationException; -import com.codesoom.assignment.user.exception.UserNotFoundException; +import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @ResponseBody @ControllerAdvice -public class GlobalExceptionHandler { - @ResponseStatus(HttpStatus.NOT_FOUND) - @ExceptionHandler(ProductNotFoundException.class) - public ErrorResponse handleProductNotFound() { - return new ErrorResponse("Product not found"); +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { + @ExceptionHandler(value = {Exception.class}) + @ResponseStatus + public ErrorResponse handleException(final Exception exception) { + return new ErrorResponse(exception.getMessage()); } - @ResponseStatus(HttpStatus.NOT_FOUND) - @ExceptionHandler(UserNotFoundException.class) - public ErrorResponse handleUserNotFound() { - return new ErrorResponse("User not found"); - } - - @ResponseStatus(HttpStatus.BAD_REQUEST) - @ExceptionHandler(UserEmailDuplicationException.class) - public ErrorResponse handleUserEmailIsAlreadyExisted() { - return new ErrorResponse("User's email address is already existed"); + @Override + protected ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException exception, + HttpHeaders headers, HttpStatus status, WebRequest request) { + return ResponseEntity + .status(HttpStatus.BAD_REQUEST) + .body(ErrorResponse.from(exception)); } } diff --git a/app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java b/app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java new file mode 100644 index 000000000..39d238e8e --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java @@ -0,0 +1,20 @@ +package com.codesoom.assignment.product.exception; + +import com.codesoom.assignment.product.presentation.ProductController; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@RestControllerAdvice(basePackageClasses = { + ProductController.class +}) +@Order(Ordered.HIGHEST_PRECEDENCE) +public @interface ProductControllerAdvice { +} diff --git a/app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java new file mode 100644 index 000000000..816967e55 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java @@ -0,0 +1,16 @@ +package com.codesoom.assignment.product.exception; + +import com.codesoom.assignment.common.exception.ErrorResponse; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +@ProductControllerAdvice +public class ProductExceptionHandler { + + @ResponseStatus(HttpStatus.NOT_FOUND) + @ExceptionHandler(ProductNotFoundException.class) + public ErrorResponse handleProductNotFound() { + return new ErrorResponse("Product not found"); + } +} diff --git a/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java index c50e96236..c53c06450 100644 --- a/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java +++ b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java @@ -25,7 +25,11 @@ public List list() { } @GetMapping("{id}") - public Product detail(@PathVariable Long id) { + public Product detail(@PathVariable Long id) throws Exception { + if (id == 3L) { + throw new Exception(); + } + return productService.getProduct(id); } diff --git a/app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java new file mode 100644 index 000000000..a6d8c7aef --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java @@ -0,0 +1,20 @@ +package com.codesoom.assignment.user.exception; + +import com.codesoom.assignment.user.presentation.UserController; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@RestControllerAdvice(basePackageClasses = { + UserController.class +}) +@Order(Ordered.HIGHEST_PRECEDENCE) +public @interface UserControllerAdvice { +} diff --git a/app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java new file mode 100644 index 000000000..964b9fa07 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java @@ -0,0 +1,22 @@ +package com.codesoom.assignment.user.exception; + +import com.codesoom.assignment.common.exception.ErrorResponse; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +@UserControllerAdvice +public class UserExceptionHandler { + + @ResponseStatus(HttpStatus.NOT_FOUND) + @ExceptionHandler(UserNotFoundException.class) + public ErrorResponse handleUserNotFound() { + return new ErrorResponse("User not found"); + } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(UserEmailDuplicationException.class) + public ErrorResponse handleUserEmailIsAlreadyExisted() { + return new ErrorResponse("User's email address is already existed"); + } +} From fa8fe31f92aebc2e20439a82e78f9a97806db88e Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 20:04:48 +0900 Subject: [PATCH 04/39] =?UTF-8?q?feat:=20(common)=20Jackson=20=EB=9D=BC?= =?UTF-8?q?=EC=9D=B4=EB=B8=8C=EB=9F=AC=EB=A6=AC=EB=A5=BC=20=ED=86=B5?= =?UTF-8?q?=ED=95=9C=20JsonUtil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/common/util/JsonUtil.java | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 app/src/main/java/com/codesoom/assignment/common/util/JsonUtil.java diff --git a/app/src/main/java/com/codesoom/assignment/common/util/JsonUtil.java b/app/src/main/java/com/codesoom/assignment/common/util/JsonUtil.java new file mode 100644 index 000000000..6baaafc90 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/util/JsonUtil.java @@ -0,0 +1,39 @@ +package com.codesoom.assignment.common.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class JsonUtil { + private static final ObjectMapper objectMapper = new ObjectMapper(); + + /** + * 주어진 JSON 콘텐츠 문자열에서 JSON 콘텐츠를 역직렬화하여 객체에 담아 리턴합니다. + * + * @param json 역직렬화 할 JSON 문자열 + * @param classType 역직렬화 한 문자열을 담을 객체 타입 + * @param element의 타입 + * @return Json 문자열을 역직렬화하여 객체로 리턴 + * @throws JsonProcessingException JSON 콘텐츠 문자열을 파싱, 생성할 때 문제가 발생할 경우 + */ + public static T readValue(final String json, Class classType) throws JsonProcessingException { + return objectMapper.readValue(json, classType); + } + + /** + * 객체의 값을 JSON 출력으로 직렬화하여 문자열로 리턴합니다, + * + * @param object 직렬화 할 객체 + * @param element의 타입 + * @return 객체를 Json 출력으로 직렬화 한 문자열 리턴 + * @throws IOException 새로운 출력 스트림을 생성할 때 문제가 발생할 경우 + */ + public static String writeValue(final T object) throws IOException { + OutputStream outputStream = new ByteArrayOutputStream(); + objectMapper.writeValue(outputStream, object); + return outputStream.toString(); + } +} From a9e167d66c7b626ed1d58f7f1779c7323b2ac239 Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 20:05:29 +0900 Subject: [PATCH 05/39] =?UTF-8?q?feat:=20(common)=20MockMvc=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EA=B2=B0=EA=B3=BC=20=EA=B0=92=EC=9D=98=20?= =?UTF-8?q?CharacterEncoding=EC=9D=84=20UTF-8=EB=A1=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MockMvcCharacterEncodingCustomizer.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java diff --git a/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java b/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java new file mode 100644 index 000000000..e3a8d4b0a --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java @@ -0,0 +1,23 @@ +package com.codesoom.assignment; + +import org.springframework.boot.test.autoconfigure.web.servlet.MockMvcBuilderCustomizer; +import org.springframework.stereotype.Component; +import org.springframework.test.web.servlet.setup.ConfigurableMockMvcBuilder; + +import java.nio.charset.StandardCharsets; + + +// Spring 5.2 / Spring Boot 2.2 부터는 charset을 사용하지 않으며, 기본 인코딩 문자도 더 이상 UTF-8이 아닙니다. +// Ref: https://github.com/spring-projects/spring-framework/issues/22788 + +/** + * MockMvc 테스트 결과값의 CharacterEncoding을 UTF-8로 설정합니다. + * 기본적으로 @AutoconfigureMockMvc를 통해 주입받는 상황에서만 적용됩니다. + */ +@Component +class MockMvcCharacterEncodingCustomizer implements MockMvcBuilderCustomizer { + @Override + public void customize(ConfigurableMockMvcBuilder builder) { + builder.alwaysDo(result -> result.getResponse().setCharacterEncoding(StandardCharsets.UTF_8.name())); + } +} From 6531d5c70818629711343ee329087e74270fed53 Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 20:20:39 +0900 Subject: [PATCH 06/39] =?UTF-8?q?test:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=84=B1=EA=B3=B5=20=EC=8B=9C=20?= =?UTF-8?q?201=20=EC=BD=94=EB=93=9C=20=EB=B0=98=ED=99=98=20=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/dto/SessionRequestDto.java | 21 ++++++ .../session/SessionControllerTest.java | 68 +++++++++++++++++++ .../assignment/support/LoginFixture.java | 32 +++++++++ 3 files changed, 121 insertions(+) create mode 100644 app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java create mode 100644 app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java create mode 100644 app/src/test/java/com/codesoom/assignment/support/LoginFixture.java diff --git a/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java b/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java new file mode 100644 index 000000000..9554a9f28 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java @@ -0,0 +1,21 @@ +package com.codesoom.assignment.session.dto; + +import lombok.Builder; +import lombok.Getter; + +import javax.validation.constraints.NotBlank; + +@Getter +public class SessionRequestDto { + @NotBlank(message = "이메일을 입력하세요") + private final String email; + + @NotBlank(message = "비밀번호를 입력하세요") + private final String password; + + @Builder + public SessionRequestDto(String email, String password) { + this.email = email; + this.password = password; + } +} diff --git a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java new file mode 100644 index 000000000..b0867f835 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java @@ -0,0 +1,68 @@ +package com.codesoom.assignment.session; + +import com.codesoom.assignment.common.util.JsonUtil; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static com.codesoom.assignment.support.LoginFixture.LOGIN_VALID; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/* + 세션 등록 -> POST /session +*/ +@SpringBootTest +@AutoConfigureMockMvc +@DisplayName("SessionController 웹 테스트") +class SessionControllerTest { + private final MockMvc mockMvc; + private final SessionController sessionController; + + @Autowired + SessionControllerTest(MockMvc mockMvc, SessionController sessionController) { + this.mockMvc = mockMvc; + this.sessionController = sessionController; + } + + /* + 로그인 API는 + - 유효한 회원 정보가 주어지면 + - 세션 토큰을 헤더로 반환한다. 201 + - 유효하지 않는 회원 정보가 주어지면 + - 빈 값이 주어질 경우 + - 예외를 던진다 (@Valid : 400) + - 찾을 수 없는 Email일 경우 + - 예외를 던진다 (UserNotFoundException : 404) + - 비밀번호가 틀렸을 경우 + - 예외를 던진다 (InvalidUserPasswordException : 400) + */ + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class 로그인_API는 { + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class 유효한_회원_정보가_주어지면 { + @Test + @DisplayName("세션 토큰을 헤더로 반환한다.") + void it_returns_session() throws Exception { + mockMvc.perform( + post("/session") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(LOGIN_VALID.로그인_요청_데이터_생성())) + ) + .andExpect(status().isCreated()) + .andExpect(content().string(containsString("."))); + } + } + } +} diff --git a/app/src/test/java/com/codesoom/assignment/support/LoginFixture.java b/app/src/test/java/com/codesoom/assignment/support/LoginFixture.java new file mode 100644 index 000000000..58071c8f6 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/support/LoginFixture.java @@ -0,0 +1,32 @@ +package com.codesoom.assignment.support; + +import com.codesoom.assignment.session.dto.SessionRequestDto; + +public enum LoginFixture { + LOGIN_VALID("dev.gibeom@gmail.com", "비밀번호486"), + LOGIN_INVALID("dev.gibeom@gmail.com", "password486"), + ; + + private String email; + private String password; + + LoginFixture(String email, String password) { + this.email = email; + this.password = password; + } + + public String EMAIL() { + return email; + } + + public String PASSWORD() { + return password; + } + + public SessionRequestDto 로그인_요청_데이터_생성() { + return SessionRequestDto.builder() + .email(this.email) + .password(this.password) + .build(); + } +} From 26cfd82dae12723d7e82f66da7cfd54d96ab341c Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 20:29:40 +0900 Subject: [PATCH 07/39] =?UTF-8?q?feat:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/session/SessionController.java | 28 +++++++++++++++++++ .../session/dto/SessionResponseDto.java | 14 ++++++++++ .../session/SessionControllerTest.java | 10 +++---- 3 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/codesoom/assignment/session/SessionController.java create mode 100644 app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java diff --git a/app/src/main/java/com/codesoom/assignment/session/SessionController.java b/app/src/main/java/com/codesoom/assignment/session/SessionController.java new file mode 100644 index 000000000..a27b53e14 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/session/SessionController.java @@ -0,0 +1,28 @@ +package com.codesoom.assignment.session; + +import com.codesoom.assignment.session.dto.SessionRequestDto; +import com.codesoom.assignment.session.dto.SessionResponseDto; +import org.springframework.http.HttpStatus; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/session") +public class SessionController { + private final AuthenticationService authenticationService; + + public SessionController(AuthenticationService authenticationService) { + this.authenticationService = authenticationService; + } + + @PostMapping + @ResponseStatus(HttpStatus.CREATED) + public SessionResponseDto login(@RequestBody SessionRequestDto sessionRequestDto) { + return SessionResponseDto.builder() + .accessToken(authenticationService.login(sessionRequestDto)) + .build(); + } +} diff --git a/app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java b/app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java new file mode 100644 index 000000000..58e86dfc9 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java @@ -0,0 +1,14 @@ +package com.codesoom.assignment.session.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +public class SessionResponseDto { + private final String accessToken; + + @Builder + public SessionResponseDto(String accessToken) { + this.accessToken = accessToken; + } +} diff --git a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java index b0867f835..b5693410d 100644 --- a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java @@ -37,14 +37,14 @@ class SessionControllerTest { /* 로그인 API는 - 유효한 회원 정보가 주어지면 - - 세션 토큰을 헤더로 반환한다. 201 + - 201 코드로 반환한다 (세션 토큰) - 유효하지 않는 회원 정보가 주어지면 - 빈 값이 주어질 경우 - - 예외를 던진다 (@Valid : 400) + - 400 코드를 반환한다 (@Valid) - 찾을 수 없는 Email일 경우 - - 예외를 던진다 (UserNotFoundException : 404) + - 404 코드를 반환한다 (UserNotFoundException) - 비밀번호가 틀렸을 경우 - - 예외를 던진다 (InvalidUserPasswordException : 400) + - 400 코드를 반환한다 (InvalidUserPasswordException) */ @Nested @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @@ -53,7 +53,7 @@ class 로그인_API는 { @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class 유효한_회원_정보가_주어지면 { @Test - @DisplayName("세션 토큰을 헤더로 반환한다.") + @DisplayName("201 코드로 반환한다.") void it_returns_session() throws Exception { mockMvc.perform( post("/session") From 3fbca85cd9fa10d779b05ea8dd281123719399b5 Mon Sep 17 00:00:00 2001 From: giibeom Date: Tue, 15 Nov 2022 20:53:58 +0900 Subject: [PATCH 08/39] =?UTF-8?q?test:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=84=B1=EA=B3=B5=20=EC=8B=9C=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=EB=B0=98=ED=99=98=20=EC=BC=80=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/AuthenticationServiceTest.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java diff --git a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java new file mode 100644 index 000000000..891a1f596 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java @@ -0,0 +1,50 @@ +package com.codesoom.assignment.session; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import static com.codesoom.assignment.support.LoginFixture.LOGIN_VALID; +import static org.assertj.core.api.Assertions.assertThat; + +/* + - login 메서드는 + - 유효한 회원 정보가 주어지면 + - 토큰을 반환한다 + - 유효하지 않는 회원 정보가 주어지면 + - 찾을 수 없는 Email일 경우 + - 예외를 던진다 (UserNotFoundException) + - 비밀번호가 틀렸을 경우 + - 예외를 던진다 (InvalidUserPasswordException) +*/ +@DisplayName("AuthenticationService 단위 테스트") +class AuthenticationServiceTest { + private AuthenticationService authenticationService; + + @BeforeEach + void setUpVariable() { + authenticationService = new AuthenticationService(); + } + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class login_메서드는 { + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class 유효한_회원_정보가_주어지면 { + @Test + @DisplayName("토큰을 반환한다") + void it_returns_token() { + String accessToken = authenticationService.login(LOGIN_VALID.로그인_요청_데이터_생성()); + + assertThat(accessToken).isNotBlank(); + // TODO: 실제 유저의 accessToken 값인지 검증하는 로직이 있으면 좋을 것 같음 + assertThat(accessToken).contains("."); + } + } + } +} From 15b58c0d2456946083434a8f99c00e6bb7554b41 Mon Sep 17 00:00:00 2001 From: giibeom Date: Wed, 16 Nov 2022 20:11:17 +0900 Subject: [PATCH 09/39] =?UTF-8?q?test:=20(session-presentation)=20Controll?= =?UTF-8?q?er=20=EB=82=B4=EB=B6=80=20=EA=B5=AC=ED=98=84=20mock=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20(authenticationService.login())?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/SessionControllerTest.java | 33 +++++++++++-------- .../assignment/support/TokenFixture.java | 28 ++++++++++++++++ 2 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 app/src/test/java/com/codesoom/assignment/support/TokenFixture.java diff --git a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java index b5693410d..7e26614ed 100644 --- a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java @@ -1,6 +1,7 @@ package com.codesoom.assignment.session; import com.codesoom.assignment.common.util.JsonUtil; +import com.codesoom.assignment.session.dto.SessionRequestDto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; @@ -9,11 +10,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import static com.codesoom.assignment.support.LoginFixture.LOGIN_VALID; +import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; +import static com.codesoom.assignment.support.UserFixture.USER_1; import static org.hamcrest.Matchers.containsString; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -25,26 +30,23 @@ @AutoConfigureMockMvc @DisplayName("SessionController 웹 테스트") class SessionControllerTest { - private final MockMvc mockMvc; - private final SessionController sessionController; - @Autowired - SessionControllerTest(MockMvc mockMvc, SessionController sessionController) { - this.mockMvc = mockMvc; - this.sessionController = sessionController; - } + private MockMvc mockMvc; + + @MockBean + private AuthenticationService authenticationService; /* 로그인 API는 - 유효한 회원 정보가 주어지면 - - 201 코드로 반환한다 (세션 토큰) + - 201 코드로 응답한다 (세션 토큰) - 유효하지 않는 회원 정보가 주어지면 - 빈 값이 주어질 경우 - - 400 코드를 반환한다 (@Valid) + - 400 코드를 응답한다 (@Valid) - 찾을 수 없는 Email일 경우 - - 404 코드를 반환한다 (UserNotFoundException) + - 404 코드를 응답한다 (UserNotFoundException) - 비밀번호가 틀렸을 경우 - - 400 코드를 반환한다 (InvalidUserPasswordException) + - 400 코드를 응답한다 (InvalidUserPasswordException) */ @Nested @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @@ -53,12 +55,15 @@ class 로그인_API는 { @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class 유효한_회원_정보가_주어지면 { @Test - @DisplayName("201 코드로 반환한다.") + @DisplayName("201 코드로 응답한다") void it_returns_session() throws Exception { + given(authenticationService.login(any(SessionRequestDto.class))) + .willReturn(ACCESS_TOKEN_1_VALID.토큰()); + mockMvc.perform( post("/session") .contentType(MediaType.APPLICATION_JSON) - .content(JsonUtil.writeValue(LOGIN_VALID.로그인_요청_데이터_생성())) + .content(JsonUtil.writeValue(USER_1.로그인_요청_데이터_생성())) ) .andExpect(status().isCreated()) .andExpect(content().string(containsString("."))); diff --git a/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java b/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java new file mode 100644 index 000000000..209b5762d --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java @@ -0,0 +1,28 @@ +package com.codesoom.assignment.support; + +public enum TokenFixture { + ACCESS_TOKEN_1_VALID("giibeomIsA2YearsBackendDeveloper", 1L , "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.u-4fczk36juKx46aceMNuz2WJJJj1STWPjfLQA-Z5xY"), + ACCESS_TOKEN_1_INVALID("giibeomIsA2YearsBackendDeveloper", 1L, "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + + private final String secretKey; + private final Long id; + private final String token; + + TokenFixture(String secretKey, Long id, String token) { + this.secretKey = secretKey; + this.id = id; + this.token = token; + } + + public String 시크릿_키() { + return secretKey; + } + + public Long 아이디() { + return id; + } + + public String 토큰() { + return token; + } +} From 986939b830f6162c3c84c31f9111de0ef207d978 Mon Sep 17 00:00:00 2001 From: giibeom Date: Wed, 16 Nov 2022 20:14:47 +0900 Subject: [PATCH 10/39] =?UTF-8?q?feat:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EC=9C=A0=EC=A0=80=EC=9D=98=20?= =?UTF-8?q?id=EB=A5=BC=20=EC=9D=B8=EC=BD=94=EB=94=A9=20=ED=95=9C=20jwt=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=EC=9D=84=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/AuthenticationService.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java diff --git a/app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java b/app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java new file mode 100644 index 000000000..d6620ec74 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java @@ -0,0 +1,24 @@ +package com.codesoom.assignment.session; + +import com.codesoom.assignment.common.util.JwtUtil; +import com.codesoom.assignment.session.dto.SessionRequestDto; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; +import org.springframework.stereotype.Service; + +@Service +public class AuthenticationService { + private final UserRepository userRepository; + private final JwtUtil jwtUtil; + + public AuthenticationService(UserRepository userRepository, JwtUtil jwtUtil) { + this.userRepository = userRepository; + this.jwtUtil = jwtUtil; + } + + public String login(SessionRequestDto sessionRequestDto) { + User user = userRepository.findByEmail(sessionRequestDto.getEmail()).get(); + + return jwtUtil.encode(user.getId()); + } +} From 144bd167bccfba90980d7d35ac2f949a8865a481 Mon Sep 17 00:00:00 2001 From: giibeom Date: Wed, 16 Nov 2022 20:23:44 +0900 Subject: [PATCH 11/39] =?UTF-8?q?test:=20(session-application)=20=EC=9C=A0?= =?UTF-8?q?=ED=9A=A8=ED=95=9C=20=ED=9A=8C=EC=9B=90=20=EC=A0=95=EB=B3=B4?= =?UTF-8?q?=EA=B0=80=20=EC=A3=BC=EC=96=B4=EC=A7=80=EB=A9=B4=20=ED=95=B4?= =?UTF-8?q?=EB=8B=B9=20id=EB=A1=9C=20=EC=9D=B8=EC=BD=94=EB=94=A9=20?= =?UTF-8?q?=EB=90=9C=20=ED=86=A0=ED=81=B0=20=EB=B0=98=ED=99=98=20=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/AuthenticationServiceTest.java | 34 ++++++++++-- .../assignment/support/IdFixture.java | 17 ++++++ .../assignment/support/LoginFixture.java | 32 ----------- .../assignment/support/UserFixture.java | 55 +++++++++++++++++++ 4 files changed, 100 insertions(+), 38 deletions(-) create mode 100644 app/src/test/java/com/codesoom/assignment/support/IdFixture.java delete mode 100644 app/src/test/java/com/codesoom/assignment/support/LoginFixture.java create mode 100644 app/src/test/java/com/codesoom/assignment/support/UserFixture.java diff --git a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java index 891a1f596..3efe0c7d8 100644 --- a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java @@ -1,5 +1,7 @@ package com.codesoom.assignment.session; +import com.codesoom.assignment.common.util.JwtUtil; +import com.codesoom.assignment.user.domain.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; @@ -7,8 +9,16 @@ import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import static com.codesoom.assignment.support.LoginFixture.LOGIN_VALID; +import java.util.Optional; + +import static com.codesoom.assignment.support.IdFixture.ID_MIN; +import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; +import static com.codesoom.assignment.support.UserFixture.USER_1; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; /* - login 메서드는 @@ -23,10 +33,12 @@ @DisplayName("AuthenticationService 단위 테스트") class AuthenticationServiceTest { private AuthenticationService authenticationService; + private final UserRepository userRepository = mock(UserRepository.class); + private final JwtUtil jwtUtil = mock(JwtUtil.class); @BeforeEach void setUpVariable() { - authenticationService = new AuthenticationService(); + authenticationService = new AuthenticationService(userRepository, jwtUtil); } @Nested @@ -39,11 +51,21 @@ class 유효한_회원_정보가_주어지면 { @Test @DisplayName("토큰을 반환한다") void it_returns_token() { - String accessToken = authenticationService.login(LOGIN_VALID.로그인_요청_데이터_생성()); + given(userRepository.findByEmail(USER_1.EMAIL())) + .willReturn( + Optional.of(USER_1.회원_엔티티_생성(ID_MIN.value())) + ); + + given(jwtUtil.encode(any(Long.class))) + .willReturn(ACCESS_TOKEN_1_VALID.토큰()); + + String accessToken = authenticationService.login(USER_1.로그인_요청_데이터_생성()); + + assertThat(accessToken).isNotBlank() + .contains("."); - assertThat(accessToken).isNotBlank(); - // TODO: 실제 유저의 accessToken 값인지 검증하는 로직이 있으면 좋을 것 같음 - assertThat(accessToken).contains("."); + verify(userRepository).findByEmail(USER_1.EMAIL()); + verify(jwtUtil).encode(any(Long.class)); } } } diff --git a/app/src/test/java/com/codesoom/assignment/support/IdFixture.java b/app/src/test/java/com/codesoom/assignment/support/IdFixture.java new file mode 100644 index 000000000..f6d223773 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/support/IdFixture.java @@ -0,0 +1,17 @@ +package com.codesoom.assignment.support; + +public enum IdFixture { + ID_MIN(1L), + ID_MAX(Long.MAX_VALUE), + ; + + private final Long id; + + IdFixture(Long id) { + this.id = id; + } + + public Long value() { + return id; + } +} diff --git a/app/src/test/java/com/codesoom/assignment/support/LoginFixture.java b/app/src/test/java/com/codesoom/assignment/support/LoginFixture.java deleted file mode 100644 index 58071c8f6..000000000 --- a/app/src/test/java/com/codesoom/assignment/support/LoginFixture.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.codesoom.assignment.support; - -import com.codesoom.assignment.session.dto.SessionRequestDto; - -public enum LoginFixture { - LOGIN_VALID("dev.gibeom@gmail.com", "비밀번호486"), - LOGIN_INVALID("dev.gibeom@gmail.com", "password486"), - ; - - private String email; - private String password; - - LoginFixture(String email, String password) { - this.email = email; - this.password = password; - } - - public String EMAIL() { - return email; - } - - public String PASSWORD() { - return password; - } - - public SessionRequestDto 로그인_요청_데이터_생성() { - return SessionRequestDto.builder() - .email(this.email) - .password(this.password) - .build(); - } -} diff --git a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java new file mode 100644 index 000000000..bc210e444 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java @@ -0,0 +1,55 @@ +package com.codesoom.assignment.support; + +import com.codesoom.assignment.session.dto.SessionRequestDto; +import com.codesoom.assignment.user.domain.User; + +public enum UserFixture { + USER_1("기범", "dev.gibeom@gmail.com", "비밀번호486"), + USER_2("Alex", "dev.gibeom@gmail.com", "password486"), + USER_INVALID_NAME("", "alex@gmail.com", "코드숨6주차"), + USER_INVALID_EMAIL("이메일에 골뱅이가 없어요", "alexgmail.com", "코드숨6주차"), + USER_INVALID_PASSWORD("이메일에 골뱅이가 없어요", "alexgmail.com", ""), + ; + + private String name; + private String email; + private String password; + + UserFixture(String name, String email, String password) { + this.name = name; + this.email = email; + this.password = password; + } + + public User 회원_엔티티_생성() { + return 회원_엔티티_생성(null); + } + + public User 회원_엔티티_생성(Long id) { + return User.builder() + .id(id) + .name(this.name) + .email(this.email) + .password(this.password) + .build(); + } + + public SessionRequestDto 로그인_요청_데이터_생성() { + return SessionRequestDto.builder() + .email(this.email) + .password(this.password) + .build(); + } + + public String NAME() { + return name; + } + + public String EMAIL() { + return email; + } + + public String PASSWORD() { + return password; + } +} From 100af53d5eec10a51d5cf5c844be507f39432e67 Mon Sep 17 00:00:00 2001 From: giibeom Date: Wed, 16 Nov 2022 20:26:15 +0900 Subject: [PATCH 12/39] =?UTF-8?q?test:=20(common)=20JwtUtil=20id=EB=A1=9C?= =?UTF-8?q?=20=ED=86=A0=ED=81=B0=20=EC=9D=B8=EC=BD=94=EB=94=A9=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=20=EC=BC=80=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/common/util/JwtUtilTest.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java diff --git a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java new file mode 100644 index 000000000..601379af1 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java @@ -0,0 +1,21 @@ +package com.codesoom.assignment.common.util; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; + +import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; +import static org.assertj.core.api.Assertions.assertThat; + +@WebMvcTest(JwtUtil.class) +class JwtUtilTest { + @Autowired + private JwtUtil jwtUtil; + + @Test + void it_returns_token() { + String encode = jwtUtil.encode(ACCESS_TOKEN_1_VALID.아이디()); + + assertThat(encode).isEqualTo(ACCESS_TOKEN_1_VALID.토큰()); + } +} From 75a144edd61a7d6069c07036c6001573667ef45b Mon Sep 17 00:00:00 2001 From: giibeom Date: Wed, 16 Nov 2022 20:45:37 +0900 Subject: [PATCH 13/39] =?UTF-8?q?feat:=20(common)=20JwtUtil=20id=EB=A5=BC?= =?UTF-8?q?=20=EC=82=AC=EC=9A=A9=ED=95=9C=20=ED=86=A0=ED=81=B0=20=EC=9D=B8?= =?UTF-8?q?=EC=BD=94=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/common/util/JwtUtil.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java diff --git a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java new file mode 100644 index 000000000..9d8e9fc89 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java @@ -0,0 +1,24 @@ +package com.codesoom.assignment.common.util; + +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.security.Keys; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.security.Key; + +@Component +public class JwtUtil { + private final Key key; + + public JwtUtil(@Value("${jwt.secret}") String secretKey) { + key = Keys.hmacShaKeyFor(secretKey.getBytes()); + } + + public String encode(Long id) { + return Jwts.builder() + .claim("userId", id) + .signWith(key) + .compact(); + } +} From 5a1d34a971c8cb8f1563b1bc1db0c4d5895c6946 Mon Sep 17 00:00:00 2001 From: giibeom Date: Wed, 16 Nov 2022 20:53:48 +0900 Subject: [PATCH 14/39] =?UTF-8?q?refactor:=20mock=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9D=98=20=ED=96=89=EC=9C=84=20=EA=B2=80=EC=A6=9D(ve?= =?UTF-8?q?rify)=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20given=20=EC=A0=88=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/dto/SessionRequestDto.java | 2 ++ .../session/AuthenticationServiceTest.java | 15 +++++++----- .../session/SessionControllerTest.java | 23 +++++++++++-------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java b/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java index 9554a9f28..dd185d4c9 100644 --- a/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java +++ b/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java @@ -1,11 +1,13 @@ package com.codesoom.assignment.session.dto; import lombok.Builder; +import lombok.EqualsAndHashCode; import lombok.Getter; import javax.validation.constraints.NotBlank; @Getter +@EqualsAndHashCode public class SessionRequestDto { @NotBlank(message = "이메일을 입력하세요") private final String email; diff --git a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java index 3efe0c7d8..2ecb96dcb 100644 --- a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java @@ -15,7 +15,6 @@ import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static com.codesoom.assignment.support.UserFixture.USER_1; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -48,24 +47,28 @@ class login_메서드는 { @Nested @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class 유효한_회원_정보가_주어지면 { - @Test - @DisplayName("토큰을 반환한다") - void it_returns_token() { + @BeforeEach + void setUpGiven() { given(userRepository.findByEmail(USER_1.EMAIL())) .willReturn( Optional.of(USER_1.회원_엔티티_생성(ID_MIN.value())) ); - given(jwtUtil.encode(any(Long.class))) + given(jwtUtil.encode(ID_MIN.value())) .willReturn(ACCESS_TOKEN_1_VALID.토큰()); + } + @Test + @DisplayName("토큰을 반환한다") + void it_returns_token() { String accessToken = authenticationService.login(USER_1.로그인_요청_데이터_생성()); + assertThat(accessToken).isNotBlank() .contains("."); verify(userRepository).findByEmail(USER_1.EMAIL()); - verify(jwtUtil).encode(any(Long.class)); + verify(jwtUtil).encode(ID_MIN.value()); } } } diff --git a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java index 7e26614ed..8fc3cdebf 100644 --- a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.session; import com.codesoom.assignment.common.util.JsonUtil; -import com.codesoom.assignment.session.dto.SessionRequestDto; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; import org.junit.jupiter.api.DisplayNameGenerator; @@ -17,8 +17,8 @@ import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static com.codesoom.assignment.support.UserFixture.USER_1; import static org.hamcrest.Matchers.containsString; -import static org.mockito.ArgumentMatchers.any; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -54,19 +54,24 @@ class 로그인_API는 { @Nested @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class 유효한_회원_정보가_주어지면 { + @BeforeEach + void setUpGiven() { + given(authenticationService.login(USER_1.로그인_요청_데이터_생성())) + .willReturn(ACCESS_TOKEN_1_VALID.토큰()); + } + @Test @DisplayName("201 코드로 응답한다") void it_returns_session() throws Exception { - given(authenticationService.login(any(SessionRequestDto.class))) - .willReturn(ACCESS_TOKEN_1_VALID.토큰()); - mockMvc.perform( - post("/session") - .contentType(MediaType.APPLICATION_JSON) - .content(JsonUtil.writeValue(USER_1.로그인_요청_데이터_생성())) - ) + post("/session") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(USER_1.로그인_요청_데이터_생성())) + ) .andExpect(status().isCreated()) .andExpect(content().string(containsString("."))); + + verify(authenticationService).login(USER_1.로그인_요청_데이터_생성()); } } } From 66ff673dbede807423dd3ee2553ce0baacef05c7 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 00:08:41 +0900 Subject: [PATCH 15/39] =?UTF-8?q?refactor:=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=ED=98=95?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD,=20HelloController=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ref: https://cheese10yun.github.io/spring-guide-directory/ --- .../codesoom/assignment/HelloController.java | 12 --- .../product/application/ProductService.java | 10 +- .../{ => domain}/product/domain/Product.java | 2 +- .../product/domain/ProductRepository.java | 2 +- .../exception/ProductErrorAdvice.java} | 6 +- .../exception/ProductExceptionHandler.java | 4 +- .../exception/ProductNotFoundException.java | 2 +- .../product/infra/JpaProductRepository.java | 6 +- .../presentation/ProductController.java | 19 +++- .../product/presentation/dto/ProductData.java | 2 +- .../application}/AuthenticationService.java | 12 +-- .../controller}/SessionController.java | 11 ++- .../controller}/dto/SessionRequestDto.java | 2 +- .../controller}/dto/SessionResponseDto.java | 2 +- .../user/application/UserService.java | 16 ++-- .../{ => domain}/user/domain/User.java | 2 +- .../user/domain/UserRepository.java | 2 +- .../UserEmailDuplicationException.java | 2 +- .../user/exception/UserErrorAdvice.java} | 6 +- .../user/exception/UserExceptionHandler.java | 4 +- .../user/exception/UserNotFoundException.java | 2 +- .../domain/user/infra/JpaUserRepository.java | 20 ++++ .../user/presentation/UserController.java | 22 +++-- .../dto/UserModificationData.java | 2 +- .../dto/UserRegistrationData.java | 2 +- .../user/presentation/dto/UserResultData.java | 2 +- .../user/infra/JpaUserRepository.java | 20 ---- .../assignment/HelloControllerTest.java | 14 --- .../application/ProductServiceTest.java | 10 +- .../product/domain/ProductTest.java | 2 +- .../presentation/ProductControllerTest.java | 93 ++++++++++--------- .../AuthenticationServiceTest.java | 4 +- .../controller}/SessionControllerTest.java | 3 +- .../user/application/UserServiceTest.java | 16 ++-- .../{ => domain}/user/domain/UserTest.java | 2 +- .../user/presentation/UserControllerTest.java | 16 ++-- .../assignment/support/UserFixture.java | 4 +- 37 files changed, 178 insertions(+), 180 deletions(-) delete mode 100644 app/src/main/java/com/codesoom/assignment/HelloController.java rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/application/ProductService.java (79%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/domain/Product.java (95%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/domain/ProductRepository.java (80%) rename app/src/main/java/com/codesoom/assignment/{product/exception/ProductControllerAdvice.java => domain/product/exception/ProductErrorAdvice.java} (74%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/exception/ProductExceptionHandler.java (86%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/exception/ProductNotFoundException.java (73%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/infra/JpaProductRepository.java (65%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/presentation/ProductController.java (59%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/product/presentation/dto/ProductData.java (88%) rename app/src/main/java/com/codesoom/assignment/{session => domain/session/application}/AuthenticationService.java (51%) rename app/src/main/java/com/codesoom/assignment/{session => domain/session/controller}/SessionController.java (61%) rename app/src/main/java/com/codesoom/assignment/{session => domain/session/controller}/dto/SessionRequestDto.java (89%) rename app/src/main/java/com/codesoom/assignment/{session => domain/session/controller}/dto/SessionResponseDto.java (79%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/application/UserService.java (72%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/domain/User.java (93%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/domain/UserRepository.java (84%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/exception/UserEmailDuplicationException.java (77%) rename app/src/main/java/com/codesoom/assignment/{user/exception/UserControllerAdvice.java => domain/user/exception/UserErrorAdvice.java} (75%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/exception/UserExceptionHandler.java (90%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/exception/UserNotFoundException.java (73%) create mode 100644 app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/presentation/UserController.java (55%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/presentation/dto/UserModificationData.java (88%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/presentation/dto/UserRegistrationData.java (90%) rename app/src/main/java/com/codesoom/assignment/{ => domain}/user/presentation/dto/UserResultData.java (78%) delete mode 100644 app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java delete mode 100644 app/src/test/java/com/codesoom/assignment/HelloControllerTest.java rename app/src/test/java/com/codesoom/assignment/{ => domain}/product/application/ProductServiceTest.java (92%) rename app/src/test/java/com/codesoom/assignment/{ => domain}/product/domain/ProductTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{ => domain}/product/presentation/ProductControllerTest.java (64%) rename app/src/test/java/com/codesoom/assignment/{session => domain/session/application}/AuthenticationServiceTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{session => domain/session/controller}/SessionControllerTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{ => domain}/user/application/UserServiceTest.java (91%) rename app/src/test/java/com/codesoom/assignment/{ => domain}/user/domain/UserTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{ => domain}/user/presentation/UserControllerTest.java (89%) diff --git a/app/src/main/java/com/codesoom/assignment/HelloController.java b/app/src/main/java/com/codesoom/assignment/HelloController.java deleted file mode 100644 index 42b03e93e..000000000 --- a/app/src/main/java/com/codesoom/assignment/HelloController.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.codesoom.assignment; - -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class HelloController { - @RequestMapping("/") - public String sayHello() { - return "Hello, world!"; - } -} diff --git a/app/src/main/java/com/codesoom/assignment/product/application/ProductService.java b/app/src/main/java/com/codesoom/assignment/domain/product/application/ProductService.java similarity index 79% rename from app/src/main/java/com/codesoom/assignment/product/application/ProductService.java rename to app/src/main/java/com/codesoom/assignment/domain/product/application/ProductService.java index 532bf88b1..164296386 100644 --- a/app/src/main/java/com/codesoom/assignment/product/application/ProductService.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/application/ProductService.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.product.application; +package com.codesoom.assignment.domain.product.application; -import com.codesoom.assignment.product.domain.Product; -import com.codesoom.assignment.product.domain.ProductRepository; -import com.codesoom.assignment.product.presentation.dto.ProductData; -import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.domain.ProductRepository; +import com.codesoom.assignment.domain.product.exception.ProductNotFoundException; +import com.codesoom.assignment.domain.product.presentation.dto.ProductData; import com.github.dozermapper.core.Mapper; import org.springframework.stereotype.Service; diff --git a/app/src/main/java/com/codesoom/assignment/product/domain/Product.java b/app/src/main/java/com/codesoom/assignment/domain/product/domain/Product.java similarity index 95% rename from app/src/main/java/com/codesoom/assignment/product/domain/Product.java rename to app/src/main/java/com/codesoom/assignment/domain/product/domain/Product.java index 87fe9214c..6810a7064 100644 --- a/app/src/main/java/com/codesoom/assignment/product/domain/Product.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/domain/Product.java @@ -14,7 +14,7 @@ // 3. 가격 - 5,000원 (판매가) // 4. 이미지 - static, CDN => image URL -package com.codesoom.assignment.product.domain; +package com.codesoom.assignment.domain.product.domain; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java b/app/src/main/java/com/codesoom/assignment/domain/product/domain/ProductRepository.java similarity index 80% rename from app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java rename to app/src/main/java/com/codesoom/assignment/domain/product/domain/ProductRepository.java index 44082966e..ec033ae80 100644 --- a/app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/domain/ProductRepository.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.product.domain; +package com.codesoom.assignment.domain.product.domain; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java similarity index 74% rename from app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java rename to app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java index 39d238e8e..6d74b302f 100644 --- a/app/src/main/java/com/codesoom/assignment/product/exception/ProductControllerAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java @@ -1,6 +1,6 @@ -package com.codesoom.assignment.product.exception; +package com.codesoom.assignment.domain.product.exception; -import com.codesoom.assignment.product.presentation.ProductController; +import com.codesoom.assignment.domain.product.presentation.ProductController; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -16,5 +16,5 @@ ProductController.class }) @Order(Ordered.HIGHEST_PRECEDENCE) -public @interface ProductControllerAdvice { +public @interface ProductErrorAdvice { } diff --git a/app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java similarity index 86% rename from app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java rename to app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java index 816967e55..02d7c5c16 100644 --- a/app/src/main/java/com/codesoom/assignment/product/exception/ProductExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.product.exception; +package com.codesoom.assignment.domain.product.exception; import com.codesoom.assignment.common.exception.ErrorResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; -@ProductControllerAdvice +@ProductErrorAdvice public class ProductExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) diff --git a/app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductNotFoundException.java similarity index 73% rename from app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java rename to app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductNotFoundException.java index f962b0e4f..9d0eb4740 100644 --- a/app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductNotFoundException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.product.exception; +package com.codesoom.assignment.domain.product.exception; public class ProductNotFoundException extends RuntimeException { public ProductNotFoundException(Long id) { diff --git a/app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java b/app/src/main/java/com/codesoom/assignment/domain/product/infra/JpaProductRepository.java similarity index 65% rename from app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java rename to app/src/main/java/com/codesoom/assignment/domain/product/infra/JpaProductRepository.java index 05b32a803..eafb192be 100644 --- a/app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/infra/JpaProductRepository.java @@ -1,7 +1,7 @@ -package com.codesoom.assignment.product.infra; +package com.codesoom.assignment.domain.product.infra; -import com.codesoom.assignment.product.domain.Product; -import com.codesoom.assignment.product.domain.ProductRepository; +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.domain.ProductRepository; import org.springframework.data.repository.CrudRepository; import java.util.List; diff --git a/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java b/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java similarity index 59% rename from app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java rename to app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java index c53c06450..f1b4acca3 100644 --- a/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java @@ -1,10 +1,19 @@ -package com.codesoom.assignment.product.presentation; +package com.codesoom.assignment.domain.product.presentation; -import com.codesoom.assignment.product.application.ProductService; -import com.codesoom.assignment.product.domain.Product; -import com.codesoom.assignment.product.presentation.dto.ProductData; +import com.codesoom.assignment.domain.product.application.ProductService; +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.presentation.dto.ProductData; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; import java.util.List; diff --git a/app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java b/app/src/main/java/com/codesoom/assignment/domain/product/presentation/dto/ProductData.java similarity index 88% rename from app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java rename to app/src/main/java/com/codesoom/assignment/domain/product/presentation/dto/ProductData.java index d9bd6d451..3ad48c576 100644 --- a/app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/presentation/dto/ProductData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.product.presentation.dto; +package com.codesoom.assignment.domain.product.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.*; diff --git a/app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java b/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java similarity index 51% rename from app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java rename to app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java index d6620ec74..13883ceb0 100644 --- a/app/src/main/java/com/codesoom/assignment/session/AuthenticationService.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.session; +package com.codesoom.assignment.domain.session.application; import com.codesoom.assignment.common.util.JwtUtil; -import com.codesoom.assignment.session.dto.SessionRequestDto; -import com.codesoom.assignment.user.domain.User; -import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; +import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.domain.user.domain.UserRepository; import org.springframework.stereotype.Service; @Service @@ -11,12 +11,12 @@ public class AuthenticationService { private final UserRepository userRepository; private final JwtUtil jwtUtil; - public AuthenticationService(UserRepository userRepository, JwtUtil jwtUtil) { + public AuthenticationService(final UserRepository userRepository, final JwtUtil jwtUtil) { this.userRepository = userRepository; this.jwtUtil = jwtUtil; } - public String login(SessionRequestDto sessionRequestDto) { + public String login(final SessionRequestDto sessionRequestDto) { User user = userRepository.findByEmail(sessionRequestDto.getEmail()).get(); return jwtUtil.encode(user.getId()); diff --git a/app/src/main/java/com/codesoom/assignment/session/SessionController.java b/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java similarity index 61% rename from app/src/main/java/com/codesoom/assignment/session/SessionController.java rename to app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java index a27b53e14..0d4789366 100644 --- a/app/src/main/java/com/codesoom/assignment/session/SessionController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java @@ -1,7 +1,8 @@ -package com.codesoom.assignment.session; +package com.codesoom.assignment.domain.session.controller; -import com.codesoom.assignment.session.dto.SessionRequestDto; -import com.codesoom.assignment.session.dto.SessionResponseDto; +import com.codesoom.assignment.domain.session.application.AuthenticationService; +import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; +import com.codesoom.assignment.domain.session.controller.dto.SessionResponseDto; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -14,13 +15,13 @@ public class SessionController { private final AuthenticationService authenticationService; - public SessionController(AuthenticationService authenticationService) { + public SessionController(final AuthenticationService authenticationService) { this.authenticationService = authenticationService; } @PostMapping @ResponseStatus(HttpStatus.CREATED) - public SessionResponseDto login(@RequestBody SessionRequestDto sessionRequestDto) { + public SessionResponseDto login(@RequestBody final SessionRequestDto sessionRequestDto) { return SessionResponseDto.builder() .accessToken(authenticationService.login(sessionRequestDto)) .build(); diff --git a/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java b/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionRequestDto.java similarity index 89% rename from app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java rename to app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionRequestDto.java index dd185d4c9..f5e3b9cd4 100644 --- a/app/src/main/java/com/codesoom/assignment/session/dto/SessionRequestDto.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionRequestDto.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.session.dto; +package com.codesoom.assignment.domain.session.controller.dto; import lombok.Builder; import lombok.EqualsAndHashCode; diff --git a/app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java b/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionResponseDto.java similarity index 79% rename from app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java rename to app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionResponseDto.java index 58e86dfc9..c27d2821b 100644 --- a/app/src/main/java/com/codesoom/assignment/session/dto/SessionResponseDto.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionResponseDto.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.session.dto; +package com.codesoom.assignment.domain.session.controller.dto; import lombok.Builder; import lombok.Getter; diff --git a/app/src/main/java/com/codesoom/assignment/user/application/UserService.java b/app/src/main/java/com/codesoom/assignment/domain/user/application/UserService.java similarity index 72% rename from app/src/main/java/com/codesoom/assignment/user/application/UserService.java rename to app/src/main/java/com/codesoom/assignment/domain/user/application/UserService.java index e1c45f71a..8608ff64e 100644 --- a/app/src/main/java/com/codesoom/assignment/user/application/UserService.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/application/UserService.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.user.application; - -import com.codesoom.assignment.user.domain.User; -import com.codesoom.assignment.user.domain.UserRepository; -import com.codesoom.assignment.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; -import com.codesoom.assignment.user.exception.UserEmailDuplicationException; -import com.codesoom.assignment.user.exception.UserNotFoundException; +package com.codesoom.assignment.domain.user.application; + +import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.domain.user.exception.UserNotFoundException; +import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; import com.github.dozermapper.core.Mapper; import org.springframework.stereotype.Service; diff --git a/app/src/main/java/com/codesoom/assignment/user/domain/User.java b/app/src/main/java/com/codesoom/assignment/domain/user/domain/User.java similarity index 93% rename from app/src/main/java/com/codesoom/assignment/user/domain/User.java rename to app/src/main/java/com/codesoom/assignment/domain/user/domain/User.java index 1c3b1562f..c0f93558d 100644 --- a/app/src/main/java/com/codesoom/assignment/user/domain/User.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/domain/User.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.domain; +package com.codesoom.assignment.domain.user.domain; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java b/app/src/main/java/com/codesoom/assignment/domain/user/domain/UserRepository.java similarity index 84% rename from app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java rename to app/src/main/java/com/codesoom/assignment/domain/user/domain/UserRepository.java index dc5c096f3..12f152823 100644 --- a/app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/domain/UserRepository.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.domain; +package com.codesoom.assignment.domain.user.domain; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserEmailDuplicationException.java similarity index 77% rename from app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java rename to app/src/main/java/com/codesoom/assignment/domain/user/exception/UserEmailDuplicationException.java index ed54c6ae2..cc3ccaffa 100644 --- a/app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserEmailDuplicationException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.exception; +package com.codesoom.assignment.domain.user.exception; public class UserEmailDuplicationException extends RuntimeException { public UserEmailDuplicationException(String email) { diff --git a/app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java similarity index 75% rename from app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java rename to app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java index a6d8c7aef..c3fba10a9 100644 --- a/app/src/main/java/com/codesoom/assignment/user/exception/UserControllerAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java @@ -1,6 +1,6 @@ -package com.codesoom.assignment.user.exception; +package com.codesoom.assignment.domain.user.exception; -import com.codesoom.assignment.user.presentation.UserController; +import com.codesoom.assignment.domain.user.presentation.UserController; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -16,5 +16,5 @@ UserController.class }) @Order(Ordered.HIGHEST_PRECEDENCE) -public @interface UserControllerAdvice { +public @interface UserErrorAdvice { } diff --git a/app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java similarity index 90% rename from app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java rename to app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java index 964b9fa07..56fe8301a 100644 --- a/app/src/main/java/com/codesoom/assignment/user/exception/UserExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.user.exception; +package com.codesoom.assignment.domain.user.exception; import com.codesoom.assignment.common.exception.ErrorResponse; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; -@UserControllerAdvice +@UserErrorAdvice public class UserExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) diff --git a/app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java similarity index 73% rename from app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java rename to app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java index 26df1e09f..4d914b31c 100644 --- a/app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.exception; +package com.codesoom.assignment.domain.user.exception; public class UserNotFoundException extends RuntimeException { public UserNotFoundException(Long id) { diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java b/app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java new file mode 100644 index 000000000..d4c145b03 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java @@ -0,0 +1,20 @@ +package com.codesoom.assignment.domain.user.infra; + +import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.domain.user.domain.UserRepository; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface JpaUserRepository + extends UserRepository, JpaRepository { + User save(User user); + + boolean existsByEmail(String email); + + Optional findById(Long id); + + Optional findByIdAndDeletedIsFalse(Long id); + + Optional findByEmail(String email); +} diff --git a/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java similarity index 55% rename from app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java rename to app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java index 687511d53..8f9825792 100644 --- a/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java @@ -1,12 +1,20 @@ -package com.codesoom.assignment.user.presentation; +package com.codesoom.assignment.domain.user.presentation; -import com.codesoom.assignment.user.application.UserService; -import com.codesoom.assignment.user.domain.User; -import com.codesoom.assignment.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; -import com.codesoom.assignment.user.presentation.dto.UserResultData; +import com.codesoom.assignment.domain.user.application.UserService; +import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.domain.user.presentation.dto.UserResultData; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PatchMapping; +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.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; import javax.validation.Valid; diff --git a/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserModificationData.java similarity index 88% rename from app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java rename to app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserModificationData.java index 5fc387cff..99b50bb13 100644 --- a/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserModificationData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.presentation.dto; +package com.codesoom.assignment.domain.user.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserRegistrationData.java similarity index 90% rename from app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java rename to app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserRegistrationData.java index 428c32f77..63f61a6c5 100644 --- a/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserRegistrationData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.presentation.dto; +package com.codesoom.assignment.domain.user.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserResultData.java similarity index 78% rename from app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java rename to app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserResultData.java index f295e5046..f2d9d615a 100644 --- a/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserResultData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.presentation.dto; +package com.codesoom.assignment.domain.user.presentation.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java b/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java deleted file mode 100644 index 2d13a9534..000000000 --- a/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.codesoom.assignment.user.infra; - -import com.codesoom.assignment.user.domain.User; -import com.codesoom.assignment.user.domain.UserRepository; -import org.springframework.data.repository.CrudRepository; - -import java.util.Optional; - -public interface JpaUserRepository - extends UserRepository, CrudRepository { - User save(User user); - - boolean existsByEmail(String email); - - Optional findById(Long id); - - Optional findByIdAndDeletedIsFalse(Long id); - - Optional findByEmail(String email); -} diff --git a/app/src/test/java/com/codesoom/assignment/HelloControllerTest.java b/app/src/test/java/com/codesoom/assignment/HelloControllerTest.java deleted file mode 100644 index 81fe6bf7b..000000000 --- a/app/src/test/java/com/codesoom/assignment/HelloControllerTest.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.codesoom.assignment; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -class HelloControllerTest { - @Test - void sayHello() { - HelloController controller = new HelloController(); - - assertThat(controller.sayHello()).isEqualTo("Hello, world!"); - } -} diff --git a/app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java b/app/src/test/java/com/codesoom/assignment/domain/product/application/ProductServiceTest.java similarity index 92% rename from app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java rename to app/src/test/java/com/codesoom/assignment/domain/product/application/ProductServiceTest.java index 106a836d6..a1c59c335 100644 --- a/app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/product/application/ProductServiceTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.product.application; +package com.codesoom.assignment.domain.product.application; -import com.codesoom.assignment.product.domain.Product; -import com.codesoom.assignment.product.domain.ProductRepository; -import com.codesoom.assignment.product.presentation.dto.ProductData; -import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.domain.ProductRepository; +import com.codesoom.assignment.domain.product.exception.ProductNotFoundException; +import com.codesoom.assignment.domain.product.presentation.dto.ProductData; import com.github.dozermapper.core.DozerBeanMapperBuilder; import com.github.dozermapper.core.Mapper; import org.junit.jupiter.api.BeforeEach; diff --git a/app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java b/app/src/test/java/com/codesoom/assignment/domain/product/domain/ProductTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java rename to app/src/test/java/com/codesoom/assignment/domain/product/domain/ProductTest.java index 652060808..99dbb16df 100644 --- a/app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/product/domain/ProductTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.product.domain; +package com.codesoom.assignment.domain.product.domain; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/product/presentation/ProductControllerTest.java similarity index 64% rename from app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java rename to app/src/test/java/com/codesoom/assignment/domain/product/presentation/ProductControllerTest.java index 7074f6f80..b0eea852c 100644 --- a/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/product/presentation/ProductControllerTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.product.presentation; +package com.codesoom.assignment.domain.product.presentation; -import com.codesoom.assignment.product.application.ProductService; -import com.codesoom.assignment.product.domain.Product; -import com.codesoom.assignment.product.presentation.dto.ProductData; -import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.domain.product.application.ProductService; +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.exception.ProductNotFoundException; +import com.codesoom.assignment.domain.product.presentation.dto.ProductData; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -19,7 +19,10 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -76,9 +79,9 @@ void setUp() { @Test void list() throws Exception { mockMvc.perform( - get("/products") - .accept(MediaType.APPLICATION_JSON_UTF8) - ) + get("/products") + .accept(MediaType.APPLICATION_JSON_UTF8) + ) .andExpect(status().isOk()) .andExpect(content().string(containsString("쥐돌이"))); } @@ -86,9 +89,9 @@ void list() throws Exception { @Test void deatilWithExsitedProduct() throws Exception { mockMvc.perform( - get("/products/1") - .accept(MediaType.APPLICATION_JSON_UTF8) - ) + get("/products/1") + .accept(MediaType.APPLICATION_JSON_UTF8) + ) .andExpect(status().isOk()) .andExpect(content().string(containsString("쥐돌이"))); } @@ -102,12 +105,12 @@ void deatilWithNotExsitedProduct() throws Exception { @Test void createWithValidAttributes() throws Exception { mockMvc.perform( - post("/products") - .accept(MediaType.APPLICATION_JSON_UTF8) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"쥐돌이\",\"maker\":\"냥이월드\"," + - "\"price\":5000}") - ) + post("/products") + .accept(MediaType.APPLICATION_JSON_UTF8) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"쥐돌이\",\"maker\":\"냥이월드\"," + + "\"price\":5000}") + ) .andExpect(status().isCreated()) .andExpect(content().string(containsString("쥐돌이"))); @@ -117,24 +120,24 @@ void createWithValidAttributes() throws Exception { @Test void createWithInvalidAttributes() throws Exception { mockMvc.perform( - post("/products") - .accept(MediaType.APPLICATION_JSON_UTF8) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"\",\"maker\":\"\"," + - "\"price\":0}") - ) + post("/products") + .accept(MediaType.APPLICATION_JSON_UTF8) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"\",\"maker\":\"\"," + + "\"price\":0}") + ) .andExpect(status().isBadRequest()); } @Test void updateWithExistedProduct() throws Exception { mockMvc.perform( - patch("/products/1") - .accept(MediaType.APPLICATION_JSON_UTF8) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"쥐순이\",\"maker\":\"냥이월드\"," + - "\"price\":5000}") - ) + patch("/products/1") + .accept(MediaType.APPLICATION_JSON_UTF8) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"쥐순이\",\"maker\":\"냥이월드\"," + + "\"price\":5000}") + ) .andExpect(status().isOk()) .andExpect(content().string(containsString("쥐순이"))); @@ -144,11 +147,11 @@ void updateWithExistedProduct() throws Exception { @Test void updateWithNotExistedProduct() throws Exception { mockMvc.perform( - patch("/products/1000") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"쥐순이\",\"maker\":\"냥이월드\"," + - "\"price\":5000}") - ) + patch("/products/1000") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"쥐순이\",\"maker\":\"냥이월드\"," + + "\"price\":5000}") + ) .andExpect(status().isNotFound()); verify(productService).updateProduct(eq(1000L), any(ProductData.class)); @@ -157,20 +160,20 @@ void updateWithNotExistedProduct() throws Exception { @Test void updateWithInvalidAttributes() throws Exception { mockMvc.perform( - patch("/products/1") - .accept(MediaType.APPLICATION_JSON_UTF8) - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"\",\"maker\":\"\"," + - "\"price\":0}") - ) + patch("/products/1") + .accept(MediaType.APPLICATION_JSON_UTF8) + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"\",\"maker\":\"\"," + + "\"price\":0}") + ) .andExpect(status().isBadRequest()); } @Test void destroyWithExistedProduct() throws Exception { mockMvc.perform( - delete("/products/1") - ) + delete("/products/1") + ) .andExpect(status().isNoContent()); verify(productService).deleteProduct(1L); @@ -179,8 +182,8 @@ void destroyWithExistedProduct() throws Exception { @Test void destroyWithNotExistedProduct() throws Exception { mockMvc.perform( - delete("/products/1000") - ) + delete("/products/1000") + ) .andExpect(status().isNotFound()); verify(productService).deleteProduct(1000L); diff --git a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java rename to app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java index 2ecb96dcb..d36298b78 100644 --- a/app/src/test/java/com/codesoom/assignment/session/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java @@ -1,7 +1,7 @@ -package com.codesoom.assignment.session; +package com.codesoom.assignment.domain.session.application; import com.codesoom.assignment.common.util.JwtUtil; -import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.domain.UserRepository; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; diff --git a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java rename to app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java index 8fc3cdebf..1bfc84e2b 100644 --- a/app/src/test/java/com/codesoom/assignment/session/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java @@ -1,6 +1,7 @@ -package com.codesoom.assignment.session; +package com.codesoom.assignment.domain.session.controller; import com.codesoom.assignment.common.util.JsonUtil; +import com.codesoom.assignment.domain.session.application.AuthenticationService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; diff --git a/app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java b/app/src/test/java/com/codesoom/assignment/domain/user/application/UserServiceTest.java similarity index 91% rename from app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java rename to app/src/test/java/com/codesoom/assignment/domain/user/application/UserServiceTest.java index d9794876e..f48725270 100644 --- a/app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/user/application/UserServiceTest.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.user.application; - -import com.codesoom.assignment.user.domain.User; -import com.codesoom.assignment.user.domain.UserRepository; -import com.codesoom.assignment.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; -import com.codesoom.assignment.user.exception.UserEmailDuplicationException; -import com.codesoom.assignment.user.exception.UserNotFoundException; +package com.codesoom.assignment.domain.user.application; + +import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.domain.user.exception.UserNotFoundException; +import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; import com.github.dozermapper.core.DozerBeanMapperBuilder; import com.github.dozermapper.core.Mapper; import org.junit.jupiter.api.BeforeEach; diff --git a/app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java b/app/src/test/java/com/codesoom/assignment/domain/user/domain/UserTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java rename to app/src/test/java/com/codesoom/assignment/domain/user/domain/UserTest.java index 097cdae82..d26d018cc 100644 --- a/app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/user/domain/UserTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.user.domain; +package com.codesoom.assignment.domain.user.domain; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/user/presentation/UserControllerTest.java similarity index 89% rename from app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java rename to app/src/test/java/com/codesoom/assignment/domain/user/presentation/UserControllerTest.java index d1ca7bf08..c35b2a593 100644 --- a/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/user/presentation/UserControllerTest.java @@ -1,10 +1,10 @@ -package com.codesoom.assignment.user.presentation; +package com.codesoom.assignment.domain.user.presentation; -import com.codesoom.assignment.user.application.UserService; -import com.codesoom.assignment.user.domain.User; -import com.codesoom.assignment.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; -import com.codesoom.assignment.user.exception.UserNotFoundException; +import com.codesoom.assignment.domain.user.application.UserService; +import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.domain.user.exception.UserNotFoundException; +import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -18,7 +18,9 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; diff --git a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java index bc210e444..f0177c532 100644 --- a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.support; -import com.codesoom.assignment.session.dto.SessionRequestDto; -import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; +import com.codesoom.assignment.domain.user.domain.User; public enum UserFixture { USER_1("기범", "dev.gibeom@gmail.com", "비밀번호486"), From bbe5eb37b6b02a0a340f5267243e2dbdad2512bf Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 16:25:40 +0900 Subject: [PATCH 16/39] =?UTF-8?q?test:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20=EC=8B=A4=ED=8C=A8=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=20(=EC=9D=B4=EB=A9=94=EC=9D=BC,=20=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SessionControllerTest.java | 68 ++++++++++++++----- .../assignment/support/UserFixture.java | 4 +- 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java index 1bfc84e2b..fad557e82 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java @@ -17,6 +17,8 @@ import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static com.codesoom.assignment.support.UserFixture.USER_1; +import static com.codesoom.assignment.support.UserFixture.USER_INVALID_BLANK_EMAIL; +import static com.codesoom.assignment.support.UserFixture.USER_INVALID_BLANK_PASSWORD; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; @@ -29,32 +31,20 @@ */ @SpringBootTest @AutoConfigureMockMvc -@DisplayName("SessionController 웹 테스트") -class SessionControllerTest { +@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) +class Session_Controller_웹_테스트 { @Autowired private MockMvc mockMvc; @MockBean private AuthenticationService authenticationService; - /* - 로그인 API는 - - 유효한 회원 정보가 주어지면 - - 201 코드로 응답한다 (세션 토큰) - - 유효하지 않는 회원 정보가 주어지면 - - 빈 값이 주어질 경우 - - 400 코드를 응답한다 (@Valid) - - 찾을 수 없는 Email일 경우 - - 404 코드를 응답한다 (UserNotFoundException) - - 비밀번호가 틀렸을 경우 - - 400 코드를 응답한다 (InvalidUserPasswordException) - */ @Nested @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) class 로그인_API는 { @Nested - @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) - class 유효한_회원_정보가_주어지면 { + @DisplayName("유효한 회원 정보가 주어지면") + class Context_with_valid_user { @BeforeEach void setUpGiven() { given(authenticationService.login(USER_1.로그인_요청_데이터_생성())) @@ -63,7 +53,7 @@ void setUpGiven() { @Test @DisplayName("201 코드로 응답한다") - void it_returns_session() throws Exception { + void it_responses_201() throws Exception { mockMvc.perform( post("/session") .contentType(MediaType.APPLICATION_JSON) @@ -75,5 +65,49 @@ void it_returns_session() throws Exception { verify(authenticationService).login(USER_1.로그인_요청_데이터_생성()); } } + + /* + 로그인 API는 + - 유효하지 않는 회원 정보가 주어지면 + - 빈 값이 주어질 경우 + - 400 코드를 응답한다 (@Valid) + - 찾을 수 없는 계정일 경우 + - 404 코드를 응답한다 (UserNotFoundException) + - 비밀번호가 틀렸을 경우 + - 400 코드를 응답한다 (InvalidUserPasswordException) + */ + @Nested + @DisplayName("유효하지 않는 회원 정보가 주어지면") + class Context_with_invalid_user { + @Nested + @DisplayName("이메일이 공백으로 주어질 경우") + class Context_with_blank_email { + @Test + @DisplayName("400 코드로 응답한다") + void it_responses_400() throws Exception { + mockMvc.perform( + post("/session") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(USER_INVALID_BLANK_EMAIL.로그인_요청_데이터_생성())) + ) + .andExpect(status().isBadRequest()); + } + } + + @Nested + @DisplayName("비밀번호가 공백으로 주어질 경우") + class Context_with_blank_password { + @Test + @DisplayName("400 코드로 응답한다") + void it_responses_400() throws Exception { + mockMvc.perform( + post("/session") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(USER_INVALID_BLANK_PASSWORD.로그인_요청_데이터_생성())) + ) + .andExpect(status().isBadRequest()); + } + } + } } } diff --git a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java index f0177c532..dbcf0ef79 100644 --- a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java @@ -7,8 +7,8 @@ public enum UserFixture { USER_1("기범", "dev.gibeom@gmail.com", "비밀번호486"), USER_2("Alex", "dev.gibeom@gmail.com", "password486"), USER_INVALID_NAME("", "alex@gmail.com", "코드숨6주차"), - USER_INVALID_EMAIL("이메일에 골뱅이가 없어요", "alexgmail.com", "코드숨6주차"), - USER_INVALID_PASSWORD("이메일에 골뱅이가 없어요", "alexgmail.com", ""), + USER_INVALID_BLANK_EMAIL("이메일에 골뱅이가 없어요", " ", "코드숨6주차"), + USER_INVALID_BLANK_PASSWORD("이메일에 골뱅이가 없어요", "alexgmail.com", " "), ; private String name; From dd99412eeb2d082bba863d64b7dbf3a587cb031c Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 16:31:28 +0900 Subject: [PATCH 17/39] =?UTF-8?q?feat:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20?= =?UTF-8?q?=EA=B2=80=EC=82=AC=20(=EC=9D=B4=EB=A9=94=EC=9D=BC,=20=EB=B9=84?= =?UTF-8?q?=EB=B0=80=EB=B2=88=ED=98=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/session/controller/SessionController.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java b/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java index 0d4789366..3086717db 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java @@ -10,6 +10,8 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import javax.validation.Valid; + @RestController @RequestMapping("/session") public class SessionController { @@ -21,7 +23,7 @@ public SessionController(final AuthenticationService authenticationService) { @PostMapping @ResponseStatus(HttpStatus.CREATED) - public SessionResponseDto login(@RequestBody final SessionRequestDto sessionRequestDto) { + public SessionResponseDto login(@RequestBody @Valid final SessionRequestDto sessionRequestDto) { return SessionResponseDto.builder() .accessToken(authenticationService.login(sessionRequestDto)) .build(); From 57457669c7f1c070fd4e464a50e457a94bca2dbe Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 16:50:29 +0900 Subject: [PATCH 18/39] =?UTF-8?q?test:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EA=B0=80=EC=9E=85?= =?UTF-8?q?=EB=90=9C=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=EC=9D=98=20=EC=98=88=EC=99=B8=20=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SessionControllerTest.java | 22 +++++++++++++++++++ .../assignment/support/UserFixture.java | 7 +++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java index fad557e82..52ddb59d5 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java @@ -2,6 +2,7 @@ import com.codesoom.assignment.common.util.JsonUtil; import com.codesoom.assignment.domain.session.application.AuthenticationService; +import com.codesoom.assignment.domain.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; @@ -19,6 +20,7 @@ import static com.codesoom.assignment.support.UserFixture.USER_1; import static com.codesoom.assignment.support.UserFixture.USER_INVALID_BLANK_EMAIL; import static com.codesoom.assignment.support.UserFixture.USER_INVALID_BLANK_PASSWORD; +import static com.codesoom.assignment.support.UserFixture.USER_NOT_REGISTER; import static org.hamcrest.Matchers.containsString; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.verify; @@ -108,6 +110,26 @@ void it_responses_400() throws Exception { .andExpect(status().isBadRequest()); } } + + @Nested + @DisplayName("찾을 수 없는 계정일 경우") + class Context_with_not_found_user { + @Test + @DisplayName("404 코드로 응답한다") + void it_responses_404() throws Exception { + given(authenticationService.login(USER_NOT_REGISTER.로그인_요청_데이터_생성())) + .willThrow(new UserNotFoundException(USER_NOT_REGISTER.EMAIL())); + + mockMvc.perform( + post("/session") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(USER_NOT_REGISTER.로그인_요청_데이터_생성())) + ) + .andExpect(status().isNotFound()); + + verify(authenticationService).login(USER_NOT_REGISTER.로그인_요청_데이터_생성()); + } + } } } } diff --git a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java index dbcf0ef79..1f4362ca3 100644 --- a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java @@ -6,9 +6,10 @@ public enum UserFixture { USER_1("기범", "dev.gibeom@gmail.com", "비밀번호486"), USER_2("Alex", "dev.gibeom@gmail.com", "password486"), - USER_INVALID_NAME("", "alex@gmail.com", "코드숨6주차"), - USER_INVALID_BLANK_EMAIL("이메일에 골뱅이가 없어요", " ", "코드숨6주차"), - USER_INVALID_BLANK_PASSWORD("이메일에 골뱅이가 없어요", "alexgmail.com", " "), + USER_NOT_REGISTER("등록되지 않은 회원이에요", "not_register@gmail.com", "password486"), + USER_INVALID_NAME("", "name_invalid@gmail.com", "name.invalid"), + USER_INVALID_BLANK_EMAIL("이메일이 유효하지 않아요", " ", "email.invalid"), + USER_INVALID_BLANK_PASSWORD("비밀번호가 유효하지 않아요", "password_invalid@gmail.com", " "), ; private String name; From 2e8a930307b9a5c6fb03e200fb50ad7fea61c540 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 16:52:59 +0900 Subject: [PATCH 19/39] =?UTF-8?q?feat:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EA=B0=80=EC=9E=85?= =?UTF-8?q?=EB=90=9C=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EC=95=84=EB=8B=8C=20?= =?UTF-8?q?=EA=B2=BD=EC=9A=B0=20404=20=EC=9D=91=EB=8B=B5=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/domain/user/exception/UserErrorAdvice.java | 4 +++- .../domain/user/exception/UserNotFoundException.java | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java index c3fba10a9..29997ab39 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java @@ -1,5 +1,6 @@ package com.codesoom.assignment.domain.user.exception; +import com.codesoom.assignment.domain.session.controller.SessionController; import com.codesoom.assignment.domain.user.presentation.UserController; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; @@ -13,7 +14,8 @@ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @RestControllerAdvice(basePackageClasses = { - UserController.class + UserController.class, + SessionController.class }) @Order(Ordered.HIGHEST_PRECEDENCE) public @interface UserErrorAdvice { diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java index 4d914b31c..42f7054ee 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java @@ -4,4 +4,8 @@ public class UserNotFoundException extends RuntimeException { public UserNotFoundException(Long id) { super("User not found: " + id); } + + public UserNotFoundException(String email) { + super("User not found: " + email); + } } From 54177644848460ac5c4ecf0c16f618de63f744c3 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 17:53:31 +0900 Subject: [PATCH 20/39] =?UTF-8?q?test:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EA=B0=80=20=ED=8B=80=EB=A6=B0=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=EC=9D=98=20=EC=98=88=EC=99=B8=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/SessionControllerTest.java | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java index 52ddb59d5..6e709ad2e 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java @@ -2,6 +2,7 @@ import com.codesoom.assignment.common.util.JsonUtil; import com.codesoom.assignment.domain.session.application.AuthenticationService; +import com.codesoom.assignment.domain.user.exception.UserInvalidPasswordException; import com.codesoom.assignment.domain.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -18,6 +19,7 @@ import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static com.codesoom.assignment.support.UserFixture.USER_1; +import static com.codesoom.assignment.support.UserFixture.USER_2; import static com.codesoom.assignment.support.UserFixture.USER_INVALID_BLANK_EMAIL; import static com.codesoom.assignment.support.UserFixture.USER_INVALID_BLANK_PASSWORD; import static com.codesoom.assignment.support.UserFixture.USER_NOT_REGISTER; @@ -28,9 +30,6 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -/* - 세션 등록 -> POST /session -*/ @SpringBootTest @AutoConfigureMockMvc @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) @@ -68,16 +67,6 @@ void it_responses_201() throws Exception { } } - /* - 로그인 API는 - - 유효하지 않는 회원 정보가 주어지면 - - 빈 값이 주어질 경우 - - 400 코드를 응답한다 (@Valid) - - 찾을 수 없는 계정일 경우 - - 404 코드를 응답한다 (UserNotFoundException) - - 비밀번호가 틀렸을 경우 - - 400 코드를 응답한다 (InvalidUserPasswordException) - */ @Nested @DisplayName("유효하지 않는 회원 정보가 주어지면") class Context_with_invalid_user { @@ -114,12 +103,15 @@ void it_responses_400() throws Exception { @Nested @DisplayName("찾을 수 없는 계정일 경우") class Context_with_not_found_user { - @Test - @DisplayName("404 코드로 응답한다") - void it_responses_404() throws Exception { + @BeforeEach + void setUpGiven() { given(authenticationService.login(USER_NOT_REGISTER.로그인_요청_데이터_생성())) .willThrow(new UserNotFoundException(USER_NOT_REGISTER.EMAIL())); + } + @Test + @DisplayName("404 코드로 응답한다") + void it_responses_404() throws Exception { mockMvc.perform( post("/session") .contentType(MediaType.APPLICATION_JSON) @@ -130,6 +122,29 @@ void it_responses_404() throws Exception { verify(authenticationService).login(USER_NOT_REGISTER.로그인_요청_데이터_생성()); } } + + @Nested + @DisplayName("비밀번호가 틀렸을 경우") + class Context_with_wrong_password { + @BeforeEach + void setUpGiven() { + given(authenticationService.login(USER_2.로그인_요청_데이터_생성())) + .willThrow(new UserInvalidPasswordException(USER_2.EMAIL())); + } + + @Test + @DisplayName("403 코드로 응답한다") + void it_responses_403() throws Exception { + mockMvc.perform( + post("/session") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(USER_2.로그인_요청_데이터_생성())) + ) + .andExpect(status().isForbidden()); + + verify(authenticationService).login(USER_2.로그인_요청_데이터_생성()); + } + } } } } From 2643cafba821e53ffcb47ff8c44b4b7ade8b1b3e Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 18:05:02 +0900 Subject: [PATCH 21/39] =?UTF-8?q?feat:=20(session-presentation)=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EA=B0=80=20=ED=8B=80=EB=A6=B0=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=20403=20=EC=9D=91=EB=8B=B5=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=B0=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/exception/UserExceptionHandler.java | 6 ++++++ .../user/exception/UserInvalidPasswordException.java | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java index 56fe8301a..3f1d9dac0 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java @@ -19,4 +19,10 @@ public ErrorResponse handleUserNotFound() { public ErrorResponse handleUserEmailIsAlreadyExisted() { return new ErrorResponse("User's email address is already existed"); } + + @ResponseStatus(HttpStatus.FORBIDDEN) + @ExceptionHandler(UserInvalidPasswordException.class) + public ErrorResponse handleUserInvalidPassword(UserInvalidPasswordException exception) { + return new ErrorResponse(exception.getMessage()); + } } diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java new file mode 100644 index 000000000..f69eb4fba --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java @@ -0,0 +1,7 @@ +package com.codesoom.assignment.domain.user.exception; + +public class UserInvalidPasswordException extends RuntimeException{ + public UserInvalidPasswordException(String email) { + super("비밀번호가 일치하지 않습니다: " + email); + } +} From 0260115ffae0b51f3be13a20956426b5fa4c9418 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 19:15:51 +0900 Subject: [PATCH 22/39] =?UTF-8?q?test:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EC=B0=BE=EC=9D=84=20=EC=88=98?= =?UTF-8?q?=20=EC=97=86=EB=8A=94=20=EA=B3=84=EC=A0=95=EC=9D=BC=20=EA=B2=BD?= =?UTF-8?q?=EC=9A=B0=EC=9D=98=20=EC=98=88=EC=99=B8=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuthenticationServiceTest.java | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java index d36298b78..0a79f2ac6 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java @@ -2,6 +2,7 @@ import com.codesoom.assignment.common.util.JwtUtil; import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; @@ -14,21 +15,13 @@ import static com.codesoom.assignment.support.IdFixture.ID_MIN; import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static com.codesoom.assignment.support.UserFixture.USER_1; +import static com.codesoom.assignment.support.UserFixture.USER_NOT_REGISTER; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -/* - - login 메서드는 - - 유효한 회원 정보가 주어지면 - - 토큰을 반환한다 - - 유효하지 않는 회원 정보가 주어지면 - - 찾을 수 없는 Email일 경우 - - 예외를 던진다 (UserNotFoundException) - - 비밀번호가 틀렸을 경우 - - 예외를 던진다 (InvalidUserPasswordException) -*/ @DisplayName("AuthenticationService 단위 테스트") class AuthenticationServiceTest { private AuthenticationService authenticationService; @@ -45,8 +38,8 @@ void setUpVariable() { class login_메서드는 { @Nested - @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) - class 유효한_회원_정보가_주어지면 { + @DisplayName("유효한 회원 정보가 주어지면") + class Context_with_valid_user { @BeforeEach void setUpGiven() { given(userRepository.findByEmail(USER_1.EMAIL())) @@ -71,5 +64,34 @@ void it_returns_token() { verify(jwtUtil).encode(ID_MIN.value()); } } + + /* + - login 메서드는 + - 유효하지 않는 회원 정보가 주어지면 + - 찾을 수 없는 Email일 경우 + - 예외를 던진다 (UserNotFoundException) + - 비밀번호가 틀렸을 경우 + - 예외를 던진다 (UserInvalidPasswordException) + */ + @Nested + @DisplayName("유효하지 않는 회원 정보가 주어지면") + class Context_with_invalid_user { + @Nested + @DisplayName("찾을 수 없는 계정일 경우") + class Context_with_not_found_user { + @BeforeEach + void setUpGiven() { + given(userRepository.findByEmail(USER_NOT_REGISTER.EMAIL())) + .willThrow(new UserNotFoundException(USER_NOT_REGISTER.EMAIL())); + } + + @Test + @DisplayName("예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> authenticationService.login(USER_NOT_REGISTER.로그인_요청_데이터_생성())) + .isInstanceOf(UserNotFoundException.class); + } + } + } } } From f88281155ceb7dccd4fad947092d3087adcfeacc Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 19:24:40 +0900 Subject: [PATCH 23/39] =?UTF-8?q?feat:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=ED=95=B4=EB=8B=B9=20=EA=B3=84?= =?UTF-8?q?=EC=A0=95=EC=9D=B4=20=EC=97=86=EB=8B=A4=EB=A9=B4=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EB=B0=9C=EC=83=9D=20(UserNotFoundException)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/session/application/AuthenticationService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java b/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java index 13883ceb0..2b1cb67bf 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java @@ -4,6 +4,7 @@ import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; import com.codesoom.assignment.domain.user.domain.User; import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.exception.UserNotFoundException; import org.springframework.stereotype.Service; @Service @@ -17,7 +18,8 @@ public AuthenticationService(final UserRepository userRepository, final JwtUtil } public String login(final SessionRequestDto sessionRequestDto) { - User user = userRepository.findByEmail(sessionRequestDto.getEmail()).get(); + User user = userRepository.findByEmail(sessionRequestDto.getEmail()) + .orElseThrow(() -> new UserNotFoundException(sessionRequestDto.getEmail())); return jwtUtil.encode(user.getId()); } From 254787cf2b765fd02a40446da559b30f4d240609 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 19:50:28 +0900 Subject: [PATCH 24/39] =?UTF-8?q?test:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EA=B0=80=20=ED=8B=80=EB=A6=B0=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=EC=9D=98=20=EC=98=88=EC=99=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AuthenticationServiceTest.java | 30 ++++++++++++++----- .../assignment/support/UserFixture.java | 1 + 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java index 0a79f2ac6..b6c333383 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java @@ -2,6 +2,7 @@ import com.codesoom.assignment.common.util.JwtUtil; import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.exception.UserInvalidPasswordException; import com.codesoom.assignment.domain.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -15,6 +16,8 @@ import static com.codesoom.assignment.support.IdFixture.ID_MIN; import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static com.codesoom.assignment.support.UserFixture.USER_1; +import static com.codesoom.assignment.support.UserFixture.USER_2; +import static com.codesoom.assignment.support.UserFixture.USER_2_DIFFERENT_PASSWORD; import static com.codesoom.assignment.support.UserFixture.USER_NOT_REGISTER; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -65,14 +68,6 @@ void it_returns_token() { } } - /* - - login 메서드는 - - 유효하지 않는 회원 정보가 주어지면 - - 찾을 수 없는 Email일 경우 - - 예외를 던진다 (UserNotFoundException) - - 비밀번호가 틀렸을 경우 - - 예외를 던진다 (UserInvalidPasswordException) - */ @Nested @DisplayName("유효하지 않는 회원 정보가 주어지면") class Context_with_invalid_user { @@ -92,6 +87,25 @@ void it_returns_exception() { .isInstanceOf(UserNotFoundException.class); } } + + @Nested + @DisplayName("비밀번호가 틀렸을 경우") + class Context_with_wrong_password { + @BeforeEach + void setUpGiven() { + given(userRepository.findByEmail(USER_2.EMAIL())) + .willReturn(Optional.of(USER_2_DIFFERENT_PASSWORD.회원_엔티티_생성(ID_MIN.value()))); + } + + @Test + @DisplayName("예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> authenticationService.login(USER_2.로그인_요청_데이터_생성())) + .isInstanceOf(UserInvalidPasswordException.class); + + verify(userRepository).findByEmail(USER_2.EMAIL()); + } + } } } } diff --git a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java index 1f4362ca3..7de554899 100644 --- a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java @@ -6,6 +6,7 @@ public enum UserFixture { USER_1("기범", "dev.gibeom@gmail.com", "비밀번호486"), USER_2("Alex", "dev.gibeom@gmail.com", "password486"), + USER_2_DIFFERENT_PASSWORD("Alex", "dev.gibeom@gmail.com", "비밀번호 틀렸지롱"), USER_NOT_REGISTER("등록되지 않은 회원이에요", "not_register@gmail.com", "password486"), USER_INVALID_NAME("", "name_invalid@gmail.com", "name.invalid"), USER_INVALID_BLANK_EMAIL("이메일이 유효하지 않아요", " ", "email.invalid"), From 8dc5d21ac1ac601ea8ef987e6879041b43e1f980 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 19:58:07 +0900 Subject: [PATCH 25/39] =?UTF-8?q?feat:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EB=B9=84=EB=B0=80=EB=B2=88?= =?UTF-8?q?=ED=98=B8=EA=B0=80=20=ED=8B=80=EB=A0=B8=EB=8B=A4=EB=A9=B4=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EB=B0=9C=EC=83=9D=20(UserInvalidPasswordE?= =?UTF-8?q?xception)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../session/application/AuthenticationService.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java b/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java index 2b1cb67bf..cca08eb65 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java @@ -4,6 +4,7 @@ import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; import com.codesoom.assignment.domain.user.domain.User; import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.domain.user.exception.UserInvalidPasswordException; import com.codesoom.assignment.domain.user.exception.UserNotFoundException; import org.springframework.stereotype.Service; @@ -21,6 +22,14 @@ public String login(final SessionRequestDto sessionRequestDto) { User user = userRepository.findByEmail(sessionRequestDto.getEmail()) .orElseThrow(() -> new UserNotFoundException(sessionRequestDto.getEmail())); + if (isIncorrectPassword(sessionRequestDto, user)) { + throw new UserInvalidPasswordException(sessionRequestDto.getEmail()); + } + return jwtUtil.encode(user.getId()); } + + private boolean isIncorrectPassword(final SessionRequestDto sessionRequestDto, final User user) { + return !sessionRequestDto.getPassword().equals(user.getPassword()); + } } From 57425288a9091f19d3e21f38b54abaa2f3983cc6 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 20:30:39 +0900 Subject: [PATCH 26/39] =?UTF-8?q?test:=20(common-util)=20=EB=94=94?= =?UTF-8?q?=EC=BD=94=EB=94=A9=20=ED=95=A0=20=ED=86=A0=ED=81=B0=EC=9D=B4=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=ED=95=A0=20=EA=B2=BD=EC=9A=B0=20userId?= =?UTF-8?q?=EA=B0=80=20=ED=8F=AC=ED=95=A8=EB=90=9C=20=ED=81=B4=EB=A0=88?= =?UTF-8?q?=EC=9E=84=20=EB=B0=98=ED=99=98=20=EC=BC=80=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/common/util/JwtUtilTest.java | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java index 601379af1..6e8004f54 100644 --- a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java +++ b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java @@ -1,5 +1,10 @@ package com.codesoom.assignment.common.util; +import io.jsonwebtoken.Claims; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; @@ -12,10 +17,31 @@ class JwtUtilTest { @Autowired private JwtUtil jwtUtil; - @Test - void it_returns_token() { - String encode = jwtUtil.encode(ACCESS_TOKEN_1_VALID.아이디()); + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class encode_메서드는 { + @Test + @DisplayName("토큰을 secretKey로 인코딩하여 리턴한다") + void it_returns_token() { + String token = jwtUtil.encode(ACCESS_TOKEN_1_VALID.아이디()); - assertThat(encode).isEqualTo(ACCESS_TOKEN_1_VALID.토큰()); + assertThat(token).isEqualTo(ACCESS_TOKEN_1_VALID.토큰()); + } + } + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class decode_메서드는 { + @Nested + @DisplayName("유효한 토큰이 주어질 경우") + class Context_with_blank_token { + @Test + @DisplayName("userId가 포함된 클레임을 리턴한다") + void it_returns_exception() { + Claims claims = jwtUtil.decode(ACCESS_TOKEN_1_VALID.토큰()); + + assertThat(claims.get("userId", Long.class)).isEqualTo(ACCESS_TOKEN_1_VALID.아이디()); + } + } } } From 9741fdd0fce403f79e11e9bcec6003bb9f916860 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 20:32:02 +0900 Subject: [PATCH 27/39] =?UTF-8?q?feat:=20(common-jwtUtil)=20secretKey?= =?UTF-8?q?=EB=A5=BC=20=EC=82=AC=EC=9A=A9=ED=95=9C=20=ED=86=A0=ED=81=B0=20?= =?UTF-8?q?=EB=94=94=EC=BD=94=EB=94=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../codesoom/assignment/common/util/JwtUtil.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java index 9d8e9fc89..8b18f2707 100644 --- a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java +++ b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java @@ -1,5 +1,6 @@ package com.codesoom.assignment.common.util; +import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; import org.springframework.beans.factory.annotation.Value; @@ -9,16 +10,24 @@ @Component public class JwtUtil { - private final Key key; + private final Key secretKey; public JwtUtil(@Value("${jwt.secret}") String secretKey) { - key = Keys.hmacShaKeyFor(secretKey.getBytes()); + this.secretKey = Keys.hmacShaKeyFor(secretKey.getBytes()); } public String encode(Long id) { return Jwts.builder() .claim("userId", id) - .signWith(key) + .signWith(secretKey) .compact(); } + + public Claims decode(String token) { + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token) + .getBody(); + } } From 29389dd7c371687019d8bb0f50cf5df0423bdbe2 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 20:41:40 +0900 Subject: [PATCH 28/39] =?UTF-8?q?test:=20(common-jwtUtil)=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=9D=B4=20=EC=9C=A0=ED=9A=A8=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EA=B1=B0=EB=82=98=20=EA=B3=B5=EB=B0=B1=EC=9D=B8=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/InvalidTokenException.java | 7 +++++ .../assignment/common/util/JwtUtilTest.java | 30 +++++++++++++++++-- .../assignment/support/TokenFixture.java | 3 +- 3 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java b/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java new file mode 100644 index 000000000..3aff8c445 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java @@ -0,0 +1,7 @@ +package com.codesoom.assignment.domain.session.exception; + +public class InvalidTokenException extends RuntimeException{ + public InvalidTokenException(String token) { + super("토큰이 유효하지 않습니다: " + token); + } +} diff --git a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java index 6e8004f54..ec8a85971 100644 --- a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java +++ b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java @@ -1,5 +1,6 @@ package com.codesoom.assignment.common.util; +import com.codesoom.assignment.domain.session.exception.InvalidTokenException; import io.jsonwebtoken.Claims; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; @@ -9,8 +10,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_INVALID; +import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_INVALID_BLANK; import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; @WebMvcTest(JwtUtil.class) class JwtUtilTest { @@ -34,14 +38,36 @@ void it_returns_token() { class decode_메서드는 { @Nested @DisplayName("유효한 토큰이 주어질 경우") - class Context_with_blank_token { + class Context_with_valid_token { @Test @DisplayName("userId가 포함된 클레임을 리턴한다") - void it_returns_exception() { + void it_returns_claims() { Claims claims = jwtUtil.decode(ACCESS_TOKEN_1_VALID.토큰()); assertThat(claims.get("userId", Long.class)).isEqualTo(ACCESS_TOKEN_1_VALID.아이디()); } } + + @Nested + @DisplayName("유효하지 않은 토큰이 주어질 경우") + class Context_with_invalid_token { + @Test + @DisplayName("예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> jwtUtil.decode(ACCESS_TOKEN_1_INVALID.토큰())) + .isInstanceOf(InvalidTokenException.class); + } + } + + @Nested + @DisplayName("토큰이 공백으로 주어질 경우") + class Context_with_blank_token { + @Test + @DisplayName("예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> jwtUtil.decode(ACCESS_TOKEN_1_INVALID_BLANK.토큰())) + .isInstanceOf(InvalidTokenException.class); + } + } } } diff --git a/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java b/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java index 209b5762d..cac5eb92f 100644 --- a/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java @@ -2,7 +2,8 @@ public enum TokenFixture { ACCESS_TOKEN_1_VALID("giibeomIsA2YearsBackendDeveloper", 1L , "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.u-4fczk36juKx46aceMNuz2WJJJj1STWPjfLQA-Z5xY"), - ACCESS_TOKEN_1_INVALID("giibeomIsA2YearsBackendDeveloper", 1L, "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + ACCESS_TOKEN_1_INVALID("giibeomIsA2YearsBackendDeveloper", 1L, "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"), + ACCESS_TOKEN_1_INVALID_BLANK("giibeomIsA2YearsBackendDeveloper", 1L, " "); private final String secretKey; private final Long id; From 2d9eea1967d4e6fccbe0234793a580c972ba327e Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 20:47:53 +0900 Subject: [PATCH 29/39] =?UTF-8?q?feat:=20(common-jwtUtil)=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=EC=9D=B4=20=EC=9C=A0=ED=9A=A8=ED=95=98=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EA=B1=B0=EB=82=98=20=EA=B3=B5=EB=B0=B1=EC=9D=B4?= =?UTF-8?q?=EB=A9=B4=20=EC=98=88=EC=99=B8=20=EB=B0=9C=EC=83=9D=20(InvalidT?= =?UTF-8?q?okenException)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/common/util/JwtUtil.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java index 8b18f2707..faebc9a8b 100644 --- a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java +++ b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java @@ -1,8 +1,10 @@ package com.codesoom.assignment.common.util; +import com.codesoom.assignment.domain.session.exception.InvalidTokenException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -24,10 +26,18 @@ public String encode(Long id) { } public Claims decode(String token) { - return Jwts.parserBuilder() - .setSigningKey(secretKey) - .build() - .parseClaimsJws(token) - .getBody(); + if (token == null || token.isBlank()) { + throw new InvalidTokenException(token); + } + + try { + return Jwts.parserBuilder() + .setSigningKey(secretKey) + .build() + .parseClaimsJws(token) + .getBody(); + } catch (SignatureException exception) { + throw new InvalidTokenException(token); + } } } From 863f8a0d8344a5a290195186f134b10499b42377 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 21:55:45 +0900 Subject: [PATCH 30/39] =?UTF-8?q?fix:=20(session-application)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=8B=9C=20=EC=B0=BE=EC=9D=84=20=EC=88=98?= =?UTF-8?q?=20=EC=97=86=EB=8A=94=20=EA=B3=84=EC=A0=95=EC=9D=B8=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EC=BC=80=EC=9D=B4=EC=8A=A4=EC=97=90=EC=84=9C=20moc?= =?UTF-8?q?king=20=EB=B0=98=ED=99=98=20=EA=B0=92=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/session/application/AuthenticationServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java index b6c333383..724c31a4a 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java @@ -77,7 +77,7 @@ class Context_with_not_found_user { @BeforeEach void setUpGiven() { given(userRepository.findByEmail(USER_NOT_REGISTER.EMAIL())) - .willThrow(new UserNotFoundException(USER_NOT_REGISTER.EMAIL())); + .willReturn(Optional.empty()); } @Test From db0ca44738dc510631ee0984fc4c3eed95367866 Mon Sep 17 00:00:00 2001 From: giibeom Date: Thu, 17 Nov 2022 22:03:33 +0900 Subject: [PATCH 31/39] =?UTF-8?q?fix:=20(common-jwtUtil)=20secretKey?= =?UTF-8?q?=EB=A5=BC=20=EA=B8=B0=EC=A1=B4=20=EA=B0=92=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=ED=95=98=EC=97=AC=20=ED=86=A0=ED=81=B0=20fix?= =?UTF-8?q?ture=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EC=9D=98=20=EC=9D=B8?= =?UTF-8?q?=EC=BD=94=EB=94=A9=20=EB=94=94=EC=BD=94=EB=94=A9=20=EA=B0=92=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/codesoom/assignment/support/TokenFixture.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java b/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java index cac5eb92f..9e2047257 100644 --- a/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/TokenFixture.java @@ -1,9 +1,9 @@ package com.codesoom.assignment.support; public enum TokenFixture { - ACCESS_TOKEN_1_VALID("giibeomIsA2YearsBackendDeveloper", 1L , "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.u-4fczk36juKx46aceMNuz2WJJJj1STWPjfLQA-Z5xY"), - ACCESS_TOKEN_1_INVALID("giibeomIsA2YearsBackendDeveloper", 1L, "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"), - ACCESS_TOKEN_1_INVALID_BLANK("giibeomIsA2YearsBackendDeveloper", 1L, " "); + ACCESS_TOKEN_1_VALID("12345678901234567890123456789010", 1L , "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.neCsyNLzy3lQ4o2yliotWT06FwSGZagaHpKdAkjnGGw"), + ACCESS_TOKEN_1_INVALID("12345678901234567890123456789010", 1L, "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"), + ACCESS_TOKEN_1_INVALID_BLANK("12345678901234567890123456789010", 1L, " "); private final String secretKey; private final Long id; From 4235ee9eb96c51bad89d79ab3b7a4a947e7bd653 Mon Sep 17 00:00:00 2001 From: giibeom Date: Fri, 18 Nov 2022 17:16:51 +0900 Subject: [PATCH 32/39] =?UTF-8?q?feat:=20(common-interceptor)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20han?= =?UTF-8?q?dler=EB=A1=9C=20API=20=EC=9A=94=EC=B2=AD=EC=9D=B4=20=EC=98=AC?= =?UTF-8?q?=20=EB=95=8C=20Auth=20=ED=86=A0=ED=81=B0=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Controller 메서드에 `@Login`이 선언되어 있는 handler인 경우에 Auth 토큰을 검증 - `@Login`의 required default 값은 true --- .../auth/AuthenticationInterceptor.java | 57 +++++++++++++++++++ .../assignment/common/auth/Login.java | 13 +++++ .../assignment/common/config/WebConfig.java | 25 ++++++++ .../assignment/common/util/JwtUtil.java | 14 +++++ .../exception/InvalidTokenException.java | 6 +- .../exception/TokenNotExistException.java | 7 +++ 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java create mode 100644 app/src/main/java/com/codesoom/assignment/common/auth/Login.java create mode 100644 app/src/main/java/com/codesoom/assignment/common/config/WebConfig.java create mode 100644 app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java diff --git a/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java b/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java new file mode 100644 index 000000000..911f37d86 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java @@ -0,0 +1,57 @@ +package com.codesoom.assignment.common.auth; + +import com.codesoom.assignment.common.util.JwtUtil; +import com.codesoom.assignment.domain.session.exception.TokenNotExistException; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Component; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@Component +public class AuthenticationInterceptor implements HandlerInterceptor { + + private final JwtUtil jwtUtil; + + public AuthenticationInterceptor(JwtUtil jwtUtil) { + this.jwtUtil = jwtUtil; + } + + @Override + public boolean preHandle(final HttpServletRequest request, + final HttpServletResponse response, + final Object handler) throws Exception { + if (isNotHandlerMethod(handler) || isNotRequiredAuth(handler)) { + return true; + } + + if (isNotExistAuthorization(request)) { + throw new TokenNotExistException(); + } + + validateAuthToken(request); + + return true; + } + + private void validateAuthToken(HttpServletRequest request) { + jwtUtil.validateAccessToken(request.getHeader(HttpHeaders.AUTHORIZATION)); + } + + private static boolean isNotExistAuthorization(HttpServletRequest request) { + return request.getHeader(HttpHeaders.AUTHORIZATION) == null; + } + + private static boolean isNotHandlerMethod(Object handler) { + return !(handler instanceof HandlerMethod); + } + + private boolean isNotRequiredAuth(Object handler) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Login auth = handlerMethod.getMethodAnnotation(Login.class); + + return auth == null || !auth.required(); + } +} diff --git a/app/src/main/java/com/codesoom/assignment/common/auth/Login.java b/app/src/main/java/com/codesoom/assignment/common/auth/Login.java new file mode 100644 index 000000000..f30c9c071 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/auth/Login.java @@ -0,0 +1,13 @@ +package com.codesoom.assignment.common.auth; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Login { + + boolean required() default true; +} diff --git a/app/src/main/java/com/codesoom/assignment/common/config/WebConfig.java b/app/src/main/java/com/codesoom/assignment/common/config/WebConfig.java new file mode 100644 index 000000000..90af75435 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/config/WebConfig.java @@ -0,0 +1,25 @@ +package com.codesoom.assignment.common.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.util.List; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + private final List interceptors; + + public WebConfig(List interceptors) { + this.interceptors = interceptors; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + for (HandlerInterceptor interceptor : interceptors) { + registry.addInterceptor(interceptor); + } + } +} diff --git a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java index faebc9a8b..751a0bc0e 100644 --- a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java +++ b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java @@ -1,6 +1,7 @@ package com.codesoom.assignment.common.util; import com.codesoom.assignment.domain.session.exception.InvalidTokenException; +import com.codesoom.assignment.domain.session.exception.TokenNotExistException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; @@ -12,6 +13,7 @@ @Component public class JwtUtil { + private static final String ACCESS_TOKEN_TYPE = "Bearer"; private final Key secretKey; public JwtUtil(@Value("${jwt.secret}") String secretKey) { @@ -40,4 +42,16 @@ public Claims decode(String token) { throw new InvalidTokenException(token); } } + + public void validateAccessToken(String authHeader) { + if (authHeader == null) { + throw new TokenNotExistException(); + } + + if (!authHeader.startsWith(ACCESS_TOKEN_TYPE)) { + throw new InvalidTokenException(); + } + + decode(authHeader.substring(ACCESS_TOKEN_TYPE.length())); + } } diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java b/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java index 3aff8c445..62f78d1ed 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java @@ -1,6 +1,10 @@ package com.codesoom.assignment.domain.session.exception; -public class InvalidTokenException extends RuntimeException{ +public class InvalidTokenException extends RuntimeException { + public InvalidTokenException() { + super("토큰이 유효하지 않습니다"); + } + public InvalidTokenException(String token) { super("토큰이 유효하지 않습니다: " + token); } diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java b/app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java new file mode 100644 index 000000000..632980f58 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java @@ -0,0 +1,7 @@ +package com.codesoom.assignment.domain.session.exception; + +public class TokenNotExistException extends RuntimeException { + public TokenNotExistException() { + super("토큰이 존재하지 않습니다"); + } +} From 492feee8a8a23cdc597ed07d5b04825659a6b3fe Mon Sep 17 00:00:00 2001 From: giibeom Date: Fri, 18 Nov 2022 17:42:38 +0900 Subject: [PATCH 33/39] =?UTF-8?q?test:=20(common-jwtUtil)=20accessToken=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=8B=9C=20=ED=86=A0=ED=81=B0=EC=9D=B4=20?= =?UTF-8?q?=EC=9C=A0=ED=9A=A8=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=80=203?= =?UTF-8?q?=EA=B0=9C=EC=9D=98=20=EC=98=88=EC=99=B8=20=EC=BC=80=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - null이 주어질 경우 - 토큰 타입이 Bearer가 아닐 경우 - 토큰 타입이 Bearer이지만 유효하지 않은 토큰일 경우 --- .../assignment/common/util/JwtUtilTest.java | 45 +++++++++++++++++++ .../assignment/support/AuthHeaderFixture.java | 16 +++++++ 2 files changed, 61 insertions(+) create mode 100644 app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java diff --git a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java index ec8a85971..80fba0111 100644 --- a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java +++ b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java @@ -1,6 +1,7 @@ package com.codesoom.assignment.common.util; import com.codesoom.assignment.domain.session.exception.InvalidTokenException; +import com.codesoom.assignment.domain.session.exception.TokenNotExistException; import io.jsonwebtoken.Claims; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; @@ -10,6 +11,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import static com.codesoom.assignment.support.AuthHeaderFixture.INVALID_TOKEN_TYPE; +import static com.codesoom.assignment.support.AuthHeaderFixture.INVALID_TOKEN_VALUE; import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_INVALID; import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_INVALID_BLANK; import static com.codesoom.assignment.support.TokenFixture.ACCESS_TOKEN_1_VALID; @@ -70,4 +73,46 @@ void it_returns_exception() { } } } + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class validateAccessToken_메서드는 { + + @Nested + @DisplayName("null이 주어질 경우") + class Context_with_null { + @Test + @DisplayName("TokenNotExistException 예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> jwtUtil.validateAccessToken(null)) + .isInstanceOf(TokenNotExistException.class); + } + } + + @Nested + @DisplayName("토큰 타입이 Bearer가 아닐 경우") + class Context_with_no_start_bearer { + @Test + @DisplayName("InvalidTokenException 예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> jwtUtil.validateAccessToken(INVALID_TOKEN_TYPE.인증_헤더값())) + .isInstanceOf(InvalidTokenException.class); + } + } + + @Nested + @DisplayName("토큰 타입이 Bearer일 경우") + class Context_with_start_bearer { + @Nested + @DisplayName("유효하지 않은 토큰이 주어지면") + class Context_with_valid_token { + @Test + @DisplayName("InvalidTokenException 예외를 던진다") + void it_returns_exception() { + assertThatThrownBy(() -> jwtUtil.validateAccessToken(INVALID_TOKEN_VALUE.인증_헤더값())) + .isInstanceOf(InvalidTokenException.class); + } + } + } + } } diff --git a/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java b/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java new file mode 100644 index 000000000..de39133d2 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java @@ -0,0 +1,16 @@ +package com.codesoom.assignment.support; + +public enum AuthHeaderFixture { + INVALID_TOKEN_TYPE("Giibeom eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.neCsyNLzy3lQ4o2yliotWT06FwSGZagaHpKdAkjnGGw"), + INVALID_TOKEN_VALUE("Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + + AuthHeaderFixture(String authorization) { + this.authorization = authorization; + } + + private final String authorization; + + public String 인증_헤더값() { + return authorization; + } +} From 98f56bb10a496579c79b2adda577c9028fa77695 Mon Sep 17 00:00:00 2001 From: giibeom Date: Fri, 18 Nov 2022 20:42:08 +0900 Subject: [PATCH 34/39] =?UTF-8?q?test:=20(common-interceptor)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20API?= =?UTF-8?q?=20=EC=9A=94=EC=B2=AD=20=EC=8B=9C=20Auth=20=ED=86=A0=ED=81=B0?= =?UTF-8?q?=EC=9D=B4=20=EC=97=86=EB=8A=94=20=EC=98=88=EC=99=B8=20=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 상품 등록 API - 상품 수정 API - 상품 삭제 API --- .../auth/AuthenticationInterceptorTest.java | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java diff --git a/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java b/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java new file mode 100644 index 000000000..06342397a --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java @@ -0,0 +1,97 @@ +package com.codesoom.assignment.common.auth; + +import com.codesoom.assignment.common.util.JsonUtil; +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.presentation.ProductController; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.DisplayNameGeneration; +import org.junit.jupiter.api.DisplayNameGenerator; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import static com.codesoom.assignment.support.ProductFixture.TOY_1; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.patch; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +class AuthenticationInterceptorTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ProductController productController; + + @Nested + @DisplayName("Auth 토큰이 존재하지 않을 경우") + class Context_with_not_exist_auth_token { + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class 장난감_등록하기_API는 { + @Test + @DisplayName("401 코드로 응답한다") + void it_responses_401() throws Exception { + mockMvc.perform( + post("/products") + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(TOY_1.요청_데이터_생성())) + ) + .andExpect(status().isUnauthorized()); + } + } + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class 장난감_수정하기_API는 { + private Long fixtureId; + + @BeforeEach + void setUpCreateFixture() { + Product productSource = productController.create(TOY_1.요청_데이터_생성()); + fixtureId = productSource.getId(); + } + + @Test + @DisplayName("401 코드로 응답한다") + void it_responses_401() throws Exception { + mockMvc.perform( + patch("/products/" + fixtureId) + .contentType(MediaType.APPLICATION_JSON) + .content(JsonUtil.writeValue(TOY_1.요청_데이터_생성())) + ) + .andExpect(status().isUnauthorized()); + } + } + + @Nested + @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class) + class 장난감_삭제하기_API는 { + private Long fixtureId; + + @BeforeEach + void setUpCreateFixture() { + Product productSource = productController.create(TOY_1.요청_데이터_생성()); + fixtureId = productSource.getId(); + } + + @Test + @DisplayName("401 코드로 응답한다") + void it_responses_401() throws Exception { + mockMvc.perform( + delete("/products/" + fixtureId) + ) + .andExpect(status().isUnauthorized()); + } + } + } +} From 069a3b83b14036ecc7374802b5b574d7dab4fe8e Mon Sep 17 00:00:00 2001 From: giibeom Date: Fri, 18 Nov 2022 20:43:06 +0900 Subject: [PATCH 35/39] =?UTF-8?q?feat:=20(common-interceptor)=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20API?= =?UTF-8?q?=EC=97=90=20`@Login`=EC=9D=84=20=EC=84=A0=EC=96=B8=ED=95=98?= =?UTF-8?q?=EC=97=AC=20Auth=20=ED=86=A0=ED=81=B0=20=EA=B2=80=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 상품 등록 API - 상품 수정 API - 상품 삭제 API --- .../presentation/ProductController.java | 6 ++ .../session/controller/SessionController.java | 2 + .../session/exception/SessionErrorAdvice.java | 20 ++++++ .../exception/SessionExceptionHandler.java | 22 +++++++ .../user/presentation/UserController.java | 4 ++ .../assignment/support/ProductFixture.java | 65 +++++++++++++++++++ 6 files changed, 119 insertions(+) create mode 100644 app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java create mode 100644 app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java create mode 100644 app/src/test/java/com/codesoom/assignment/support/ProductFixture.java diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java b/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java index f1b4acca3..f5a811bd4 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java @@ -1,5 +1,6 @@ package com.codesoom.assignment.domain.product.presentation; +import com.codesoom.assignment.common.auth.Login; import com.codesoom.assignment.domain.product.application.ProductService; import com.codesoom.assignment.domain.product.domain.Product; import com.codesoom.assignment.domain.product.presentation.dto.ProductData; @@ -29,11 +30,13 @@ public ProductController(ProductService productService) { } @GetMapping + @Login(required = false) public List list() { return productService.getProducts(); } @GetMapping("{id}") + @Login(required = false) public Product detail(@PathVariable Long id) throws Exception { if (id == 3L) { throw new Exception(); @@ -44,6 +47,7 @@ public Product detail(@PathVariable Long id) throws Exception { @PostMapping @ResponseStatus(HttpStatus.CREATED) + @Login public Product create( @RequestBody @Valid ProductData productData ) { @@ -51,6 +55,7 @@ public Product create( } @PatchMapping("{id}") + @Login public Product update( @PathVariable Long id, @RequestBody @Valid ProductData productData @@ -60,6 +65,7 @@ public Product update( @DeleteMapping("{id}") @ResponseStatus(HttpStatus.NO_CONTENT) + @Login public void destroy( @PathVariable Long id ) { diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java b/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java index 3086717db..1f93504bf 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java @@ -1,5 +1,6 @@ package com.codesoom.assignment.domain.session.controller; +import com.codesoom.assignment.common.auth.Login; import com.codesoom.assignment.domain.session.application.AuthenticationService; import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; import com.codesoom.assignment.domain.session.controller.dto.SessionResponseDto; @@ -23,6 +24,7 @@ public SessionController(final AuthenticationService authenticationService) { @PostMapping @ResponseStatus(HttpStatus.CREATED) + @Login(required = false) public SessionResponseDto login(@RequestBody @Valid final SessionRequestDto sessionRequestDto) { return SessionResponseDto.builder() .accessToken(authenticationService.login(sessionRequestDto)) diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java new file mode 100644 index 000000000..5a8eead5c --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java @@ -0,0 +1,20 @@ +package com.codesoom.assignment.domain.session.exception; + +import com.codesoom.assignment.domain.product.presentation.ProductController; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@RestControllerAdvice(basePackageClasses = { + ProductController.class +}) +@Order(Ordered.HIGHEST_PRECEDENCE) +public @interface SessionErrorAdvice { +} diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java new file mode 100644 index 000000000..9c1d26eb6 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java @@ -0,0 +1,22 @@ +package com.codesoom.assignment.domain.session.exception; + +import com.codesoom.assignment.common.exception.ErrorResponse; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +@SessionErrorAdvice +public class SessionExceptionHandler { + + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ExceptionHandler(InvalidTokenException.class) + public ErrorResponse handleInvalidToken() { + return new ErrorResponse("토큰이 유효하지 않습니다"); + } + + @ResponseStatus(HttpStatus.UNAUTHORIZED) + @ExceptionHandler(TokenNotExistException.class) + public ErrorResponse handleTokenNotExist() { + return new ErrorResponse("토큰이 존재하지 않습니다"); + } +} diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java index 8f9825792..0fba5778d 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java +++ b/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java @@ -1,5 +1,6 @@ package com.codesoom.assignment.domain.user.presentation; +import com.codesoom.assignment.common.auth.Login; import com.codesoom.assignment.domain.user.application.UserService; import com.codesoom.assignment.domain.user.domain.User; import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; @@ -30,12 +31,14 @@ public UserController(UserService userService) { @PostMapping @ResponseStatus(HttpStatus.CREATED) + @Login(required = false) UserResultData create(@RequestBody @Valid UserRegistrationData registrationData) { User user = userService.registerUser(registrationData); return getUserResultData(user); } @PatchMapping("{id}") + @Login(required = false) UserResultData update( @PathVariable Long id, @RequestBody @Valid UserModificationData modificationData @@ -46,6 +49,7 @@ UserResultData update( @DeleteMapping("{id}") @ResponseStatus(HttpStatus.NO_CONTENT) + @Login(required = false) void destroy(@PathVariable Long id) { userService.deleteUser(id); } diff --git a/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java b/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java new file mode 100644 index 000000000..38b2ff4b3 --- /dev/null +++ b/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java @@ -0,0 +1,65 @@ +package com.codesoom.assignment.support; + +import com.codesoom.assignment.domain.product.domain.Product; +import com.codesoom.assignment.domain.product.presentation.dto.ProductData; + +public enum ProductFixture { + TOY_1("범냐옹", "메이드인 코리아", 2000000, "https://avatars.githubusercontent.com/u/59248326"), + TOY_2("기냐옹", "메이드인 안양", 3000000, "https://avatars.githubusercontent.com/u/59248326"), + TOY_3("코드숨냐옹", "매이드인 서울", 5000000, null), + TOY_INVALID_NAME("", "메이드인 코리아", 2000000, "https://avatars.githubusercontent.com/u/59248326"), + TOY_INVALID_MAKER("이름은 있지롱", "", 2000000, "https://avatars.githubusercontent.com/u/59248326"), + TOY_INVALID_PRICE("가격은 있지롱", "메이드인 코리아", -20000, "https://avatars.githubusercontent.com/u/59248326"), + ; + + private final String name; + private final String maker; + private final int price; + private final String imageUrl; + + ProductFixture(String name, String maker, int price, String imageUrl) { + this.name = name; + this.maker = maker; + this.price = price; + this.imageUrl = imageUrl; + } + + public Product 엔티티_생성() { + return 엔티티_생성(null); + } + + public Product 엔티티_생성(final Long id) { + return Product.builder() + .id(id) + .name(name) + .maker(maker) + .price(price) + .imageUrl(imageUrl) + .build(); + } + + public ProductData 요청_데이터_생성() { + return ProductData.builder() + .name(name) + .maker(maker) + .price(price) + .imageUrl(imageUrl) + .build(); + } + + public String NAME() { + return name; + } + + public String MAKER() { + return maker; + } + + public int PRICE() { + return price; + } + + public String IMAGE() { + return imageUrl; + } +} From d16fb31bf9c012c8686e9bbafe45f25e28884f5f Mon Sep 17 00:00:00 2001 From: giibeom Date: Sat, 19 Nov 2022 17:06:31 +0900 Subject: [PATCH 36/39] =?UTF-8?q?refactor:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD=20(exception)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 각 도메인 별 ErrorAdvice를 common 패키지의 error 패키지로 이관 - 각 도메인 별 Exception은 도메인 패키지의 exception 패키지에 응집 --- .../auth/AuthenticationInterceptor.java | 2 +- .../{exception => error}/ErrorResponse.java | 2 +- .../GlobalErrorAdvice.java} | 10 ++-- .../common/error/ProductErrorAdvice.java | 23 ++++++++ .../error/SessionErrorAdvice.java} | 16 ++++-- .../error/UserErrorAdvice.java} | 19 +++++-- .../assignment/common/util/JwtUtil.java | 28 +++++----- .../product/exception/ProductErrorAdvice.java | 20 ------- .../exception/ProductExceptionHandler.java | 16 ------ .../session/exception/SessionErrorAdvice.java | 20 ------- .../user/exception/UserErrorAdvice.java | 22 -------- .../product/application/ProductService.java | 10 ++-- .../{domain => }/product/domain/Product.java | 2 +- .../product/domain/ProductRepository.java | 2 +- .../exception/ProductNotFoundException.java | 2 +- .../product/infra/JpaProductRepository.java | 6 +-- .../presentation/ProductController.java | 8 +-- .../product/presentation/dto/ProductData.java | 8 ++- .../application/AuthenticationService.java | 12 ++--- .../session/controller/SessionController.java | 8 +-- .../controller/dto/SessionRequestDto.java | 2 +- .../controller/dto/SessionResponseDto.java | 2 +- .../exception/InvalidTokenException.java | 2 +- .../exception/TokenNotExistException.java | 2 +- .../user/application/UserService.java | 16 +++--- .../{domain => }/user/domain/User.java | 2 +- .../user/domain/UserRepository.java | 2 +- .../UserEmailDuplicationException.java | 2 +- .../UserInvalidPasswordException.java | 4 +- .../user/exception/UserNotFoundException.java | 2 +- .../user/infra/JpaUserRepository.java | 6 +-- .../user/presentation/UserController.java | 12 ++--- .../dto/UserModificationData.java | 2 +- .../dto/UserRegistrationData.java | 2 +- .../user/presentation/dto/UserResultData.java | 2 +- .../auth/AuthenticationInterceptorTest.java | 4 +- .../assignment/common/util/JwtUtilTest.java | 4 +- .../controller/SessionControllerTest.java | 6 +-- .../application/ProductServiceTest.java | 10 ++-- .../product/domain/ProductTest.java | 2 +- .../presentation/ProductControllerTest.java | 10 ++-- .../AuthenticationServiceTest.java | 8 +-- .../assignment/support/ProductFixture.java | 4 +- .../assignment/support/UserFixture.java | 4 +- .../user/application/UserServiceTest.java | 16 +++--- .../{domain => }/user/domain/UserTest.java | 2 +- .../user/presentation/UserControllerTest.java | 54 +++++++++---------- 47 files changed, 193 insertions(+), 227 deletions(-) rename app/src/main/java/com/codesoom/assignment/common/{exception => error}/ErrorResponse.java (93%) rename app/src/main/java/com/codesoom/assignment/common/{exception/GlobalExceptionHandler.java => error/GlobalErrorAdvice.java} (78%) create mode 100644 app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java rename app/src/main/java/com/codesoom/assignment/{domain/session/exception/SessionExceptionHandler.java => common/error/SessionErrorAdvice.java} (52%) rename app/src/main/java/com/codesoom/assignment/{domain/user/exception/UserExceptionHandler.java => common/error/UserErrorAdvice.java} (54%) delete mode 100644 app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java delete mode 100644 app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java delete mode 100644 app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java delete mode 100644 app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java rename app/src/main/java/com/codesoom/assignment/{domain => }/product/application/ProductService.java (79%) rename app/src/main/java/com/codesoom/assignment/{domain => }/product/domain/Product.java (95%) rename app/src/main/java/com/codesoom/assignment/{domain => }/product/domain/ProductRepository.java (80%) rename app/src/main/java/com/codesoom/assignment/{domain => }/product/exception/ProductNotFoundException.java (73%) rename app/src/main/java/com/codesoom/assignment/{domain => }/product/infra/JpaProductRepository.java (65%) rename app/src/main/java/com/codesoom/assignment/{domain => }/product/presentation/ProductController.java (88%) rename app/src/main/java/com/codesoom/assignment/{domain => }/product/presentation/dto/ProductData.java (72%) rename app/src/main/java/com/codesoom/assignment/{domain => }/session/application/AuthenticationService.java (72%) rename app/src/main/java/com/codesoom/assignment/{domain => }/session/controller/SessionController.java (78%) rename app/src/main/java/com/codesoom/assignment/{domain => }/session/controller/dto/SessionRequestDto.java (89%) rename app/src/main/java/com/codesoom/assignment/{domain => }/session/controller/dto/SessionResponseDto.java (79%) rename app/src/main/java/com/codesoom/assignment/{domain => }/session/exception/InvalidTokenException.java (82%) rename app/src/main/java/com/codesoom/assignment/{domain => }/session/exception/TokenNotExistException.java (73%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/application/UserService.java (72%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/domain/User.java (93%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/domain/UserRepository.java (84%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/exception/UserEmailDuplicationException.java (77%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/exception/UserInvalidPasswordException.java (77%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/exception/UserNotFoundException.java (82%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/infra/JpaUserRepository.java (69%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/presentation/UserController.java (82%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/presentation/dto/UserModificationData.java (88%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/presentation/dto/UserRegistrationData.java (90%) rename app/src/main/java/com/codesoom/assignment/{domain => }/user/presentation/dto/UserResultData.java (78%) rename app/src/test/java/com/codesoom/assignment/{domain => }/product/application/ProductServiceTest.java (92%) rename app/src/test/java/com/codesoom/assignment/{domain => }/product/domain/ProductTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{domain => }/product/presentation/ProductControllerTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{domain => }/session/application/AuthenticationServiceTest.java (93%) rename app/src/test/java/com/codesoom/assignment/{domain => }/user/application/UserServiceTest.java (91%) rename app/src/test/java/com/codesoom/assignment/{domain => }/user/domain/UserTest.java (95%) rename app/src/test/java/com/codesoom/assignment/{domain => }/user/presentation/UserControllerTest.java (75%) diff --git a/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java b/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java index 911f37d86..768f71240 100644 --- a/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java +++ b/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.common.auth; import com.codesoom.assignment.common.util.JwtUtil; -import com.codesoom.assignment.domain.session.exception.TokenNotExistException; +import com.codesoom.assignment.session.exception.TokenNotExistException; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; diff --git a/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java b/app/src/main/java/com/codesoom/assignment/common/error/ErrorResponse.java similarity index 93% rename from app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java rename to app/src/main/java/com/codesoom/assignment/common/error/ErrorResponse.java index a8eea17bf..4cfd0b0da 100644 --- a/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java +++ b/app/src/main/java/com/codesoom/assignment/common/error/ErrorResponse.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.common.exception; +package com.codesoom.assignment.common.error; import lombok.Getter; import org.springframework.context.support.DefaultMessageSourceResolvable; diff --git a/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/common/error/GlobalErrorAdvice.java similarity index 78% rename from app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java rename to app/src/main/java/com/codesoom/assignment/common/error/GlobalErrorAdvice.java index 7a9ee8d24..d4454f74d 100644 --- a/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/common/error/GlobalErrorAdvice.java @@ -1,19 +1,17 @@ -package com.codesoom.assignment.common.exception; +package com.codesoom.assignment.common.error; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; -@ResponseBody -@ControllerAdvice -public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { +@RestControllerAdvice +public class GlobalErrorAdvice extends ResponseEntityExceptionHandler { @ExceptionHandler(value = {Exception.class}) @ResponseStatus public ErrorResponse handleException(final Exception exception) { diff --git a/app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java new file mode 100644 index 000000000..10bb01938 --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java @@ -0,0 +1,23 @@ +package com.codesoom.assignment.common.error; + +import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.product.presentation.ProductController; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice(basePackageClasses = { + ProductController.class +}) +@Order(Ordered.HIGHEST_PRECEDENCE) +public class ProductErrorAdvice { + + @ResponseStatus(HttpStatus.NOT_FOUND) + @ExceptionHandler(ProductNotFoundException.class) + public ErrorResponse handleProductNotFound() { + return new ErrorResponse("Product not found"); + } +} diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/common/error/SessionErrorAdvice.java similarity index 52% rename from app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java rename to app/src/main/java/com/codesoom/assignment/common/error/SessionErrorAdvice.java index 9c1d26eb6..d3aeb8b6f 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/common/error/SessionErrorAdvice.java @@ -1,12 +1,20 @@ -package com.codesoom.assignment.domain.session.exception; +package com.codesoom.assignment.common.error; -import com.codesoom.assignment.common.exception.ErrorResponse; +import com.codesoom.assignment.product.presentation.ProductController; +import com.codesoom.assignment.session.exception.InvalidTokenException; +import com.codesoom.assignment.session.exception.TokenNotExistException; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; -@SessionErrorAdvice -public class SessionExceptionHandler { +@RestControllerAdvice(basePackageClasses = { + ProductController.class +}) +@Order(Ordered.HIGHEST_PRECEDENCE) +public class SessionErrorAdvice { @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(InvalidTokenException.class) diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/common/error/UserErrorAdvice.java similarity index 54% rename from app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java rename to app/src/main/java/com/codesoom/assignment/common/error/UserErrorAdvice.java index 3f1d9dac0..c518c4c65 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserExceptionHandler.java +++ b/app/src/main/java/com/codesoom/assignment/common/error/UserErrorAdvice.java @@ -1,12 +1,23 @@ -package com.codesoom.assignment.domain.user.exception; +package com.codesoom.assignment.common.error; -import com.codesoom.assignment.common.exception.ErrorResponse; +import com.codesoom.assignment.session.controller.SessionController; +import com.codesoom.assignment.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.user.exception.UserInvalidPasswordException; +import com.codesoom.assignment.user.exception.UserNotFoundException; +import com.codesoom.assignment.user.presentation.UserController; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; -@UserErrorAdvice -public class UserExceptionHandler { +@RestControllerAdvice(basePackageClasses = { + UserController.class, + SessionController.class +}) +@Order(Ordered.HIGHEST_PRECEDENCE) +public class UserErrorAdvice { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(UserNotFoundException.class) diff --git a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java index 751a0bc0e..a61ec388a 100644 --- a/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java +++ b/app/src/main/java/com/codesoom/assignment/common/util/JwtUtil.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.common.util; -import com.codesoom.assignment.domain.session.exception.InvalidTokenException; -import com.codesoom.assignment.domain.session.exception.TokenNotExistException; +import com.codesoom.assignment.session.exception.InvalidTokenException; +import com.codesoom.assignment.session.exception.TokenNotExistException; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.security.Keys; @@ -20,6 +20,18 @@ public JwtUtil(@Value("${jwt.secret}") String secretKey) { this.secretKey = Keys.hmacShaKeyFor(secretKey.getBytes()); } + public void validateAccessToken(String authHeader) { + if (authHeader == null) { + throw new TokenNotExistException(); + } + + if (!authHeader.startsWith(ACCESS_TOKEN_TYPE)) { + throw new InvalidTokenException(); + } + + decode(authHeader.substring(ACCESS_TOKEN_TYPE.length())); + } + public String encode(Long id) { return Jwts.builder() .claim("userId", id) @@ -42,16 +54,4 @@ public Claims decode(String token) { throw new InvalidTokenException(token); } } - - public void validateAccessToken(String authHeader) { - if (authHeader == null) { - throw new TokenNotExistException(); - } - - if (!authHeader.startsWith(ACCESS_TOKEN_TYPE)) { - throw new InvalidTokenException(); - } - - decode(authHeader.substring(ACCESS_TOKEN_TYPE.length())); - } } diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java deleted file mode 100644 index 6d74b302f..000000000 --- a/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductErrorAdvice.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.codesoom.assignment.domain.product.exception; - -import com.codesoom.assignment.domain.product.presentation.ProductController; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@RestControllerAdvice(basePackageClasses = { - ProductController.class -}) -@Order(Ordered.HIGHEST_PRECEDENCE) -public @interface ProductErrorAdvice { -} diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java b/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java deleted file mode 100644 index 02d7c5c16..000000000 --- a/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductExceptionHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.codesoom.assignment.domain.product.exception; - -import com.codesoom.assignment.common.exception.ErrorResponse; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; - -@ProductErrorAdvice -public class ProductExceptionHandler { - - @ResponseStatus(HttpStatus.NOT_FOUND) - @ExceptionHandler(ProductNotFoundException.class) - public ErrorResponse handleProductNotFound() { - return new ErrorResponse("Product not found"); - } -} diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java deleted file mode 100644 index 5a8eead5c..000000000 --- a/app/src/main/java/com/codesoom/assignment/domain/session/exception/SessionErrorAdvice.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.codesoom.assignment.domain.session.exception; - -import com.codesoom.assignment.domain.product.presentation.ProductController; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@RestControllerAdvice(basePackageClasses = { - ProductController.class -}) -@Order(Ordered.HIGHEST_PRECEDENCE) -public @interface SessionErrorAdvice { -} diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java deleted file mode 100644 index 29997ab39..000000000 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserErrorAdvice.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.codesoom.assignment.domain.user.exception; - -import com.codesoom.assignment.domain.session.controller.SessionController; -import com.codesoom.assignment.domain.user.presentation.UserController; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.web.bind.annotation.RestControllerAdvice; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.RUNTIME) -@RestControllerAdvice(basePackageClasses = { - UserController.class, - SessionController.class -}) -@Order(Ordered.HIGHEST_PRECEDENCE) -public @interface UserErrorAdvice { -} diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/application/ProductService.java b/app/src/main/java/com/codesoom/assignment/product/application/ProductService.java similarity index 79% rename from app/src/main/java/com/codesoom/assignment/domain/product/application/ProductService.java rename to app/src/main/java/com/codesoom/assignment/product/application/ProductService.java index 164296386..2dddba564 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/application/ProductService.java +++ b/app/src/main/java/com/codesoom/assignment/product/application/ProductService.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.domain.product.application; +package com.codesoom.assignment.product.application; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.domain.ProductRepository; -import com.codesoom.assignment.domain.product.exception.ProductNotFoundException; -import com.codesoom.assignment.domain.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.domain.ProductRepository; +import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.product.presentation.dto.ProductData; import com.github.dozermapper.core.Mapper; import org.springframework.stereotype.Service; diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/domain/Product.java b/app/src/main/java/com/codesoom/assignment/product/domain/Product.java similarity index 95% rename from app/src/main/java/com/codesoom/assignment/domain/product/domain/Product.java rename to app/src/main/java/com/codesoom/assignment/product/domain/Product.java index 6810a7064..87fe9214c 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/domain/Product.java +++ b/app/src/main/java/com/codesoom/assignment/product/domain/Product.java @@ -14,7 +14,7 @@ // 3. 가격 - 5,000원 (판매가) // 4. 이미지 - static, CDN => image URL -package com.codesoom.assignment.domain.product.domain; +package com.codesoom.assignment.product.domain; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/domain/ProductRepository.java b/app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java similarity index 80% rename from app/src/main/java/com/codesoom/assignment/domain/product/domain/ProductRepository.java rename to app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java index ec033ae80..44082966e 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/domain/ProductRepository.java +++ b/app/src/main/java/com/codesoom/assignment/product/domain/ProductRepository.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.product.domain; +package com.codesoom.assignment.product.domain; import java.util.List; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductNotFoundException.java b/app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java similarity index 73% rename from app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductNotFoundException.java rename to app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java index 9d0eb4740..f962b0e4f 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/exception/ProductNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/product/exception/ProductNotFoundException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.product.exception; +package com.codesoom.assignment.product.exception; public class ProductNotFoundException extends RuntimeException { public ProductNotFoundException(Long id) { diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/infra/JpaProductRepository.java b/app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java similarity index 65% rename from app/src/main/java/com/codesoom/assignment/domain/product/infra/JpaProductRepository.java rename to app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java index eafb192be..05b32a803 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/infra/JpaProductRepository.java +++ b/app/src/main/java/com/codesoom/assignment/product/infra/JpaProductRepository.java @@ -1,7 +1,7 @@ -package com.codesoom.assignment.domain.product.infra; +package com.codesoom.assignment.product.infra; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.domain.ProductRepository; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.domain.ProductRepository; import org.springframework.data.repository.CrudRepository; import java.util.List; diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java similarity index 88% rename from app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java rename to app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java index f5a811bd4..678d04b8e 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/presentation/ProductController.java +++ b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.domain.product.presentation; +package com.codesoom.assignment.product.presentation; import com.codesoom.assignment.common.auth.Login; -import com.codesoom.assignment.domain.product.application.ProductService; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.application.ProductService; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.presentation.dto.ProductData; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.DeleteMapping; diff --git a/app/src/main/java/com/codesoom/assignment/domain/product/presentation/dto/ProductData.java b/app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java similarity index 72% rename from app/src/main/java/com/codesoom/assignment/domain/product/presentation/dto/ProductData.java rename to app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java index 3ad48c576..caf9acb78 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/product/presentation/dto/ProductData.java +++ b/app/src/main/java/com/codesoom/assignment/product/presentation/dto/ProductData.java @@ -1,7 +1,11 @@ -package com.codesoom.assignment.domain.product.presentation.dto; +package com.codesoom.assignment.product.presentation.dto; import com.github.dozermapper.core.Mapping; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java b/app/src/main/java/com/codesoom/assignment/session/application/AuthenticationService.java similarity index 72% rename from app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java rename to app/src/main/java/com/codesoom/assignment/session/application/AuthenticationService.java index cca08eb65..d12da8f45 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/application/AuthenticationService.java +++ b/app/src/main/java/com/codesoom/assignment/session/application/AuthenticationService.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.domain.session.application; +package com.codesoom.assignment.session.application; import com.codesoom.assignment.common.util.JwtUtil; -import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; -import com.codesoom.assignment.domain.user.domain.User; -import com.codesoom.assignment.domain.user.domain.UserRepository; -import com.codesoom.assignment.domain.user.exception.UserInvalidPasswordException; -import com.codesoom.assignment.domain.user.exception.UserNotFoundException; +import com.codesoom.assignment.session.controller.dto.SessionRequestDto; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.user.exception.UserInvalidPasswordException; +import com.codesoom.assignment.user.exception.UserNotFoundException; import org.springframework.stereotype.Service; @Service diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java b/app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java similarity index 78% rename from app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java rename to app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java index 1f93504bf..dc753fcd3 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/controller/SessionController.java +++ b/app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.domain.session.controller; +package com.codesoom.assignment.session.controller; import com.codesoom.assignment.common.auth.Login; -import com.codesoom.assignment.domain.session.application.AuthenticationService; -import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; -import com.codesoom.assignment.domain.session.controller.dto.SessionResponseDto; +import com.codesoom.assignment.session.application.AuthenticationService; +import com.codesoom.assignment.session.controller.dto.SessionRequestDto; +import com.codesoom.assignment.session.controller.dto.SessionResponseDto; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionRequestDto.java b/app/src/main/java/com/codesoom/assignment/session/controller/dto/SessionRequestDto.java similarity index 89% rename from app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionRequestDto.java rename to app/src/main/java/com/codesoom/assignment/session/controller/dto/SessionRequestDto.java index f5e3b9cd4..ea9ebf83d 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionRequestDto.java +++ b/app/src/main/java/com/codesoom/assignment/session/controller/dto/SessionRequestDto.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.session.controller.dto; +package com.codesoom.assignment.session.controller.dto; import lombok.Builder; import lombok.EqualsAndHashCode; diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionResponseDto.java b/app/src/main/java/com/codesoom/assignment/session/controller/dto/SessionResponseDto.java similarity index 79% rename from app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionResponseDto.java rename to app/src/main/java/com/codesoom/assignment/session/controller/dto/SessionResponseDto.java index c27d2821b..a3031a1c1 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/controller/dto/SessionResponseDto.java +++ b/app/src/main/java/com/codesoom/assignment/session/controller/dto/SessionResponseDto.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.session.controller.dto; +package com.codesoom.assignment.session.controller.dto; import lombok.Builder; import lombok.Getter; diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java b/app/src/main/java/com/codesoom/assignment/session/exception/InvalidTokenException.java similarity index 82% rename from app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java rename to app/src/main/java/com/codesoom/assignment/session/exception/InvalidTokenException.java index 62f78d1ed..4bb0a6476 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/exception/InvalidTokenException.java +++ b/app/src/main/java/com/codesoom/assignment/session/exception/InvalidTokenException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.session.exception; +package com.codesoom.assignment.session.exception; public class InvalidTokenException extends RuntimeException { public InvalidTokenException() { diff --git a/app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java b/app/src/main/java/com/codesoom/assignment/session/exception/TokenNotExistException.java similarity index 73% rename from app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java rename to app/src/main/java/com/codesoom/assignment/session/exception/TokenNotExistException.java index 632980f58..ed508149c 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/session/exception/TokenNotExistException.java +++ b/app/src/main/java/com/codesoom/assignment/session/exception/TokenNotExistException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.session.exception; +package com.codesoom.assignment.session.exception; public class TokenNotExistException extends RuntimeException { public TokenNotExistException() { diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/application/UserService.java b/app/src/main/java/com/codesoom/assignment/user/application/UserService.java similarity index 72% rename from app/src/main/java/com/codesoom/assignment/domain/user/application/UserService.java rename to app/src/main/java/com/codesoom/assignment/user/application/UserService.java index 8608ff64e..a974f3038 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/application/UserService.java +++ b/app/src/main/java/com/codesoom/assignment/user/application/UserService.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.domain.user.application; - -import com.codesoom.assignment.domain.user.domain.User; -import com.codesoom.assignment.domain.user.domain.UserRepository; -import com.codesoom.assignment.domain.user.exception.UserEmailDuplicationException; -import com.codesoom.assignment.domain.user.exception.UserNotFoundException; -import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; +package com.codesoom.assignment.user.application; + +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.user.exception.UserNotFoundException; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; import com.github.dozermapper.core.Mapper; import org.springframework.stereotype.Service; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/domain/User.java b/app/src/main/java/com/codesoom/assignment/user/domain/User.java similarity index 93% rename from app/src/main/java/com/codesoom/assignment/domain/user/domain/User.java rename to app/src/main/java/com/codesoom/assignment/user/domain/User.java index c0f93558d..1c3b1562f 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/domain/User.java +++ b/app/src/main/java/com/codesoom/assignment/user/domain/User.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.domain; +package com.codesoom.assignment.user.domain; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/domain/UserRepository.java b/app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java similarity index 84% rename from app/src/main/java/com/codesoom/assignment/domain/user/domain/UserRepository.java rename to app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java index 12f152823..dc5c096f3 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/domain/UserRepository.java +++ b/app/src/main/java/com/codesoom/assignment/user/domain/UserRepository.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.domain; +package com.codesoom.assignment.user.domain; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserEmailDuplicationException.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java similarity index 77% rename from app/src/main/java/com/codesoom/assignment/domain/user/exception/UserEmailDuplicationException.java rename to app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java index cc3ccaffa..ed54c6ae2 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserEmailDuplicationException.java +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserEmailDuplicationException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.exception; +package com.codesoom.assignment.user.exception; public class UserEmailDuplicationException extends RuntimeException { public UserEmailDuplicationException(String email) { diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserInvalidPasswordException.java similarity index 77% rename from app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java rename to app/src/main/java/com/codesoom/assignment/user/exception/UserInvalidPasswordException.java index f69eb4fba..b412ace71 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserInvalidPasswordException.java +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserInvalidPasswordException.java @@ -1,6 +1,6 @@ -package com.codesoom.assignment.domain.user.exception; +package com.codesoom.assignment.user.exception; -public class UserInvalidPasswordException extends RuntimeException{ +public class UserInvalidPasswordException extends RuntimeException { public UserInvalidPasswordException(String email) { super("비밀번호가 일치하지 않습니다: " + email); } diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java b/app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java similarity index 82% rename from app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java rename to app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java index 42f7054ee..9852ccc00 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/exception/UserNotFoundException.java +++ b/app/src/main/java/com/codesoom/assignment/user/exception/UserNotFoundException.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.exception; +package com.codesoom.assignment.user.exception; public class UserNotFoundException extends RuntimeException { public UserNotFoundException(Long id) { diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java b/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java similarity index 69% rename from app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java rename to app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java index d4c145b03..3bd2927d6 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/infra/JpaUserRepository.java +++ b/app/src/main/java/com/codesoom/assignment/user/infra/JpaUserRepository.java @@ -1,7 +1,7 @@ -package com.codesoom.assignment.domain.user.infra; +package com.codesoom.assignment.user.infra; -import com.codesoom.assignment.domain.user.domain.User; -import com.codesoom.assignment.domain.user.domain.UserRepository; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java b/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java similarity index 82% rename from app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java index 0fba5778d..fdce50357 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/UserController.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.domain.user.presentation; +package com.codesoom.assignment.user.presentation; import com.codesoom.assignment.common.auth.Login; -import com.codesoom.assignment.domain.user.application.UserService; -import com.codesoom.assignment.domain.user.domain.User; -import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; -import com.codesoom.assignment.domain.user.presentation.dto.UserResultData; +import com.codesoom.assignment.user.application.UserService; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.user.presentation.dto.UserResultData; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.DeleteMapping; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserModificationData.java b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java similarity index 88% rename from app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserModificationData.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java index 99b50bb13..5fc387cff 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserModificationData.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserModificationData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.presentation.dto; +package com.codesoom.assignment.user.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserRegistrationData.java b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java similarity index 90% rename from app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserRegistrationData.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java index 63f61a6c5..428c32f77 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserRegistrationData.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserRegistrationData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.presentation.dto; +package com.codesoom.assignment.user.presentation.dto; import com.github.dozermapper.core.Mapping; import lombok.AllArgsConstructor; diff --git a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserResultData.java b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java similarity index 78% rename from app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserResultData.java rename to app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java index f2d9d615a..f295e5046 100644 --- a/app/src/main/java/com/codesoom/assignment/domain/user/presentation/dto/UserResultData.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/dto/UserResultData.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.presentation.dto; +package com.codesoom.assignment.user.presentation.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java b/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java index 06342397a..239c46dcf 100644 --- a/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java +++ b/app/src/test/java/com/codesoom/assignment/common/auth/AuthenticationInterceptorTest.java @@ -1,8 +1,8 @@ package com.codesoom.assignment.common.auth; import com.codesoom.assignment.common.util.JsonUtil; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.presentation.ProductController; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.presentation.ProductController; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; diff --git a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java index 80fba0111..9370a4f8c 100644 --- a/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java +++ b/app/src/test/java/com/codesoom/assignment/common/util/JwtUtilTest.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.common.util; -import com.codesoom.assignment.domain.session.exception.InvalidTokenException; -import com.codesoom.assignment.domain.session.exception.TokenNotExistException; +import com.codesoom.assignment.session.exception.InvalidTokenException; +import com.codesoom.assignment.session.exception.TokenNotExistException; import io.jsonwebtoken.Claims; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java index 6e709ad2e..ef03f976c 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/domain/session/controller/SessionControllerTest.java @@ -1,9 +1,9 @@ package com.codesoom.assignment.domain.session.controller; import com.codesoom.assignment.common.util.JsonUtil; -import com.codesoom.assignment.domain.session.application.AuthenticationService; -import com.codesoom.assignment.domain.user.exception.UserInvalidPasswordException; -import com.codesoom.assignment.domain.user.exception.UserNotFoundException; +import com.codesoom.assignment.session.application.AuthenticationService; +import com.codesoom.assignment.user.exception.UserInvalidPasswordException; +import com.codesoom.assignment.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; diff --git a/app/src/test/java/com/codesoom/assignment/domain/product/application/ProductServiceTest.java b/app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java similarity index 92% rename from app/src/test/java/com/codesoom/assignment/domain/product/application/ProductServiceTest.java rename to app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java index a1c59c335..67f551d9c 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/product/application/ProductServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/application/ProductServiceTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.domain.product.application; +package com.codesoom.assignment.product.application; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.domain.ProductRepository; -import com.codesoom.assignment.domain.product.exception.ProductNotFoundException; -import com.codesoom.assignment.domain.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.domain.ProductRepository; +import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.product.presentation.dto.ProductData; import com.github.dozermapper.core.DozerBeanMapperBuilder; import com.github.dozermapper.core.Mapper; import org.junit.jupiter.api.BeforeEach; diff --git a/app/src/test/java/com/codesoom/assignment/domain/product/domain/ProductTest.java b/app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/domain/product/domain/ProductTest.java rename to app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java index 99dbb16df..652060808 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/product/domain/ProductTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/domain/ProductTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.product.domain; +package com.codesoom.assignment.product.domain; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/domain/product/presentation/ProductControllerTest.java b/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/domain/product/presentation/ProductControllerTest.java rename to app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java index b0eea852c..c18c78bf7 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/product/presentation/ProductControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.domain.product.presentation; +package com.codesoom.assignment.product.presentation; -import com.codesoom.assignment.domain.product.application.ProductService; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.exception.ProductNotFoundException; -import com.codesoom.assignment.domain.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.application.ProductService; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.exception.ProductNotFoundException; +import com.codesoom.assignment.product.presentation.dto.ProductData; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; diff --git a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java b/app/src/test/java/com/codesoom/assignment/session/application/AuthenticationServiceTest.java similarity index 93% rename from app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java rename to app/src/test/java/com/codesoom/assignment/session/application/AuthenticationServiceTest.java index 724c31a4a..c29e724c0 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/session/application/AuthenticationServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/session/application/AuthenticationServiceTest.java @@ -1,9 +1,9 @@ -package com.codesoom.assignment.domain.session.application; +package com.codesoom.assignment.session.application; import com.codesoom.assignment.common.util.JwtUtil; -import com.codesoom.assignment.domain.user.domain.UserRepository; -import com.codesoom.assignment.domain.user.exception.UserInvalidPasswordException; -import com.codesoom.assignment.domain.user.exception.UserNotFoundException; +import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.user.exception.UserInvalidPasswordException; +import com.codesoom.assignment.user.exception.UserNotFoundException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayNameGeneration; diff --git a/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java b/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java index 38b2ff4b3..5c12cda14 100644 --- a/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/ProductFixture.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.support; -import com.codesoom.assignment.domain.product.domain.Product; -import com.codesoom.assignment.domain.product.presentation.dto.ProductData; +import com.codesoom.assignment.product.domain.Product; +import com.codesoom.assignment.product.presentation.dto.ProductData; public enum ProductFixture { TOY_1("범냐옹", "메이드인 코리아", 2000000, "https://avatars.githubusercontent.com/u/59248326"), diff --git a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java index 7de554899..807012d36 100644 --- a/app/src/test/java/com/codesoom/assignment/support/UserFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/UserFixture.java @@ -1,7 +1,7 @@ package com.codesoom.assignment.support; -import com.codesoom.assignment.domain.session.controller.dto.SessionRequestDto; -import com.codesoom.assignment.domain.user.domain.User; +import com.codesoom.assignment.session.controller.dto.SessionRequestDto; +import com.codesoom.assignment.user.domain.User; public enum UserFixture { USER_1("기범", "dev.gibeom@gmail.com", "비밀번호486"), diff --git a/app/src/test/java/com/codesoom/assignment/domain/user/application/UserServiceTest.java b/app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java similarity index 91% rename from app/src/test/java/com/codesoom/assignment/domain/user/application/UserServiceTest.java rename to app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java index f48725270..ab3850a37 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/user/application/UserServiceTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/application/UserServiceTest.java @@ -1,11 +1,11 @@ -package com.codesoom.assignment.domain.user.application; - -import com.codesoom.assignment.domain.user.domain.User; -import com.codesoom.assignment.domain.user.domain.UserRepository; -import com.codesoom.assignment.domain.user.exception.UserEmailDuplicationException; -import com.codesoom.assignment.domain.user.exception.UserNotFoundException; -import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; +package com.codesoom.assignment.user.application; + +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.domain.UserRepository; +import com.codesoom.assignment.user.exception.UserEmailDuplicationException; +import com.codesoom.assignment.user.exception.UserNotFoundException; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; import com.github.dozermapper.core.DozerBeanMapperBuilder; import com.github.dozermapper.core.Mapper; import org.junit.jupiter.api.BeforeEach; diff --git a/app/src/test/java/com/codesoom/assignment/domain/user/domain/UserTest.java b/app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java similarity index 95% rename from app/src/test/java/com/codesoom/assignment/domain/user/domain/UserTest.java rename to app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java index d26d018cc..097cdae82 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/user/domain/UserTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/domain/UserTest.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.domain.user.domain; +package com.codesoom.assignment.user.domain; import org.junit.jupiter.api.Test; diff --git a/app/src/test/java/com/codesoom/assignment/domain/user/presentation/UserControllerTest.java b/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java similarity index 75% rename from app/src/test/java/com/codesoom/assignment/domain/user/presentation/UserControllerTest.java rename to app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java index c35b2a593..0e333b7a9 100644 --- a/app/src/test/java/com/codesoom/assignment/domain/user/presentation/UserControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java @@ -1,10 +1,10 @@ -package com.codesoom.assignment.domain.user.presentation; +package com.codesoom.assignment.user.presentation; -import com.codesoom.assignment.domain.user.application.UserService; -import com.codesoom.assignment.domain.user.domain.User; -import com.codesoom.assignment.domain.user.exception.UserNotFoundException; -import com.codesoom.assignment.domain.user.presentation.dto.UserModificationData; -import com.codesoom.assignment.domain.user.presentation.dto.UserRegistrationData; +import com.codesoom.assignment.user.application.UserService; +import com.codesoom.assignment.user.domain.User; +import com.codesoom.assignment.user.exception.UserNotFoundException; +import com.codesoom.assignment.user.presentation.dto.UserModificationData; +import com.codesoom.assignment.user.presentation.dto.UserRegistrationData; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -67,11 +67,11 @@ void setUp() { @Test void registerUserWithValidAttributes() throws Exception { mockMvc.perform( - post("/users") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"email\":\"tester@example.com\"," + - "\"name\":\"Tester\",\"password\":\"test\"}") - ) + post("/users") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"email\":\"tester@example.com\"," + + "\"name\":\"Tester\",\"password\":\"test\"}") + ) .andExpect(status().isCreated()) .andExpect(content().string( containsString("\"id\":13") @@ -89,20 +89,20 @@ void registerUserWithValidAttributes() throws Exception { @Test void registerUserWithInvalidAttributes() throws Exception { mockMvc.perform( - post("/users") - .contentType(MediaType.APPLICATION_JSON) - .content("{}") - ) + post("/users") + .contentType(MediaType.APPLICATION_JSON) + .content("{}") + ) .andExpect(status().isBadRequest()); } @Test void updateUserWithValidAttributes() throws Exception { mockMvc.perform( - patch("/users/1") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"TEST\",\"password\":\"test\"}") - ) + patch("/users/1") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"TEST\",\"password\":\"test\"}") + ) .andExpect(status().isOk()) .andExpect(content().string( containsString("\"id\":1") @@ -117,20 +117,20 @@ void updateUserWithValidAttributes() throws Exception { @Test void updateUserWithInvalidAttributes() throws Exception { mockMvc.perform( - patch("/users/1") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"\",\"password\":\"\"}") - ) + patch("/users/1") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"\",\"password\":\"\"}") + ) .andExpect(status().isBadRequest()); } @Test void updateUserWithNotExsitedId() throws Exception { mockMvc.perform( - patch("/users/100") - .contentType(MediaType.APPLICATION_JSON) - .content("{\"name\":\"TEST\",\"password\":\"TEST\"}") - ) + patch("/users/100") + .contentType(MediaType.APPLICATION_JSON) + .content("{\"name\":\"TEST\",\"password\":\"TEST\"}") + ) .andExpect(status().isNotFound()); verify(userService) From 25cfbec27b59cc293b9997bd885a74d028d8743e Mon Sep 17 00:00:00 2001 From: giibeom Date: Sat, 19 Nov 2022 17:34:53 +0900 Subject: [PATCH 37/39] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=EC=9D=B4=20=ED=95=84=EC=9A=94=ED=95=9C=20Controller=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=EC=97=90=20Auth=20=ED=86=A0?= =?UTF-8?q?=ED=81=B0=20=ED=97=A4=EB=8D=94=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MockMvcCharacterEncodingCustomizer.java | 2 +- .../presentation/ProductControllerTest.java | 24 ++++++++++++------- .../assignment/support/AuthHeaderFixture.java | 3 ++- .../user/presentation/UserControllerTest.java | 5 +++- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java b/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java index e3a8d4b0a..312e6e1a5 100644 --- a/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java +++ b/app/src/test/java/com/codesoom/assignment/MockMvcCharacterEncodingCustomizer.java @@ -15,7 +15,7 @@ * 기본적으로 @AutoconfigureMockMvc를 통해 주입받는 상황에서만 적용됩니다. */ @Component -class MockMvcCharacterEncodingCustomizer implements MockMvcBuilderCustomizer { +public class MockMvcCharacterEncodingCustomizer implements MockMvcBuilderCustomizer { @Override public void customize(ConfigurableMockMvcBuilder builder) { builder.alwaysDo(result -> result.getResponse().setCharacterEncoding(StandardCharsets.UTF_8.name())); diff --git a/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java b/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java index c18c78bf7..9c577dd4c 100644 --- a/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/product/presentation/ProductControllerTest.java @@ -1,5 +1,8 @@ package com.codesoom.assignment.product.presentation; +import com.codesoom.assignment.MockMvcCharacterEncodingCustomizer; +import com.codesoom.assignment.common.auth.AuthenticationInterceptor; +import com.codesoom.assignment.common.util.JwtUtil; import com.codesoom.assignment.product.application.ProductService; import com.codesoom.assignment.product.domain.Product; import com.codesoom.assignment.product.exception.ProductNotFoundException; @@ -9,11 +12,13 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import java.util.List; +import static com.codesoom.assignment.support.AuthHeaderFixture.VALID_TOKEN_VALUE; import static org.hamcrest.Matchers.containsString; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -26,7 +31,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@WebMvcTest(ProductController.class) +@WebMvcTest({ProductController.class, AuthenticationInterceptor.class, JwtUtil.class, MockMvcCharacterEncodingCustomizer.class}) class ProductControllerTest { private static final String VALID_TOKEN = "eyJhbGciOiJIUzI1NiJ9." + "eyJ1c2VySWQiOjF9.ZZ3CUl0jxeLGvQ1Js5nG2Ty5qGTlqai5ubDMXZOdaDk"; @@ -80,7 +85,6 @@ void setUp() { void list() throws Exception { mockMvc.perform( get("/products") - .accept(MediaType.APPLICATION_JSON_UTF8) ) .andExpect(status().isOk()) .andExpect(content().string(containsString("쥐돌이"))); @@ -90,7 +94,6 @@ void list() throws Exception { void deatilWithExsitedProduct() throws Exception { mockMvc.perform( get("/products/1") - .accept(MediaType.APPLICATION_JSON_UTF8) ) .andExpect(status().isOk()) .andExpect(content().string(containsString("쥐돌이"))); @@ -98,7 +101,9 @@ void deatilWithExsitedProduct() throws Exception { @Test void deatilWithNotExsitedProduct() throws Exception { - mockMvc.perform(get("/products/1000")) + mockMvc.perform( + get("/products/1000") + ) .andExpect(status().isNotFound()); } @@ -106,7 +111,7 @@ void deatilWithNotExsitedProduct() throws Exception { void createWithValidAttributes() throws Exception { mockMvc.perform( post("/products") - .accept(MediaType.APPLICATION_JSON_UTF8) + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"쥐돌이\",\"maker\":\"냥이월드\"," + "\"price\":5000}") @@ -121,7 +126,7 @@ void createWithValidAttributes() throws Exception { void createWithInvalidAttributes() throws Exception { mockMvc.perform( post("/products") - .accept(MediaType.APPLICATION_JSON_UTF8) + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"\",\"maker\":\"\"," + "\"price\":0}") @@ -133,7 +138,7 @@ void createWithInvalidAttributes() throws Exception { void updateWithExistedProduct() throws Exception { mockMvc.perform( patch("/products/1") - .accept(MediaType.APPLICATION_JSON_UTF8) + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"쥐순이\",\"maker\":\"냥이월드\"," + "\"price\":5000}") @@ -148,6 +153,7 @@ void updateWithExistedProduct() throws Exception { void updateWithNotExistedProduct() throws Exception { mockMvc.perform( patch("/products/1000") + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"쥐순이\",\"maker\":\"냥이월드\"," + "\"price\":5000}") @@ -161,7 +167,7 @@ void updateWithNotExistedProduct() throws Exception { void updateWithInvalidAttributes() throws Exception { mockMvc.perform( patch("/products/1") - .accept(MediaType.APPLICATION_JSON_UTF8) + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) .contentType(MediaType.APPLICATION_JSON) .content("{\"name\":\"\",\"maker\":\"\"," + "\"price\":0}") @@ -173,6 +179,7 @@ void updateWithInvalidAttributes() throws Exception { void destroyWithExistedProduct() throws Exception { mockMvc.perform( delete("/products/1") + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) ) .andExpect(status().isNoContent()); @@ -183,6 +190,7 @@ void destroyWithExistedProduct() throws Exception { void destroyWithNotExistedProduct() throws Exception { mockMvc.perform( delete("/products/1000") + .header(HttpHeaders.AUTHORIZATION, VALID_TOKEN_VALUE.인증_헤더값()) ) .andExpect(status().isNotFound()); diff --git a/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java b/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java index de39133d2..c832fb70d 100644 --- a/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java +++ b/app/src/test/java/com/codesoom/assignment/support/AuthHeaderFixture.java @@ -2,7 +2,8 @@ public enum AuthHeaderFixture { INVALID_TOKEN_TYPE("Giibeom eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.neCsyNLzy3lQ4o2yliotWT06FwSGZagaHpKdAkjnGGw"), - INVALID_TOKEN_VALUE("Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); + INVALID_TOKEN_VALUE("Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.ZZ3CUxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"), + VALID_TOKEN_VALUE("Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOjF9.neCsyNLzy3lQ4o2yliotWT06FwSGZagaHpKdAkjnGGw"); AuthHeaderFixture(String authorization) { this.authorization = authorization; diff --git a/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java b/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java index 0e333b7a9..9b0b7e77c 100644 --- a/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java +++ b/app/src/test/java/com/codesoom/assignment/user/presentation/UserControllerTest.java @@ -1,5 +1,8 @@ package com.codesoom.assignment.user.presentation; +import com.codesoom.assignment.MockMvcCharacterEncodingCustomizer; +import com.codesoom.assignment.common.auth.AuthenticationInterceptor; +import com.codesoom.assignment.common.util.JwtUtil; import com.codesoom.assignment.user.application.UserService; import com.codesoom.assignment.user.domain.User; import com.codesoom.assignment.user.exception.UserNotFoundException; @@ -24,7 +27,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@WebMvcTest(UserController.class) +@WebMvcTest({UserController.class, AuthenticationInterceptor.class, JwtUtil.class, MockMvcCharacterEncodingCustomizer.class}) class UserControllerTest { @Autowired private MockMvc mockMvc; From 03d00fc32058ac5d5f9debe4355ffcc85b4f8611 Mon Sep 17 00:00:00 2001 From: giibeom Date: Sat, 19 Nov 2022 20:52:50 +0900 Subject: [PATCH 38/39] =?UTF-8?q?refactor:=20`@Login`=20=EC=96=B4=EB=85=B8?= =?UTF-8?q?=ED=85=8C=EC=9D=B4=EC=85=98=EC=9D=84=20`@LoginRequired`?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - allowGuest의 default값은 false --- .../common/auth/AuthenticationInterceptor.java | 8 ++++---- .../codesoom/assignment/common/auth/Login.java | 13 ------------- .../assignment/common/auth/LoginRequired.java | 16 ++++++++++++++++ .../product/presentation/ProductController.java | 12 ++++++------ .../session/controller/SessionController.java | 4 ++-- .../user/presentation/UserController.java | 8 ++++---- 6 files changed, 32 insertions(+), 29 deletions(-) delete mode 100644 app/src/main/java/com/codesoom/assignment/common/auth/Login.java create mode 100644 app/src/main/java/com/codesoom/assignment/common/auth/LoginRequired.java diff --git a/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java b/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java index 768f71240..fcf589162 100644 --- a/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java +++ b/app/src/main/java/com/codesoom/assignment/common/auth/AuthenticationInterceptor.java @@ -23,7 +23,7 @@ public AuthenticationInterceptor(JwtUtil jwtUtil) { public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) throws Exception { - if (isNotHandlerMethod(handler) || isNotRequiredAuth(handler)) { + if (isNotHandlerMethod(handler) || isNotLoginRequired(handler)) { return true; } @@ -48,10 +48,10 @@ private static boolean isNotHandlerMethod(Object handler) { return !(handler instanceof HandlerMethod); } - private boolean isNotRequiredAuth(Object handler) { + private boolean isNotLoginRequired(Object handler) { HandlerMethod handlerMethod = (HandlerMethod) handler; - Login auth = handlerMethod.getMethodAnnotation(Login.class); + LoginRequired loginRequired = handlerMethod.getMethodAnnotation(LoginRequired.class); - return auth == null || !auth.required(); + return loginRequired == null || loginRequired.allowGuest(); } } diff --git a/app/src/main/java/com/codesoom/assignment/common/auth/Login.java b/app/src/main/java/com/codesoom/assignment/common/auth/Login.java deleted file mode 100644 index f30c9c071..000000000 --- a/app/src/main/java/com/codesoom/assignment/common/auth/Login.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.codesoom.assignment.common.auth; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.RUNTIME) -public @interface Login { - - boolean required() default true; -} diff --git a/app/src/main/java/com/codesoom/assignment/common/auth/LoginRequired.java b/app/src/main/java/com/codesoom/assignment/common/auth/LoginRequired.java new file mode 100644 index 000000000..ed2916cbf --- /dev/null +++ b/app/src/main/java/com/codesoom/assignment/common/auth/LoginRequired.java @@ -0,0 +1,16 @@ +package com.codesoom.assignment.common.auth; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 리소스 요청 시 로그인 인증이 필요한 경우에 사용되는 어노테이션입니다. + * 비로그인 상태에서 리소스 요청을 허용하려면 allowGuest를 true로 설정해주세요. + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface LoginRequired { + boolean allowGuest() default false; +} diff --git a/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java index 678d04b8e..c5b9c715d 100644 --- a/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java +++ b/app/src/main/java/com/codesoom/assignment/product/presentation/ProductController.java @@ -1,6 +1,6 @@ package com.codesoom.assignment.product.presentation; -import com.codesoom.assignment.common.auth.Login; +import com.codesoom.assignment.common.auth.LoginRequired; import com.codesoom.assignment.product.application.ProductService; import com.codesoom.assignment.product.domain.Product; import com.codesoom.assignment.product.presentation.dto.ProductData; @@ -30,13 +30,13 @@ public ProductController(ProductService productService) { } @GetMapping - @Login(required = false) + @LoginRequired(allowGuest = true) public List list() { return productService.getProducts(); } @GetMapping("{id}") - @Login(required = false) + @LoginRequired(allowGuest = true) public Product detail(@PathVariable Long id) throws Exception { if (id == 3L) { throw new Exception(); @@ -47,7 +47,7 @@ public Product detail(@PathVariable Long id) throws Exception { @PostMapping @ResponseStatus(HttpStatus.CREATED) - @Login + @LoginRequired public Product create( @RequestBody @Valid ProductData productData ) { @@ -55,7 +55,7 @@ public Product create( } @PatchMapping("{id}") - @Login + @LoginRequired public Product update( @PathVariable Long id, @RequestBody @Valid ProductData productData @@ -65,7 +65,7 @@ public Product update( @DeleteMapping("{id}") @ResponseStatus(HttpStatus.NO_CONTENT) - @Login + @LoginRequired public void destroy( @PathVariable Long id ) { diff --git a/app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java b/app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java index dc753fcd3..2e2d7e736 100644 --- a/app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java +++ b/app/src/main/java/com/codesoom/assignment/session/controller/SessionController.java @@ -1,6 +1,6 @@ package com.codesoom.assignment.session.controller; -import com.codesoom.assignment.common.auth.Login; +import com.codesoom.assignment.common.auth.LoginRequired; import com.codesoom.assignment.session.application.AuthenticationService; import com.codesoom.assignment.session.controller.dto.SessionRequestDto; import com.codesoom.assignment.session.controller.dto.SessionResponseDto; @@ -24,7 +24,7 @@ public SessionController(final AuthenticationService authenticationService) { @PostMapping @ResponseStatus(HttpStatus.CREATED) - @Login(required = false) + @LoginRequired(allowGuest = true) public SessionResponseDto login(@RequestBody @Valid final SessionRequestDto sessionRequestDto) { return SessionResponseDto.builder() .accessToken(authenticationService.login(sessionRequestDto)) diff --git a/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java b/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java index fdce50357..a68939d50 100644 --- a/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java +++ b/app/src/main/java/com/codesoom/assignment/user/presentation/UserController.java @@ -1,6 +1,6 @@ package com.codesoom.assignment.user.presentation; -import com.codesoom.assignment.common.auth.Login; +import com.codesoom.assignment.common.auth.LoginRequired; import com.codesoom.assignment.user.application.UserService; import com.codesoom.assignment.user.domain.User; import com.codesoom.assignment.user.presentation.dto.UserModificationData; @@ -31,14 +31,14 @@ public UserController(UserService userService) { @PostMapping @ResponseStatus(HttpStatus.CREATED) - @Login(required = false) + @LoginRequired(allowGuest = true) UserResultData create(@RequestBody @Valid UserRegistrationData registrationData) { User user = userService.registerUser(registrationData); return getUserResultData(user); } @PatchMapping("{id}") - @Login(required = false) + @LoginRequired(allowGuest = true) UserResultData update( @PathVariable Long id, @RequestBody @Valid UserModificationData modificationData @@ -49,7 +49,7 @@ UserResultData update( @DeleteMapping("{id}") @ResponseStatus(HttpStatus.NO_CONTENT) - @Login(required = false) + @LoginRequired(allowGuest = true) void destroy(@PathVariable Long id) { userService.deleteUser(id); } From 48399f69382380cecd7546323a430853ef5ef634 Mon Sep 17 00:00:00 2001 From: giibeom Date: Sun, 20 Nov 2022 03:45:15 +0900 Subject: [PATCH 39/39] =?UTF-8?q?refactor:=20error=20=ED=8C=A8=ED=82=A4?= =?UTF-8?q?=EC=A7=80=20=EB=B0=8F=20=EA=B0=9D=EC=B2=B4=20=EB=AA=A8=EB=91=90?= =?UTF-8?q?=20exception=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../assignment/common/{error => exception}/ErrorResponse.java | 2 +- .../GlobalExceptionHandler.java} | 4 ++-- .../ProductExceptionHandler.java} | 4 ++-- .../SessionExceptionHandler.java} | 4 ++-- .../UserExceptionHandler.java} | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) rename app/src/main/java/com/codesoom/assignment/common/{error => exception}/ErrorResponse.java (93%) rename app/src/main/java/com/codesoom/assignment/common/{error/GlobalErrorAdvice.java => exception/GlobalExceptionHandler.java} (89%) rename app/src/main/java/com/codesoom/assignment/common/{error/ProductErrorAdvice.java => exception/ProductExceptionHandler.java} (90%) rename app/src/main/java/com/codesoom/assignment/common/{error/SessionErrorAdvice.java => exception/SessionExceptionHandler.java} (92%) rename app/src/main/java/com/codesoom/assignment/common/{error/UserErrorAdvice.java => exception/UserExceptionHandler.java} (94%) diff --git a/app/src/main/java/com/codesoom/assignment/common/error/ErrorResponse.java b/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java similarity index 93% rename from app/src/main/java/com/codesoom/assignment/common/error/ErrorResponse.java rename to app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java index 4cfd0b0da..a8eea17bf 100644 --- a/app/src/main/java/com/codesoom/assignment/common/error/ErrorResponse.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/ErrorResponse.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.common.error; +package com.codesoom.assignment.common.exception; import lombok.Getter; import org.springframework.context.support.DefaultMessageSourceResolvable; diff --git a/app/src/main/java/com/codesoom/assignment/common/error/GlobalErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java similarity index 89% rename from app/src/main/java/com/codesoom/assignment/common/error/GlobalErrorAdvice.java rename to app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java index d4454f74d..1cfe70b68 100644 --- a/app/src/main/java/com/codesoom/assignment/common/error/GlobalErrorAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/GlobalExceptionHandler.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.common.error; +package com.codesoom.assignment.common.exception; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -11,7 +11,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @RestControllerAdvice -public class GlobalErrorAdvice extends ResponseEntityExceptionHandler { +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(value = {Exception.class}) @ResponseStatus public ErrorResponse handleException(final Exception exception) { diff --git a/app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/common/exception/ProductExceptionHandler.java similarity index 90% rename from app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java rename to app/src/main/java/com/codesoom/assignment/common/exception/ProductExceptionHandler.java index 10bb01938..71da4970a 100644 --- a/app/src/main/java/com/codesoom/assignment/common/error/ProductErrorAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/ProductExceptionHandler.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.common.error; +package com.codesoom.assignment.common.exception; import com.codesoom.assignment.product.exception.ProductNotFoundException; import com.codesoom.assignment.product.presentation.ProductController; @@ -13,7 +13,7 @@ ProductController.class }) @Order(Ordered.HIGHEST_PRECEDENCE) -public class ProductErrorAdvice { +public class ProductExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(ProductNotFoundException.class) diff --git a/app/src/main/java/com/codesoom/assignment/common/error/SessionErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/common/exception/SessionExceptionHandler.java similarity index 92% rename from app/src/main/java/com/codesoom/assignment/common/error/SessionErrorAdvice.java rename to app/src/main/java/com/codesoom/assignment/common/exception/SessionExceptionHandler.java index d3aeb8b6f..f3ef4444b 100644 --- a/app/src/main/java/com/codesoom/assignment/common/error/SessionErrorAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/SessionExceptionHandler.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.common.error; +package com.codesoom.assignment.common.exception; import com.codesoom.assignment.product.presentation.ProductController; import com.codesoom.assignment.session.exception.InvalidTokenException; @@ -14,7 +14,7 @@ ProductController.class }) @Order(Ordered.HIGHEST_PRECEDENCE) -public class SessionErrorAdvice { +public class SessionExceptionHandler { @ResponseStatus(HttpStatus.UNAUTHORIZED) @ExceptionHandler(InvalidTokenException.class) diff --git a/app/src/main/java/com/codesoom/assignment/common/error/UserErrorAdvice.java b/app/src/main/java/com/codesoom/assignment/common/exception/UserExceptionHandler.java similarity index 94% rename from app/src/main/java/com/codesoom/assignment/common/error/UserErrorAdvice.java rename to app/src/main/java/com/codesoom/assignment/common/exception/UserExceptionHandler.java index c518c4c65..2de7d3586 100644 --- a/app/src/main/java/com/codesoom/assignment/common/error/UserErrorAdvice.java +++ b/app/src/main/java/com/codesoom/assignment/common/exception/UserExceptionHandler.java @@ -1,4 +1,4 @@ -package com.codesoom.assignment.common.error; +package com.codesoom.assignment.common.exception; import com.codesoom.assignment.session.controller.SessionController; import com.codesoom.assignment.user.exception.UserEmailDuplicationException; @@ -17,7 +17,7 @@ SessionController.class }) @Order(Ordered.HIGHEST_PRECEDENCE) -public class UserErrorAdvice { +public class UserExceptionHandler { @ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler(UserNotFoundException.class)