From 17a4cc8d1319d93797031af8424c319a3dd1f8c1 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 19:59:39 +0900 Subject: [PATCH 01/73] =?UTF-8?q?[chore]=20.gitkeep=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/camp/woowak/lab/customer/domain/.gitkeep | 0 src/main/java/camp/woowak/lab/customer/repository/.gitkeep | 0 src/main/java/camp/woowak/lab/customer/service/.gitkeep | 0 3 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/customer/domain/.gitkeep delete mode 100644 src/main/java/camp/woowak/lab/customer/repository/.gitkeep delete mode 100644 src/main/java/camp/woowak/lab/customer/service/.gitkeep diff --git a/src/main/java/camp/woowak/lab/customer/domain/.gitkeep b/src/main/java/camp/woowak/lab/customer/domain/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/camp/woowak/lab/customer/repository/.gitkeep b/src/main/java/camp/woowak/lab/customer/repository/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/java/camp/woowak/lab/customer/service/.gitkeep b/src/main/java/camp/woowak/lab/customer/service/.gitkeep deleted file mode 100644 index e69de29b..00000000 From 38c81a25f69e2dddcf1510e31482e6eadd7bffca Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:10:36 +0900 Subject: [PATCH 02/73] =?UTF-8?q?[feat]=20PasswordEncoder=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - NoOpPasswordEncoder: 아무런 기능을 제공하지 않는 PasswordEncoder --- .../web/authentication/NoOpPasswordEncoder.java | 15 +++++++++++++++ .../lab/web/authentication/PasswordEncoder.java | 7 +++++++ .../config/AuthenticationConfig.java | 15 +++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/authentication/NoOpPasswordEncoder.java create mode 100644 src/main/java/camp/woowak/lab/web/authentication/PasswordEncoder.java create mode 100644 src/main/java/camp/woowak/lab/web/authentication/config/AuthenticationConfig.java diff --git a/src/main/java/camp/woowak/lab/web/authentication/NoOpPasswordEncoder.java b/src/main/java/camp/woowak/lab/web/authentication/NoOpPasswordEncoder.java new file mode 100644 index 00000000..0d685015 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/authentication/NoOpPasswordEncoder.java @@ -0,0 +1,15 @@ +package camp.woowak.lab.web.authentication; + +import java.util.Objects; + +public class NoOpPasswordEncoder implements PasswordEncoder { + @Override + public String encode(String password) { + return password; + } + + @Override + public boolean matches(String password, String encodedPassword) { + return Objects.equals(password, encodedPassword); + } +} \ No newline at end of file diff --git a/src/main/java/camp/woowak/lab/web/authentication/PasswordEncoder.java b/src/main/java/camp/woowak/lab/web/authentication/PasswordEncoder.java new file mode 100644 index 00000000..d039c949 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/authentication/PasswordEncoder.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.web.authentication; + +public interface PasswordEncoder { + String encode(String password); + + boolean matches(String password, String encodedPassword); +} \ No newline at end of file diff --git a/src/main/java/camp/woowak/lab/web/authentication/config/AuthenticationConfig.java b/src/main/java/camp/woowak/lab/web/authentication/config/AuthenticationConfig.java new file mode 100644 index 00000000..4f40bd1f --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/authentication/config/AuthenticationConfig.java @@ -0,0 +1,15 @@ +package camp.woowak.lab.web.authentication.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import camp.woowak.lab.web.authentication.NoOpPasswordEncoder; +import camp.woowak.lab.web.authentication.PasswordEncoder; + +@Configuration +public class AuthenticationConfig { + @Bean + public PasswordEncoder passwordEncoder() { + return new NoOpPasswordEncoder(); + } +} \ No newline at end of file From deb1f8b9934e03031fb1e299e9a86c3e980002a9 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:11:24 +0900 Subject: [PATCH 03/73] =?UTF-8?q?[feat]=20Vendor=20CustomException=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20DuplicateException:=20unique=20?= =?UTF-8?q?=EC=A0=9C=EC=95=BD=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=B6=80?= =?UTF-8?q?=ED=95=A9=ED=95=98=EC=A7=80=20=EC=95=8A=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20=EC=98=88=EC=99=B8=20-?= =?UTF-8?q?=20InvalidCreationException:=20=EA=B8=B0=ED=83=80=20=EC=A0=9C?= =?UTF-8?q?=EC=95=BD=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=B6=80=ED=95=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EA=B2=BD=EC=9A=B0=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20=EC=98=88=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/customer/exception/DuplicateEmailException.java | 4 ++++ .../woowak/lab/customer/exception/DuplicateException.java | 4 ++++ .../lab/customer/exception/InvalidCreationException.java | 7 +++++++ 3 files changed, 15 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java create mode 100644 src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java create mode 100644 src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java diff --git a/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java b/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java new file mode 100644 index 00000000..4614a21b --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java @@ -0,0 +1,4 @@ +package camp.woowak.lab.customer.exception; + +public class DuplicateEmailException extends DuplicateException { +} diff --git a/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java b/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java new file mode 100644 index 00000000..a6364e76 --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java @@ -0,0 +1,4 @@ +package camp.woowak.lab.customer.exception; + +public abstract class DuplicateException extends Exception { +} diff --git a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java new file mode 100644 index 00000000..bdfc625a --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.customer.exception; + +public class InvalidCreationException extends Exception { + public InvalidCreationException(String message) { + super(message); + } +} From 030a8c0d7f6ac071057c7786eb36c40079896f95 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:11:51 +0900 Subject: [PATCH 04/73] =?UTF-8?q?[feat]=20PayAccountRepository=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 회원가입에 필요해 미리 구현 --- .../lab/payaccount/repository/PayAccountRepository.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/payaccount/repository/PayAccountRepository.java diff --git a/src/main/java/camp/woowak/lab/payaccount/repository/PayAccountRepository.java b/src/main/java/camp/woowak/lab/payaccount/repository/PayAccountRepository.java new file mode 100644 index 00000000..6feb2c36 --- /dev/null +++ b/src/main/java/camp/woowak/lab/payaccount/repository/PayAccountRepository.java @@ -0,0 +1,8 @@ +package camp.woowak.lab.payaccount.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import camp.woowak.lab.payaccount.domain.PayAccount; + +public interface PayAccountRepository extends JpaRepository { +} \ No newline at end of file From bffe230d4ccfa30936b6a24e3f00ee114f1a5af2 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:13:44 +0900 Subject: [PATCH 05/73] [test] SignUpCustomerServiceTest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 회원가입 테스트 구현 - 정상 회원가입 테스트 - 중복 이메일 회원가입 불가 테스트 --- .../service/SignUpCustomerServiceTest.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java diff --git a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java new file mode 100644 index 00000000..9727de50 --- /dev/null +++ b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java @@ -0,0 +1,56 @@ +package camp.woowak.lab.customer.service; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import camp.woowak.lab.customer.domain.Customer; +import camp.woowak.lab.customer.exception.DuplicateEmailException; +import camp.woowak.lab.customer.exception.InvalidCreationException; +import camp.woowak.lab.customer.repository.CustomerRepository; +import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; + +@SpringBootTest +class SignUpCustomerServiceTest { + + @Autowired + SignUpCustomerService signUpCustomerService; + + @Autowired + CustomerRepository customerRepository; + + @BeforeEach + void setUp() { + customerRepository.deleteAll(); + } + + @Test + @DisplayName("구매자 회원가입 테스트") + void testSignUp() throws InvalidCreationException, DuplicateEmailException { + SignUpCustomerCommand cmd = new SignUpCustomerCommand("name", "email", "password", "phone"); + + Long id = signUpCustomerService.signUp(cmd); + + Customer customer = customerRepository.findById(id).orElseThrow(); + + assertEquals("name", customer.getName()); + assertEquals("email", customer.getEmail()); + assertEquals("password", customer.getPassword()); + assertEquals("phone", customer.getPhone()); + } + + @Test + @DisplayName("구매자 이메일 중복 회원가입 테스트") + void testSignUpWithExistingEmail() { + SignUpCustomerCommand cmd = new SignUpCustomerCommand("name", "email", "password", "phone"); + + assertThrows(DuplicateEmailException.class, () -> { + signUpCustomerService.signUp(cmd); + signUpCustomerService.signUp(cmd); + }); + } +} \ No newline at end of file From 0313777234372f5d903d4d70ecfc12a24bcef0fb Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:14:54 +0900 Subject: [PATCH 06/73] =?UTF-8?q?[feat]=20Customer=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=EC=A1=B0=EA=B1=B4=EC=97=90=20=EB=A7=9E?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이름, 이메일, 비밀번호, 전화번호 필드 추가 - 필드 검증 메서드 추가 --- .../woowak/lab/customer/domain/Customer.java | 91 +++++++++++++++++-- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/domain/Customer.java b/src/main/java/camp/woowak/lab/customer/domain/Customer.java index d3fc6511..13fda5f6 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/Customer.java +++ b/src/main/java/camp/woowak/lab/customer/domain/Customer.java @@ -1,13 +1,92 @@ package camp.woowak.lab.customer.domain; +import camp.woowak.lab.customer.exception.InvalidCreationException; import camp.woowak.lab.payaccount.domain.PayAccount; -import jakarta.persistence.*; +import camp.woowak.lab.web.authentication.PasswordEncoder; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToOne; +import lombok.Getter; @Entity +@Getter public class Customer { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - @OneToOne(fetch = FetchType.LAZY) - private PayAccount payAccount; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @Column(nullable = false, length = 50) + private String name; + @Column(unique = true, nullable = false, length = 100) + private String email; + @Column(nullable = false, length = 30) + private String password; + @Column(nullable = false, length = 30) + private String phone; + @OneToOne(fetch = FetchType.LAZY) + private PayAccount payAccount; + + public Customer() { + } + + public Customer(String name, String email, String password, String phone, PayAccount payAccount, + PasswordEncoder passwordEncoder) throws + InvalidCreationException { + checkName(name); + checkEmail(email); + checkPassword(password); + checkPhone(phone); + checkPayAccount(payAccount); + this.name = name; + this.email = email; + this.password = passwordEncoder.encode(password); + this.phone = phone; + this.payAccount = payAccount; + } + + private void checkPayAccount(PayAccount payAccount) throws InvalidCreationException { + if (payAccount == null) { + throw new InvalidCreationException("Pay account cannot be null"); + } + } + + private void checkPhone(String phone) throws InvalidCreationException { + if (phone == null || phone.isBlank()) { + throw new InvalidCreationException("Vendor phone cannot be blank"); + } + if (phone.trim().length() > 30) { + throw new InvalidCreationException("Vendor phone cannot be longer than 30 characters"); + } + } + + private void checkPassword(String password) throws InvalidCreationException { + if (password == null || password.isBlank()) { + throw new InvalidCreationException("Vendor password cannot be blank"); + } + if (password.trim().length() > 30) { + throw new InvalidCreationException("Vendor password cannot be longer than 30 characters"); + } + } + + private void checkEmail(String email) throws InvalidCreationException { + if (email == null || email.isBlank()) { + throw new InvalidCreationException("Vendor email cannot be blank"); + } + if (email.trim().length() > 100) { + throw new InvalidCreationException("Vendor email cannot be longer than 100 characters"); + } + } + + private void checkName(String name) throws InvalidCreationException { + if (name == null || name.isBlank()) { + throw new InvalidCreationException("Vendor name cannot be blank"); + } + if (name.length() > 50) { + throw new InvalidCreationException("Vendor name cannot exceed 50 characters"); + } + } + } From d7482dc2f3111c465221523c12dafc9408bdfa27 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:15:45 +0900 Subject: [PATCH 07/73] =?UTF-8?q?[feat]=20CustomerRepository=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 영속화를 위한 Repository 인터페이스 구현 --- .../lab/customer/repository/CustomerRepository.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java diff --git a/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java b/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java new file mode 100644 index 00000000..9b8e9bc4 --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java @@ -0,0 +1,10 @@ +package camp.woowak.lab.customer.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import camp.woowak.lab.customer.domain.Customer; + +@Repository +public interface CustomerRepository extends JpaRepository { +} From 8a9470120b260423a72764305119003eefe53d4b Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:16:35 +0900 Subject: [PATCH 08/73] =?UTF-8?q?[feat]=20SignUpCustomerCommand=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SignUpCustomerService.signUp 파라미터 구현 --- .../lab/customer/service/command/SignUpCustomerCommand.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/customer/service/command/SignUpCustomerCommand.java diff --git a/src/main/java/camp/woowak/lab/customer/service/command/SignUpCustomerCommand.java b/src/main/java/camp/woowak/lab/customer/service/command/SignUpCustomerCommand.java new file mode 100644 index 00000000..d59b8160 --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/service/command/SignUpCustomerCommand.java @@ -0,0 +1,4 @@ +package camp.woowak.lab.customer.service.command; + +public record SignUpCustomerCommand(String name, String email, String password, String phone) { +} From 04f61a0fa99a65f32344b0c22a55e93d3413e569 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:17:11 +0900 Subject: [PATCH 09/73] =?UTF-8?q?[feat]=20SignUpCustomerService=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 회원가입 구현 --- .../service/SignUpCustomerService.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java diff --git a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java new file mode 100644 index 00000000..be5cd040 --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java @@ -0,0 +1,42 @@ +package camp.woowak.lab.customer.service; + +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; + +import camp.woowak.lab.customer.domain.Customer; +import camp.woowak.lab.customer.exception.DuplicateEmailException; +import camp.woowak.lab.customer.exception.InvalidCreationException; +import camp.woowak.lab.customer.repository.CustomerRepository; +import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; +import camp.woowak.lab.payaccount.domain.PayAccount; +import camp.woowak.lab.payaccount.repository.PayAccountRepository; +import camp.woowak.lab.web.authentication.PasswordEncoder; + +@Service +public class SignUpCustomerService { + private final CustomerRepository customerRepository; + private final PayAccountRepository payAccountRepository; + private final PasswordEncoder passwordEncoder; + + public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRepository payAccountRepository, + PasswordEncoder passwordEncoder) { + this.customerRepository = customerRepository; + this.payAccountRepository = payAccountRepository; + this.passwordEncoder = passwordEncoder; + } + + public Long signUp(SignUpCustomerCommand cmd) throws InvalidCreationException, DuplicateEmailException { + PayAccount payAccount = new PayAccount(); + payAccountRepository.save(payAccount); + + Customer newCustomer = new Customer(cmd.name(), cmd.email(), cmd.password(), cmd.phone(), payAccount, + passwordEncoder); + + try { + customerRepository.save(newCustomer); + } catch (DataIntegrityViolationException e) { + throw new DuplicateEmailException(); + } + return newCustomer.getId(); + } +} From 29006814b4b99f66271beaffa0ee85040d32ef7f Mon Sep 17 00:00:00 2001 From: donghar Date: Sat, 10 Aug 2024 16:24:31 +0900 Subject: [PATCH 10/73] =?UTF-8?q?[feat]=20Vendor=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=EC=A0=84=EC=86=A1=20=EA=B3=84=EC=B8=B5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `+` AuthController: "/auth" 컨텍스트 처리 `+` ApiResponse: 공통 응답처리를 위한 모델 `+` ErrorCode: 공통 예외처리를 위한 코드 `+` SignUpVendorRequest: POST /auth/vendor 요청을 받는 dto --- .../woowak/lab/web/api/AuthController.java | 42 +++++++++++++++++++ .../web/dto/request/SignUpVendorRequest.java | 9 ++++ .../lab/web/dto/response/ApiResponse.java | 40 ++++++++++++++++++ .../camp/woowak/lab/web/error/ErrorCode.java | 22 ++++++++++ 4 files changed, 113 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/api/AuthController.java create mode 100644 src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java create mode 100644 src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java create mode 100644 src/main/java/camp/woowak/lab/web/error/ErrorCode.java diff --git a/src/main/java/camp/woowak/lab/web/api/AuthController.java b/src/main/java/camp/woowak/lab/web/api/AuthController.java new file mode 100644 index 00000000..933f1125 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/api/AuthController.java @@ -0,0 +1,42 @@ +package camp.woowak.lab.web.api; + +import java.net.URI; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import camp.woowak.lab.vendor.exception.DuplicateEmailException; +import camp.woowak.lab.vendor.exception.InvalidCreationException; +import camp.woowak.lab.vendor.service.SignUpVendorService; +import camp.woowak.lab.vendor.service.command.SignUpVendorCommand; +import camp.woowak.lab.web.dto.request.SignUpVendorRequest; +import camp.woowak.lab.web.dto.response.ApiResponse; +import camp.woowak.lab.web.error.ErrorCode; + +@RestController +@RequestMapping("/auth") +public class AuthController { + private final SignUpVendorService signUpVendorService; + + public AuthController(SignUpVendorService signUpVendorService) { + this.signUpVendorService = signUpVendorService; + } + + @PostMapping("/vendors") + public ResponseEntity signUpVendor(@RequestBody SignUpVendorRequest request) { + SignUpVendorCommand command = + new SignUpVendorCommand(request.name(), request.email(), request.password(), request.phone()); + Long registeredId; + try { + registeredId = signUpVendorService.signUp(command); + } catch (InvalidCreationException e) { + return ResponseEntity.badRequest().body(ApiResponse.error(ErrorCode.SIGNUP_INVALID_REQUEST)); + } catch (DuplicateEmailException e) { + return ResponseEntity.ok(ApiResponse.error(ErrorCode.AUTH_DUPLICATE_EMAIL)); + } + return ResponseEntity.created(URI.create("/vendors/" + registeredId)).build(); + } +} diff --git a/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java new file mode 100644 index 00000000..60044894 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java @@ -0,0 +1,9 @@ +package camp.woowak.lab.web.dto.request; + +public record SignUpVendorRequest( + String name, + String email, + String password, + String phone +) { +} diff --git a/src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java b/src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java new file mode 100644 index 00000000..7f0be70f --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java @@ -0,0 +1,40 @@ +package camp.woowak.lab.web.dto.response; + +import camp.woowak.lab.web.error.ErrorCode; + +public class ApiResponse { + private String code; + private String message; + private T data; + + private ApiResponse(String code, String message) { + this.code = code; + this.message = message; + } + + private ApiResponse(String code, String message, T data) { + this.code = code; + this.message = message; + this.data = data; + } + + public static ApiResponse ok(T data) { + return new ApiResponse<>("OK", "success", data); + } + + public static ApiResponse error(ErrorCode errorCode) { + return new ApiResponse<>(errorCode.getCode(), errorCode.getMessage()); + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public T getData() { + return data; + } +} diff --git a/src/main/java/camp/woowak/lab/web/error/ErrorCode.java b/src/main/java/camp/woowak/lab/web/error/ErrorCode.java new file mode 100644 index 00000000..53b0e82e --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/error/ErrorCode.java @@ -0,0 +1,22 @@ +package camp.woowak.lab.web.error; + +public enum ErrorCode { + AUTH_DUPLICATE_EMAIL("a1", "이미 가입된 이메일 입니다."), + SIGNUP_INVALID_REQUEST("s1", "잘못된 요청입니다."); + + private final String code; + private final String message; + + ErrorCode(String code, String message) { + this.code = code; + this.message = message; + } + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } +} From 4d6a20cdf5a1dc366daa18f926121c436ca5cbdf Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:57:21 +0900 Subject: [PATCH 11/73] =?UTF-8?q?[feat]=20SignUpCustomerRequest=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 회원가입 요청 DTO 생성 --- .../lab/web/dto/request/SignUpCustomerRequest.java | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java diff --git a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java new file mode 100644 index 00000000..4f1e877c --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java @@ -0,0 +1,9 @@ +package camp.woowak.lab.web.dto.request; + +public record SignUpCustomerRequest( + String name, + String email, + String password, + String phone +) { +} From f93f83d940e5ea536ffcc7aefef9bea204cab80c Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sat, 10 Aug 2024 20:58:00 +0900 Subject: [PATCH 12/73] =?UTF-8?q?[feat]=20AuthController.signUpCustomer=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 회원가입 API 구현 --- .../woowak/lab/web/api/AuthController.java | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/camp/woowak/lab/web/api/AuthController.java b/src/main/java/camp/woowak/lab/web/api/AuthController.java index 933f1125..59b67e7d 100644 --- a/src/main/java/camp/woowak/lab/web/api/AuthController.java +++ b/src/main/java/camp/woowak/lab/web/api/AuthController.java @@ -8,10 +8,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import camp.woowak.lab.customer.service.SignUpCustomerService; +import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; import camp.woowak.lab.vendor.exception.DuplicateEmailException; import camp.woowak.lab.vendor.exception.InvalidCreationException; import camp.woowak.lab.vendor.service.SignUpVendorService; import camp.woowak.lab.vendor.service.command.SignUpVendorCommand; +import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; import camp.woowak.lab.web.dto.request.SignUpVendorRequest; import camp.woowak.lab.web.dto.response.ApiResponse; import camp.woowak.lab.web.error.ErrorCode; @@ -20,9 +23,11 @@ @RequestMapping("/auth") public class AuthController { private final SignUpVendorService signUpVendorService; + private final SignUpCustomerService signUpCustomerService; - public AuthController(SignUpVendorService signUpVendorService) { + public AuthController(SignUpVendorService signUpVendorService, SignUpCustomerService signUpCustomerService) { this.signUpVendorService = signUpVendorService; + this.signUpCustomerService = signUpCustomerService; } @PostMapping("/vendors") @@ -39,4 +44,19 @@ public ResponseEntity signUpVendor(@RequestBody SignUpVendorRequest request) } return ResponseEntity.created(URI.create("/vendors/" + registeredId)).build(); } + + @PostMapping("/customers") + public ResponseEntity signUpCustomer(@RequestBody SignUpCustomerRequest request) { + SignUpCustomerCommand command = + new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone()); + Long registeredId; + try { + registeredId = signUpCustomerService.signUp(command); + } catch (camp.woowak.lab.customer.exception.InvalidCreationException e) { + return ResponseEntity.badRequest().body(ApiResponse.error(ErrorCode.SIGNUP_INVALID_REQUEST)); + } catch (camp.woowak.lab.customer.exception.DuplicateEmailException e) { + return ResponseEntity.ok(ApiResponse.error(ErrorCode.AUTH_DUPLICATE_EMAIL)); + } + return ResponseEntity.created(URI.create("/customers/" + registeredId)).build(); + } } From c1bd5dc5eb48e2b1b21c9831c48fd615d0a96cfe Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 11:37:26 +0900 Subject: [PATCH 13/73] [refactor] AuthController -> CustomerController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 회원가입 API 클래스명 변경 --- ...ontroller.java => CustomerController.java} | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) rename src/main/java/camp/woowak/lab/web/api/{AuthController.java => CustomerController.java} (52%) diff --git a/src/main/java/camp/woowak/lab/web/api/AuthController.java b/src/main/java/camp/woowak/lab/web/api/CustomerController.java similarity index 52% rename from src/main/java/camp/woowak/lab/web/api/AuthController.java rename to src/main/java/camp/woowak/lab/web/api/CustomerController.java index 59b67e7d..490da989 100644 --- a/src/main/java/camp/woowak/lab/web/api/AuthController.java +++ b/src/main/java/camp/woowak/lab/web/api/CustomerController.java @@ -5,46 +5,22 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import camp.woowak.lab.customer.service.SignUpCustomerService; import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; -import camp.woowak.lab.vendor.exception.DuplicateEmailException; -import camp.woowak.lab.vendor.exception.InvalidCreationException; -import camp.woowak.lab.vendor.service.SignUpVendorService; -import camp.woowak.lab.vendor.service.command.SignUpVendorCommand; import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; -import camp.woowak.lab.web.dto.request.SignUpVendorRequest; import camp.woowak.lab.web.dto.response.ApiResponse; import camp.woowak.lab.web.error.ErrorCode; @RestController -@RequestMapping("/auth") -public class AuthController { - private final SignUpVendorService signUpVendorService; +public class CustomerController { private final SignUpCustomerService signUpCustomerService; - public AuthController(SignUpVendorService signUpVendorService, SignUpCustomerService signUpCustomerService) { - this.signUpVendorService = signUpVendorService; + public CustomerController(SignUpCustomerService signUpCustomerService) { this.signUpCustomerService = signUpCustomerService; } - @PostMapping("/vendors") - public ResponseEntity signUpVendor(@RequestBody SignUpVendorRequest request) { - SignUpVendorCommand command = - new SignUpVendorCommand(request.name(), request.email(), request.password(), request.phone()); - Long registeredId; - try { - registeredId = signUpVendorService.signUp(command); - } catch (InvalidCreationException e) { - return ResponseEntity.badRequest().body(ApiResponse.error(ErrorCode.SIGNUP_INVALID_REQUEST)); - } catch (DuplicateEmailException e) { - return ResponseEntity.ok(ApiResponse.error(ErrorCode.AUTH_DUPLICATE_EMAIL)); - } - return ResponseEntity.created(URI.create("/vendors/" + registeredId)).build(); - } - @PostMapping("/customers") public ResponseEntity signUpCustomer(@RequestBody SignUpCustomerRequest request) { SignUpCustomerCommand command = From 07cd0511d3418902e6938d029a35321d09898080 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 11:41:54 +0900 Subject: [PATCH 14/73] =?UTF-8?q?[test]=20Customer=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 제약조건 테스트(점주 제약조건 참조함) --- .../lab/customer/domain/CustomerTest.java | 200 ++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/customer/domain/CustomerTest.java diff --git a/src/test/java/camp/woowak/lab/customer/domain/CustomerTest.java b/src/test/java/camp/woowak/lab/customer/domain/CustomerTest.java new file mode 100644 index 00000000..28adbfd2 --- /dev/null +++ b/src/test/java/camp/woowak/lab/customer/domain/CustomerTest.java @@ -0,0 +1,200 @@ +package camp.woowak.lab.customer.domain; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import camp.woowak.lab.customer.exception.InvalidCreationException; +import camp.woowak.lab.payaccount.domain.PayAccount; +import camp.woowak.lab.payaccount.domain.TestPayAccount; +import camp.woowak.lab.web.authentication.NoOpPasswordEncoder; +import camp.woowak.lab.web.authentication.PasswordEncoder; + +class CustomerTest { + + private PayAccount payAccount; + private PasswordEncoder passwordEncoder; + + @BeforeEach + void setUp() { + payAccount = new TestPayAccount(1L); + passwordEncoder = new NoOpPasswordEncoder(); + } + + @Nested + @DisplayName("Customer 생성은") + class IsConstructed { + @Nested + @DisplayName("이름이") + class NameMust { + @Test + @DisplayName("[성공] 50자까지 허용한다.") + void successWith50() { + Assertions.assertDoesNotThrow( + () -> new Customer("aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeee", + "validEmail@validEmail.com", + "validPassword", "010-0000-0000", payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] null이면 예외가 발생한다.") + void failWithNull() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer(null, "validEmail@validEmail.com", "validPassword", "010-0000-0000", payAccount, + passwordEncoder)); + } + + @Test + @DisplayName("[예외] 공란이면 예외가 발생한다.") + void failWithBlank() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer(" ", "validEmail@validEmail.com", "validPassword", "010-0000-0000", payAccount, + passwordEncoder)); + } + + @Test + @DisplayName("[예외] 50자를 초과하면 예외가 발생한다.") + void failWith51() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeef", + "validEmail@validEmail.com", + "validPassword", "010-0000-0000", payAccount, passwordEncoder)); + } + } + + @Nested + @DisplayName("이메일이") + class EmailMust { + @Test + @DisplayName("[성공] 100자까지 허용한다.") + void successWith100() { + Assertions.assertDoesNotThrow( + () -> new Customer("aaaaaaaaaa", + "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeee", + "validPassword", "010-0000-0000", payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] null이면 예외가 발생한다.") + void failWithNull() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", null, "validPassword", "010-0000-0000", payAccount, + passwordEncoder)); + } + + @Test + @DisplayName("[예외] 공란이면 예외가 발생한다.") + void failWithBlank() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", " ", "validPassword", "010-0000-0000", payAccount, + passwordEncoder)); + } + + @Test + @DisplayName("[예외] 100자를 초과하면 예외가 발생한다.") + void failWith101() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", + "aaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeeaaaaaaaaaabbbbbbbbbbccccccccccddddddddddeeeeeeeeeea", + "validPassword", "010-0000-0000", payAccount, passwordEncoder)); + } + } + + @Nested + @DisplayName("비밀번호가") + class PasswordMust { + @Test + @DisplayName("[성공] 30자까지 허용한다.") + void successWith30() { + Assertions.assertDoesNotThrow( + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "thisstringsizeisthirtyalsnvien", + "010-0000-0000", payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] null이면 예외가 발생한다.") + void failWithNull() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", null, "010-0000-0000", payAccount, + passwordEncoder)); + } + + @Test + @DisplayName("[예외] 공란이면 예외가 발생한다.") + void failWithBlank() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", " ", "010-0000-0000", payAccount, + passwordEncoder)); + } + + @Test + @DisplayName("[예외] 30자를 초과하면 예외가 발생한다.") + void failWith31() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "thisstringsizeisthirtyonesnvien", + "010-0000-0000", payAccount, passwordEncoder)); + } + } + + @Nested + @DisplayName("전화번호가") + class PhoneMust { + @Test + @DisplayName("[성공] 30자까지 허용한다.") + void successWith30() { + Assertions.assertDoesNotThrow( + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "validPassword", + "0000000000-0000000000-00000000", + payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] null이면 예외가 발생한다.") + void failWithNull() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "validPassword", null, + payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] 공란이면 예외가 발생한다.") + void failWithBlank() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "validPassword", " ", + payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] 30자를 초과하면 예외가 발생한다.") + void failWith31() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "validPassword", + "0000000000-0000000000-000000000", + payAccount, passwordEncoder)); + } + } + + @Nested + @DisplayName("페이계좌가") + class PayAccountMust { + @Test + @DisplayName("[성공] 있으면 성공한다.") + void successWithExist() { + Assertions.assertDoesNotThrow( + () -> new Customer("validName", "validEmail@validEmail.com", "validPassword", "010-0000-0000", + payAccount, passwordEncoder)); + } + + @Test + @DisplayName("[예외] null이면 예외가 발생한다.") + void failWithNull() { + Assertions.assertThrows(InvalidCreationException.class, + () -> new Customer("aaaaaaaaaa", "validEmail@validEmail.com", "validPassword", "010-0000-0000", + null, + passwordEncoder)); + } + } + } +} From 17fb832af0f5145cd55797ec33a6f1556f891f39 Mon Sep 17 00:00:00 2001 From: donghar Date: Sat, 10 Aug 2024 23:05:10 +0900 Subject: [PATCH 15/73] =?UTF-8?q?[feat]=20Phone=20=EA=B2=80=EC=A6=9D=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전화번호를 검증하기 위한 어노테이션 및 커스텀 Validator 구현 --- .../web/dto/request/SignUpVendorRequest.java | 9 ++++++++ .../lab/web/validation/annotation/Phone.java | 21 +++++++++++++++++++ .../validator/PhoneNumberValidator.java | 17 +++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/validation/annotation/Phone.java create mode 100644 src/main/java/camp/woowak/lab/web/validation/validator/PhoneNumberValidator.java diff --git a/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java index 60044894..00cbe2ab 100644 --- a/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java +++ b/src/main/java/camp/woowak/lab/web/dto/request/SignUpVendorRequest.java @@ -1,9 +1,18 @@ package camp.woowak.lab.web.dto.request; +import org.hibernate.validator.constraints.Length; + +import camp.woowak.lab.web.validation.annotation.Phone; +import jakarta.validation.constraints.Email; + public record SignUpVendorRequest( + @Length(min = 1, max = 50) String name, + @Email String email, + @Length(min = 1, max = 30) String password, + @Phone String phone ) { } diff --git a/src/main/java/camp/woowak/lab/web/validation/annotation/Phone.java b/src/main/java/camp/woowak/lab/web/validation/annotation/Phone.java new file mode 100644 index 00000000..60deb9ec --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/validation/annotation/Phone.java @@ -0,0 +1,21 @@ +package camp.woowak.lab.web.validation.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import camp.woowak.lab.web.validation.validator.PhoneNumberValidator; +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +@Target({ElementType.FIELD, ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = PhoneNumberValidator.class) +public @interface Phone { + String message() default "Invalid phone number"; + + Class[] groups() default {}; + + Class[] payload() default {}; +} diff --git a/src/main/java/camp/woowak/lab/web/validation/validator/PhoneNumberValidator.java b/src/main/java/camp/woowak/lab/web/validation/validator/PhoneNumberValidator.java new file mode 100644 index 00000000..788ec848 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/validation/validator/PhoneNumberValidator.java @@ -0,0 +1,17 @@ +package camp.woowak.lab.web.validation.validator; + +import camp.woowak.lab.web.validation.annotation.Phone; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; + +public class PhoneNumberValidator implements ConstraintValidator { + private static final String PHONE_NUMBER_PATTERN = "^(01[0167]|02|0[3-6][1-4])-\\d{3,4}-\\d{4}$"; + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) { + return false; + } + return value.matches(PHONE_NUMBER_PATTERN); + } +} From bbafb207888faab72aec8849c93a1f5f14206807 Mon Sep 17 00:00:00 2001 From: donghar Date: Sat, 10 Aug 2024 16:18:01 +0900 Subject: [PATCH 16/73] =?UTF-8?q?[feat]=20jpa=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `~` show-sql: 실행되는 sql 조회 `~` generate-ddl: 테스트시 테이블 자동 생성 `~` ddl-auto: 어플리케이션 생성시 생성, 종료시 삭제 `~` open-in-view: 의도하지 않은 조회 쿼리 발생 방지 --- src/main/resources/application.properties | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index cc1ad9a6..66b1c0c5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,5 @@ spring.application.name=lab +spring.jpa.show-sql=true +spring.jpa.generate-ddl=true +spring.jpa.open-in-view=false +spring.jpa.hibernate.ddl-auto=create-drop From a9201d787b30a3e2936955116d7687b5d434b6e0 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:13:33 +0900 Subject: [PATCH 17/73] =?UTF-8?q?[test]=20CustomerController=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 구매자 API RequestBody 제약조건 테스트 --- .../lab/web/api/CustomerControllerTest.java | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java diff --git a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java new file mode 100644 index 00000000..b2fcd5c4 --- /dev/null +++ b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java @@ -0,0 +1,191 @@ +package camp.woowak.lab.web.api; + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.BDDMockito.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +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.data.jpa.mapping.JpaMetamodelMappingContext; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import camp.woowak.lab.customer.exception.DuplicateEmailException; +import camp.woowak.lab.customer.service.SignUpCustomerService; +import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; +import camp.woowak.lab.web.error.ErrorCode; + +@WebMvcTest(CustomerController.class) +@MockBean(JpaMetamodelMappingContext.class) +class CustomerControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private SignUpCustomerService signUpCustomerService; + + @Autowired + private ObjectMapper objectMapper; + + @Test + @DisplayName("구매자 회원가입 테스트 - 성공") + void testSignUpCustomer() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", + "010-1234-5678"); + given(signUpCustomerService.signUp(any())).willReturn(1L); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isCreated()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 이름이 없는 경우") + void testSignUpCustomerWithoutName() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("", "email@test.com", "password123", "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 이메일이 없는 경우") + void testSignUpCustomerWithoutEmail() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "", "password123", "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 비밀번호가 없는 경우") + void testSignUpCustomerWithoutPassword() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "", "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 전화번호가 없는 경우") + void testSignUpCustomerWithoutPhone() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", ""); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 이름이 50자 초과인 경우") + void testSignUpCustomerWithLongName() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("n".repeat(51), "email@test.com", "password123", + "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 이메일이 100자 초과인 경우") + void testSignUpCustomerWithLongEmail() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "e".repeat(90) + "@test.com", "password123", + "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 비밀번호가 20자 초과인 경우") + void testSignUpCustomerWithLongPassword() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "p".repeat(21), + "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 비밀번호가 8자 미만인 경우") + void testSignUpCustomerWithShortPassword() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "pass", "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 전화번호가 30자 초과인 경우") + void testSignUpCustomerWithLongPhone() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", + "0".repeat(31)); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 이메일 형식이 아닌 경우") + void testSignUpCustomerWithInvalidEmail() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "invalid-email", "password123", + "01012345678"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 전화번호 형식이 아닌 경우") + void testSignUpCustomerWithInvalidPhone() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", + "invalid-phone"); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()); + } + + @Test + @DisplayName("구매자 회원가입 테스트 - 중복된 이메일인 경우") + void testSignUpCustomerWithDuplicateEmail() throws Exception { + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "duplicate@test.com", "password123", + "010-1234-5678"); + given(signUpCustomerService.signUp(any())).willThrow(new DuplicateEmailException()); + + mockMvc.perform(post("/customers") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.code").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getCode())) + .andExpect(jsonPath("$.message").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getMessage())); + } +} \ No newline at end of file From 2d54d492668b76d6db8ab4bff99c01b8353ca652 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:14:19 +0900 Subject: [PATCH 18/73] =?UTF-8?q?[feat]=20SignUpCustomerRequest=20?= =?UTF-8?q?=EC=A0=9C=EC=95=BD=20=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 이름 길이 1~50 - 이메일 - 비밀번호 8~20 - 전화번호 --- .../lab/web/dto/request/SignUpCustomerRequest.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java index 4f1e877c..753cb1a1 100644 --- a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java +++ b/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java @@ -1,9 +1,18 @@ package camp.woowak.lab.web.dto.request; +import org.hibernate.validator.constraints.Length; + +import camp.woowak.lab.web.validation.annotation.Phone; +import jakarta.validation.constraints.Email; + public record SignUpCustomerRequest( + @Length(min = 1, max = 50) String name, + @Email String email, + @Length(min = 8, max = 20) String password, + @Phone String phone ) { } From 98f450b88cf235066120c06f421002d0a170224a Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:15:11 +0900 Subject: [PATCH 19/73] =?UTF-8?q?[feat]=20CustomerController.signUp=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20Valid=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/camp/woowak/lab/web/api/CustomerController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/camp/woowak/lab/web/api/CustomerController.java b/src/main/java/camp/woowak/lab/web/api/CustomerController.java index 490da989..498070b0 100644 --- a/src/main/java/camp/woowak/lab/web/api/CustomerController.java +++ b/src/main/java/camp/woowak/lab/web/api/CustomerController.java @@ -12,6 +12,7 @@ import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; import camp.woowak.lab.web.dto.response.ApiResponse; import camp.woowak.lab.web.error.ErrorCode; +import jakarta.validation.Valid; @RestController public class CustomerController { @@ -22,7 +23,7 @@ public CustomerController(SignUpCustomerService signUpCustomerService) { } @PostMapping("/customers") - public ResponseEntity signUpCustomer(@RequestBody SignUpCustomerRequest request) { + public ResponseEntity signUp(@Valid @RequestBody SignUpCustomerRequest request) { SignUpCustomerCommand command = new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone()); Long registeredId; From 6d718e5ae9ea94043466b8e6e3a9ff98be04f5b4 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:48:44 +0900 Subject: [PATCH 20/73] =?UTF-8?q?[refactor]=20SignUpCustomerServiceTest=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Repository 의존성 제거 --- .../service/SignUpCustomerServiceTest.java | 77 ++++++++++++------- 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java index 9727de50..0f8f93af 100644 --- a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java +++ b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java @@ -1,56 +1,79 @@ package camp.woowak.lab.customer.service; -import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.*; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.dao.DataIntegrityViolationException; import camp.woowak.lab.customer.domain.Customer; import camp.woowak.lab.customer.exception.DuplicateEmailException; +import camp.woowak.lab.customer.exception.DuplicateException; import camp.woowak.lab.customer.exception.InvalidCreationException; import camp.woowak.lab.customer.repository.CustomerRepository; import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; +import camp.woowak.lab.fixture.CustomerFixture; +import camp.woowak.lab.payaccount.domain.PayAccount; +import camp.woowak.lab.payaccount.repository.PayAccountRepository; +import camp.woowak.lab.web.authentication.NoOpPasswordEncoder; +import camp.woowak.lab.web.authentication.PasswordEncoder; -@SpringBootTest -class SignUpCustomerServiceTest { +@ExtendWith(MockitoExtension.class) +class SignUpCustomerServiceTest implements CustomerFixture { - @Autowired - SignUpCustomerService signUpCustomerService; + @InjectMocks + private SignUpCustomerService service; - @Autowired - CustomerRepository customerRepository; + @Mock + private CustomerRepository customerRepository; - @BeforeEach - void setUp() { - customerRepository.deleteAll(); - } + @Mock + private PayAccountRepository payAccountRepository; + + @Mock + private PasswordEncoder passwordEncoder; @Test @DisplayName("구매자 회원가입 테스트") void testSignUp() throws InvalidCreationException, DuplicateEmailException { - SignUpCustomerCommand cmd = new SignUpCustomerCommand("name", "email", "password", "phone"); + // given + given(passwordEncoder.encode(Mockito.anyString())).willReturn("password"); + PayAccount payAccount = createPayAccount(); + Customer customer = createCustomer(payAccount, new NoOpPasswordEncoder()); + given(payAccountRepository.save(Mockito.any(PayAccount.class))).willReturn(payAccount); + given(customerRepository.save(Mockito.any(Customer.class))).willReturn(customer); - Long id = signUpCustomerService.signUp(cmd); + // when + SignUpCustomerCommand command = + new SignUpCustomerCommand("name", "email@example.com", "password", "01012345678"); + Long id = service.signUp(command); - Customer customer = customerRepository.findById(id).orElseThrow(); - - assertEquals("name", customer.getName()); - assertEquals("email", customer.getEmail()); - assertEquals("password", customer.getPassword()); - assertEquals("phone", customer.getPhone()); + // then + then(payAccountRepository).should().save(Mockito.any(PayAccount.class)); + then(customerRepository).should().save(Mockito.any(Customer.class)); } @Test @DisplayName("구매자 이메일 중복 회원가입 테스트") void testSignUpWithExistingEmail() { - SignUpCustomerCommand cmd = new SignUpCustomerCommand("name", "email", "password", "phone"); + // given + given(passwordEncoder.encode(Mockito.anyString())).willReturn("password"); + given(payAccountRepository.save(Mockito.any(PayAccount.class))).willReturn(createPayAccount()); + when(customerRepository.save(Mockito.any(Customer.class))).thenThrow(DataIntegrityViolationException.class); + + // when + SignUpCustomerCommand command = + new SignUpCustomerCommand("name", "email@example.com", "password", "01012345678"); - assertThrows(DuplicateEmailException.class, () -> { - signUpCustomerService.signUp(cmd); - signUpCustomerService.signUp(cmd); - }); + // then + Assertions.assertThrows(DuplicateException.class, () -> service.signUp(command)); + then(payAccountRepository).should().save(Mockito.any(PayAccount.class)); + then(customerRepository).should().save(Mockito.any(Customer.class)); } } \ No newline at end of file From 5197be330fb59df763095a284296b9452e41d6a5 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:49:16 +0900 Subject: [PATCH 21/73] =?UTF-8?q?[feat]=20CustomerFixture=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 반복되는 생성 추상화 --- .../woowak/lab/fixture/CustomerFixture.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/fixture/CustomerFixture.java diff --git a/src/test/java/camp/woowak/lab/fixture/CustomerFixture.java b/src/test/java/camp/woowak/lab/fixture/CustomerFixture.java new file mode 100644 index 00000000..75c1ac1b --- /dev/null +++ b/src/test/java/camp/woowak/lab/fixture/CustomerFixture.java @@ -0,0 +1,22 @@ +package camp.woowak.lab.fixture; + +import camp.woowak.lab.customer.domain.Customer; +import camp.woowak.lab.customer.exception.InvalidCreationException; +import camp.woowak.lab.payaccount.domain.PayAccount; +import camp.woowak.lab.web.authentication.PasswordEncoder; + +public interface CustomerFixture { + default PayAccount createPayAccount() { + return new PayAccount(); + } + + default Customer createCustomer(PayAccount payAccount, PasswordEncoder passwordEncoder) { + try { + return new Customer("vendorName", "vendorEmail@example.com", "vendorPassword", "010-0000-0000", payAccount, + passwordEncoder); + } catch (InvalidCreationException e) { + throw new RuntimeException(e); + } + } + +} From 476489cdc842fa9fce21819f3dc60403d89a0fb2 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:51:14 +0900 Subject: [PATCH 22/73] =?UTF-8?q?[chore]=20CustomerControllerTest=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80=20-=20given,=20when,=20?= =?UTF-8?q?then=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/api/CustomerControllerTest.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java index b2fcd5c4..04c31f3e 100644 --- a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java +++ b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java @@ -37,10 +37,12 @@ class CustomerControllerTest { @Test @DisplayName("구매자 회원가입 테스트 - 성공") void testSignUpCustomer() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", "010-1234-5678"); given(signUpCustomerService.signUp(any())).willReturn(1L); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -51,7 +53,9 @@ void testSignUpCustomer() throws Exception { @DisplayName("구매자 회원가입 테스트 - 이름이 없는 경우") void testSignUpCustomerWithoutName() throws Exception { SignUpCustomerRequest request = new SignUpCustomerRequest("", "email@test.com", "password123", "01012345678"); + // given + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -62,7 +66,9 @@ void testSignUpCustomerWithoutName() throws Exception { @DisplayName("구매자 회원가입 테스트 - 이메일이 없는 경우") void testSignUpCustomerWithoutEmail() throws Exception { SignUpCustomerRequest request = new SignUpCustomerRequest("name", "", "password123", "01012345678"); + // given + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -73,7 +79,9 @@ void testSignUpCustomerWithoutEmail() throws Exception { @DisplayName("구매자 회원가입 테스트 - 비밀번호가 없는 경우") void testSignUpCustomerWithoutPassword() throws Exception { SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "", "01012345678"); + // given + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -83,8 +91,10 @@ void testSignUpCustomerWithoutPassword() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 전화번호가 없는 경우") void testSignUpCustomerWithoutPhone() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", ""); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -94,9 +104,11 @@ void testSignUpCustomerWithoutPhone() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 이름이 50자 초과인 경우") void testSignUpCustomerWithLongName() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("n".repeat(51), "email@test.com", "password123", "01012345678"); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -106,9 +118,11 @@ void testSignUpCustomerWithLongName() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 이메일이 100자 초과인 경우") void testSignUpCustomerWithLongEmail() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "e".repeat(90) + "@test.com", "password123", "01012345678"); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -131,7 +145,9 @@ void testSignUpCustomerWithLongPassword() throws Exception { @DisplayName("구매자 회원가입 테스트 - 비밀번호가 8자 미만인 경우") void testSignUpCustomerWithShortPassword() throws Exception { SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "pass", "01012345678"); + // given + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -141,9 +157,11 @@ void testSignUpCustomerWithShortPassword() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 전화번호가 30자 초과인 경우") void testSignUpCustomerWithLongPhone() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", "0".repeat(31)); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -153,9 +171,11 @@ void testSignUpCustomerWithLongPhone() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 이메일 형식이 아닌 경우") void testSignUpCustomerWithInvalidEmail() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "invalid-email", "password123", "01012345678"); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -165,9 +185,11 @@ void testSignUpCustomerWithInvalidEmail() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 전화번호 형식이 아닌 경우") void testSignUpCustomerWithInvalidPhone() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "password123", "invalid-phone"); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) @@ -177,10 +199,12 @@ void testSignUpCustomerWithInvalidPhone() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 중복된 이메일인 경우") void testSignUpCustomerWithDuplicateEmail() throws Exception { + // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "duplicate@test.com", "password123", "010-1234-5678"); given(signUpCustomerService.signUp(any())).willThrow(new DuplicateEmailException()); + // when & then mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) From 4adf5de577e407b67943a9fbc934224457028ece Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 12:53:29 +0900 Subject: [PATCH 23/73] =?UTF-8?q?[fix]=20CustomerControllerTest=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?-=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EC=8B=9C=20=ED=95=AD=EC=83=81=20=EC=9E=98=EB=AA=BB=EB=90=9C?= =?UTF-8?q?=20=EC=A0=84=ED=99=94=EB=B2=88=ED=98=B8=20=ED=98=95=EC=8B=9D?= =?UTF-8?q?=EC=9D=B4=20=EB=93=A4=EC=96=B4=EA=B0=80=EB=8A=94=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/api/CustomerControllerTest.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java index 04c31f3e..0799d428 100644 --- a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java +++ b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java @@ -52,8 +52,8 @@ void testSignUpCustomer() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 이름이 없는 경우") void testSignUpCustomerWithoutName() throws Exception { - SignUpCustomerRequest request = new SignUpCustomerRequest("", "email@test.com", "password123", "01012345678"); // given + SignUpCustomerRequest request = new SignUpCustomerRequest("", "email@test.com", "password123", "010-1234-5678"); // when & then mockMvc.perform(post("/customers") @@ -65,8 +65,8 @@ void testSignUpCustomerWithoutName() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 이메일이 없는 경우") void testSignUpCustomerWithoutEmail() throws Exception { - SignUpCustomerRequest request = new SignUpCustomerRequest("name", "", "password123", "01012345678"); // given + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "", "password123", "010-1234-5678"); // when & then mockMvc.perform(post("/customers") @@ -78,8 +78,8 @@ void testSignUpCustomerWithoutEmail() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 비밀번호가 없는 경우") void testSignUpCustomerWithoutPassword() throws Exception { - SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "", "01012345678"); // given + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "", "010-1234-5678"); // when & then mockMvc.perform(post("/customers") @@ -106,7 +106,7 @@ void testSignUpCustomerWithoutPhone() throws Exception { void testSignUpCustomerWithLongName() throws Exception { // given SignUpCustomerRequest request = new SignUpCustomerRequest("n".repeat(51), "email@test.com", "password123", - "01012345678"); + "010-1234-5678"); // when & then mockMvc.perform(post("/customers") @@ -120,7 +120,7 @@ void testSignUpCustomerWithLongName() throws Exception { void testSignUpCustomerWithLongEmail() throws Exception { // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "e".repeat(90) + "@test.com", "password123", - "01012345678"); + "010-1234-5678"); // when & then mockMvc.perform(post("/customers") @@ -133,7 +133,7 @@ void testSignUpCustomerWithLongEmail() throws Exception { @DisplayName("구매자 회원가입 테스트 - 비밀번호가 20자 초과인 경우") void testSignUpCustomerWithLongPassword() throws Exception { SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "p".repeat(21), - "01012345678"); + "010-1234-5678"); mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) @@ -144,8 +144,8 @@ void testSignUpCustomerWithLongPassword() throws Exception { @Test @DisplayName("구매자 회원가입 테스트 - 비밀번호가 8자 미만인 경우") void testSignUpCustomerWithShortPassword() throws Exception { - SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "pass", "01012345678"); // given + SignUpCustomerRequest request = new SignUpCustomerRequest("name", "email@test.com", "pass", "010-1234-5678"); // when & then mockMvc.perform(post("/customers") @@ -173,7 +173,7 @@ void testSignUpCustomerWithLongPhone() throws Exception { void testSignUpCustomerWithInvalidEmail() throws Exception { // given SignUpCustomerRequest request = new SignUpCustomerRequest("name", "invalid-email", "password123", - "01012345678"); + "010-1234-5678"); // when & then mockMvc.perform(post("/customers") From 5f51c1e24f0b8968d1cc76fa9ecae7617f5bd01b Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 13:45:25 +0900 Subject: [PATCH 24/73] =?UTF-8?q?[test]=20SignUpCustomerServiceIntegration?= =?UTF-8?q?Test=20=EC=B6=94=EA=B0=80=20-=20=EC=A4=91=EB=B3=B5=20=EC=9D=B4?= =?UTF-8?q?=EB=A9=94=EC=9D=BC=20=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20?= =?UTF-8?q?=EC=8B=9C=20=EB=A1=A4=EB=B0=B1=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SignUpCustomerServiceIntegrationTest.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceIntegrationTest.java diff --git a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceIntegrationTest.java b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceIntegrationTest.java new file mode 100644 index 00000000..afb237b4 --- /dev/null +++ b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceIntegrationTest.java @@ -0,0 +1,52 @@ +package camp.woowak.lab.customer.service; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +import camp.woowak.lab.customer.exception.DuplicateEmailException; +import camp.woowak.lab.customer.exception.InvalidCreationException; +import camp.woowak.lab.customer.repository.CustomerRepository; +import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; +import camp.woowak.lab.payaccount.repository.PayAccountRepository; + +@SpringBootTest +class SignUpCustomerServiceIntegrationTest { + + @Autowired + private SignUpCustomerService service; + + @Autowired + private CustomerRepository customerRepository; + + @Autowired + private PayAccountRepository payAccountRepository; + + @Test + @DisplayName("이메일 중복 시 롤백 테스트") + void testRollbackOnDuplicateEmail() throws InvalidCreationException, DuplicateEmailException { + // given + SignUpCustomerCommand command1 = new SignUpCustomerCommand("name1", "email@example.com", "password", + "010-1234-5678"); + SignUpCustomerCommand command2 = new SignUpCustomerCommand("name2", "email@example.com", "password", + "010-8765-4321"); + + // when + service.signUp(command1); + + assertEquals(1, customerRepository.count()); + assertEquals(1, payAccountRepository.count()); + + // then + try { + service.signUp(command2); + fail("중복 이메일 예외가 발생해야 합니다."); + } catch (DuplicateEmailException e) { + assertEquals(1, customerRepository.count()); + assertEquals(1, payAccountRepository.count()); + } + } +} \ No newline at end of file From 1ceeb0d21141b75dfb92dc2898b27326c305f4ca Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 13:45:59 +0900 Subject: [PATCH 25/73] =?UTF-8?q?[feat]=20SignUpCustomerService.signUp=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20@Transactional=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/customer/service/SignUpCustomerService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java index be5cd040..0a4f70cb 100644 --- a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java +++ b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java @@ -11,6 +11,7 @@ import camp.woowak.lab.payaccount.domain.PayAccount; import camp.woowak.lab.payaccount.repository.PayAccountRepository; import camp.woowak.lab.web.authentication.PasswordEncoder; +import jakarta.transaction.Transactional; @Service public class SignUpCustomerService { @@ -25,6 +26,7 @@ public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRe this.passwordEncoder = passwordEncoder; } + @Transactional public Long signUp(SignUpCustomerCommand cmd) throws InvalidCreationException, DuplicateEmailException { PayAccount payAccount = new PayAccount(); payAccountRepository.save(payAccount); From 8dcc908c56356e28b03359b7318dc04b6687d2d4 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 13:48:56 +0900 Subject: [PATCH 26/73] =?UTF-8?q?[feat]=20DuplicateException,=20InvalidCre?= =?UTF-8?q?ationException=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - RuntimeException 을 사용해 @Transactional 내의 예상하지 못한 RuntimeException이 발생해도 트랜잭션이 롤백되도록 수정 --- .../camp/woowak/lab/customer/exception/DuplicateException.java | 2 +- .../woowak/lab/customer/exception/InvalidCreationException.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java b/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java index a6364e76..8b3e6d10 100644 --- a/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java +++ b/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java @@ -1,4 +1,4 @@ package camp.woowak.lab.customer.exception; -public abstract class DuplicateException extends Exception { +public abstract class DuplicateException extends RuntimeException { } diff --git a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java index bdfc625a..dc469af6 100644 --- a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java +++ b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java @@ -1,6 +1,6 @@ package camp.woowak.lab.customer.exception; -public class InvalidCreationException extends Exception { +public class InvalidCreationException extends RuntimeException { public InvalidCreationException(String message) { super(message); } From f0aa992eef613e2afc46da14104b8e773a2461e9 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 13:51:55 +0900 Subject: [PATCH 27/73] =?UTF-8?q?[fix]=20SignUpCustomerRequest=20-=20email?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=EC=97=90=20@NotBlank=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=20-=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EC=9D=B4=20""=20=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=8F=84=20=ED=86=B5=EA=B3=BC=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java index 753cb1a1..50b7ec2d 100644 --- a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java +++ b/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java @@ -4,10 +4,12 @@ import camp.woowak.lab.web.validation.annotation.Phone; import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; public record SignUpCustomerRequest( @Length(min = 1, max = 50) String name, + @NotBlank @Email String email, @Length(min = 8, max = 20) From a06d1c68ce4c94474805a8bcfa099b5dba0a5e8a Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 14:20:17 +0900 Subject: [PATCH 28/73] =?UTF-8?q?[feat]=20TestPayAccount=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20-=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20TestPayAccount=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/payaccount/domain/TestPayAccount.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/payaccount/domain/TestPayAccount.java diff --git a/src/test/java/camp/woowak/lab/payaccount/domain/TestPayAccount.java b/src/test/java/camp/woowak/lab/payaccount/domain/TestPayAccount.java new file mode 100644 index 00000000..0e0dc6c1 --- /dev/null +++ b/src/test/java/camp/woowak/lab/payaccount/domain/TestPayAccount.java @@ -0,0 +1,14 @@ +package camp.woowak.lab.payaccount.domain; + +public class TestPayAccount extends PayAccount { + private Long id; + private PayAccount payAccount; + + public TestPayAccount(Long id) { + this.payAccount = payAccount; + } + + public Long getId() { + return id; + } +} \ No newline at end of file From 2750dbcf5c3392440af1566a03a86fa950b7a22a Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Sun, 11 Aug 2024 20:20:58 +0900 Subject: [PATCH 29/73] =?UTF-8?q?[chore]=20=EC=98=A4=EB=A5=98=20=EB=A9=94?= =?UTF-8?q?=EC=84=B8=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../woowak/lab/customer/domain/Customer.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/domain/Customer.java b/src/main/java/camp/woowak/lab/customer/domain/Customer.java index 13fda5f6..db1fefb5 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/Customer.java +++ b/src/main/java/camp/woowak/lab/customer/domain/Customer.java @@ -55,37 +55,37 @@ private void checkPayAccount(PayAccount payAccount) throws InvalidCreationExcept private void checkPhone(String phone) throws InvalidCreationException { if (phone == null || phone.isBlank()) { - throw new InvalidCreationException("Vendor phone cannot be blank"); + throw new InvalidCreationException("Customer phone cannot be blank"); } if (phone.trim().length() > 30) { - throw new InvalidCreationException("Vendor phone cannot be longer than 30 characters"); + throw new InvalidCreationException("Customer phone cannot be longer than 30 characters"); } } private void checkPassword(String password) throws InvalidCreationException { if (password == null || password.isBlank()) { - throw new InvalidCreationException("Vendor password cannot be blank"); + throw new InvalidCreationException("Customer password cannot be blank"); } if (password.trim().length() > 30) { - throw new InvalidCreationException("Vendor password cannot be longer than 30 characters"); + throw new InvalidCreationException("Customer password cannot be longer than 30 characters"); } } private void checkEmail(String email) throws InvalidCreationException { if (email == null || email.isBlank()) { - throw new InvalidCreationException("Vendor email cannot be blank"); + throw new InvalidCreationException("Customer email cannot be blank"); } if (email.trim().length() > 100) { - throw new InvalidCreationException("Vendor email cannot be longer than 100 characters"); + throw new InvalidCreationException("Customer email cannot be longer than 100 characters"); } } private void checkName(String name) throws InvalidCreationException { if (name == null || name.isBlank()) { - throw new InvalidCreationException("Vendor name cannot be blank"); + throw new InvalidCreationException("Customer name cannot be blank"); } if (name.length() > 50) { - throw new InvalidCreationException("Vendor name cannot exceed 50 characters"); + throw new InvalidCreationException("Customer name cannot exceed 50 characters"); } } From 196b911715d07e5bc2bcb37a11bb60297cef82c8 Mon Sep 17 00:00:00 2001 From: donghar Date: Sat, 10 Aug 2024 23:26:18 +0900 Subject: [PATCH 30/73] =?UTF-8?q?[build]=20=EA=B9=83=ED=97=99=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `~` PR 템플릿 파일 이름 변경 `~` ISSUE 템플릿 내용 일부 수정 --- .github/ISSUE_TEMPLATE/bug-report.md | 4 ++-- .github/ISSUE_TEMPLATE/feature-request.md | 4 ++-- .github/{pr-template.md => pull_request_template.md} | 0 3 files changed, 4 insertions(+), 4 deletions(-) rename .github/{pr-template.md => pull_request_template.md} (100%) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 2675453c..51088305 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,8 +1,8 @@ --- name: Report bug about: 오류가 발생한 영역에 대해 보고합니다 [Dev] -title: "[BUG] " -labels: bug +title: "[오류] " +labels: 🐞 BugFix assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index c5f818a0..74c97725 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,8 +1,8 @@ --- name: Feature request about: Github Discussion, 회의에서 화제가 된 주제에 대해 제안합니다 [Moderator, Chef] -title: '[REQ]' -labels: enhancement +title: "[기능] " +labels: ✨ Feature assignees: '' --- diff --git a/.github/pr-template.md b/.github/pull_request_template.md similarity index 100% rename from .github/pr-template.md rename to .github/pull_request_template.md From 9ae90e9959ff4a7e5fed1aea056e71ec9c75e9a7 Mon Sep 17 00:00:00 2001 From: donghar Date: Sat, 10 Aug 2024 23:38:35 +0900 Subject: [PATCH 31/73] =?UTF-8?q?[build]=20=EA=B9=83=ED=97=99=20=ED=85=9C?= =?UTF-8?q?=ED=94=8C=EB=A6=BF=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `~` PR 템플릿의 Issue Link 위치 변경 --- .github/pull_request_template.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2d54b96a..c920935a 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,11 +1,12 @@ ## 💡 다음 이슈를 해결했어요. +### Issue Link - #1 + - (가능한 한 자세히 작성해 주시면 도움이 됩니다.)
## 💡 이슈를 처리하면서 추가된 코드가 있어요. -### Issue Link - #1 - (없다면 이 문항을 지워주세요.) From 56ec6f2a50661c6c2a3292bccfc08518c6f5f464 Mon Sep 17 00:00:00 2001 From: donghar Date: Sun, 11 Aug 2024 00:13:38 +0900 Subject: [PATCH 32/73] =?UTF-8?q?[build]=20=EA=B9=83=ED=97=99=20=EC=95=A1?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 빌드 테스트 액션 추가 --- .github/workflows/build.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..cc8cb265 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,21 @@ +name: Build-Test + +on: + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v4 + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: 'temurin' + java-version: 17 + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + - name: Build with Gradle + run: ./gradlew build From 8e8691037e32c3ee47ae33f7d66df8ff1b28a3e6 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Mon, 12 Aug 2024 21:02:34 +0900 Subject: [PATCH 33/73] =?UTF-8?q?[feat]=20APIResponse=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회의 결과로 결정된 API Response 형식에 맞게 status 와 Generic type의 data를 포함하는 클래스 생성 - 이 Response의 생성자는 해당 패키지의 Utils의 메서드를 이용해서만 생성할 수 있도록 private-default 접근 제어자로 설정 --- .../woowak/lab/web/api/utils/APIResponse.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java diff --git a/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java b/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java new file mode 100644 index 00000000..bf74a9d8 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java @@ -0,0 +1,21 @@ +package camp.woowak.lab.web.api.utils; + +import org.springframework.http.HttpStatus; + +public class APIResponse { + private final T data; + private final int status; + + APIResponse(final HttpStatus status, final T data) { + this.data = data; + this.status = status.value(); + } + + public T getData() { + return data; + } + + public int getStatus() { + return status; + } +} From 079708478dcc7dd7c0ab1ab01109433759683273 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Mon, 12 Aug 2024 21:04:05 +0900 Subject: [PATCH 34/73] =?UTF-8?q?[feat]=20APIUtils=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - of 메서드를 이용해 APIResponse를 body에 포함한 ResponseEntity를 만들어 낼 수 있습니다. --- .../woowak/lab/web/api/utils/APIUtils.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/api/utils/APIUtils.java diff --git a/src/main/java/camp/woowak/lab/web/api/utils/APIUtils.java b/src/main/java/camp/woowak/lab/web/api/utils/APIUtils.java new file mode 100644 index 00000000..9bdb3c68 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/api/utils/APIUtils.java @@ -0,0 +1,19 @@ +package camp.woowak.lab.web.api.utils; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +/** + * + * API Utils + * of Method는 status와 data를 이용해 APIResponse객체를 만들 수 있습니다. + * + */ +public final class APIUtils { + private APIUtils() { + } + + public static ResponseEntity> of(HttpStatus status, T data) { + return new ResponseEntity<>(new APIResponse<>(status, data), status); + } +} From b9a7e0b986a36b2b2ede8901fbf589af9d732323 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Mon, 12 Aug 2024 21:04:49 +0900 Subject: [PATCH 35/73] =?UTF-8?q?[test]=20APIUtils=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - APIUtils에 대한 테스트코드입니다. - 원시타입의 변수를 Generic으로 설정 가능합니다. - 객체 타입의 변수를 설정할 수 있습니다. --- .../lab/web/api/utils/APIUtilsTest.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 src/test/java/camp/woowak/lab/web/api/utils/APIUtilsTest.java diff --git a/src/test/java/camp/woowak/lab/web/api/utils/APIUtilsTest.java b/src/test/java/camp/woowak/lab/web/api/utils/APIUtilsTest.java new file mode 100644 index 00000000..a421a8fa --- /dev/null +++ b/src/test/java/camp/woowak/lab/web/api/utils/APIUtilsTest.java @@ -0,0 +1,73 @@ +package camp.woowak.lab.web.api.utils; + +import static org.assertj.core.api.Assertions.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import com.fasterxml.jackson.core.JsonProcessingException; + +@DisplayName("APIUtils 클래스") +class APIUtilsTest { + @Nested + @DisplayName("of메서드의") + class OfTest { + @Nested + @DisplayName("HttpStatus 값과 Data를 파라미터로 받는 메서드는") + class ParamWithHttpStatusAndData { + @Test + @DisplayName("data와 status를 가지는 APIResponse를 생성할 수 있다.") + void APIResponseWithHttpStatusAndData() throws JsonProcessingException { + //given + HttpStatus status = HttpStatus.OK; + String message = "hello world"; + + //when + ResponseEntity> apiResponse = APIUtils.of(status, message); + + //then + assertThat(apiResponse.getStatusCode()).isEqualTo(status); + assertThat(apiResponse.getBody().getData()).isEqualTo(message); + assertThat(apiResponse.getBody().getStatus()).isEqualTo(status.value()); + } + + @Test + @DisplayName("data가 객체인 경우도 APIResponse를 생성할 수 있다.") + void APIResponseWithObjectData() throws JsonProcessingException { + //given + HttpStatus status = HttpStatus.OK; + Example example = new Example(27, "Hyeon-Uk"); + + //when + ResponseEntity> apiResponse = APIUtils.of(status, example); + + //then + assertThat(apiResponse.getStatusCode()).isEqualTo(status); + assertThat(apiResponse.getBody().getData()).isEqualTo(example); + assertThat(apiResponse.getBody().getStatus()).isEqualTo(status.value()); + } + + private class Example { + int age; + String name; + + public Example(int age, String name) { + this.age = age; + this.name = name; + } + + public int getAge() { + return age; + } + + public String getName() { + return name; + } + } + } + + } +} \ No newline at end of file From 8c9a2229a0a45857433cd459500991f639992d75 Mon Sep 17 00:00:00 2001 From: Hyeon-Uk Date: Mon, 12 Aug 2024 21:06:17 +0900 Subject: [PATCH 36/73] =?UTF-8?q?[docs]=20APIResponse=EC=97=90=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=8B=9C=20=EC=A3=BC=EC=9D=98=EC=82=AC=ED=95=AD=20?= =?UTF-8?q?=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Jackson의 ObjectMapper와 함께 사용하기 위해서는 data로 들어오는 변수에 Getter가 필수적으로 있어야한다는 내용을 주석으로 추가 --- src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java b/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java index bf74a9d8..e41f44a8 100644 --- a/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java +++ b/src/main/java/camp/woowak/lab/web/api/utils/APIResponse.java @@ -2,6 +2,10 @@ import org.springframework.http.HttpStatus; +/** + * APIResponse를 Jackson의 ObjectMapper와 함께 사용하려면, + * Generic Type의 {@code data}에는 Getter 메서드가 필요합니다. + */ public class APIResponse { private final T data; private final int status; From e43860cb58bcbd7093770ced545722cd5609b37e Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Mon, 12 Aug 2024 21:03:13 +0900 Subject: [PATCH 37/73] =?UTF-8?q?[feat]=20HttpStatusException=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20HttpStatus=20=EC=97=90=20=EA=B8=B0=EB=B0=98?= =?UTF-8?q?=ED=95=9C=20exception=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/common/exception/HttpStatusException.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/common/exception/HttpStatusException.java diff --git a/src/main/java/camp/woowak/lab/common/exception/HttpStatusException.java b/src/main/java/camp/woowak/lab/common/exception/HttpStatusException.java new file mode 100644 index 00000000..b9c07ac1 --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/HttpStatusException.java @@ -0,0 +1,14 @@ +package camp.woowak.lab.common.exception; + +public class HttpStatusException extends RuntimeException { + private final ErrorCode errorCode; + + public HttpStatusException(ErrorCode errorCode) { + super(errorCode.getMessage()); + this.errorCode = errorCode; + } + + public ErrorCode errorCode() { + return errorCode; + } +} From 587c0d5efdaa9c32c3614cd4a766b04bad340a92 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Mon, 12 Aug 2024 21:09:10 +0900 Subject: [PATCH 38/73] =?UTF-8?q?[feat]=20HttpStatusException=20=EB=A5=BC?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84=ED=95=98=EB=8A=94=20Exception=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20-=20BadRequestException:=20400=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20Exception=20-=20UnauthorizedEx?= =?UTF-8?q?ception:=20401=20=EC=97=90=EB=9F=AC=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20Exception=20-=20ForbiddenException:=20403=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=97=90=20=EB=8C=80=ED=95=9C=20Exception=20?= =?UTF-8?q?-=20NotFoundException:=20404=20=EC=97=90=EB=9F=AC=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20Exception=20-=20MethodNotAllowedException:?= =?UTF-8?q?=20405=20=EC=97=90=EB=9F=AC=EC=97=90=20=EB=8C=80=ED=95=9C=20Exc?= =?UTF-8?q?eption=20-=20ConflictException:=20409=20=EC=97=90=EB=9F=AC?= =?UTF-8?q?=EC=97=90=20=EB=8C=80=ED=95=9C=20Exception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/advice/GlobalExceptionHandler.java | 27 +++++++++++++++++++ .../common/exception/BadRequestException.java | 7 +++++ .../common/exception/ConflictException.java | 7 +++++ .../common/exception/ForbiddenException.java | 7 +++++ .../exception/MethodNotAllowedException.java | 7 +++++ .../common/exception/NotFoundException.java | 7 +++++ .../exception/UnauthorizedException.java | 7 +++++ 7 files changed, 69 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java create mode 100644 src/main/java/camp/woowak/lab/common/exception/BadRequestException.java create mode 100644 src/main/java/camp/woowak/lab/common/exception/ConflictException.java create mode 100644 src/main/java/camp/woowak/lab/common/exception/ForbiddenException.java create mode 100644 src/main/java/camp/woowak/lab/common/exception/MethodNotAllowedException.java create mode 100644 src/main/java/camp/woowak/lab/common/exception/NotFoundException.java create mode 100644 src/main/java/camp/woowak/lab/common/exception/UnauthorizedException.java diff --git a/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java b/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java new file mode 100644 index 00000000..6f9bc5fc --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java @@ -0,0 +1,27 @@ +package camp.woowak.lab.common.advice; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.http.HttpStatus; +import org.springframework.http.ProblemDetail; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionHandler { + + @ExceptionHandler(Exception.class) + public ResponseEntity handleAllUncaughtException(Exception e) { + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, + e.getMessage()); + problemDetail.setProperty("errorCode", "9999"); + + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(problemDetail); + } +} diff --git a/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java b/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java new file mode 100644 index 00000000..3b4d4090 --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public class BadRequestException extends HttpStatusException { + public BadRequestException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/camp/woowak/lab/common/exception/ConflictException.java b/src/main/java/camp/woowak/lab/common/exception/ConflictException.java new file mode 100644 index 00000000..e7b16219 --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/ConflictException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public class ConflictException extends HttpStatusException { + public ConflictException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/camp/woowak/lab/common/exception/ForbiddenException.java b/src/main/java/camp/woowak/lab/common/exception/ForbiddenException.java new file mode 100644 index 00000000..05ab0863 --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/ForbiddenException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public class ForbiddenException extends HttpStatusException { + public ForbiddenException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/camp/woowak/lab/common/exception/MethodNotAllowedException.java b/src/main/java/camp/woowak/lab/common/exception/MethodNotAllowedException.java new file mode 100644 index 00000000..6704a8cd --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/MethodNotAllowedException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public class MethodNotAllowedException extends HttpStatusException { + public MethodNotAllowedException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/camp/woowak/lab/common/exception/NotFoundException.java b/src/main/java/camp/woowak/lab/common/exception/NotFoundException.java new file mode 100644 index 00000000..6928975e --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/NotFoundException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public class NotFoundException extends HttpStatusException { + public NotFoundException(ErrorCode errorCode) { + super(errorCode); + } +} diff --git a/src/main/java/camp/woowak/lab/common/exception/UnauthorizedException.java b/src/main/java/camp/woowak/lab/common/exception/UnauthorizedException.java new file mode 100644 index 00000000..ba2e1237 --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/UnauthorizedException.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public class UnauthorizedException extends HttpStatusException { + public UnauthorizedException(ErrorCode errorCode) { + super(errorCode); + } +} From 3d2bc74d54469b38b6f45ae82dbf34da403b2583 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Mon, 12 Aug 2024 21:09:31 +0900 Subject: [PATCH 39/73] =?UTF-8?q?[feat]=20ErrorCode=20interface=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/camp/woowak/lab/common/exception/ErrorCode.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/common/exception/ErrorCode.java diff --git a/src/main/java/camp/woowak/lab/common/exception/ErrorCode.java b/src/main/java/camp/woowak/lab/common/exception/ErrorCode.java new file mode 100644 index 00000000..54a2beda --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/exception/ErrorCode.java @@ -0,0 +1,7 @@ +package camp.woowak.lab.common.exception; + +public interface ErrorCode { + int getStatus(); + String getErrorCode(); + String getMessage(); +} From 11994fbbe81863f737636cf75dfe6416c1329880 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Mon, 12 Aug 2024 21:15:55 +0900 Subject: [PATCH 40/73] =?UTF-8?q?[feat]=20CustomRestControllerAdvice=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20-=20ControllerAdvice=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=20=EC=83=9D=EC=84=B1=20=EC=9A=B0=EC=84=A0=20=EC=88=9C=EC=9C=84?= =?UTF-8?q?=20=EB=AC=B8=EC=A0=9C=20=EB=95=8C=EB=AC=B8=EC=97=90=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=ED=95=9C=20CustomRestControllerAdvice=20-=20=EA=B8=B0?= =?UTF-8?q?=EC=A1=B4=20RestControllerAdvice=20=EB=B3=B4=EB=8B=A4=20?= =?UTF-8?q?=EC=9A=B0=EC=84=A0=20=EC=88=9C=EC=9C=84=EA=B0=80=20=ED=95=9C=20?= =?UTF-8?q?=EB=8B=A8=EA=B3=84=20=EB=86=92=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../advice/CustomRestControllerAdvice.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java diff --git a/src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java b/src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java new file mode 100644 index 00000000..4fd5b48a --- /dev/null +++ b/src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java @@ -0,0 +1,27 @@ +package camp.woowak.lab.common.advice; + +import org.springframework.core.Ordered; +import org.springframework.core.annotation.AliasFor; +import org.springframework.core.annotation.Order; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.lang.annotation.*; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@RestControllerAdvice +@Order(Ordered.LOWEST_PRECEDENCE - 1) +public @interface CustomRestControllerAdvice { + @AliasFor(annotation = RestControllerAdvice.class, attribute = "basePackages") + String[] basePackages() default {}; + + @AliasFor(annotation = RestControllerAdvice.class, attribute = "basePackageClasses") + Class[] basePackageClasses() default {}; + + @AliasFor(annotation = RestControllerAdvice.class, attribute = "assignableTypes") + Class[] assignableTypes() default {}; + + @AliasFor(annotation = RestControllerAdvice.class, attribute = "annotations") + Class[] annotations() default {}; +} From 99df6fda5ac0e3e088213712d3a6c29b7fd4a971 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Mon, 12 Aug 2024 21:23:02 +0900 Subject: [PATCH 41/73] =?UTF-8?q?[chore]=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/common/advice/GlobalExceptionHandler.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java b/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java index 6f9bc5fc..69c86318 100644 --- a/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java +++ b/src/main/java/camp/woowak/lab/common/advice/GlobalExceptionHandler.java @@ -1,12 +1,9 @@ package camp.woowak.lab.common.advice; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; import org.springframework.http.HttpStatus; import org.springframework.http.ProblemDetail; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; import lombok.extern.slf4j.Slf4j; From 7d5773747e85c11d6cb88570e6b0d574ccbb6dea Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Mon, 12 Aug 2024 22:01:48 +0900 Subject: [PATCH 42/73] =?UTF-8?q?[refactor]=20CustomRestControllerAdvice?= =?UTF-8?q?=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20-=20DomainExceptio?= =?UTF-8?q?nHandler=20=EB=A1=9C=20=EB=B3=80=EA=B2=BD=ED=96=88=EC=8A=B5?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...trollerAdvice.java => DomainExceptionHandler.java} | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) rename src/main/java/camp/woowak/lab/common/advice/{CustomRestControllerAdvice.java => DomainExceptionHandler.java} (76%) diff --git a/src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java b/src/main/java/camp/woowak/lab/common/advice/DomainExceptionHandler.java similarity index 76% rename from src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java rename to src/main/java/camp/woowak/lab/common/advice/DomainExceptionHandler.java index 4fd5b48a..56a9c564 100644 --- a/src/main/java/camp/woowak/lab/common/advice/CustomRestControllerAdvice.java +++ b/src/main/java/camp/woowak/lab/common/advice/DomainExceptionHandler.java @@ -1,18 +1,23 @@ package camp.woowak.lab.common.advice; +import java.lang.annotation.Annotation; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + import org.springframework.core.Ordered; import org.springframework.core.annotation.AliasFor; import org.springframework.core.annotation.Order; import org.springframework.web.bind.annotation.RestControllerAdvice; -import java.lang.annotation.*; - @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @RestControllerAdvice @Order(Ordered.LOWEST_PRECEDENCE - 1) -public @interface CustomRestControllerAdvice { +public @interface DomainExceptionHandler { @AliasFor(annotation = RestControllerAdvice.class, attribute = "basePackages") String[] basePackages() default {}; From 0677fb48732a736a03396c716f46aab6e2facfb3 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:00:00 +0900 Subject: [PATCH 43/73] =?UTF-8?q?[fix]=20open-in-view=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=EC=9C=BC=EB=A1=9C=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 66b1c0c5..b4956434 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,5 +1,4 @@ spring.application.name=lab spring.jpa.show-sql=true spring.jpa.generate-ddl=true -spring.jpa.open-in-view=false spring.jpa.hibernate.ddl-auto=create-drop From eb702f8aef5956cab3e32772f8719f62cdff9af2 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:24:03 +0900 Subject: [PATCH 44/73] =?UTF-8?q?[chore]=20.gitkeep=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/camp/woowak/lab/web/dto/request/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/web/dto/request/.gitkeep diff --git a/src/main/java/camp/woowak/lab/web/dto/request/.gitkeep b/src/main/java/camp/woowak/lab/web/dto/request/.gitkeep deleted file mode 100644 index e69de29b..00000000 From b76a98f3315f78f2f01f2fc0f068623cde097f50 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:24:25 +0900 Subject: [PATCH 45/73] =?UTF-8?q?[chore]=20.gitkeep=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/camp/woowak/lab/web/api/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/web/api/.gitkeep diff --git a/src/main/java/camp/woowak/lab/web/api/.gitkeep b/src/main/java/camp/woowak/lab/web/api/.gitkeep deleted file mode 100644 index e69de29b..00000000 From 6ec34a9134a361f600881b1b71effdafc921412a Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:27:42 +0900 Subject: [PATCH 46/73] =?UTF-8?q?[feat]=20CustomerErrorCode=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20-=20INVALID=5FPAY=5FACCOUNT=5FIS=5FNOT=5FNULL:=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98=20=EA=B3=84=EC=A2=8C?= =?UTF-8?q?=EB=8A=94=20Null=EC=9D=B4=20=EB=90=A0=20=EC=88=98=20=EC=97=86?= =?UTF-8?q?=EB=8B=A4.=20-=20INVALID=5FPHONE=5FIS=5FNOT=5FBLANK:=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98=20=EC=A0=84=ED=99=94?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EB=8A=94=20=EB=B9=84=EC=96=B4=EC=9E=88?= =?UTF-8?q?=EC=9D=84=20=EC=88=98=20=EC=97=86=EB=8B=A4.=20-=20INVALID=5FPHO?= =?UTF-8?q?NE=5FIS=5FTOO=5FLONG:=20=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98=20?= =?UTF-8?q?=EC=A0=84=ED=99=94=EB=B2=88=ED=98=B8=EB=8A=94=2030=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EC=B4=88=EA=B3=BC=ED=95=A0=20=EC=88=98=20=EC=97=86?= =?UTF-8?q?=EB=8B=A4.=20-=20INVALID=5FPASSWORD=5FIS=5FNOT=5FBLANK:=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98=20=EB=B9=84=EB=B0=80?= =?UTF-8?q?=EB=B2=88=ED=98=B8=EB=8A=94=20=EB=B9=84=EC=96=B4=EC=9E=88?= =?UTF-8?q?=EC=9D=84=20=EC=88=98=20=EC=97=86=EB=8B=A4.=20-=20INVALID=5FPAS?= =?UTF-8?q?SWORD=5FIS=5FTOO=5FLONG:=20=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98?= =?UTF-8?q?=20=EB=B9=84=EB=B0=80=EB=B2=88=ED=98=B8=EB=8A=94=2030=EC=9E=90?= =?UTF-8?q?=EB=A5=BC=20=EC=B4=88=EA=B3=BC=ED=95=A0=20=EC=88=98=20=EC=97=86?= =?UTF-8?q?=EB=8B=A4.=20-=20INVALID=5FEMAIL=5FIS=5FNOT=5FBLANK:=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98=20=EC=9D=B4=EB=A9=94?= =?UTF-8?q?=EC=9D=BC=EC=9D=80=20=EB=B9=84=EC=96=B4=EC=9E=88=EC=9D=84=20?= =?UTF-8?q?=EC=88=98=20=EC=97=86=EB=8B=A4.=20-=20INVALID=5FEMAIL=5FIS=5FTO?= =?UTF-8?q?O=5FLONG:=20=EA=B5=AC=EB=A7=A4=EC=9E=90=EC=9D=98=20=EC=9D=B4?= =?UTF-8?q?=EB=A9=94=EC=9D=BC=EC=9D=80=20100=EC=9E=90=EB=A5=BC=20=EC=B4=88?= =?UTF-8?q?=EA=B3=BC=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8B=A4.=20-=20INVA?= =?UTF-8?q?LID=5FNAME=5FIS=5FNOT=5FBLANK:=20=EA=B5=AC=EB=A7=A4=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A6=84=EC=9D=80=20=EB=B9=84=EC=96=B4?= =?UTF-8?q?=EC=9E=88=EC=9D=84=20=EC=88=98=20=EC=97=86=EB=8B=A4.=20-=20INVA?= =?UTF-8?q?LID=5FNAME=5FIS=5FTOO=5FLONG:=20=EA=B5=AC=EB=A7=A4=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A6=84=EC=9D=80=20100=EC=9E=90=EB=A5=BC?= =?UTF-8?q?=20=EC=B4=88=EA=B3=BC=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8B=A4?= =?UTF-8?q?.=20-=20DUPLICATE=5FEMAIL:=20=EA=B5=AC=EB=A7=A4=EC=9E=90?= =?UTF-8?q?=EC=9D=98=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EC=9D=B4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=20=EC=82=AC=EC=9A=A9=20=EC=A4=91=EC=9D=B4=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/exception/CustomerErrorCode.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java diff --git a/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java b/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java new file mode 100644 index 00000000..fae69360 --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java @@ -0,0 +1,41 @@ +package camp.woowak.lab.customer.exception; + +import camp.woowak.lab.common.exception.ErrorCode; + +public enum CustomerErrorCode implements ErrorCode { + INVALID_PAY_ACCOUNT_IS_NOT_NULL(400, "C1", "Customer payAccount cannot be null"), + INVALID_PHONE_IS_NOT_BLANK(400, "C2", "Customer phone cannot be blank"), + INVALID_PHONE_IS_TOO_LONG(400, "C3", "Customer phone cannot be longer than 30 characters"), + INVALID_PASSWORD_IS_NOT_BLANK(400, "C4", "Customer password cannot be blank"), + INVALID_PASSWORD_IS_TOO_LONG(400, "C5", "Customer password cannot be longer than 30 characters"), + INVALID_EMAIL_IS_NOT_BLANK(400, "C6", "Customer email cannot be blank"), + INVALID_EMAIL_IS_TOO_LONG(400, "C7", "Customer email cannot be longer than 100 characters"), + INVALID_NAME_IS_NOT_BLANK(400, "C8", "Customer name cannot be blank"), + INVALID_NAME_IS_TOO_LONG(400, "C9", "Customer name cannot be longer than 100 characters"), + DUPLICATE_EMAIL(400, "C10", "Customer email is already in use"); + + private final int status; + private final String errorCode; + private final String message; + + CustomerErrorCode(int status, String errorCode, String message) { + this.status = status; + this.errorCode = errorCode; + this.message = message; + } + + @Override + public int getStatus() { + return status; + } + + @Override + public String getErrorCode() { + return errorCode; + } + + @Override + public String getMessage() { + return message; + } +} From ed6a9b82526d3f87640d45eddf6e50946f4e23a6 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:28:35 +0900 Subject: [PATCH 47/73] =?UTF-8?q?[refactor]=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20Validation=20=EC=A3=BC=EC=B2=B4=20=EB=B6=84=EB=A6=AC=20-=20C?= =?UTF-8?q?ustomerValidator=20=EB=A5=BC=20=ED=86=B5=ED=95=B4=20Customer=20?= =?UTF-8?q?=EC=9D=98=20validation=20=EC=9D=84=20=EC=A7=84=ED=96=89?= =?UTF-8?q?=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../woowak/lab/customer/domain/Customer.java | 49 +-------------- .../customer/domain/CustomerValidator.java | 59 +++++++++++++++++++ 2 files changed, 60 insertions(+), 48 deletions(-) create mode 100644 src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java diff --git a/src/main/java/camp/woowak/lab/customer/domain/Customer.java b/src/main/java/camp/woowak/lab/customer/domain/Customer.java index db1fefb5..be53fb4f 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/Customer.java +++ b/src/main/java/camp/woowak/lab/customer/domain/Customer.java @@ -35,58 +35,11 @@ public Customer() { public Customer(String name, String email, String password, String phone, PayAccount payAccount, PasswordEncoder passwordEncoder) throws InvalidCreationException { - checkName(name); - checkEmail(email); - checkPassword(password); - checkPhone(phone); - checkPayAccount(payAccount); + CustomerValidator.validateCreation(name, email, password, phone, payAccount); this.name = name; this.email = email; this.password = passwordEncoder.encode(password); this.phone = phone; this.payAccount = payAccount; } - - private void checkPayAccount(PayAccount payAccount) throws InvalidCreationException { - if (payAccount == null) { - throw new InvalidCreationException("Pay account cannot be null"); - } - } - - private void checkPhone(String phone) throws InvalidCreationException { - if (phone == null || phone.isBlank()) { - throw new InvalidCreationException("Customer phone cannot be blank"); - } - if (phone.trim().length() > 30) { - throw new InvalidCreationException("Customer phone cannot be longer than 30 characters"); - } - } - - private void checkPassword(String password) throws InvalidCreationException { - if (password == null || password.isBlank()) { - throw new InvalidCreationException("Customer password cannot be blank"); - } - if (password.trim().length() > 30) { - throw new InvalidCreationException("Customer password cannot be longer than 30 characters"); - } - } - - private void checkEmail(String email) throws InvalidCreationException { - if (email == null || email.isBlank()) { - throw new InvalidCreationException("Customer email cannot be blank"); - } - if (email.trim().length() > 100) { - throw new InvalidCreationException("Customer email cannot be longer than 100 characters"); - } - } - - private void checkName(String name) throws InvalidCreationException { - if (name == null || name.isBlank()) { - throw new InvalidCreationException("Customer name cannot be blank"); - } - if (name.length() > 50) { - throw new InvalidCreationException("Customer name cannot exceed 50 characters"); - } - } - } diff --git a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java new file mode 100644 index 00000000..5e8d5ece --- /dev/null +++ b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java @@ -0,0 +1,59 @@ +package camp.woowak.lab.customer.domain; + +import camp.woowak.lab.customer.exception.CustomerErrorCode; +import camp.woowak.lab.customer.exception.InvalidCreationException; +import camp.woowak.lab.payaccount.domain.PayAccount; + +public class CustomerValidator { + + public static void validateCreation(String name, String email, String password, String phone, + PayAccount payAccount) throws InvalidCreationException { + validateName(name); + validateEmail(email); + validatePassword(password); + validatePhone(phone); + validatePayAccount(payAccount); + } + + public static void validateName(String name) throws InvalidCreationException { + if (name == null || name.isBlank()) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_NAME_IS_NOT_BLANK); + } + if (name.length() > 50) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_NAME_IS_TOO_LONG); + } + } + + public static void validateEmail(String email) throws InvalidCreationException { + if (email == null || email.isBlank()) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_EMAIL_IS_NOT_BLANK); + } + if (email.trim().length() > 100) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_EMAIL_IS_TOO_LONG); + } + } + + public static void validatePassword(String password) throws InvalidCreationException { + if (password == null || password.isBlank()) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_PASSWORD_IS_NOT_BLANK); + } + if (password.trim().length() > 30) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_PASSWORD_IS_TOO_LONG); + } + } + + public static void validatePhone(String phone) throws InvalidCreationException { + if (phone == null || phone.isBlank()) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_PHONE_IS_NOT_BLANK); + } + if (phone.trim().length() > 30) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_PHONE_IS_TOO_LONG); + } + } + + public static void validatePayAccount(PayAccount payAccount) throws InvalidCreationException { + if (payAccount == null) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_PAY_ACCOUNT_IS_NOT_NULL); + } + } +} From 70f0f1454780b3790052cd87e709e03855032c22 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:30:48 +0900 Subject: [PATCH 48/73] =?UTF-8?q?[refactor]=20CustomerException=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20=EA=B3=B5=ED=86=B5=20Exception=20?= =?UTF-8?q?=EC=9D=84=20=EC=83=81=EC=86=8D=EB=B0=9B=EC=95=84=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/customer/exception/DuplicateEmailException.java | 7 ++++++- .../lab/customer/exception/DuplicateException.java | 4 ---- .../lab/customer/exception/InvalidCreationException.java | 9 ++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java diff --git a/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java b/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java index 4614a21b..643729b0 100644 --- a/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java +++ b/src/main/java/camp/woowak/lab/customer/exception/DuplicateEmailException.java @@ -1,4 +1,9 @@ package camp.woowak.lab.customer.exception; -public class DuplicateEmailException extends DuplicateException { +import camp.woowak.lab.common.exception.BadRequestException; + +public class DuplicateEmailException extends BadRequestException { + public DuplicateEmailException() { + super(CustomerErrorCode.DUPLICATE_EMAIL); + } } diff --git a/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java b/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java deleted file mode 100644 index 8b3e6d10..00000000 --- a/src/main/java/camp/woowak/lab/customer/exception/DuplicateException.java +++ /dev/null @@ -1,4 +0,0 @@ -package camp.woowak.lab.customer.exception; - -public abstract class DuplicateException extends RuntimeException { -} diff --git a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java index dc469af6..72e05311 100644 --- a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java +++ b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java @@ -1,7 +1,10 @@ package camp.woowak.lab.customer.exception; -public class InvalidCreationException extends RuntimeException { - public InvalidCreationException(String message) { - super(message); +import camp.woowak.lab.common.exception.BadRequestException; +import camp.woowak.lab.common.exception.ErrorCode; + +public class InvalidCreationException extends BadRequestException { + public InvalidCreationException(ErrorCode errorCode) { + super(errorCode); } } From a542d7c60e1b2a9dad3f08e6cece2ce81191ee51 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:31:43 +0900 Subject: [PATCH 49/73] =?UTF-8?q?[fix]=20=EC=98=AC=EB=B0=94=EB=A5=B8=20Exc?= =?UTF-8?q?eption=20=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20-=20Exceptio?= =?UTF-8?q?n=20=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=EC=97=90=20=EC=82=AC=EC=9A=A9=EB=90=9C=20Exception=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../woowak/lab/customer/service/SignUpCustomerServiceTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java index 0f8f93af..c9f0432a 100644 --- a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java +++ b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java @@ -14,7 +14,6 @@ import camp.woowak.lab.customer.domain.Customer; import camp.woowak.lab.customer.exception.DuplicateEmailException; -import camp.woowak.lab.customer.exception.DuplicateException; import camp.woowak.lab.customer.exception.InvalidCreationException; import camp.woowak.lab.customer.repository.CustomerRepository; import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; @@ -72,7 +71,7 @@ void testSignUpWithExistingEmail() { new SignUpCustomerCommand("name", "email@example.com", "password", "01012345678"); // then - Assertions.assertThrows(DuplicateException.class, () -> service.signUp(command)); + Assertions.assertThrows(DuplicateEmailException.class, () -> service.signUp(command)); then(payAccountRepository).should().save(Mockito.any(PayAccount.class)); then(customerRepository).should().save(Mockito.any(Customer.class)); } From 956fb2b650431acee370283a7246d8c24b51c032 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:32:23 +0900 Subject: [PATCH 50/73] =?UTF-8?q?[chore]=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../woowak/lab/customer/service/SignUpCustomerServiceTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java index c9f0432a..f3bbb0d9 100644 --- a/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java +++ b/src/test/java/camp/woowak/lab/customer/service/SignUpCustomerServiceTest.java @@ -51,7 +51,7 @@ void testSignUp() throws InvalidCreationException, DuplicateEmailException { // when SignUpCustomerCommand command = new SignUpCustomerCommand("name", "email@example.com", "password", "01012345678"); - Long id = service.signUp(command); + service.signUp(command); // then then(payAccountRepository).should().save(Mockito.any(PayAccount.class)); From f3b814241f2345093db9a89dfe0095b5f4827d4e Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:34:03 +0900 Subject: [PATCH 51/73] =?UTF-8?q?[chore]=20Exception=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20Service=20=EC=A3=BC=EC=84=9D=20=EC=B6=94=EA=B0=80=20-=20Sign?= =?UTF-8?q?UpCustomerService.signUp=20=EC=97=90=EC=84=9C=20=EB=B0=9C?= =?UTF-8?q?=EC=83=9D=ED=95=98=EB=8A=94=20Exception=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=AA=85=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../woowak/lab/customer/service/SignUpCustomerService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java index 0a4f70cb..64b69f50 100644 --- a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java +++ b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java @@ -26,6 +26,11 @@ public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRe this.passwordEncoder = passwordEncoder; } + /** + * + * @throws InvalidCreationException 구매자 생성에 오류가 나는 경우 + * @throws DuplicateEmailException 이메일이 중복되는 경우 + */ @Transactional public Long signUp(SignUpCustomerCommand cmd) throws InvalidCreationException, DuplicateEmailException { PayAccount payAccount = new PayAccount(); From ca680490525d458eb70df00cd177ded52fe22e39 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 00:34:57 +0900 Subject: [PATCH 52/73] =?UTF-8?q?[feat]=20CustomerController=20=EB=A5=BC?= =?UTF-8?q?=20=EC=A0=84=EB=8B=B4=ED=95=98=EB=8A=94=20DomainExceptionHandle?= =?UTF-8?q?r=20=EA=B5=AC=ED=98=84=20-=20BadRequestException=20=EB=A5=BC=20?= =?UTF-8?q?=EC=83=81=EC=86=8D=ED=95=98=EB=8A=94=20Exception=20=EA=B3=BC=20?= =?UTF-8?q?Validation=20=EC=8B=9C=20=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94?= =?UTF-8?q?=20MethodArgumentNotValidException=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/api/CustomerExceptionHandler.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java diff --git a/src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java b/src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java new file mode 100644 index 00000000..272fea86 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java @@ -0,0 +1,24 @@ +package camp.woowak.lab.web.api; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ProblemDetail; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; + +import camp.woowak.lab.common.advice.DomainExceptionHandler; +import camp.woowak.lab.common.exception.BadRequestException; + +@DomainExceptionHandler +public class CustomerExceptionHandler { + + /** + * + * BadRequestException.class 와 MethodArgumentNotValidException.class 를 처리한다. + */ + @ExceptionHandler({BadRequestException.class, MethodArgumentNotValidException.class}) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ProblemDetail handleBadRequestException(BadRequestException e) { + return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage()); + } +} From e81511de029dba5b83815282f75c75ccc3741b62 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 09:19:34 +0900 Subject: [PATCH 53/73] =?UTF-8?q?[refactor]=20CustomerController=20?= =?UTF-8?q?=EC=9D=98=20=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC=20=EC=A3=BC?= =?UTF-8?q?=EC=B2=B4=20=EB=B3=80=EA=B2=BD=20-=20CustomerController=20?= =?UTF-8?q?=EC=9D=98=20=EC=97=90=EB=9F=AC=EC=B2=98=EB=A6=AC=EB=A5=BC=20Cus?= =?UTF-8?q?tomerExceptionHandler=20=EC=97=90=20=EC=9C=84=EC=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/web/api/CustomerController.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/main/java/camp/woowak/lab/web/api/CustomerController.java b/src/main/java/camp/woowak/lab/web/api/CustomerController.java index 498070b0..cd013915 100644 --- a/src/main/java/camp/woowak/lab/web/api/CustomerController.java +++ b/src/main/java/camp/woowak/lab/web/api/CustomerController.java @@ -10,8 +10,6 @@ import camp.woowak.lab.customer.service.SignUpCustomerService; import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; -import camp.woowak.lab.web.dto.response.ApiResponse; -import camp.woowak.lab.web.error.ErrorCode; import jakarta.validation.Valid; @RestController @@ -27,13 +25,9 @@ public ResponseEntity signUp(@Valid @RequestBody SignUpCustomerRequest reques SignUpCustomerCommand command = new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone()); Long registeredId; - try { - registeredId = signUpCustomerService.signUp(command); - } catch (camp.woowak.lab.customer.exception.InvalidCreationException e) { - return ResponseEntity.badRequest().body(ApiResponse.error(ErrorCode.SIGNUP_INVALID_REQUEST)); - } catch (camp.woowak.lab.customer.exception.DuplicateEmailException e) { - return ResponseEntity.ok(ApiResponse.error(ErrorCode.AUTH_DUPLICATE_EMAIL)); - } + + registeredId = signUpCustomerService.signUp(command); + return ResponseEntity.created(URI.create("/customers/" + registeredId)).build(); } } From 140dbcc464ee2b653461303692b92255666519bb Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 09:20:34 +0900 Subject: [PATCH 54/73] =?UTF-8?q?[test]=20CustomerControllerTest=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20=EC=A4=91=EB=B3=B5=20=EC=9D=B4?= =?UTF-8?q?=EB=A9=94=EC=9D=BC=20=EC=97=90=EB=9F=AC=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B8=ED=95=9C=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/web/api/CustomerControllerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java index 0799d428..4f85d3cd 100644 --- a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java +++ b/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java @@ -208,8 +208,8 @@ void testSignUpCustomerWithDuplicateEmail() throws Exception { mockMvc.perform(post("/customers") .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) - .andExpect(status().isOk()) - .andExpect(jsonPath("$.code").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getCode())) - .andExpect(jsonPath("$.message").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getMessage())); + .andExpect(status().isConflict()) + .andExpect(jsonPath("$.errorCode").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getCode())) + .andExpect(jsonPath("$.detail").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getMessage())); } -} \ No newline at end of file +} From 9f90cf1485ec8a2a0ec84d530fd4a7d23405eb1a Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 13:48:40 +0900 Subject: [PATCH 55/73] =?UTF-8?q?[chore]=20.gitkeep=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/camp/woowak/lab/web/dto/response/.gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/web/dto/response/.gitkeep diff --git a/src/main/java/camp/woowak/lab/web/dto/response/.gitkeep b/src/main/java/camp/woowak/lab/web/dto/response/.gitkeep deleted file mode 100644 index e69de29b..00000000 From ca72425c6e954266aff80a31d2b690eac8ad6259 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 13:48:53 +0900 Subject: [PATCH 56/73] =?UTF-8?q?[chore]=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/dto/response/ApiResponse.java | 40 ------------------- 1 file changed, 40 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java diff --git a/src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java b/src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java deleted file mode 100644 index 7f0be70f..00000000 --- a/src/main/java/camp/woowak/lab/web/dto/response/ApiResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -package camp.woowak.lab.web.dto.response; - -import camp.woowak.lab.web.error.ErrorCode; - -public class ApiResponse { - private String code; - private String message; - private T data; - - private ApiResponse(String code, String message) { - this.code = code; - this.message = message; - } - - private ApiResponse(String code, String message, T data) { - this.code = code; - this.message = message; - this.data = data; - } - - public static ApiResponse ok(T data) { - return new ApiResponse<>("OK", "success", data); - } - - public static ApiResponse error(ErrorCode errorCode) { - return new ApiResponse<>(errorCode.getCode(), errorCode.getMessage()); - } - - public String getCode() { - return code; - } - - public String getMessage() { - return message; - } - - public T getData() { - return data; - } -} From c38cbdb3ed1c029abe449643888543b70dad4acb Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 13:49:31 +0900 Subject: [PATCH 57/73] =?UTF-8?q?[chore]=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/web/error/ErrorCode.java | 22 ------------------- 1 file changed, 22 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/web/error/ErrorCode.java diff --git a/src/main/java/camp/woowak/lab/web/error/ErrorCode.java b/src/main/java/camp/woowak/lab/web/error/ErrorCode.java deleted file mode 100644 index 53b0e82e..00000000 --- a/src/main/java/camp/woowak/lab/web/error/ErrorCode.java +++ /dev/null @@ -1,22 +0,0 @@ -package camp.woowak.lab.web.error; - -public enum ErrorCode { - AUTH_DUPLICATE_EMAIL("a1", "이미 가입된 이메일 입니다."), - SIGNUP_INVALID_REQUEST("s1", "잘못된 요청입니다."); - - private final String code; - private final String message; - - ErrorCode(String code, String message) { - this.code = code; - this.message = message; - } - - public String getCode() { - return code; - } - - public String getMessage() { - return message; - } -} From ba7ef9591ae94ebb920c6bc8dd46b4658dfbe94b Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:10:23 +0900 Subject: [PATCH 58/73] =?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?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/api/CustomerExceptionHandler.java | 24 ----------- .../{ => customer}/CustomerController.java | 2 +- .../customer/CustomerExceptionHandler.java | 43 +++++++++++++++++++ .../CustomerControllerTest.java | 6 +-- 4 files changed, 47 insertions(+), 28 deletions(-) delete mode 100644 src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java rename src/main/java/camp/woowak/lab/web/api/{ => customer}/CustomerController.java (96%) create mode 100644 src/main/java/camp/woowak/lab/web/api/customer/CustomerExceptionHandler.java rename src/test/java/camp/woowak/lab/web/api/{ => customer}/CustomerControllerTest.java (97%) diff --git a/src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java b/src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java deleted file mode 100644 index 272fea86..00000000 --- a/src/main/java/camp/woowak/lab/web/api/CustomerExceptionHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package camp.woowak.lab.web.api; - -import org.springframework.http.HttpStatus; -import org.springframework.http.ProblemDetail; -import org.springframework.web.bind.MethodArgumentNotValidException; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseStatus; - -import camp.woowak.lab.common.advice.DomainExceptionHandler; -import camp.woowak.lab.common.exception.BadRequestException; - -@DomainExceptionHandler -public class CustomerExceptionHandler { - - /** - * - * BadRequestException.class 와 MethodArgumentNotValidException.class 를 처리한다. - */ - @ExceptionHandler({BadRequestException.class, MethodArgumentNotValidException.class}) - @ResponseStatus(HttpStatus.BAD_REQUEST) - public ProblemDetail handleBadRequestException(BadRequestException e) { - return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, e.getMessage()); - } -} diff --git a/src/main/java/camp/woowak/lab/web/api/CustomerController.java b/src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java similarity index 96% rename from src/main/java/camp/woowak/lab/web/api/CustomerController.java rename to src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java index cd013915..5207aa87 100644 --- a/src/main/java/camp/woowak/lab/web/api/CustomerController.java +++ b/src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java @@ -1,4 +1,4 @@ -package camp.woowak.lab.web.api; +package camp.woowak.lab.web.api.customer; import java.net.URI; diff --git a/src/main/java/camp/woowak/lab/web/api/customer/CustomerExceptionHandler.java b/src/main/java/camp/woowak/lab/web/api/customer/CustomerExceptionHandler.java new file mode 100644 index 00000000..e7fb2482 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/api/customer/CustomerExceptionHandler.java @@ -0,0 +1,43 @@ +package camp.woowak.lab.web.api.customer; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ProblemDetail; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +import camp.woowak.lab.common.advice.DomainExceptionHandler; +import camp.woowak.lab.common.exception.BadRequestException; +import camp.woowak.lab.customer.exception.DuplicateEmailException; +import camp.woowak.lab.customer.exception.InvalidCreationException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@DomainExceptionHandler +public class CustomerExceptionHandler extends ResponseEntityExceptionHandler { + /** + * + * BadRequestException.class 와 MethodArgumentNotValidException.class 를 처리한다. + */ + @ExceptionHandler({InvalidCreationException.class}) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ProblemDetail handleBadRequestException(BadRequestException e) { + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, + e.errorCode().getErrorCode()); + problemDetail.setProperty("errorCode", e.errorCode().getErrorCode()); + return problemDetail; + } + + /** + * + * DuplicateEmailException.class 를 처리한다. + */ + @ExceptionHandler({DuplicateEmailException.class}) + @ResponseStatus(HttpStatus.CONFLICT) + public ProblemDetail handleDuplicateEmailException(DuplicateEmailException e) { + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT, + e.errorCode().getMessage()); + problemDetail.setProperty("errorCode", e.errorCode().getErrorCode()); + return problemDetail; + } +} diff --git a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java similarity index 97% rename from src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java rename to src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java index 4f85d3cd..499a8303 100644 --- a/src/test/java/camp/woowak/lab/web/api/CustomerControllerTest.java +++ b/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java @@ -1,4 +1,4 @@ -package camp.woowak.lab.web.api; +package camp.woowak.lab.web.api.customer; import static org.mockito.ArgumentMatchers.*; import static org.mockito.BDDMockito.*; @@ -16,10 +16,10 @@ import com.fasterxml.jackson.databind.ObjectMapper; +import camp.woowak.lab.customer.exception.CustomerErrorCode; import camp.woowak.lab.customer.exception.DuplicateEmailException; import camp.woowak.lab.customer.service.SignUpCustomerService; -import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; -import camp.woowak.lab.web.error.ErrorCode; +import camp.woowak.lab.web.dto.request.customer.SignUpCustomerRequest; @WebMvcTest(CustomerController.class) @MockBean(JpaMetamodelMappingContext.class) From 3b07854a6552893a79584375c0387a686973abdd Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:13:04 +0900 Subject: [PATCH 59/73] =?UTF-8?q?[test]=20=EC=97=90=EB=9F=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20=EC=88=98=EC=A0=95=20-=20Error?= =?UTF-8?q?Code=20=EC=82=AD=EC=A0=9C=20=ED=9B=84=20CustomerErrorCode=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../woowak/lab/web/api/customer/CustomerControllerTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java index 499a8303..6d372caa 100644 --- a/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java +++ b/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java @@ -209,7 +209,7 @@ void testSignUpCustomerWithDuplicateEmail() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isConflict()) - .andExpect(jsonPath("$.errorCode").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getCode())) - .andExpect(jsonPath("$.detail").value(ErrorCode.AUTH_DUPLICATE_EMAIL.getMessage())); + .andExpect(jsonPath("$.errorCode").value(CustomerErrorCode.DUPLICATE_EMAIL.getErrorCode())) + .andExpect(jsonPath("$.detail").value(CustomerErrorCode.DUPLICATE_EMAIL.getMessage())); } } From d3d1cfc59428669a2af3be947fb7b6a497e562aa Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:13:24 +0900 Subject: [PATCH 60/73] =?UTF-8?q?[chore]=20@Repository=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/customer/repository/CustomerRepository.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java b/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java index 9b8e9bc4..32b96ef2 100644 --- a/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java +++ b/src/main/java/camp/woowak/lab/customer/repository/CustomerRepository.java @@ -1,10 +1,8 @@ package camp.woowak.lab.customer.repository; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; import camp.woowak.lab.customer.domain.Customer; -@Repository public interface CustomerRepository extends JpaRepository { } From 6be87cdd9bd71efbc72d77e2b55e41f251dd2b09 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:16:20 +0900 Subject: [PATCH 61/73] =?UTF-8?q?[chore]=20CustomerController=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD=20-=20CustomerController=20->=20?= =?UTF-8?q?CustomerApiController?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/customer/CustomerApiController.java | 38 +++++++++++++++++++ .../web/api/customer/CustomerController.java | 33 ---------------- ...st.java => CustomerApiControllerTest.java} | 4 +- 3 files changed, 40 insertions(+), 35 deletions(-) create mode 100644 src/main/java/camp/woowak/lab/web/api/customer/CustomerApiController.java delete mode 100644 src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java rename src/test/java/camp/woowak/lab/web/api/customer/{CustomerControllerTest.java => CustomerApiControllerTest.java} (99%) diff --git a/src/main/java/camp/woowak/lab/web/api/customer/CustomerApiController.java b/src/main/java/camp/woowak/lab/web/api/customer/CustomerApiController.java new file mode 100644 index 00000000..17397fcd --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/api/customer/CustomerApiController.java @@ -0,0 +1,38 @@ +package camp.woowak.lab.web.api.customer; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import camp.woowak.lab.customer.service.SignUpCustomerService; +import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; +import camp.woowak.lab.web.api.utils.APIResponse; +import camp.woowak.lab.web.api.utils.APIUtils; +import camp.woowak.lab.web.dto.request.customer.SignUpCustomerRequest; +import camp.woowak.lab.web.dto.response.customer.SignUpCustomerResponse; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; + +@RestController +public class CustomerApiController { + private final SignUpCustomerService signUpCustomerService; + + public CustomerApiController(SignUpCustomerService signUpCustomerService) { + this.signUpCustomerService = signUpCustomerService; + } + + @PostMapping("/customers") + public ResponseEntity> signUp(@Valid @RequestBody SignUpCustomerRequest request, + HttpServletResponse response) { + SignUpCustomerCommand command = + new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone()); + + Long registeredId = signUpCustomerService.signUp(command); + + response.setHeader("Location", "/customers/" + registeredId); + + return APIUtils.of(HttpStatus.CREATED, new SignUpCustomerResponse(registeredId)); + } +} diff --git a/src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java b/src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java deleted file mode 100644 index 5207aa87..00000000 --- a/src/main/java/camp/woowak/lab/web/api/customer/CustomerController.java +++ /dev/null @@ -1,33 +0,0 @@ -package camp.woowak.lab.web.api.customer; - -import java.net.URI; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; - -import camp.woowak.lab.customer.service.SignUpCustomerService; -import camp.woowak.lab.customer.service.command.SignUpCustomerCommand; -import camp.woowak.lab.web.dto.request.SignUpCustomerRequest; -import jakarta.validation.Valid; - -@RestController -public class CustomerController { - private final SignUpCustomerService signUpCustomerService; - - public CustomerController(SignUpCustomerService signUpCustomerService) { - this.signUpCustomerService = signUpCustomerService; - } - - @PostMapping("/customers") - public ResponseEntity signUp(@Valid @RequestBody SignUpCustomerRequest request) { - SignUpCustomerCommand command = - new SignUpCustomerCommand(request.name(), request.email(), request.password(), request.phone()); - Long registeredId; - - registeredId = signUpCustomerService.signUp(command); - - return ResponseEntity.created(URI.create("/customers/" + registeredId)).build(); - } -} diff --git a/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java b/src/test/java/camp/woowak/lab/web/api/customer/CustomerApiControllerTest.java similarity index 99% rename from src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java rename to src/test/java/camp/woowak/lab/web/api/customer/CustomerApiControllerTest.java index 6d372caa..4d55fbe2 100644 --- a/src/test/java/camp/woowak/lab/web/api/customer/CustomerControllerTest.java +++ b/src/test/java/camp/woowak/lab/web/api/customer/CustomerApiControllerTest.java @@ -21,9 +21,9 @@ import camp.woowak.lab.customer.service.SignUpCustomerService; import camp.woowak.lab.web.dto.request.customer.SignUpCustomerRequest; -@WebMvcTest(CustomerController.class) +@WebMvcTest(CustomerApiController.class) @MockBean(JpaMetamodelMappingContext.class) -class CustomerControllerTest { +class CustomerApiControllerTest { @Autowired private MockMvc mockMvc; From e6b0b0c2ff99614dbc0ec09539588e6ba7cf6429 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:17:37 +0900 Subject: [PATCH 62/73] =?UTF-8?q?[refactor]=20SignUpCustomerRequest=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20-=20camp.woowak.lab.web.dto.request.customer=20?= =?UTF-8?q?=EB=B0=91=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/dto/request/{ => customer}/SignUpCustomerRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/camp/woowak/lab/web/dto/request/{ => customer}/SignUpCustomerRequest.java (88%) diff --git a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java similarity index 88% rename from src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java rename to src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java index 50b7ec2d..06d257d5 100644 --- a/src/main/java/camp/woowak/lab/web/dto/request/SignUpCustomerRequest.java +++ b/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java @@ -1,4 +1,4 @@ -package camp.woowak.lab.web.dto.request; +package camp.woowak.lab.web.dto.request.customer; import org.hibernate.validator.constraints.Length; From f6d3346983ab0cd741a58099456c663dd1dde8c9 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:18:57 +0900 Subject: [PATCH 63/73] =?UTF-8?q?[feat]=20BadRequestException=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80=20-=20BadRequestExcepti?= =?UTF-8?q?on(ErrorCode,=20String)=20=EC=83=9D=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/common/exception/BadRequestException.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java b/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java index 3b4d4090..4fb65cd5 100644 --- a/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java +++ b/src/main/java/camp/woowak/lab/common/exception/BadRequestException.java @@ -4,4 +4,8 @@ public class BadRequestException extends HttpStatusException { public BadRequestException(ErrorCode errorCode) { super(errorCode); } + + public BadRequestException(ErrorCode errorCode, String message) { + super(errorCode, message); + } } From 16ff26ce1acb24a343d4998ef950a46fbea919b7 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:20:19 +0900 Subject: [PATCH 64/73] =?UTF-8?q?[feat]=20=EC=97=90=EB=9F=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95=20-=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=EC=97=90=20=EB=82=A8=EA=B8=B0=EA=B3=A0=20=EC=8B=B6?= =?UTF-8?q?=EC=9D=80=20=EB=A1=9C=EA=B7=B8=EB=8A=94=20=EC=A7=81=EC=A0=91=20?= =?UTF-8?q?=EC=9E=85=EB=A0=A5=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20-=20=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=EC=97=90?= =?UTF-8?q?=20=EC=9E=88=EB=8A=94=20=EB=A9=94=EC=8B=9C=EC=A7=80=EB=8A=94=20?= =?UTF-8?q?=ED=81=B4=EB=9D=BC=EC=9D=B4=EC=96=B8=ED=8A=B8=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EA=B2=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/customer/exception/CustomerErrorCode.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java b/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java index fae69360..7ad34f6c 100644 --- a/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java +++ b/src/main/java/camp/woowak/lab/customer/exception/CustomerErrorCode.java @@ -3,16 +3,8 @@ import camp.woowak.lab.common.exception.ErrorCode; public enum CustomerErrorCode implements ErrorCode { - INVALID_PAY_ACCOUNT_IS_NOT_NULL(400, "C1", "Customer payAccount cannot be null"), - INVALID_PHONE_IS_NOT_BLANK(400, "C2", "Customer phone cannot be blank"), - INVALID_PHONE_IS_TOO_LONG(400, "C3", "Customer phone cannot be longer than 30 characters"), - INVALID_PASSWORD_IS_NOT_BLANK(400, "C4", "Customer password cannot be blank"), - INVALID_PASSWORD_IS_TOO_LONG(400, "C5", "Customer password cannot be longer than 30 characters"), - INVALID_EMAIL_IS_NOT_BLANK(400, "C6", "Customer email cannot be blank"), - INVALID_EMAIL_IS_TOO_LONG(400, "C7", "Customer email cannot be longer than 100 characters"), - INVALID_NAME_IS_NOT_BLANK(400, "C8", "Customer name cannot be blank"), - INVALID_NAME_IS_TOO_LONG(400, "C9", "Customer name cannot be longer than 100 characters"), - DUPLICATE_EMAIL(400, "C10", "Customer email is already in use"); + INVALID_CREATION(400, "C1", "잘못된 요청입니다."), + DUPLICATE_EMAIL(400, "C2", "이미 존재하는 이메일입니다."); private final int status; private final String errorCode; From f932caeb697222a2f75f2293538c981ef6d0603a Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:20:38 +0900 Subject: [PATCH 65/73] =?UTF-8?q?[feat]=20=EC=97=90=EB=9F=AC=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A0=95=EC=B1=85=20=EB=B3=80=EA=B2=BD=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customer/domain/CustomerValidator.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java index 5e8d5ece..d890eff8 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java +++ b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java @@ -7,7 +7,7 @@ public class CustomerValidator { public static void validateCreation(String name, String email, String password, String phone, - PayAccount payAccount) throws InvalidCreationException { + PayAccount payAccount) throws InvalidCreationException { validateName(name); validateEmail(email); validatePassword(password); @@ -17,43 +17,48 @@ public static void validateCreation(String name, String email, String password, public static void validateName(String name) throws InvalidCreationException { if (name == null || name.isBlank()) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_NAME_IS_NOT_BLANK); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer name cannot be blank"); } if (name.length() > 50) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_NAME_IS_TOO_LONG); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, + "Customer name cannot be longer than 50 characters"); } } public static void validateEmail(String email) throws InvalidCreationException { if (email == null || email.isBlank()) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_EMAIL_IS_NOT_BLANK); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer email cannot be blank"); } if (email.trim().length() > 100) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_EMAIL_IS_TOO_LONG); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, + "Customer email cannot be longer than 100 characters"); } } public static void validatePassword(String password) throws InvalidCreationException { if (password == null || password.isBlank()) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_PASSWORD_IS_NOT_BLANK); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer password cannot be blank"); } if (password.trim().length() > 30) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_PASSWORD_IS_TOO_LONG); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, + "Customer password cannot be longer than 30 characters"); } } public static void validatePhone(String phone) throws InvalidCreationException { if (phone == null || phone.isBlank()) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_PHONE_IS_NOT_BLANK); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer phone cannot be blank"); } if (phone.trim().length() > 30) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_PHONE_IS_TOO_LONG); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, + "Customer phone cannot be longer than 30 characters"); } } public static void validatePayAccount(PayAccount payAccount) throws InvalidCreationException { if (payAccount == null) { - throw new InvalidCreationException(CustomerErrorCode.INVALID_PAY_ACCOUNT_IS_NOT_NULL); + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, + "Customer payAccount cannot be null"); } } } From 54840c1d85bed69a4511179512171f92045fe596 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:21:34 +0900 Subject: [PATCH 66/73] =?UTF-8?q?[feat]=20InvalidCreationException=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20-=20InvalidCreationException(ErrorCode,=20?= =?UTF-8?q?String)=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/customer/exception/InvalidCreationException.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java index 72e05311..26ae7d49 100644 --- a/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java +++ b/src/main/java/camp/woowak/lab/customer/exception/InvalidCreationException.java @@ -4,7 +4,7 @@ import camp.woowak.lab.common.exception.ErrorCode; public class InvalidCreationException extends BadRequestException { - public InvalidCreationException(ErrorCode errorCode) { - super(errorCode); + public InvalidCreationException(ErrorCode errorCode, String message) { + super(errorCode, message); } } From c8784cda9ec1e8f8c4053edbba8a39e1e8b8fdbd Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:22:31 +0900 Subject: [PATCH 67/73] =?UTF-8?q?[feat]=20SignUpCustomerResponse=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20SignUp=20API=20=EC=9D=91=EB=8B=B5?= =?UTF-8?q?=EC=9D=98=20Response=20DTO=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/dto/response/customer/SignUpCustomerResponse.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/camp/woowak/lab/web/dto/response/customer/SignUpCustomerResponse.java diff --git a/src/main/java/camp/woowak/lab/web/dto/response/customer/SignUpCustomerResponse.java b/src/main/java/camp/woowak/lab/web/dto/response/customer/SignUpCustomerResponse.java new file mode 100644 index 00000000..87b9a605 --- /dev/null +++ b/src/main/java/camp/woowak/lab/web/dto/response/customer/SignUpCustomerResponse.java @@ -0,0 +1,4 @@ +package camp.woowak.lab.web.dto.response.customer; + +public record SignUpCustomerResponse(Long id) { +} From 6f125c943c62a25ba5ce9fe27016e2431c39a3de Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 14:25:30 +0900 Subject: [PATCH 68/73] =?UTF-8?q?[feat]=20CustomerValidator=20private=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=B6=94=EA=B0=80=20-=20?= =?UTF-8?q?=EC=9C=A0=ED=8B=B8=EB=A6=AC=ED=8B=B0=20=ED=81=B4=EB=9E=98?= =?UTF-8?q?=EC=8A=A4=EC=97=90=20private=20=EC=83=9D=EC=84=B1=EC=9E=90=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/customer/domain/CustomerValidator.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java index d890eff8..4db3c2d0 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java +++ b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java @@ -6,6 +6,9 @@ public class CustomerValidator { + private CustomerValidator() { + } + public static void validateCreation(String name, String email, String password, String phone, PayAccount payAccount) throws InvalidCreationException { validateName(name); From ae0385d5755edf984bedebb27ff4ad23e881d53b Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 15:16:04 +0900 Subject: [PATCH 69/73] =?UTF-8?q?[style]=20=EC=BD=94=EB=93=9C=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/camp/woowak/lab/customer/domain/Customer.java | 2 +- .../camp/woowak/lab/customer/service/SignUpCustomerService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/domain/Customer.java b/src/main/java/camp/woowak/lab/customer/domain/Customer.java index be53fb4f..c18a476a 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/Customer.java +++ b/src/main/java/camp/woowak/lab/customer/domain/Customer.java @@ -33,7 +33,7 @@ public Customer() { } public Customer(String name, String email, String password, String phone, PayAccount payAccount, - PasswordEncoder passwordEncoder) throws + PasswordEncoder passwordEncoder) throws InvalidCreationException { CustomerValidator.validateCreation(name, email, password, phone, payAccount); this.name = name; diff --git a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java index 64b69f50..c8b1cbdb 100644 --- a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java +++ b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java @@ -20,7 +20,7 @@ public class SignUpCustomerService { private final PasswordEncoder passwordEncoder; public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRepository payAccountRepository, - PasswordEncoder passwordEncoder) { + PasswordEncoder passwordEncoder) { this.customerRepository = customerRepository; this.payAccountRepository = payAccountRepository; this.passwordEncoder = passwordEncoder; From 7a44fac3c69ffbe4a92acf27c55e9dca4d5b95aa Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 16:21:11 +0900 Subject: [PATCH 70/73] =?UTF-8?q?[feat]=20SignUpCustomerRequest=20annotati?= =?UTF-8?q?on=20param=20=EC=88=98=EC=A0=95=20-=20Validation=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=20=EC=8B=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=AA=85?= =?UTF-8?q?=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/dto/request/customer/SignUpCustomerRequest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java index 06d257d5..48cc5397 100644 --- a/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java +++ b/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java @@ -7,14 +7,14 @@ import jakarta.validation.constraints.NotBlank; public record SignUpCustomerRequest( - @Length(min = 1, max = 50) + @Length(min = 1, max = 50, message = "이름은 1자 이상 50자 이하여야 합니다.") String name, @NotBlank - @Email + @Email(message = "이메일 형식이 올바르지 않습니다.") String email, - @Length(min = 8, max = 20) + @Length(min = 8, max = 20, message = "비밀번호는 8자 이상 20자 이하여야 합니다.") String password, - @Phone + @Phone(message = "전화번호 형식이 올바르지 않습니다.") String phone ) { } From b28cc5dfb00bd811bd43281c3ee9560d9d0edcf8 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 16:22:14 +0900 Subject: [PATCH 71/73] =?UTF-8?q?[refactor]=20Validation=20=EC=83=81?= =?UTF-8?q?=EC=88=98=20=EA=B0=92=20=EC=B6=94=EC=B6=9C=20-=20Validate=20?= =?UTF-8?q?=EC=8B=9C=20=EC=97=90=EC=84=9C=20=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EA=B0=92=EC=9D=84=20Validator=20=EC=9D=98=20field=20=EB=A1=9C?= =?UTF-8?q?=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/customer/domain/CustomerValidator.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java index 4db3c2d0..118692fb 100644 --- a/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java +++ b/src/main/java/camp/woowak/lab/customer/domain/CustomerValidator.java @@ -5,6 +5,11 @@ import camp.woowak.lab.payaccount.domain.PayAccount; public class CustomerValidator { + private static final int MAX_NAME_LENGTH = 50; + private static final int MAX_EMAIL_LENGTH = 100; + private static final int MIN_PASSWORD_LENGTH = 8; + private static final int MAX_PASSWORD_LENGTH = 30; + private static final int MAX_PHONE_LENGTH = 30; private CustomerValidator() { } @@ -22,7 +27,7 @@ public static void validateName(String name) throws InvalidCreationException { if (name == null || name.isBlank()) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer name cannot be blank"); } - if (name.length() > 50) { + if (name.length() > MAX_NAME_LENGTH) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer name cannot be longer than 50 characters"); } @@ -32,7 +37,7 @@ public static void validateEmail(String email) throws InvalidCreationException { if (email == null || email.isBlank()) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer email cannot be blank"); } - if (email.trim().length() > 100) { + if (email.trim().length() > MAX_EMAIL_LENGTH) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer email cannot be longer than 100 characters"); } @@ -42,7 +47,11 @@ public static void validatePassword(String password) throws InvalidCreationExcep if (password == null || password.isBlank()) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer password cannot be blank"); } - if (password.trim().length() > 30) { + if (password.trim().length() < MIN_PASSWORD_LENGTH) { + throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, + "Customer password cannot be shorter than 8 characters"); + } + if (password.trim().length() > MAX_PASSWORD_LENGTH) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer password cannot be longer than 30 characters"); } @@ -52,7 +61,7 @@ public static void validatePhone(String phone) throws InvalidCreationException { if (phone == null || phone.isBlank()) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer phone cannot be blank"); } - if (phone.trim().length() > 30) { + if (phone.trim().length() > MAX_PHONE_LENGTH) { throw new InvalidCreationException(CustomerErrorCode.INVALID_CREATION, "Customer phone cannot be longer than 30 characters"); } From 7a1e3fbef03d60da9e2bf8a62138fce9e39649b4 Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 16:31:49 +0900 Subject: [PATCH 72/73] =?UTF-8?q?[feat]=20SignUpCustomerRequest=20annotati?= =?UTF-8?q?on=20param=20=EC=88=98=EC=A0=95=20-=20Validation=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=20=EC=8B=9C=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EB=AA=85?= =?UTF-8?q?=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lab/web/dto/request/customer/SignUpCustomerRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java b/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java index 48cc5397..80dc9cbe 100644 --- a/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java +++ b/src/main/java/camp/woowak/lab/web/dto/request/customer/SignUpCustomerRequest.java @@ -9,7 +9,7 @@ public record SignUpCustomerRequest( @Length(min = 1, max = 50, message = "이름은 1자 이상 50자 이하여야 합니다.") String name, - @NotBlank + @NotBlank(message = "이메일은 필수 입력값입니다.") @Email(message = "이메일 형식이 올바르지 않습니다.") String email, @Length(min = 8, max = 20, message = "비밀번호는 8자 이상 20자 이하여야 합니다.") From b68368ac761255ca5369e126f8b6b2329a3a186b Mon Sep 17 00:00:00 2001 From: kimhyun5u <22kimhyun5u@gmail.com> Date: Tue, 13 Aug 2024 16:33:38 +0900 Subject: [PATCH 73/73] =?UTF-8?q?[chore]=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20throws=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../camp/woowak/lab/customer/service/SignUpCustomerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java index c8b1cbdb..3aa0c421 100644 --- a/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java +++ b/src/main/java/camp/woowak/lab/customer/service/SignUpCustomerService.java @@ -32,7 +32,7 @@ public SignUpCustomerService(CustomerRepository customerRepository, PayAccountRe * @throws DuplicateEmailException 이메일이 중복되는 경우 */ @Transactional - public Long signUp(SignUpCustomerCommand cmd) throws InvalidCreationException, DuplicateEmailException { + public Long signUp(SignUpCustomerCommand cmd) { PayAccount payAccount = new PayAccount(); payAccountRepository.save(payAccount);