Compare commits
6 Commits
feature/de
...
feature/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac30d96b6f | ||
|
|
0db2d78dee | ||
|
|
30ef20be3f | ||
|
|
952c1a1070 | ||
|
|
585206d528 | ||
|
|
0c26555665 |
9
.idea/Ticketing.iml
generated
Normal file
9
.idea/Ticketing.iml
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
8
.idea/modules.xml
generated
Normal file
8
.idea/modules.xml
generated
Normal file
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Ticketing.iml" filepath="$PROJECT_DIR$/.idea/Ticketing.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
10
.idea/runConfigurations.xml
generated
Normal file
10
.idea/runConfigurations.xml
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RunConfigurationProducerService">
|
||||
<option name="ignoredProducers">
|
||||
<set>
|
||||
<option value="com.android.tools.idea.compose.preview.runconfiguration.ComposePreviewRunConfigurationProducer" />
|
||||
</set>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
36
.idea/workspace.xml
generated
Normal file
36
.idea/workspace.xml
generated
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="2a93e153-a90c-44db-b1da-6c4424693422" name="Changes" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/server/src/main/java/com/ticketing/server/global/config/SwaggerConfig.java" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/server/build.gradle.kts" beforeDir="false" afterPath="$PROJECT_DIR$/server/build.gradle.kts" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
<component name="ProjectId" id="29uM8tIDp7UqdPYE3auX216NPaN" />
|
||||
<component name="ProjectViewState">
|
||||
<option name="hideEmptyMiddlePackages" value="true" />
|
||||
<option name="showLibraryContents" value="true" />
|
||||
</component>
|
||||
<component name="PropertiesComponent">
|
||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
<component name="TaskManager">
|
||||
<task active="true" id="Default" summary="Default task">
|
||||
<changelist id="2a93e153-a90c-44db-b1da-6c4424693422" name="Changes" comment="" />
|
||||
<created>1653958362269</created>
|
||||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1653958362269</updated>
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
</project>
|
||||
@@ -31,8 +31,11 @@ dependencies {
|
||||
implementation("org.springframework.boot:spring-boot-starter-validation")
|
||||
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||
implementation("org.springframework.boot:spring-boot-starter-actuator")
|
||||
implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4")
|
||||
implementation("org.springframework.boot:spring-boot-starter-log4j2")
|
||||
implementation("org.projectlombok:lombok:1.18.20")
|
||||
implementation("io.springfox:springfox-swagger2:3.0.0")
|
||||
implementation("io.springfox:springfox-swagger-ui:3.0.0")
|
||||
implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.4")
|
||||
implementation("com.lmax:disruptor:3.4.2")
|
||||
|
||||
modules {
|
||||
@@ -41,12 +44,14 @@ dependencies {
|
||||
}
|
||||
}
|
||||
|
||||
compileOnly("org.projectlombok:lombok")
|
||||
runtimeOnly("mysql:mysql-connector-java")
|
||||
annotationProcessor("org.projectlombok:lombok")
|
||||
|
||||
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||
testImplementation("org.springframework.security:spring-security-test")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1")
|
||||
|
||||
compileOnly("org.projectlombok:lombok")
|
||||
runtimeOnly("mysql:mysql-connector-java")
|
||||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1")
|
||||
annotationProcessor("org.projectlombok:lombok")
|
||||
}
|
||||
|
||||
tasks.withType<Test> {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.ticketing.server.global.config;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.ApiKey;
|
||||
import springfox.documentation.service.AuthorizationScope;
|
||||
import springfox.documentation.service.SecurityReference;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger.web.UiConfiguration;
|
||||
import springfox.documentation.swagger.web.UiConfigurationBuilder;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class SwaggerConfig {
|
||||
|
||||
public static final String SECURITY_SCHEMA_NAME = "Authorization";
|
||||
public static final String AUTHORIZATION_SCOPE_GLOBAL = "global";
|
||||
public static final String AUTHORIZATION_SCOPE_GLOBAL_DESC = "accessEverything";
|
||||
|
||||
@Bean
|
||||
public Docket api() {
|
||||
return new Docket(DocumentationType.OAS_30)
|
||||
.useDefaultResponseMessages(false)
|
||||
.select()
|
||||
.apis(RequestHandlerSelectors.any())
|
||||
.paths(PathSelectors.ant("/api/**")).build()
|
||||
.apiInfo(apiInfo())
|
||||
.securityContexts(Arrays.asList(securityContext()))
|
||||
.securitySchemes(Arrays.asList(apiKey()));
|
||||
}
|
||||
|
||||
private ApiInfo apiInfo() {
|
||||
return new ApiInfoBuilder()
|
||||
.title("Ticketing REST API Document")
|
||||
.version("v1")
|
||||
.description("Ticketing REST API 문서").build();
|
||||
}
|
||||
|
||||
private ApiKey apiKey() {
|
||||
return new ApiKey(SECURITY_SCHEMA_NAME, "Authorization", "header");
|
||||
}
|
||||
|
||||
private SecurityContext securityContext() {
|
||||
return SecurityContext.builder().securityReferences(defaultAuth()).build();
|
||||
}
|
||||
|
||||
private List<SecurityReference> defaultAuth() {
|
||||
AuthorizationScope authorizationScope = new AuthorizationScope(AUTHORIZATION_SCOPE_GLOBAL,
|
||||
AUTHORIZATION_SCOPE_GLOBAL_DESC);
|
||||
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
|
||||
authorizationScopes[0] = authorizationScope;
|
||||
return Arrays.asList(new SecurityReference(SECURITY_SCHEMA_NAME, authorizationScopes));
|
||||
}
|
||||
|
||||
@Bean
|
||||
UiConfiguration uiConfig() {
|
||||
return UiConfigurationBuilder.builder()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.ticketing.server.global.exception;
|
||||
|
||||
public class AlreadyDeletedException extends RuntimeException {
|
||||
|
||||
public AlreadyDeletedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ticketing.server.global.exception;
|
||||
|
||||
public class NotFoundEmailException extends IllegalArgumentException {
|
||||
|
||||
private static final String MESSAGE = "존재하지 않는 이메일 입니다.";
|
||||
|
||||
public NotFoundEmailException() {
|
||||
super(MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ticketing.server.global.exception;
|
||||
|
||||
public class PasswordMismatchException extends RuntimeException {
|
||||
|
||||
private static final String MESSAGE = "패스워드가 일치하지 않습니다";
|
||||
|
||||
public PasswordMismatchException() {
|
||||
super(MESSAGE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +1,24 @@
|
||||
package com.ticketing.server.movie.domain;
|
||||
|
||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Movie extends AbstractEntity {
|
||||
|
||||
@NotNull
|
||||
private String title;
|
||||
@NotNull
|
||||
@Column(unique = true)
|
||||
private String title;
|
||||
|
||||
@NotNull
|
||||
private Integer runningTime;
|
||||
@NotNull
|
||||
private Integer runningTime;
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,14 @@ package com.ticketing.server.movie.domain;
|
||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||
import javax.persistence.Entity;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class Theater extends AbstractEntity {
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -6,10 +6,10 @@ import lombok.Getter;
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TicketStatus {
|
||||
SALE("판매가능"),
|
||||
SCHEDULED("환불"),
|
||||
SOLD("판매완료");
|
||||
SALE("판매가능"),
|
||||
SCHEDULED("환불"),
|
||||
SOLD("판매완료");
|
||||
|
||||
private String name;
|
||||
private String name;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
import com.ticketing.server.movie.domain.Movie;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface MovieRepository extends JpaRepository<Movie, Long> {
|
||||
|
||||
Optional<Movie> findByTitle(String title);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
import com.ticketing.server.movie.domain.Theater;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface TheaterRepository extends JpaRepository<Theater, Long> {
|
||||
|
||||
Optional<Theater> findByTheaterNumber(Integer theaterNumber);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
package com.ticketing.server.user.application;
|
||||
|
||||
import com.ticketing.server.user.application.request.SignUpRequest;
|
||||
import com.ticketing.server.user.application.request.UserDeleteRequest;
|
||||
import com.ticketing.server.user.application.request.UserModifyPasswordRequest;
|
||||
import com.ticketing.server.user.application.response.SignUpResponse;
|
||||
import com.ticketing.server.user.application.response.UserDeleteResponse;
|
||||
import com.ticketing.server.user.application.response.UserChangePasswordResponse;
|
||||
import com.ticketing.server.user.domain.User;
|
||||
import com.ticketing.server.user.service.UserServiceImpl;
|
||||
import java.util.Optional;
|
||||
import javax.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -17,20 +24,33 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/user")
|
||||
@Slf4j
|
||||
public class UserController {
|
||||
|
||||
private final UserServiceImpl userService;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<Object> register(@RequestBody @Valid SignUpRequest signUpRequest) {
|
||||
Optional<User> user = userService.register(signUpRequest.toSignUp(passwordEncoder));
|
||||
public ResponseEntity<Object> register(@RequestBody @Valid SignUpRequest request) {
|
||||
User user = userService.register(request.toSignUpDto(passwordEncoder));
|
||||
return ResponseEntity.status(HttpStatus.CREATED).body(SignUpResponse.of(user));
|
||||
}
|
||||
|
||||
if (user.isEmpty()) {
|
||||
@DeleteMapping
|
||||
public ResponseEntity<Object> deleteUser(@RequestBody @Valid UserDeleteRequest request) {
|
||||
User user = userService.delete(request.toDeleteUserDto(passwordEncoder));
|
||||
return ResponseEntity.status(HttpStatus.OK).body(UserDeleteResponse.of(user));
|
||||
}
|
||||
|
||||
@PatchMapping("/password")
|
||||
public ResponseEntity<Object> changePassword(@RequestBody @Valid UserModifyPasswordRequest request) {
|
||||
if (request.oldEqualNew()) {
|
||||
log.error("기존 패스워드와 동일한 패스워드로 변경할 수 없습니다.");
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
|
||||
}
|
||||
|
||||
return ResponseEntity.status(HttpStatus.CREATED).build();
|
||||
User user = userService.changePassword(request.toChangePasswordDto(passwordEncoder));
|
||||
return ResponseEntity.status(HttpStatus.OK).body(UserChangePasswordResponse.of(user));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.ticketing.server.user.application.request;
|
||||
|
||||
import com.ticketing.server.global.validator.constraints.Phone;
|
||||
import com.ticketing.server.user.service.dto.SignUp;
|
||||
import com.ticketing.server.user.service.dto.SignUpDTO;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
@@ -24,8 +24,8 @@ public class SignUpRequest {
|
||||
@Phone
|
||||
private String phone;
|
||||
|
||||
public SignUp toSignUp(PasswordEncoder passwordEncoder) {
|
||||
return new SignUp(name, email, getEncodePassword(passwordEncoder), phone);
|
||||
public SignUpDTO toSignUpDto(PasswordEncoder passwordEncoder) {
|
||||
return new SignUpDTO(name, email, getEncodePassword(passwordEncoder), phone);
|
||||
}
|
||||
|
||||
private String getEncodePassword(PasswordEncoder passwordEncoder) {
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.ticketing.server.user.application.request;
|
||||
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Getter
|
||||
public class UserDeleteRequest {
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.email}")
|
||||
@Email(message = "{validation.email}")
|
||||
private String email;
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.password}")
|
||||
private String password;
|
||||
|
||||
public DeleteUserDTO toDeleteUserDto(PasswordEncoder passwordEncoder) {
|
||||
return new DeleteUserDTO(email, password, passwordEncoder);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.ticketing.server.user.application.request;
|
||||
|
||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Getter
|
||||
public class UserModifyPasswordRequest {
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.email}")
|
||||
@Email(message = "{validation.email}")
|
||||
private String email;
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.oldpassword}")
|
||||
private String oldPassword;
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.newpassword}")
|
||||
private String newPassword;
|
||||
|
||||
public ChangePasswordDTO toChangePasswordDto(PasswordEncoder passwordEncoder) {
|
||||
return new ChangePasswordDTO(email, oldPassword, newPassword, passwordEncoder);
|
||||
}
|
||||
|
||||
public boolean oldEqualNew() {
|
||||
return oldPassword.equals(newPassword);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ticketing.server.user.application.response;
|
||||
|
||||
import com.ticketing.server.user.domain.User;
|
||||
|
||||
public class SignUpResponse {
|
||||
|
||||
public static SignUpResponse of(User user) {
|
||||
return new SignUpResponse(user.getName(), user.getEmail());
|
||||
}
|
||||
|
||||
public SignUpResponse(String name, String email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
private String email;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ticketing.server.user.application.response;
|
||||
|
||||
import com.ticketing.server.user.domain.User;
|
||||
|
||||
public class UserChangePasswordResponse {
|
||||
|
||||
public static SignUpResponse of(User user) {
|
||||
return new SignUpResponse(user.getName(), user.getEmail());
|
||||
}
|
||||
|
||||
public UserChangePasswordResponse(String name, String email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
private String email;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ticketing.server.user.application.response;
|
||||
|
||||
import com.ticketing.server.user.domain.User;
|
||||
|
||||
public class UserDeleteResponse {
|
||||
|
||||
public static SignUpResponse of(User user) {
|
||||
return new SignUpResponse(user.getName(), user.getEmail());
|
||||
}
|
||||
|
||||
public UserDeleteResponse(String name, String email) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
private String email;
|
||||
|
||||
}
|
||||
@@ -1,7 +1,12 @@
|
||||
package com.ticketing.server.user.domain;
|
||||
|
||||
import com.ticketing.server.global.dto.repository.AbstractEntity;
|
||||
import com.ticketing.server.global.exception.AlreadyDeletedException;
|
||||
import com.ticketing.server.global.exception.PasswordMismatchException;
|
||||
import com.ticketing.server.global.validator.constraints.Phone;
|
||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||
import com.ticketing.server.user.service.dto.PasswordMatches;
|
||||
import java.time.LocalDateTime;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
@@ -18,6 +23,14 @@ import lombok.NoArgsConstructor;
|
||||
@NoArgsConstructor
|
||||
public class User extends AbstractEntity {
|
||||
|
||||
public User(String name, String email, String password, UserGrade grade, String phone) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.grade = grade;
|
||||
this.phone = phone;
|
||||
}
|
||||
|
||||
@Column(name = "name")
|
||||
@NotEmpty(message = "{validation.not.empty.name}")
|
||||
private String name;
|
||||
@@ -45,12 +58,29 @@ public class User extends AbstractEntity {
|
||||
|
||||
private LocalDateTime deletedAt;
|
||||
|
||||
public User(String name, String email, String password, UserGrade grade, String phone) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
this.grade = grade;
|
||||
this.phone = phone;
|
||||
public User delete(DeleteUserDTO deleteUser) {
|
||||
if (isDeleted) {
|
||||
throw new AlreadyDeletedException("이미 탈퇴된 회원 입니다.");
|
||||
}
|
||||
|
||||
checkPassword(deleteUser);
|
||||
|
||||
isDeleted = true;
|
||||
deletedAt = LocalDateTime.now();
|
||||
return this;
|
||||
}
|
||||
|
||||
public User changePassword(ChangePasswordDTO changePassword) {
|
||||
checkPassword(changePassword);
|
||||
|
||||
this.password = changePassword.getEncodePassword();
|
||||
return this;
|
||||
}
|
||||
|
||||
private void checkPassword(PasswordMatches passwordMatches) {
|
||||
if (!passwordMatches.passwordMatches(password)) {
|
||||
throw new PasswordMismatchException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,4 +10,6 @@ public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
Optional<User> findByEmail(String email);
|
||||
|
||||
Optional<User> findByEmailAndIsDeletedFalse(String email);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.ticketing.server.user.service;
|
||||
|
||||
import com.ticketing.server.global.exception.NotFoundEmailException;
|
||||
import com.ticketing.server.user.domain.User;
|
||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||
import com.ticketing.server.user.service.dto.SignUp;
|
||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||
import com.ticketing.server.user.service.dto.SignUpDTO;
|
||||
import com.ticketing.server.user.service.interfaces.UserService;
|
||||
import java.util.Optional;
|
||||
import javax.validation.Valid;
|
||||
@@ -23,15 +26,40 @@ public class UserServiceImpl implements UserService {
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Optional<User> register(@Valid SignUp signUpDto) {
|
||||
public User register(@Valid SignUpDTO signUpDto) {
|
||||
Optional<User> user = userRepository.findByEmail(signUpDto.getEmail());
|
||||
if (user.isPresent()) {
|
||||
log.error("이미 존재하는 이메일이기 때문에 신규 회원가입을 진행할 수 없습니다. :: {}", signUpDto);
|
||||
return Optional.empty();
|
||||
throw new IllegalArgumentException("이미 존재하는 이메일이기 때문에 신규 회원가입을 진행할 수 없습니다.");
|
||||
}
|
||||
|
||||
User newUser = userRepository.save(signUpDto.toUser());
|
||||
return Optional.of(newUser);
|
||||
return userRepository.save(signUpDto.toUser());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public User delete(@Valid DeleteUserDTO deleteUserDto) {
|
||||
Optional<User> optionalUser = userRepository.findByEmail(deleteUserDto.getEmail());
|
||||
if (optionalUser.isEmpty()) {
|
||||
log.error("존재하지 않는 이메일 입니다. :: {}", deleteUserDto);
|
||||
throw new NotFoundEmailException();
|
||||
}
|
||||
|
||||
User user = optionalUser.get();
|
||||
return user.delete(deleteUserDto);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public User changePassword(@Valid ChangePasswordDTO changePasswordDto) {
|
||||
Optional<User> optionalUser = userRepository.findByEmailAndIsDeletedFalse(changePasswordDto.getEmail());
|
||||
if (optionalUser.isEmpty()) {
|
||||
log.error("존재하지 않는 이메일 입니다. :: {}", changePasswordDto);
|
||||
throw new NotFoundEmailException();
|
||||
}
|
||||
|
||||
User user = optionalUser.get();
|
||||
return user.changePassword(changePasswordDto);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.ticketing.server.user.service.dto;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
public class ChangePasswordDTO implements PasswordMatches {
|
||||
|
||||
public ChangePasswordDTO(String email, String oldPassword, String newPassword, PasswordEncoder passwordEncoder) {
|
||||
this.email = email;
|
||||
this.oldPassword = oldPassword;
|
||||
this.newPassword = newPassword;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.email}")
|
||||
@Email(message = "{validation.email}")
|
||||
private String email;
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.oldpassword}")
|
||||
private String oldPassword;
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.newpassword}")
|
||||
private String newPassword;
|
||||
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passwordMatches(String password) {
|
||||
return passwordEncoder.matches(oldPassword, password);
|
||||
}
|
||||
|
||||
public String getEncodePassword() {
|
||||
return passwordEncoder.encode(newPassword);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChangePassword{" +
|
||||
"email='" + email + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ticketing.server.user.service.dto;
|
||||
|
||||
import javax.validation.constraints.Email;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
public class DeleteUserDTO implements PasswordMatches {
|
||||
|
||||
public DeleteUserDTO(String email, String inputPassword, PasswordEncoder passwordEncoder) {
|
||||
this.email = email;
|
||||
this.inputPassword = inputPassword;
|
||||
this.passwordEncoder = passwordEncoder;
|
||||
}
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.email}")
|
||||
@Email(message = "{validation.email}")
|
||||
private String email;
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.password}")
|
||||
private String inputPassword;
|
||||
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public boolean passwordMatches(String password) {
|
||||
return passwordEncoder.matches(this.inputPassword, password);
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeleteUser{" +
|
||||
"email='" + email + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.ticketing.server.user.service.dto;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface PasswordMatches {
|
||||
|
||||
boolean passwordMatches(String password);
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import javax.validation.constraints.NotEmpty;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class SignUp {
|
||||
public class SignUpDTO {
|
||||
|
||||
@NotEmpty(message = "{validation.not.empty.name}")
|
||||
private String name;
|
||||
@@ -24,7 +24,7 @@ public class SignUp {
|
||||
@Phone
|
||||
private String phone;
|
||||
|
||||
public SignUp(String name, String email, String password, String phone) {
|
||||
public SignUpDTO(String name, String email, String password, String phone) {
|
||||
this.name = name;
|
||||
this.email = email;
|
||||
this.password = password;
|
||||
@@ -1,12 +1,17 @@
|
||||
package com.ticketing.server.user.service.interfaces;
|
||||
|
||||
import com.ticketing.server.user.domain.User;
|
||||
import com.ticketing.server.user.service.dto.SignUp;
|
||||
import java.util.Optional;
|
||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||
import com.ticketing.server.user.service.dto.SignUpDTO;
|
||||
import javax.validation.Valid;
|
||||
|
||||
public interface UserService {
|
||||
|
||||
Optional<User> register(@Valid SignUp signUpDto);
|
||||
User register(@Valid SignUpDTO signUpDto);
|
||||
|
||||
User delete(@Valid DeleteUserDTO deleteUserDto);
|
||||
|
||||
User changePassword(@Valid ChangePasswordDTO changePasswordDto);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
validation.not.empty.name="\uC774\uB984\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.email="\uC774\uBA54\uC77C\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.password="\uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.oldpassword="\uD604\uC7AC \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.newpassword="\uBCC0\uACBD\uD560 \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.grade="\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
validation.not.empty.name="name is required."
|
||||
validation.not.empty.email="email is required."
|
||||
validation.not.empty.password="password is required."
|
||||
validation.not.empty.oldpassword="Old Password is required."
|
||||
validation.not.empty.newpassword="New Password is required."
|
||||
validation.not.empty.grade="user grade is required."
|
||||
validation.not.empty.phone="phone is required."
|
||||
validation.email="email is not valid."
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
validation.not.empty.name="\uC774\uB984\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.email="\uC774\uBA54\uC77C\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.password="\uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.oldpassword="\uD604\uC7AC \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.newpassword="\uBCC0\uACBD\uD560 \uD328\uC2A4\uC6CC\uB4DC\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.grade="\uC0AC\uC6A9\uC790 \uB4F1\uAE09\uC740 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.not.empty.phone="\uD734\uB300\uBC88\uD638\uB294 \uD544\uC218 \uC785\uB2C8\uB2E4."
|
||||
validation.email="\uC774\uBA54\uC77C\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.ticketing.server.movie.domain;
|
||||
|
||||
public class MovieTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.ticketing.server.movie.domain.Movie;
|
||||
import java.util.Optional;
|
||||
import javax.transaction.Transactional;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestMethodOrder;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.annotation.Rollback;
|
||||
|
||||
@SpringBootTest
|
||||
@Transactional
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class MovieRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
MovieRepository movieRepository;
|
||||
|
||||
@Order(1)
|
||||
@Test
|
||||
@Rollback(value = false)
|
||||
@DisplayName("Movie Repository - test saving movie")
|
||||
void shouldAbleToSaveMovie() {
|
||||
// given
|
||||
Movie movie = new Movie("범죄도시 2", 106);
|
||||
|
||||
// when
|
||||
Movie savedMovie = movieRepository.save(movie);
|
||||
|
||||
// then
|
||||
assertEquals(movie.getTitle(), savedMovie.getTitle());
|
||||
}
|
||||
|
||||
@Order(2)
|
||||
@Test
|
||||
@DisplayName("Movie Repository Test - finding movie with title")
|
||||
void ShouldAbleToFindMovieWithTitle() {
|
||||
// given, when
|
||||
Optional<Movie> optionalMovie = movieRepository.findByTitle("범죄도시 2");
|
||||
|
||||
// then
|
||||
assertTrue(optionalMovie.isPresent());
|
||||
}
|
||||
|
||||
@Order(3)
|
||||
@Test
|
||||
@DisplayName("Movie Repository Test - finding movie that doesn't exist")
|
||||
void ShouldNotAbleToFindMovie() {
|
||||
// given, when
|
||||
Optional<Movie> optionalMovie = movieRepository.findByTitle("존재하지 않는 영화");
|
||||
|
||||
// then
|
||||
assertFalse(optionalMovie.isPresent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
public class MovieTimesRepositoryTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
public class SeatRepositoryTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.ticketing.server.movie.domain.Theater;
|
||||
import javax.transaction.Transactional;
|
||||
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;
|
||||
|
||||
@SpringBootTest
|
||||
@Transactional
|
||||
public class TheaterRepositoryTest {
|
||||
|
||||
@Autowired
|
||||
TheaterRepository theaterRepository;
|
||||
|
||||
@Test
|
||||
@DisplayName("Theater Repository Test - saving theater")
|
||||
void ShouldAbleToSaveTheater() {
|
||||
// given
|
||||
Theater theater = new Theater(1, 100);
|
||||
|
||||
// when
|
||||
Theater savedTheater = theaterRepository.save(theater);
|
||||
|
||||
// then
|
||||
assertEquals(theater.getTheaterNumber(), savedTheater.getTheaterNumber());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.ticketing.server.movie.domain.repository;
|
||||
|
||||
public class TicketRepositoryTest {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.ticketing.server.movie.service;
|
||||
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
public class MovieServiceImplTest {
|
||||
|
||||
}
|
||||
@@ -1,8 +1,18 @@
|
||||
package com.ticketing.server.user.domain;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
|
||||
import com.ticketing.server.global.exception.AlreadyDeletedException;
|
||||
import com.ticketing.server.global.exception.PasswordMismatchException;
|
||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDtoTest;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
@@ -11,26 +21,98 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.NullAndEmptySource;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
class UserTest {
|
||||
|
||||
private static Validator validator;
|
||||
private Validator validator;
|
||||
private Map<String, User> users;
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
|
||||
validator = factory.getValidator();
|
||||
users = provideCorrectUsers().collect(Collectors.toMap(User::getEmail, user -> user));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideDifferentPasswordDeleteUsers")
|
||||
@DisplayName("입력된 패스워드가 다를 경우")
|
||||
void passwordMismatchException(DeleteUserDTO deleteUser) {
|
||||
// given
|
||||
User user = users.get(deleteUser.getEmail());
|
||||
|
||||
// when
|
||||
// then
|
||||
assertThatThrownBy(() -> user.delete(deleteUser))
|
||||
.isInstanceOf(PasswordMismatchException.class);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideDeleteUsers")
|
||||
@DisplayName("이미 회원탈퇴 되어 있는 경우")
|
||||
void alreadyDeletedException(DeleteUserDTO deleteUserDto) {
|
||||
// given
|
||||
User user = users.get(deleteUserDto.getEmail());
|
||||
|
||||
// when
|
||||
user.delete(deleteUserDto);
|
||||
|
||||
// then
|
||||
assertThatThrownBy(() -> user.delete(deleteUserDto))
|
||||
.isInstanceOf(AlreadyDeletedException.class);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideDeleteUsers")
|
||||
@DisplayName("회원탈퇴 성공")
|
||||
void deleteSuccess(DeleteUserDTO deleteUserDto) {
|
||||
// given
|
||||
User user = users.get(deleteUserDto.getEmail());
|
||||
|
||||
// when
|
||||
User deletedUser = user.delete(deleteUserDto);
|
||||
|
||||
// then
|
||||
assertAll(
|
||||
() -> assertThat(deletedUser.getDeletedAt()).isNotNull()
|
||||
, () -> assertThat(deletedUser.isDeleted()).isTrue()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("유저 검증 성공")
|
||||
void validateSuccess() {
|
||||
@DisplayName("입력받은 패스워드와 불일치로 변경 실패")
|
||||
void changePasswordFail() {
|
||||
// given
|
||||
User user = new User("유저1", "email@gmail.com", "testPassword01", UserGrade.GUEST, "010-1234-5678");
|
||||
ChangePasswordDTO changePasswordDto = new ChangePasswordDTO("ticketing1@gmail.com", "1234567", "ticketing1234", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER);
|
||||
User user = users.get(changePasswordDto.getEmail());
|
||||
|
||||
// when
|
||||
// then
|
||||
assertThatThrownBy(() -> user.changePassword(changePasswordDto))
|
||||
.isInstanceOf(PasswordMismatchException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("패스워드 변경 성공")
|
||||
void changePasswordSuccess() {
|
||||
// given
|
||||
ChangePasswordDTO changePasswordDto = new ChangePasswordDTO("ticketing1@gmail.com", "123456", "ticketing1234", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER);
|
||||
User user = users.get(changePasswordDto.getEmail());
|
||||
String oldPassword = user.getPassword();
|
||||
|
||||
// when
|
||||
User modifiedUser = user.changePassword(changePasswordDto);
|
||||
|
||||
// then
|
||||
assertThat(modifiedUser.getPassword()).isNotEqualTo(oldPassword);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideCorrectUsers")
|
||||
@DisplayName("유저 검증 성공")
|
||||
void validateSuccess(User user) {
|
||||
// given
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -39,12 +121,10 @@ class UserTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullAndEmptySource
|
||||
@MethodSource("provideNullOrEmptyOfName")
|
||||
@DisplayName("name null 혹은 빈값 검증")
|
||||
void nameNullOrEmpty(String name) {
|
||||
void nameNullOrEmpty(User user) {
|
||||
// given
|
||||
User user = new User(name, "email@gmail.com", "testPassword01", UserGrade.GUEST, "010-1234-5678");
|
||||
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -53,12 +133,10 @@ class UserTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullAndEmptySource
|
||||
@MethodSource("provideNullOrEmptyOfEmail")
|
||||
@DisplayName("email null or empty 검증")
|
||||
void emailNullOrEmpty(String email) {
|
||||
void emailNullOrEmpty(User user) {
|
||||
// given
|
||||
User user = new User("유저1", email, "testPassword01", UserGrade.GUEST, "010-1234-5678");
|
||||
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -67,12 +145,10 @@ class UserTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {"email", "@hello.com", "12Bye#domain.com"})
|
||||
@MethodSource("provideValidationFailedOfEmail")
|
||||
@DisplayName("email 실패 검증")
|
||||
void emailValid(String email) {
|
||||
void emailValid(User user) {
|
||||
// given
|
||||
User user = new User("유저1", email, "testPassword01", UserGrade.GUEST, "010-1234-5678");
|
||||
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -81,12 +157,10 @@ class UserTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@NullAndEmptySource
|
||||
@MethodSource("provideNullOrEmptyOfPassword")
|
||||
@DisplayName("password null 혹은 빈값 검증")
|
||||
void passwordNullOrEmpty(String password) {
|
||||
void passwordNullOrEmpty(User user) {
|
||||
// given
|
||||
User user = new User("유저1", "email@gmail.com", password, UserGrade.GUEST, "010-1234-5678");
|
||||
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -108,12 +182,10 @@ class UserTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideNullOrEmptyOfPhone")
|
||||
@DisplayName("phone null or empty 검증")
|
||||
@NullAndEmptySource
|
||||
void phoneNullOrEmpty(String phone) {
|
||||
void phoneNullOrEmpty(User user) {
|
||||
// given
|
||||
User user = new User("유저1", "email@gmail.com", "testPassword01", UserGrade.GUEST, phone);
|
||||
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -122,12 +194,10 @@ class UserTest {
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("provideValidationFailedOfPhone")
|
||||
@DisplayName("phone 실패 검증")
|
||||
@ValueSource(strings = {"010-123-1234", "02-0444-4044", "033-7953", "033-0455-504"})
|
||||
void phoneValid(String phone) {
|
||||
void phoneValid(User user) {
|
||||
// given
|
||||
User user = new User("유저1", "email@gmail.com", "testPassword01", UserGrade.GUEST, phone);
|
||||
|
||||
// when
|
||||
Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);
|
||||
|
||||
@@ -135,4 +205,76 @@ class UserTest {
|
||||
assertThat(constraintViolations).hasSize(1);
|
||||
}
|
||||
|
||||
public static Stream<User> provideCorrectUsers() {
|
||||
return Stream.of(
|
||||
new User("유저1", "ticketing1@gmail.com", "123456", UserGrade.GUEST, "010-1234-5678")
|
||||
, new User("유저2", "ticketing2@gmail.com", "qwe123", UserGrade.GUEST, "010-2234-5678")
|
||||
, new User("유저3", "ticketing3@gmail.com", "ticketing", UserGrade.STAFF, "010-3234-5678")
|
||||
, new User("유저4", "ticketing4@gmail.com", "ticketing123456", UserGrade.STAFF, "010-4234-5678")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<User> provideNullOrEmptyOfName() {
|
||||
return Stream.of(
|
||||
new User(null, "ticketing1@gmail.com", "123456", UserGrade.GUEST, "010-1234-5678")
|
||||
, new User("", "ticketing2@gmail.com", "qwe123", UserGrade.GUEST, "010-2234-5678")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<User> provideNullOrEmptyOfEmail() {
|
||||
return Stream.of(
|
||||
new User("유저1", null, "123456", UserGrade.GUEST, "010-1234-5678")
|
||||
, new User("유저2", "", "qwe123", UserGrade.GUEST, "010-2234-5678")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<User> provideValidationFailedOfEmail() {
|
||||
return Stream.of(
|
||||
new User("유저1", "email", "123456", UserGrade.GUEST, "010-1234-5678")
|
||||
, new User("유저2", "@gmail.com", "qwe123", UserGrade.GUEST, "010-2234-5678")
|
||||
, new User("유저3", "12Bye#domain.com", "ticketing", UserGrade.STAFF, "010-3234-5678")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<User> provideNullOrEmptyOfPassword() {
|
||||
return Stream.of(
|
||||
new User("유저1", "ticketing1@gmail.com", null, UserGrade.GUEST, "010-1234-5678")
|
||||
, new User("유저2", "ticketing2@gmail.com", "", UserGrade.GUEST, "010-2234-5678")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<User> provideNullOrEmptyOfPhone() {
|
||||
return Stream.of(
|
||||
new User("유저1", "ticketing1@gmail.com", "123456", UserGrade.GUEST, null)
|
||||
, new User("유저2", "ticketing2@gmail.com", "qwe123", UserGrade.GUEST, "")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<User> provideValidationFailedOfPhone() {
|
||||
return Stream.of(
|
||||
new User("유저1", "ticketing1@gmail.com", "123456", UserGrade.GUEST, "010-123-1234")
|
||||
, new User("유저2", "ticketing2@gmail.com", "qwe123", UserGrade.GUEST, "02-0444-4044")
|
||||
, new User("유저3", "ticketing3@gmail.com", "ticketing", UserGrade.STAFF, "033-7953")
|
||||
, new User("유저4", "ticketing4@gmail.com", "ticketing123456", UserGrade.STAFF, "033-0455-504")
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<DeleteUserDTO> provideDifferentPasswordDeleteUsers() {
|
||||
return Stream.of(
|
||||
new DeleteUserDTO("ticketing1@gmail.com", "1234561", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
, new DeleteUserDTO("ticketing2@gmail.com", "qwe1231", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
, new DeleteUserDTO("ticketing3@gmail.com", "ticketing1", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
, new DeleteUserDTO("ticketing4@gmail.com", "ticketing1234561", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
);
|
||||
}
|
||||
|
||||
public static Stream<DeleteUserDTO> provideDeleteUsers() {
|
||||
return Stream.of(
|
||||
new DeleteUserDTO("ticketing1@gmail.com", "123456", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
, new DeleteUserDTO("ticketing2@gmail.com", "qwe123", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
, new DeleteUserDTO("ticketing3@gmail.com", "ticketing", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
, new DeleteUserDTO("ticketing4@gmail.com", "ticketing123456", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
package com.ticketing.server.user.service;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.ticketing.server.global.exception.NotFoundEmailException;
|
||||
import com.ticketing.server.user.domain.User;
|
||||
import com.ticketing.server.user.domain.UserGrade;
|
||||
import com.ticketing.server.user.domain.repository.UserRepository;
|
||||
import com.ticketing.server.user.service.dto.SignUp;
|
||||
import com.ticketing.server.user.service.dto.ChangePasswordDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDTO;
|
||||
import com.ticketing.server.user.service.dto.DeleteUserDtoTest;
|
||||
import com.ticketing.server.user.service.dto.SignUpDTO;
|
||||
import java.util.Optional;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
@@ -21,7 +26,9 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
class UserServiceImplTest {
|
||||
|
||||
User user;
|
||||
SignUp signUp;
|
||||
SignUpDTO signUpDto;
|
||||
DeleteUserDTO deleteUserDto;
|
||||
ChangePasswordDTO changePasswordDto;
|
||||
|
||||
@Mock
|
||||
UserRepository userRepository;
|
||||
@@ -31,9 +38,10 @@ class UserServiceImplTest {
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
|
||||
signUp = new SignUp("유저", "ticketing@gmail.com", "123456", "010-1234-5678");
|
||||
signUpDto = new SignUpDTO("유저", "ticketing@gmail.com", "123456", "010-1234-5678");
|
||||
user = new User("유저", "ticketing@gmail.com", "123456", UserGrade.GUEST, "010-1234-5678");
|
||||
deleteUserDto = new DeleteUserDTO("ticketing@gmail.com", "123456", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER);
|
||||
changePasswordDto = new ChangePasswordDTO("ticketing@gmail.com", "123456", "ticketing1234", DeleteUserDtoTest.CUSTOM_PASSWORD_ENCODER);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -43,24 +51,73 @@ class UserServiceImplTest {
|
||||
when(userRepository.findByEmail("ticketing@gmail.com")).thenReturn(Optional.of(user));
|
||||
|
||||
// when
|
||||
Optional<User> user = userService.register(signUp);
|
||||
|
||||
// then
|
||||
assertThat(user).isEmpty();
|
||||
assertThatThrownBy(() -> userService.register(signUpDto))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("회원가입 성공했을 경우")
|
||||
void UserServiceImplTest() {
|
||||
void registerSuccess() {
|
||||
// given
|
||||
when(userRepository.findByEmail("ticketing@gmail.com")).thenReturn(Optional.empty());
|
||||
when(userRepository.save(any())).thenReturn(user);
|
||||
|
||||
// when
|
||||
Optional<User> user = userService.register(signUp);
|
||||
User user = userService.register(signUpDto);
|
||||
|
||||
// then
|
||||
assertThat(user).isPresent();
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("회원탈퇴 시 이메일이 존재하지 않을 경우")
|
||||
void deleteFail() {
|
||||
// given
|
||||
when(userRepository.findByEmail("ticketing@gmail.com")).thenReturn(Optional.empty());
|
||||
|
||||
// when
|
||||
// then
|
||||
assertThatThrownBy(() -> userService.delete(deleteUserDto))
|
||||
.isInstanceOf(NotFoundEmailException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("회원탈퇴 성공했을 경우")
|
||||
void deleteSuccess() {
|
||||
// given
|
||||
when(userRepository.findByEmail("ticketing@gmail.com")).thenReturn(Optional.of(user));
|
||||
|
||||
// when
|
||||
User user = userService.delete(deleteUserDto);
|
||||
|
||||
// then
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("패스워드 변경 시 이메일이 존재하지 않을 경우")
|
||||
void changePasswordFail() {
|
||||
// given
|
||||
when(userRepository.findByEmailAndIsDeletedFalse("ticketing@gmail.com")).thenReturn(Optional.empty());
|
||||
|
||||
// when
|
||||
// then
|
||||
assertThatThrownBy(() -> userService.changePassword(changePasswordDto))
|
||||
.isInstanceOf(NotFoundEmailException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("패스워드 변경 성공했을 경우")
|
||||
void changePasswordSuccess() {
|
||||
// given
|
||||
when(userRepository.findByEmailAndIsDeletedFalse("ticketing@gmail.com")).thenReturn(Optional.of(user));
|
||||
|
||||
// when
|
||||
User user = userService.changePassword(changePasswordDto);
|
||||
|
||||
// then
|
||||
assertThat(user).isNotNull();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ticketing.server.user.service.dto;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
public class DeleteUserDtoTest {
|
||||
|
||||
public static PasswordEncoder CUSTOM_PASSWORD_ENCODER = new CustomPasswordEncoder();
|
||||
|
||||
public static class CustomPasswordEncoder implements PasswordEncoder {
|
||||
|
||||
@Override
|
||||
public String encode(CharSequence rawPassword) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||
return rawPassword.toString().equals(encodedPassword);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("CustomPasswordEncoder matches 테스트")
|
||||
void customPasswordEncoderMatches() {
|
||||
// given
|
||||
DeleteUserDTO deleteUserDto = new DeleteUserDTO("ticketing@gmail.com", "123456", CUSTOM_PASSWORD_ENCODER);
|
||||
|
||||
// when
|
||||
// then
|
||||
assertThat(deleteUserDto.passwordMatches("123456")).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,13 +6,13 @@ import com.ticketing.server.user.domain.User;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class SignUpTest {
|
||||
class SignUpDtoTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("toUser 메소드로 User 객체 생성")
|
||||
void toUser() {
|
||||
// given
|
||||
SignUp signUp = new SignUp("유저1", "ticketing@gmail.com", "123456", "010-1234-5678");
|
||||
SignUpDTO signUp = new SignUpDTO("유저1", "ticketing@gmail.com", "123456", "010-1234-5678");
|
||||
|
||||
// when
|
||||
User user = signUp.toUser();
|
||||
Reference in New Issue
Block a user