From 680d60314afdca286c3d2e7a1aeb412fb3aaa51a Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 00:34:37 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20&=20=EC=A4=91=EB=B3=B5=20=ED=99=95=EC=9D=B8=20permi?= =?UTF-8?q?tAll=20Url=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/security/SecurityConfiguration.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/site/goldenticket/common/security/SecurityConfiguration.java b/src/main/java/site/goldenticket/common/security/SecurityConfiguration.java index da2d5069..49fe1867 100644 --- a/src/main/java/site/goldenticket/common/security/SecurityConfiguration.java +++ b/src/main/java/site/goldenticket/common/security/SecurityConfiguration.java @@ -38,9 +38,14 @@ @RequiredArgsConstructor public class SecurityConfiguration { - private static final String[] PERMIT_ALL_GET_URLS = new String[]{ + private static final String[] PERMIT_ALL_GET_URLS = new String[] { "/favicon.ico", - "/docs/**" + "/docs/**", + "/users/check/**" + }; + + private static final String[] PERMIT_ALL_POST_URLS = new String[] { + "/users" }; private final ObjectMapper objectMapper; @@ -63,6 +68,7 @@ public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Excepti .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(authorize -> authorize .requestMatchers(GET, PERMIT_ALL_GET_URLS).permitAll() + .requestMatchers(POST, PERMIT_ALL_POST_URLS).permitAll() .requestMatchers(PathRequest.toH2Console()).permitAll() .anyRequest().authenticated() ) From 5c26a54920047e2194a6c69e489554d53bb1ad67 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 00:38:22 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20=EC=9D=B4=EB=A9=94=EC=9D=BC=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=ED=99=95=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 23 +++++++++++++++++++ .../domain/user/service/UserService.java | 21 +++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 src/main/java/site/goldenticket/domain/user/controller/UserController.java create mode 100644 src/main/java/site/goldenticket/domain/user/service/UserService.java diff --git a/src/main/java/site/goldenticket/domain/user/controller/UserController.java b/src/main/java/site/goldenticket/domain/user/controller/UserController.java new file mode 100644 index 00000000..05143535 --- /dev/null +++ b/src/main/java/site/goldenticket/domain/user/controller/UserController.java @@ -0,0 +1,23 @@ +package site.goldenticket.domain.user.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import site.goldenticket.common.response.CommonResponse; +import site.goldenticket.domain.user.service.UserService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/users") +public class UserController { + + private final UserService userService; + + @GetMapping("/check/email") + public ResponseEntity> duplicateEmail(@RequestParam String email) { + return ResponseEntity.ok(CommonResponse.ok(userService.isExistEmail(email))); + } +} diff --git a/src/main/java/site/goldenticket/domain/user/service/UserService.java b/src/main/java/site/goldenticket/domain/user/service/UserService.java new file mode 100644 index 00000000..97b49b57 --- /dev/null +++ b/src/main/java/site/goldenticket/domain/user/service/UserService.java @@ -0,0 +1,21 @@ +package site.goldenticket.domain.user.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import site.goldenticket.domain.user.repository.UserRepository; + +@Slf4j +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class UserService { + + private final UserRepository userRepository; + + public boolean isExistEmail(String email) { + log.info("Duplicated Check Email = {}", email); + return userRepository.findByEmail(email).isPresent(); + } +} From 962cab794f2fcaa92e9076593a15bd41815f7df1 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 00:42:57 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20=EB=8B=89=EB=84=A4=EC=9E=84=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=20=ED=99=95=EC=9D=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../goldenticket/domain/user/controller/UserController.java | 5 +++++ .../goldenticket/domain/user/repository/UserRepository.java | 2 ++ .../site/goldenticket/domain/user/service/UserService.java | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/src/main/java/site/goldenticket/domain/user/controller/UserController.java b/src/main/java/site/goldenticket/domain/user/controller/UserController.java index 05143535..d96fbfd1 100644 --- a/src/main/java/site/goldenticket/domain/user/controller/UserController.java +++ b/src/main/java/site/goldenticket/domain/user/controller/UserController.java @@ -20,4 +20,9 @@ public class UserController { public ResponseEntity> duplicateEmail(@RequestParam String email) { return ResponseEntity.ok(CommonResponse.ok(userService.isExistEmail(email))); } + + @GetMapping("/check/nickname") + public ResponseEntity> duplicateNickname(@RequestParam String nickname) { + return ResponseEntity.ok(CommonResponse.ok(userService.isExistNickname(nickname))); + } } diff --git a/src/main/java/site/goldenticket/domain/user/repository/UserRepository.java b/src/main/java/site/goldenticket/domain/user/repository/UserRepository.java index 553afdcc..93613635 100644 --- a/src/main/java/site/goldenticket/domain/user/repository/UserRepository.java +++ b/src/main/java/site/goldenticket/domain/user/repository/UserRepository.java @@ -8,4 +8,6 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); + + boolean existsByNickname(String nickname); } diff --git a/src/main/java/site/goldenticket/domain/user/service/UserService.java b/src/main/java/site/goldenticket/domain/user/service/UserService.java index 97b49b57..61bc79c3 100644 --- a/src/main/java/site/goldenticket/domain/user/service/UserService.java +++ b/src/main/java/site/goldenticket/domain/user/service/UserService.java @@ -18,4 +18,9 @@ public boolean isExistEmail(String email) { log.info("Duplicated Check Email = {}", email); return userRepository.findByEmail(email).isPresent(); } + + public boolean isExistNickname(String nickname) { + log.info("Duplicated Check Nickname = {}", nickname); + return userRepository.existsByNickname(nickname); + } } From 91358f9d49cfbe2d361fae578de8f07d064d941c Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 18:00:56 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20User=EC=99=80=20Agreement=20?= =?UTF-8?q?=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/entity/Agreement.java | 34 +++++++++++++++++++ .../goldenticket/domain/user/entity/User.java | 33 ++++++++++++------ 2 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 src/main/java/site/goldenticket/domain/user/entity/Agreement.java diff --git a/src/main/java/site/goldenticket/domain/user/entity/Agreement.java b/src/main/java/site/goldenticket/domain/user/entity/Agreement.java new file mode 100644 index 00000000..1bc608e6 --- /dev/null +++ b/src/main/java/site/goldenticket/domain/user/entity/Agreement.java @@ -0,0 +1,34 @@ +package site.goldenticket.domain.user.entity; + +import jakarta.persistence.*; +import lombok.*; +import site.goldenticket.common.entiy.BaseTimeEntity; + +import static jakarta.persistence.FetchType.LAZY; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@ToString(exclude = {"user"}) +public class Agreement extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne(fetch = LAZY) + @JoinColumn(name = "user_id") + private User user; + + private Boolean marketing; + + @Builder + private Agreement(Boolean marketing) { + this.marketing = marketing; + } + + public void registerUser(User user) { + this.user = user; + user.registerAlertSetting(this); + } +} diff --git a/src/main/java/site/goldenticket/domain/user/entity/User.java b/src/main/java/site/goldenticket/domain/user/entity/User.java index 06c623d6..fedb12e9 100644 --- a/src/main/java/site/goldenticket/domain/user/entity/User.java +++ b/src/main/java/site/goldenticket/domain/user/entity/User.java @@ -1,5 +1,6 @@ package site.goldenticket.domain.user.entity; +import jakarta.annotation.Nullable; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; @@ -7,9 +8,12 @@ import org.hibernate.annotations.SQLRestriction; import site.goldenticket.common.entiy.BaseTimeEntity; +import static jakarta.persistence.CascadeType.ALL; import static jakarta.persistence.EnumType.STRING; +import static jakarta.persistence.FetchType.LAZY; import static jakarta.persistence.GenerationType.IDENTITY; import static lombok.AccessLevel.PROTECTED; +import static site.goldenticket.domain.user.entity.RoleType.ROLE_USER; @Getter @Entity @@ -34,27 +38,34 @@ public class User extends BaseTimeEntity { @Enumerated(STRING) private RoleType role; - private String yanoljaId; + private Long yanoljaId; private boolean deleted; + @OneToOne( + mappedBy = "user", fetch = LAZY, + cascade = ALL, orphanRemoval = true + ) + private Agreement agreement; + @Builder private User( - String name, - String nickname, - String email, - String password, - String phoneNumber, - String imageUrl, - String yanoljaId, - RoleType role + @Nullable String name, + @Nullable String nickname, + @Nullable String email, + @Nullable String password, + @Nullable String phoneNumber, + Long yanoljaId ) { + this.role = ROLE_USER; this.name = name; this.nickname = nickname; this.email = email; this.password = password; this.phoneNumber = phoneNumber; - this.imageUrl = imageUrl; this.yanoljaId = yanoljaId; - this.role = role; + } + + public void registerAlertSetting(Agreement agreement) { + this.agreement = agreement; } } From 46896b755632b64d8e2d224a6dc03312c779def0 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 18:01:48 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/dto/AgreementRequest.java | 19 +++++++++ .../domain/user/dto/JoinRequest.java | 41 +++++++++++++++++++ .../domain/user/dto/JoinResponse.java | 10 +++++ .../domain/user/service/UserService.java | 13 ++++++ 4 files changed, 83 insertions(+) create mode 100644 src/main/java/site/goldenticket/domain/user/dto/AgreementRequest.java create mode 100644 src/main/java/site/goldenticket/domain/user/dto/JoinRequest.java create mode 100644 src/main/java/site/goldenticket/domain/user/dto/JoinResponse.java diff --git a/src/main/java/site/goldenticket/domain/user/dto/AgreementRequest.java b/src/main/java/site/goldenticket/domain/user/dto/AgreementRequest.java new file mode 100644 index 00000000..e9fdfed8 --- /dev/null +++ b/src/main/java/site/goldenticket/domain/user/dto/AgreementRequest.java @@ -0,0 +1,19 @@ +package site.goldenticket.domain.user.dto; + +import jakarta.validation.constraints.NotEmpty; +import site.goldenticket.domain.user.entity.Agreement; +import site.goldenticket.domain.user.entity.User; + +public record AgreementRequest( + @NotEmpty(message = "마케팅 동의는 필수 선택 사항입니다.") + Boolean isMarketing +) { + + public Agreement toEntity(User user) { + Agreement agreement = Agreement.builder() + .marketing(isMarketing) + .build(); + agreement.registerUser(user); + return agreement; + } +} diff --git a/src/main/java/site/goldenticket/domain/user/dto/JoinRequest.java b/src/main/java/site/goldenticket/domain/user/dto/JoinRequest.java new file mode 100644 index 00000000..66bdcd0a --- /dev/null +++ b/src/main/java/site/goldenticket/domain/user/dto/JoinRequest.java @@ -0,0 +1,41 @@ +package site.goldenticket.domain.user.dto; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import site.goldenticket.domain.user.entity.User; + +public record JoinRequest( + @NotEmpty(message = "비밀번호는 필수 입력 항목입니다.") + @Size(min = 2, message = "이름은 두 글자 이상의 한글이어야 합니다.") + String name, + @NotEmpty(message = "닉네임은 필수 입력 항목입니다.") + @Size(max = 15, message = "닉네임은 1글자 이상, 15자 이하여야 합니다.") + String nickname, + @NotEmpty(message = "이메일은 필수 입력 항목입니다.") + @Email(message = "이메일은 유효한 형식이어야 합니다.") + String email, + @NotEmpty(message = "비밀번호는 필수 입력 항목입니다.") + @Size(min = 6, max = 20, message = "비밀번호는 6자 이상, 20자 이하여야 합니다.") + String password, + @NotEmpty(message = "휴대폰 번호는 필수 입력 항목입니다.") + @Pattern(regexp = "^\\d{2,3}-\\d{3,4}-\\d{4}$", message = "000-0000-0000 형식이여야 합니다.") + String phoneNumber, + Long yanoljaId, + AgreementRequest agreement +) { + + public User toEntity(String encodePassword) { + User user = User.builder() + .name(name) + .nickname(nickname) + .email(email) + .password(encodePassword) + .phoneNumber(phoneNumber) + .yanoljaId(yanoljaId) + .build(); + agreement.toEntity(user); + return user; + } +} diff --git a/src/main/java/site/goldenticket/domain/user/dto/JoinResponse.java b/src/main/java/site/goldenticket/domain/user/dto/JoinResponse.java new file mode 100644 index 00000000..1dc2fc13 --- /dev/null +++ b/src/main/java/site/goldenticket/domain/user/dto/JoinResponse.java @@ -0,0 +1,10 @@ +package site.goldenticket.domain.user.dto; + +import site.goldenticket.domain.user.entity.User; + +public record JoinResponse(Long id) { + + public static JoinResponse from(User user) { + return new JoinResponse(user.getId()); + } +} diff --git a/src/main/java/site/goldenticket/domain/user/service/UserService.java b/src/main/java/site/goldenticket/domain/user/service/UserService.java index 61bc79c3..a30eb341 100644 --- a/src/main/java/site/goldenticket/domain/user/service/UserService.java +++ b/src/main/java/site/goldenticket/domain/user/service/UserService.java @@ -2,8 +2,12 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import site.goldenticket.domain.user.dto.JoinRequest; +import site.goldenticket.domain.user.dto.JoinResponse; +import site.goldenticket.domain.user.entity.User; import site.goldenticket.domain.user.repository.UserRepository; @Slf4j @@ -13,6 +17,7 @@ public class UserService { private final UserRepository userRepository; + private final PasswordEncoder passwordEncoder; public boolean isExistEmail(String email) { log.info("Duplicated Check Email = {}", email); @@ -23,4 +28,12 @@ public boolean isExistNickname(String nickname) { log.info("Duplicated Check Nickname = {}", nickname); return userRepository.existsByNickname(nickname); } + + @Transactional + public JoinResponse join(JoinRequest joinRequest) { + String encodePassword = passwordEncoder.encode(joinRequest.password()); + User user = joinRequest.toEntity(encodePassword); + userRepository.save(user); + return JoinResponse.from(user); + } } From 428c99d79177343a007fad37e720692ec7413ec8 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 18:17:42 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20API=20=EC=83=9D=EC=84=B1=20&=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 --- .../user/controller/UserController.java | 16 +++++-- .../goldenticket/common/utils/UserUtils.java | 7 +-- .../user/controller/UserControllerTest.java | 46 +++++++++++++++++++ 3 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java diff --git a/src/main/java/site/goldenticket/domain/user/controller/UserController.java b/src/main/java/site/goldenticket/domain/user/controller/UserController.java index d96fbfd1..107fe64c 100644 --- a/src/main/java/site/goldenticket/domain/user/controller/UserController.java +++ b/src/main/java/site/goldenticket/domain/user/controller/UserController.java @@ -2,13 +2,15 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; import site.goldenticket.common.response.CommonResponse; +import site.goldenticket.domain.user.dto.JoinRequest; +import site.goldenticket.domain.user.dto.JoinResponse; import site.goldenticket.domain.user.service.UserService; +import static org.springframework.http.HttpStatus.CREATED; + @RestController @RequiredArgsConstructor @RequestMapping("/users") @@ -25,4 +27,10 @@ public ResponseEntity> duplicateEmail(@RequestParam Stri public ResponseEntity> duplicateNickname(@RequestParam String nickname) { return ResponseEntity.ok(CommonResponse.ok(userService.isExistNickname(nickname))); } + + @PostMapping + public ResponseEntity> join(@RequestBody @Validated JoinRequest joinRequest) { + JoinResponse response = userService.join(joinRequest); + return new ResponseEntity<>(CommonResponse.ok(response), CREATED); + } } diff --git a/src/test/java/site/goldenticket/common/utils/UserUtils.java b/src/test/java/site/goldenticket/common/utils/UserUtils.java index 422ee775..0ce989cf 100644 --- a/src/test/java/site/goldenticket/common/utils/UserUtils.java +++ b/src/test/java/site/goldenticket/common/utils/UserUtils.java @@ -2,15 +2,13 @@ import site.goldenticket.domain.user.entity.User; -import static site.goldenticket.domain.user.entity.RoleType.ROLE_USER; - public final class UserUtils { public static String EMAIL = "email@gamil.com"; public static String PASSWORD = "password"; public static String NAME = "name"; public static String NICKNAME = "nickname"; - public static String PHONENUMBER = "010-0000-0000"; + public static String PHONE_NUMBER = "010-0000-0000"; public static User createUser(String encodePassword) { return User.builder() @@ -18,8 +16,7 @@ public static User createUser(String encodePassword) { .password(encodePassword) .name(NAME) .nickname(NICKNAME) - .phoneNumber(PHONENUMBER) - .role(ROLE_USER) + .phoneNumber(PHONE_NUMBER) .build(); } } diff --git a/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java b/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java new file mode 100644 index 00000000..cd9c2f0e --- /dev/null +++ b/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java @@ -0,0 +1,46 @@ +package site.goldenticket.domain.user.controller; + +import io.restassured.RestAssured; +import io.restassured.response.ExtractableResponse; +import io.restassured.response.Response; +import org.junit.jupiter.api.Test; +import site.goldenticket.common.config.ApiTest; +import site.goldenticket.domain.user.dto.AgreementRequest; +import site.goldenticket.domain.user.dto.JoinRequest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.HttpStatus.CREATED; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; +import static site.goldenticket.common.utils.UserUtils.*; + +class UserControllerTest extends ApiTest { + + @Test + void join() { + // given + JoinRequest request = new JoinRequest( + NAME, + NICKNAME, + EMAIL, + PASSWORD, + PHONE_NUMBER, + null, + new AgreementRequest(true) + ); + + String url = "/users"; + + // when + ExtractableResponse result = RestAssured + .given().log().all() + .contentType(APPLICATION_JSON_VALUE) + .body(request) + .when() + .post(url) + .then().log().all() + .extract(); + + // then + assertThat(result.statusCode()).isEqualTo(CREATED.value()); + } +} From 5c4956dff405c2827094380114f66fcbde011212 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 18:22:48 +0900 Subject: [PATCH 7/9] =?UTF-8?q?test:=20=EB=B0=98=ED=99=98=20=EA=B0=92=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EC=B6=94=EA=B0=80=20=EB=B0=8F=20DisplayNa?= =?UTF-8?q?me=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/controller/UserControllerTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java b/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java index cd9c2f0e..4accf5d9 100644 --- a/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java +++ b/src/test/java/site/goldenticket/domain/user/controller/UserControllerTest.java @@ -3,6 +3,7 @@ import io.restassured.RestAssured; import io.restassured.response.ExtractableResponse; import io.restassured.response.Response; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import site.goldenticket.common.config.ApiTest; import site.goldenticket.domain.user.dto.AgreementRequest; @@ -13,9 +14,11 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; import static site.goldenticket.common.utils.UserUtils.*; +@DisplayName("UserController 검증") class UserControllerTest extends ApiTest { @Test + @DisplayName("회원가입 검증") void join() { // given JoinRequest request = new JoinRequest( @@ -42,5 +45,6 @@ void join() { // then assertThat(result.statusCode()).isEqualTo(CREATED.value()); + assertThat(result.jsonPath().getLong("data.id")).isEqualTo(1L); } } From 4af3568d8919b6393a9e870568c355a091fa0d10 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 18:28:23 +0900 Subject: [PATCH 8/9] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=8B=9C,=20=EC=9D=B4=EB=A9=94=EC=9D=BC=EA=B3=BC?= =?UTF-8?q?=20=EB=8B=89=EB=84=A4=EC=9E=84=20=EC=A4=91=EB=B3=B5=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/user/service/UserService.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/site/goldenticket/domain/user/service/UserService.java b/src/main/java/site/goldenticket/domain/user/service/UserService.java index a30eb341..ba8a0244 100644 --- a/src/main/java/site/goldenticket/domain/user/service/UserService.java +++ b/src/main/java/site/goldenticket/domain/user/service/UserService.java @@ -5,11 +5,15 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import site.goldenticket.common.exception.CustomException; import site.goldenticket.domain.user.dto.JoinRequest; import site.goldenticket.domain.user.dto.JoinResponse; import site.goldenticket.domain.user.entity.User; import site.goldenticket.domain.user.repository.UserRepository; +import static site.goldenticket.common.response.ErrorCode.ALREADY_EXIST_EMAIL; +import static site.goldenticket.common.response.ErrorCode.ALREADY_EXIST_NICKNAME; + @Slf4j @Service @RequiredArgsConstructor @@ -31,9 +35,22 @@ public boolean isExistNickname(String nickname) { @Transactional public JoinResponse join(JoinRequest joinRequest) { + joinValidate(joinRequest); + log.info("Join User Info = {}", joinRequest); + String encodePassword = passwordEncoder.encode(joinRequest.password()); User user = joinRequest.toEntity(encodePassword); userRepository.save(user); return JoinResponse.from(user); } + + private void joinValidate(JoinRequest joinRequest) { + if (isExistEmail(joinRequest.email())) { + throw new CustomException(ALREADY_EXIST_EMAIL); + } + + if (isExistNickname(joinRequest.nickname())) { + throw new CustomException(ALREADY_EXIST_NICKNAME); + } + } } From 308100d17c2aaa0f2bf4478d563b9f85cfe81d23 Mon Sep 17 00:00:00 2001 From: cyPark95 Date: Sat, 13 Jan 2024 18:28:44 +0900 Subject: [PATCH 9/9] =?UTF-8?q?feat:=20=EC=97=90=EB=9F=AC=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/site/goldenticket/common/response/ErrorCode.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/site/goldenticket/common/response/ErrorCode.java b/src/main/java/site/goldenticket/common/response/ErrorCode.java index 0db5adab..e0c53f33 100644 --- a/src/main/java/site/goldenticket/common/response/ErrorCode.java +++ b/src/main/java/site/goldenticket/common/response/ErrorCode.java @@ -22,7 +22,11 @@ public enum ErrorCode { EMPTY_FAILURE_HANDLER(INTERNAL_SERVER_ERROR, "FailureHandler 필수 값 입니다."), LOGIN_FAIL(BAD_REQUEST, "이메일, 비밀번호를 확인해주세요."), INVALID_TOKEN(UNAUTHORIZED, "유효하지 않은 토큰 입니다."), - SAVE_REFRESH_TOKEN_FAILED(UNAUTHORIZED, "Token 저장 중 오류가 발생 했습니다.") + SAVE_REFRESH_TOKEN_FAILED(UNAUTHORIZED, "Token 저장 중 오류가 발생 했습니다."), + + // User + ALREADY_EXIST_EMAIL(BAD_REQUEST, "이미 사용중인 이메일입니다. 이미 가입하신 적이 있다면 로그인을 시도해주세요"), + ALREADY_EXIST_NICKNAME(BAD_REQUEST, "이미 사용중인 아이디입니다."), ; private final HttpStatus httpStatus;