diff --git a/build.gradle b/build.gradle
index e5ec1a5..3b55e26 100644
--- a/build.gradle
+++ b/build.gradle
@@ -27,6 +27,7 @@ dependencies {
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
+ implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
diff --git a/readme.md b/readme.md
index 0e8875a..640e832 100644
--- a/readme.md
+++ b/readme.md
@@ -28,18 +28,18 @@
#### 패키지 구조
```text
├── controller
-│ └── UserController.java
+│ └── MemberController.java
├── domain
-│ ├── User.java
-│ ├── UserLevel.java
-│ └── UserType.java
+│ ├── Member.java
+│ ├── MemberLevel.java
+│ └── MemberType.java
├── repository
-│ └── UserRepository.java
+│ └── MemberRepository.java
└── service
- └── UserService.java
+ └── MemberService.java
```
-* 모든 도메인 패키지 구조는 다음을 따릅니다. (예시 : `user` 도메인)
+* 모든 도메인 패키지 구조는 다음을 따릅니다. (예시 : `Member` 도메인)
* 각 패키지 내부의 클래스들은 예시일 뿐 얼마든지 클래스를 추가로 생성하셔도 됩니다.
### 유저 도메인을 완성해봅시다.
@@ -49,8 +49,8 @@
| username | 사용자 아이디 | 사용자 로그인 아이디 |
| password | 사용자 비밀번호 | 사용자 비밀번호 |
| nickname | 사용자 닉네임 | 사용자 닉네임 |
-| userLevel | 사용자 등급 | 사용자 등급 |
-| type | 사용자 유형 | 사용자 유형으로 ADMIN, USER가 존재 |
+| MemberLevel | 사용자 등급 | 사용자 등급 |
+| type | 사용자 유형 | 사용자 유형으로 ADMIN, Member가 존재 |
| createdAt | 생성 일시 | 사용자 최초 생성 일시 |
| lastModifiedAt | 최종 수정 일시 | 사용자 최종 수정 일시 |
* 사용자는 `회원가입`이 가능합니다.
@@ -62,7 +62,7 @@
* BRONZE, SILVER, GOLD가 존재하며 추후 주문 시 결제 금액 할인이 가능합니다.
* 5번 구매를 하면 SILVER, 10번 구매를 하면 GOLD로 등급업이 됩니다.
* 사용자 별 `타입(type)`이 존재합니다.
- * USER : 일반유저로 상품을 구매는 가능하지만 추가할 수 없습니다.
+ * Member : 일반유저로 상품을 구매는 가능하지만 추가할 수 없습니다.
* ADMIN : 관리자로 상품을 구매와 추가 모두 가능합니다.
@@ -93,7 +93,7 @@
| 변수명 | 필드명 | 설명 |
|----------------|----------|------------|
| id | 주문 아이디 | 주문 엔티티 식별자 |
-| userId | 유저 아이디 | 유저 엔티티 식별자 |
+| MemberId | 유저 아이디 | 유저 엔티티 식별자 |
| orderProducts | 주문 상품 정보 | 주문의 상품의 정보 |
| price | 총 주문 가격 | 총 주문 가격 |
| orderStatus | 주문 상태 | 주문 상태 |
diff --git a/src/main/java/com/swger/tddstudy/member/controller/MemberController.java b/src/main/java/com/swger/tddstudy/member/controller/MemberController.java
new file mode 100644
index 0000000..ff02db2
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/controller/MemberController.java
@@ -0,0 +1,44 @@
+package com.swger.tddstudy.member.controller;
+
+import com.swger.tddstudy.member.domain.Member;
+import com.swger.tddstudy.member.domain.DTO.MemberDTO;
+import com.swger.tddstudy.member.domain.DTO.MemberSignInDTO;
+import com.swger.tddstudy.member.repository.MemberRepository;
+import com.swger.tddstudy.member.service.MemberService;
+import javax.servlet.http.HttpSession;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.BindException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequiredArgsConstructor
+public class MemberController {
+
+ private final MemberService memberService;
+
+ @PostMapping("/signUp")
+ public String signUp(@Validated @RequestBody MemberDTO memberDTO, BindingResult bindingResult)
+ throws Exception {
+ if (bindingResult.hasErrors()) {
+ throw new BindException(bindingResult);
+ }
+ memberService.SignUp(memberDTO);
+ return "signUpOK";
+ }
+
+ @PostMapping("/logIn")
+ public String logIn(@Validated @RequestBody MemberSignInDTO memberSignInDTO,
+ BindingResult bindingResult, HttpSession session) throws Exception {
+ if (bindingResult.hasErrors()) {
+ throw new BindException(bindingResult);
+ }
+ Member member = memberService.SignIn(memberSignInDTO);
+ session.setAttribute("id", member.getId());
+ return "LogInOK";
+ }
+
+}
diff --git a/src/main/java/com/swger/tddstudy/member/domain/DTO/MemberDTO.java b/src/main/java/com/swger/tddstudy/member/domain/DTO/MemberDTO.java
new file mode 100644
index 0000000..85370e0
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/domain/DTO/MemberDTO.java
@@ -0,0 +1,25 @@
+package com.swger.tddstudy.member.domain.DTO;
+
+import lombok.Getter;
+
+import javax.validation.constraints.NotBlank;
+
+@Getter
+public class MemberDTO {
+ @NotBlank
+ private String username;
+ @NotBlank
+ private String password;
+ @NotBlank
+ private String nickname;
+ @NotBlank
+ private String rePassword;
+
+ public MemberDTO(String username, String password, String nickname, String rePassword) {
+ this.username = username;
+ this.password = password;
+ this.nickname = nickname;
+ this.rePassword = rePassword;
+ }
+ public MemberDTO(){}
+}
diff --git a/src/main/java/com/swger/tddstudy/member/domain/DTO/MemberSignInDTO.java b/src/main/java/com/swger/tddstudy/member/domain/DTO/MemberSignInDTO.java
new file mode 100644
index 0000000..2887370
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/domain/DTO/MemberSignInDTO.java
@@ -0,0 +1,20 @@
+package com.swger.tddstudy.member.domain.DTO;
+
+import lombok.Getter;
+
+import javax.validation.constraints.NotBlank;
+
+@Getter
+public class MemberSignInDTO {
+
+ @NotBlank
+ private String username;
+ @NotBlank
+ private String password;
+
+ public MemberSignInDTO(String username, String password) {
+ this.username = username;
+ this.password = password;
+ }
+ public MemberSignInDTO(){}
+}
diff --git a/src/main/java/com/swger/tddstudy/member/domain/Member.java b/src/main/java/com/swger/tddstudy/member/domain/Member.java
new file mode 100644
index 0000000..3555636
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/domain/Member.java
@@ -0,0 +1,61 @@
+package com.swger.tddstudy.member.domain;
+
+import com.swger.tddstudy.member.domain.DTO.MemberDTO;
+import com.swger.tddstudy.util.BaseEntity;
+
+import javax.persistence.*;
+import javax.validation.constraints.NotBlank;
+
+import lombok.Getter;
+
+@Getter
+@Entity
+public class Member extends BaseEntity {
+
+ @Id @GeneratedValue
+ private Long id;
+
+ @NotBlank
+ private String username;
+
+ @NotBlank
+ private String password;
+
+ @NotBlank
+ private String nickname;
+
+ @Enumerated(EnumType.STRING)
+ private MemberLevel memberLevel;
+
+ @Enumerated(EnumType.STRING)
+ private MemberType memberType;
+
+ public Member(String username, String password, String nickname) {
+ this.username = username;
+ this.password = password;
+ this.nickname = nickname;
+ this.memberLevel = MemberLevel.BRONZE;
+ this.memberType = MemberType.Member;
+ }
+ public Member(){}
+
+ public Member(MemberDTO memberDTO){
+ this.username = memberDTO.getUsername();
+ this.password = memberDTO.getPassword();
+ this.nickname = memberDTO.getNickname();
+ this.memberLevel = MemberLevel.BRONZE;
+ this.memberType = MemberType.Member;
+ }
+ public void AdminMember(){
+ this.memberType = MemberType.ADMIN;
+ }
+ public void LevelUp() {
+ if (this.getMemberLevel().equals(MemberLevel.SILVER)) {
+ this.memberLevel = MemberLevel.GOLD;
+ }
+ if (this.getMemberLevel().equals(MemberLevel.BRONZE)) {
+ this.memberLevel = MemberLevel.SILVER;
+ }
+ }
+
+}
diff --git a/src/main/java/com/swger/tddstudy/user/domain/UserLevel.java b/src/main/java/com/swger/tddstudy/member/domain/MemberLevel.java
similarity index 70%
rename from src/main/java/com/swger/tddstudy/user/domain/UserLevel.java
rename to src/main/java/com/swger/tddstudy/member/domain/MemberLevel.java
index 4f9e926..9a884b6 100644
--- a/src/main/java/com/swger/tddstudy/user/domain/UserLevel.java
+++ b/src/main/java/com/swger/tddstudy/member/domain/MemberLevel.java
@@ -1,9 +1,9 @@
-package com.swger.tddstudy.user.domain;
+package com.swger.tddstudy.member.domain;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
-public enum UserLevel {
+public enum MemberLevel {
BRONZE("브론즈"), SILVER("실버"), GOLD("골드");
diff --git a/src/main/java/com/swger/tddstudy/member/domain/MemberType.java b/src/main/java/com/swger/tddstudy/member/domain/MemberType.java
new file mode 100644
index 0000000..9e86662
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/domain/MemberType.java
@@ -0,0 +1,12 @@
+package com.swger.tddstudy.member.domain;
+
+import lombok.RequiredArgsConstructor;
+
+@RequiredArgsConstructor
+public enum MemberType {
+
+ Member("일반회원"), ADMIN("관리자");
+
+ private final String text;
+
+}
diff --git a/src/main/java/com/swger/tddstudy/member/repository/MemberRepository.java b/src/main/java/com/swger/tddstudy/member/repository/MemberRepository.java
new file mode 100644
index 0000000..9d5d52e
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/repository/MemberRepository.java
@@ -0,0 +1,14 @@
+package com.swger.tddstudy.member.repository;
+
+import com.swger.tddstudy.member.domain.Member;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+import java.util.Optional;
+
+public interface MemberRepository extends JpaRepository {
+ Optional findByUsername(String username);
+
+ @Override
+ S save(S entity);
+}
diff --git a/src/main/java/com/swger/tddstudy/member/service/MemberService.java b/src/main/java/com/swger/tddstudy/member/service/MemberService.java
new file mode 100644
index 0000000..8864ed5
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/member/service/MemberService.java
@@ -0,0 +1,48 @@
+package com.swger.tddstudy.member.service;
+
+import com.swger.tddstudy.member.domain.Member;
+import com.swger.tddstudy.member.domain.DTO.MemberDTO;
+import com.swger.tddstudy.member.domain.DTO.MemberSignInDTO;
+import com.swger.tddstudy.member.domain.MemberLevel;
+import com.swger.tddstudy.member.domain.MemberType;
+import com.swger.tddstudy.member.repository.MemberRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+
+@Service
+@Transactional
+@RequiredArgsConstructor
+public class MemberService {
+ private final MemberRepository memberRepository;
+ public Member join(Member member){
+ memberRepository.save(member);
+ return member;
+ }
+ public Member SignUp(MemberDTO member){
+ if(!member.getPassword().equals(member.getRePassword())){
+ throw new IllegalArgumentException("RePassword Mismatch");
+ }
+ Member signUpMember = new Member(member);
+ join(signUpMember);
+ return signUpMember;
+ }
+ public Member SignUpAdmin(MemberDTO member){
+ if(!member.getPassword().equals(member.getRePassword())){
+ throw new IllegalArgumentException("RePassword Mismatch");
+ }
+ Member signUpMember = new Member(member);
+ signUpMember.AdminMember();
+ join(signUpMember);
+ return signUpMember;
+ }
+ public Member SignIn(MemberSignInDTO member){
+ Member signInMember = memberRepository.findByUsername(member.getUsername()).orElseThrow(() -> new IllegalArgumentException("Username Mismatch"));
+ if (!signInMember.getPassword().equals(member.getPassword())) {
+ throw new IllegalArgumentException("Password Mismatch");
+ }
+ return signInMember;
+ }
+
+}
diff --git a/src/main/java/com/swger/tddstudy/order/domain/Order.java b/src/main/java/com/swger/tddstudy/order/domain/Order.java
index 3267f59..bc978f1 100644
--- a/src/main/java/com/swger/tddstudy/order/domain/Order.java
+++ b/src/main/java/com/swger/tddstudy/order/domain/Order.java
@@ -2,7 +2,7 @@
import com.swger.tddstudy.orderProduct.domain.OrderProduct;
import com.swger.tddstudy.util.BaseEntity;
-import com.swger.tddstudy.user.domain.User;
+import com.swger.tddstudy.member.domain.Member;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
@@ -26,13 +26,13 @@ public class Order extends BaseEntity {
private Long id;
@ManyToOne
- private User user;
+ private Member Member;
@OneToMany(mappedBy = "order", cascade = CascadeType.ALL)
private List orderProducts;
private int price;
- @Enum태erated(EnumType.STRING)
+ @Enumerated(EnumType.STRING)
private OrderStatus orderStatus;
}
diff --git a/src/main/java/com/swger/tddstudy/product/controller/ProductController.java b/src/main/java/com/swger/tddstudy/product/controller/ProductController.java
new file mode 100644
index 0000000..acaa73f
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/product/controller/ProductController.java
@@ -0,0 +1,43 @@
+package com.swger.tddstudy.product.controller;
+
+import com.swger.tddstudy.member.domain.MemberType;
+import com.swger.tddstudy.member.repository.MemberRepository;
+import com.swger.tddstudy.member.service.MemberService;
+import com.swger.tddstudy.product.domain.DTO.ProductRegisterDTO;
+import com.swger.tddstudy.product.service.ProductService;
+import javax.naming.AuthenticationException;
+import javax.servlet.http.HttpSession;
+import lombok.RequiredArgsConstructor;
+import org.hibernate.engine.spi.ManagedEntity;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.BindException;
+import org.springframework.validation.BindingResult;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+public class ProductController {
+
+ private final ProductService productService;
+ private final MemberRepository memberRepository;
+
+ @PostMapping("/productRegister")
+ public String productRegister(@Validated @RequestBody ProductRegisterDTO DTO, BindingResult br,
+ HttpSession httpSession) throws BindException, AuthenticationException {
+ if (br.hasErrors()) throw new BindException(br);
+ productService.register(DTO);
+
+ if (httpSession.getAttribute("id") == null) {
+ throw new AuthenticationException("You must SignIn");
+ }
+
+ if(!memberRepository.findById((Long) httpSession.getAttribute("id"))
+ .get().getMemberType().equals(MemberType.ADMIN)){
+ throw new AuthenticationException("You are not Admin");
+ }
+ return "Register OK";
+ }
+}
diff --git a/src/main/java/com/swger/tddstudy/product/controller/ProductControllerAdvice.java b/src/main/java/com/swger/tddstudy/product/controller/ProductControllerAdvice.java
new file mode 100644
index 0000000..4820d06
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/product/controller/ProductControllerAdvice.java
@@ -0,0 +1,26 @@
+package com.swger.tddstudy.product.controller;
+
+import javax.naming.AuthenticationException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.BindException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+
+@ControllerAdvice
+public class ProductControllerAdvice {
+
+ @ExceptionHandler
+ public ResponseEntity> bindException(BindException e) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
+ }
+ @ExceptionHandler
+ public ResponseEntity> authenticationException(AuthenticationException e) {
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST)
+ .contentType(MediaType.APPLICATION_JSON)
+ .body(e.getMessage());
+ }
+}
diff --git a/src/main/java/com/swger/tddstudy/product/domain/DTO/ProductRegisterDTO.java b/src/main/java/com/swger/tddstudy/product/domain/DTO/ProductRegisterDTO.java
new file mode 100644
index 0000000..9a53ce1
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/product/domain/DTO/ProductRegisterDTO.java
@@ -0,0 +1,26 @@
+package com.swger.tddstudy.product.domain.DTO;
+
+import lombok.Getter;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+
+@Getter
+public class ProductRegisterDTO {
+ @NotBlank
+ private String name;
+
+ @Min(1000)
+ private int price;
+
+ @Min(1)
+ private int amount;
+
+ public ProductRegisterDTO(String name, int price, int amount) {
+ this.name = name;
+ this.price = price;
+ this.amount = amount;
+ }
+ public ProductRegisterDTO(){}
+
+}
diff --git a/src/main/java/com/swger/tddstudy/product/domain/Product.java b/src/main/java/com/swger/tddstudy/product/domain/Product.java
index e71ebd9..3729658 100644
--- a/src/main/java/com/swger/tddstudy/product/domain/Product.java
+++ b/src/main/java/com/swger/tddstudy/product/domain/Product.java
@@ -1,10 +1,11 @@
package com.swger.tddstudy.product.domain;
import com.swger.tddstudy.util.BaseEntity;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
+
+import javax.persistence.*;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -15,14 +16,56 @@
public class Product extends BaseEntity {
@Id
+ @GeneratedValue
private Long id;
+ @NotBlank
private String name;
+ @Min(1000)
private int price;
+ @Min(1)
private int amount;
@Enumerated(EnumType.STRING)
private SellingStatus sellingStatus;
+
+ public Product(String name, int price, int amount) {
+ this.name = name;
+ this.price = price;
+ this.amount = amount;
+ this.sellingStatus = SellingStatus.SELLING;
+ }
+ public boolean sellProduct(int cnt){
+ /* 사용자가 재고 이상으로 주문 */
+ if (cnt > this.amount) {
+ return false;
+ }
+ /* 사용자가 재고에 맞게 주문 */
+ this.amount -= cnt;
+ return true;
+ }
+ public void sellStop(){
+ this.sellingStatus = SellingStatus.STOP_SELLING;
+ }
+ public void sellStart(){
+ this.sellingStatus = SellingStatus.SELLING;
+ }
+
+ public boolean sellingOrNo() {
+ /* 처음부터 재고 수량 = 0 */
+ if (this.getSellingStatus() == SellingStatus.STOP_SELLING) {
+ return false;
+ }
+ /* 구매 가능 */
+ if (this.getAmount() > 0 && this.getSellingStatus() == SellingStatus.SELLING) {
+ return true;}
+ else {
+ /* 재고수량이 처음으로 0이 되었을 때 */
+ this.sellStop();
+ return false;
+ }
+ }
+
}
diff --git a/src/main/java/com/swger/tddstudy/product/repository/ProductRepository.java b/src/main/java/com/swger/tddstudy/product/repository/ProductRepository.java
new file mode 100644
index 0000000..d1fd632
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/product/repository/ProductRepository.java
@@ -0,0 +1,8 @@
+package com.swger.tddstudy.product.repository;
+
+import com.swger.tddstudy.product.domain.Product;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface ProductRepository extends JpaRepository {
+
+}
diff --git a/src/main/java/com/swger/tddstudy/product/service/ProductService.java b/src/main/java/com/swger/tddstudy/product/service/ProductService.java
new file mode 100644
index 0000000..e4c0938
--- /dev/null
+++ b/src/main/java/com/swger/tddstudy/product/service/ProductService.java
@@ -0,0 +1,24 @@
+package com.swger.tddstudy.product.service;
+
+import com.swger.tddstudy.product.domain.DTO.ProductRegisterDTO;
+import com.swger.tddstudy.product.domain.Product;
+import com.swger.tddstudy.product.domain.SellingStatus;
+import com.swger.tddstudy.product.repository.ProductRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import javax.swing.text.TableView;
+
+@Service
+@RequiredArgsConstructor
+public class ProductService {
+
+ private final ProductRepository productRepository;
+
+ public Product register(ProductRegisterDTO product) {
+ Product save = productRepository.save(new Product(product.getName()
+ , product.getPrice(), product.getAmount()));
+ return save;
+ }
+
+}
diff --git a/src/main/java/com/swger/tddstudy/user/domain/User.java b/src/main/java/com/swger/tddstudy/user/domain/User.java
deleted file mode 100644
index 8df4eaa..0000000
--- a/src/main/java/com/swger/tddstudy/user/domain/User.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package com.swger.tddstudy.user.domain;
-
-import com.swger.tddstudy.util.BaseEntity;
-import javax.persistence.Entity;
-import javax.persistence.EnumType;
-import javax.persistence.Enumerated;
-import javax.persistence.Id;
-import lombok.AccessLevel;
-import lombok.Getter;
-import lombok.NoArgsConstructor;
-
-@Getter
-@NoArgsConstructor(access = AccessLevel.PROTECTED)
-@Entity
-public class User extends BaseEntity {
-
- @Id
- private Long id;
-
- private String username;
-
- private String password;
-
- private String nickname;
-
- @Enumerated(EnumType.STRING)
- private UserLevel userLevel;
-
- @Enumerated(EnumType.STRING)
- private UserType type;
-}
diff --git a/src/main/java/com/swger/tddstudy/user/domain/UserType.java b/src/main/java/com/swger/tddstudy/user/domain/UserType.java
deleted file mode 100644
index 73912c7..0000000
--- a/src/main/java/com/swger/tddstudy/user/domain/UserType.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.swger.tddstudy.user.domain;
-
-import lombok.RequiredArgsConstructor;
-
-@RequiredArgsConstructor
-public enum UserType {
-
- USER("일반회원"), ADMIN("관리자");
-
- private final String text;
-
-}
diff --git a/src/test/java/com/swger/tddstudy/member/MemberControllerTest.java b/src/test/java/com/swger/tddstudy/member/MemberControllerTest.java
new file mode 100644
index 0000000..bf48280
--- /dev/null
+++ b/src/test/java/com/swger/tddstudy/member/MemberControllerTest.java
@@ -0,0 +1,108 @@
+package com.swger.tddstudy.member;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.swger.tddstudy.member.domain.DTO.MemberDTO;
+import com.swger.tddstudy.member.domain.DTO.MemberSignInDTO;
+import com.swger.tddstudy.member.domain.Member;
+import com.swger.tddstudy.member.repository.MemberRepository;
+import com.swger.tddstudy.member.service.MemberService;
+import org.assertj.core.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.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.validation.BindException;
+
+import javax.transaction.Transactional;
+
+
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+@SpringBootTest
+@Transactional
+@AutoConfigureMockMvc
+public class MemberControllerTest {
+ @Autowired
+ MemberRepository memberRepository;
+ @Autowired
+ MemberService memberService;
+ @Autowired
+ private MockMvc mockMvc;
+ @Autowired
+ private ObjectMapper om;
+
+ @DisplayName("회원 가입 성공")
+ @Test
+ public void SignUpSuccess() throws Exception {
+ //given
+ MemberDTO signInMember= new MemberDTO("testUsername",
+ "testPassword", "testNickname", "testPassword");
+ String content = om.writeValueAsString(signInMember);
+ //when
+ mockMvc.perform(post("/signUp")
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string("signUpOK"))
+ .andDo(print());
+ Optional getMember = memberRepository.findByUsername(signInMember.getUsername());
+ //then
+ /* 아이디, 비밀번호 같은지 확인*/
+ Assertions.assertThat(getMember.get().getUsername()).isEqualTo(signInMember.getUsername());
+ Assertions.assertThat(getMember.get().getPassword()).isEqualTo(signInMember.getPassword());
+ }
+
+ @DisplayName("회원가입 실패 - Validation 실패")
+ @Test
+ public void SignUpFail() throws Exception {
+ MemberDTO signInMember= new MemberDTO("testUsername",
+ "testPassword", null, "testPassword");
+ String content = om.writeValueAsString(signInMember);
+ mockMvc.perform(post("/signUp")
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(result -> assertTrue(result.getResolvedException()
+ .getClass().isAssignableFrom(BindException.class)))
+ .andDo(print());
+
+ }
+ @DisplayName("로그인 성공")
+ @Test
+ public void SignInSuccess() throws Exception {
+ memberService.join(new Member("testUsername", "testPassword", "testNickName"));
+ MemberSignInDTO signInMember= new MemberSignInDTO("testUsername","testPassword");
+ String content = om.writeValueAsString(signInMember);
+ mockMvc.perform(post("/logIn")
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string("LogInOK"))
+ .andDo(print());
+ }
+ @DisplayName("로그인 실패 - Vaildation 실패")
+ @Test
+ public void SignInFail() throws Exception {
+ memberService.join(new Member("testUsername", "testPassword", "testNickName"));
+ MemberSignInDTO signInMember= new MemberSignInDTO(null,"testPassword");
+ String content = om.writeValueAsString(signInMember);
+ mockMvc.perform(post("/logIn")
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(result -> assertTrue(result.getResolvedException().getClass().isAssignableFrom(BindException.class)))
+ .andDo(print());
+ }
+
+}
diff --git a/src/test/java/com/swger/tddstudy/member/MemberServiceTest.java b/src/test/java/com/swger/tddstudy/member/MemberServiceTest.java
new file mode 100644
index 0000000..7d410c5
--- /dev/null
+++ b/src/test/java/com/swger/tddstudy/member/MemberServiceTest.java
@@ -0,0 +1,109 @@
+package com.swger.tddstudy.member;
+
+import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
+import com.swger.tddstudy.member.domain.DTO.MemberDTO;
+import com.swger.tddstudy.member.domain.DTO.MemberSignInDTO;
+import com.swger.tddstudy.member.domain.Member;
+import com.swger.tddstudy.member.domain.MemberLevel;
+import com.swger.tddstudy.member.domain.MemberType;
+import com.swger.tddstudy.member.repository.MemberRepository;
+import com.swger.tddstudy.member.service.MemberService;
+import org.assertj.core.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 javax.transaction.Transactional;
+
+@SpringBootTest
+@Transactional
+public class MemberServiceTest {
+ @Autowired
+ MemberService memberService;
+ @Autowired
+ MemberRepository memberRepository;
+
+ @DisplayName("회원가입 성공")
+ @Test
+ public void SignUpSuccessInService(){
+ //given
+ MemberDTO memberDTO = new MemberDTO("testUsername",
+ "testPassword", "testNickname", "testPassword");
+ //when
+ Member member = memberService.SignUp(memberDTO);
+ Member memberInRepos = memberRepository.findById(member.getId()).get();
+ //then
+ Assertions.assertThat(member).extracting(
+ "id", "username", "nickname", "memberLevel", "memberType")
+ .containsExactly(memberInRepos.getId(),
+ memberInRepos.getUsername(),
+ memberInRepos.getNickname(),
+ memberInRepos.getMemberLevel(),
+ memberInRepos.getMemberType());
+ }
+ @DisplayName("Admin 타입으로 회원가입")
+ @Test
+ public void SignUpAdmin(){
+ //given
+ MemberDTO signUpMember= new MemberDTO("testUsername",
+ "testPassword", "testNickname", "testPassword");
+ //when
+ Member adminMember = memberService.SignUpAdmin(signUpMember);
+ //then
+ Assertions.assertThat(adminMember.getMemberType()).isEqualTo(MemberType.ADMIN);
+ }
+ @DisplayName("회원가입 실패-비밀번호 재확인")
+ @Test
+ public void SignUpFailRePassword(){
+ //given
+ MemberDTO memberDTO = new MemberDTO("testUsername",
+ "testPassword", "testNickname", "test");
+ //when
+ //then
+ Assertions.assertThatThrownBy(() -> memberService.SignUp(memberDTO))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("RePassword Mismatch");
+ }
+ @DisplayName("로그인 성공")
+ @Test
+ public void SignInSuccessInService(){
+ //given
+ Member member = memberService.join(new Member("testUsername", "testPassword", "testNickName"));
+ MemberSignInDTO signInMemberDTO= new MemberSignInDTO("testUsername","testPassword");
+ //when
+ Member signInMember = memberService.SignIn(signInMemberDTO);
+ //then
+ Assertions.assertThat(member).extracting(
+ "id", "username", "nickname", "memberLevel", "memberType")
+ .containsExactly(signInMember.getId(),
+ signInMember.getUsername(),
+ signInMember.getNickname(),
+ signInMember.getMemberLevel(),
+ signInMember.getMemberType());
+ }
+ @DisplayName("로그인 실패 - 아이디 틀림")
+ @Test
+ public void SignInFailUsername(){
+ //given
+ Member member = memberService.join(new Member("testUsername", "testPassword", "testNickName"));
+ MemberSignInDTO signInMemberDTO= new MemberSignInDTO("test","testPassword");
+ //when
+ //then
+ Assertions.assertThatThrownBy(() -> memberService.SignIn(signInMemberDTO))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Username Mismatch");
+ }
+ @DisplayName("로그인 실패 - 비밀번호 틀림")
+ @Test
+ public void SignInFailPassword(){
+ //given
+ Member member = memberService.join(new Member("testUsername", "testPassword", "testNickName"));
+ MemberSignInDTO signInMemberDTO= new MemberSignInDTO("testUsername","test");
+ //when
+ //then
+ Assertions.assertThatThrownBy(() -> memberService.SignIn(signInMemberDTO))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Password Mismatch");
+ }
+}
diff --git a/src/test/java/com/swger/tddstudy/product/ProductControllerTest.java b/src/test/java/com/swger/tddstudy/product/ProductControllerTest.java
new file mode 100644
index 0000000..e6e7e98
--- /dev/null
+++ b/src/test/java/com/swger/tddstudy/product/ProductControllerTest.java
@@ -0,0 +1,140 @@
+package com.swger.tddstudy.product;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.swger.tddstudy.member.domain.DTO.MemberDTO;
+import com.swger.tddstudy.member.domain.Member;
+import com.swger.tddstudy.member.service.MemberService;
+import com.swger.tddstudy.product.domain.DTO.ProductRegisterDTO;
+import com.swger.tddstudy.product.repository.ProductRepository;
+import com.swger.tddstudy.product.service.ProductService;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+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.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.mock.web.MockHttpSession;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.validation.BindException;
+
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
+
+import javax.transaction.Transactional;
+
+@SpringBootTest
+@AutoConfigureMockMvc
+@Transactional
+public class ProductControllerTest {
+
+ @Autowired
+ ProductRepository productRepository;
+ @Autowired
+ ProductService productService;
+ @Autowired
+ MemberService memberService;
+ @Autowired
+ MockMvc mockMvc;
+ @Autowired
+ ObjectMapper om;
+
+ @DisplayName("상품 등록이 가능합니다")
+ @Test
+ public void registerSuccess() throws Exception {
+ //given
+ ProductRegisterDTO product = new ProductRegisterDTO("testName", 1000, 10);
+ Member member = memberService.SignUpAdmin(new MemberDTO("testUsername",
+ "testPassword", "testNickname", "testPassword"));
+ MockHttpSession session = new MockHttpSession();
+ session.setAttribute("id", member.getId());
+ //when, then
+ String content = om.writeValueAsString(product);
+ mockMvc.perform(post("/productRegister")
+ .session(session)
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk())
+ .andExpect(content().string("Register OK"))
+ .andDo(print());
+
+ }
+ @DisplayName("상품 등록이 불가능합니다- 로그인을 하지 않음")
+ @Test
+ public void registerFailNotLogin() throws Exception {
+ //given
+ ProductRegisterDTO product = new ProductRegisterDTO("testName", 1000, 10);
+ MockHttpSession session = new MockHttpSession();
+ //when, then
+ String content = om.writeValueAsString(product);
+ mockMvc.perform(post("/productRegister")
+ .session(session)
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().string("You must SignIn"))
+ .andDo(print());
+
+ }
+ @DisplayName("상품 등록이 불가능합니다- Admin 계정이 아님")
+ @Test
+ public void registerFailNotAdmin() throws Exception {
+ //given
+ ProductRegisterDTO product = new ProductRegisterDTO("testName", 1000, 10);
+ Member member = memberService.SignUp(new MemberDTO("testUsername",
+ "testPassword", "testNickname", "testPassword"));
+ MockHttpSession session = new MockHttpSession();
+ session.setAttribute("id", member.getId());
+ //when, then
+ String content = om.writeValueAsString(product);
+ mockMvc.perform(post("/productRegister")
+ .session(session)
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isBadRequest())
+ .andExpect(content().string("You are not Admin"))
+ .andDo(print());
+
+ }
+
+
+ @DisplayName("상품 등록이 불가능합니다 - NotBlank")
+ @Test
+ public void registerFailNotBlank() throws Exception {
+ //given
+ ProductRegisterDTO product = new ProductRegisterDTO(null, 1000, 10);
+ //when, then
+ String content = om.writeValueAsString(product);
+ mockMvc.perform(post("/productRegister")
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(result -> assertTrue(result.getResolvedException()
+ .getClass().isAssignableFrom(BindException.class)))
+ .andDo(print());
+ }
+
+ @DisplayName("상품 등록이 불가능합니다 - Min")
+ @Test
+ public void registerFailMin() throws Exception {
+ //given
+ ProductRegisterDTO product = new ProductRegisterDTO("testname", 10000, 0);
+ //when, then
+ String content = om.writeValueAsString(product);
+ mockMvc.perform(post("/productRegister")
+ .content(content)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON))
+ .andExpect(result -> assertTrue(result.getResolvedException()
+ .getClass().isAssignableFrom(BindException.class)))
+ .andDo(print());
+ }
+
+}
diff --git a/src/test/java/com/swger/tddstudy/product/ProductServiceTest.java b/src/test/java/com/swger/tddstudy/product/ProductServiceTest.java
new file mode 100644
index 0000000..a30b992
--- /dev/null
+++ b/src/test/java/com/swger/tddstudy/product/ProductServiceTest.java
@@ -0,0 +1,70 @@
+package com.swger.tddstudy.product;
+
+import com.swger.tddstudy.product.domain.DTO.ProductRegisterDTO;
+import com.swger.tddstudy.product.domain.Product;
+import com.swger.tddstudy.product.repository.ProductRepository;
+import com.swger.tddstudy.product.service.ProductService;
+import org.assertj.core.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 javax.transaction.Transactional;
+import java.util.Optional;
+
+
+@SpringBootTest
+@Transactional
+public class ProductServiceTest {
+
+ @Autowired
+ ProductService productService;
+ @Autowired
+ ProductRepository productRepository;
+
+ @DisplayName("상품 등록이 가능합니다")
+ @Test
+ public void productRegisterSuccess() {
+ //given
+ ProductRegisterDTO product = new ProductRegisterDTO("testName", 1000, 10);
+ //when
+ Product registeredProduct = productService.register(product);
+ Optional productOptional = productRepository.findById(registeredProduct.getId());
+ //then
+ Assertions.assertThat(registeredProduct.getId())
+ .isEqualTo(productOptional.get().getId());
+ }
+
+
+ @DisplayName("상품 주문이 가능합니다")
+ @Test
+ public void sellingSuccess() {
+ //given
+ Product product = new Product("testName", 1000, 10);
+ //when, then
+ Assertions.assertThat(product.sellingOrNo()).isTrue();
+ }
+
+ @DisplayName("상품 주문이 불가능합니다 - 재고 부족1")
+ @Test
+ public void sellingFailAmount1() {
+ //given
+ Product product = new Product("testName", 1000, 0);
+ //when, then
+ Assertions.assertThat(product.sellingOrNo()).isFalse();
+ }
+
+ @DisplayName("상품 주문이 불가능합니다 - 재고 부족2")
+ @Test
+ public void sellingFailAmount2() {
+ //given
+ Product product = new Product("testName", 1000, 1);
+ //when
+ product.sellProduct(1);
+ //then
+ Assertions.assertThat(product.sellingOrNo()).isFalse();
+ }
+
+
+}