Skip to content
Open
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
8238f3e
User -> Member 변경
KwonJuHwan Jul 27, 2023
c8c7952
DTO로 받아오는 환경 설정을 위해 MemberDTO 생성
KwonJuHwan Jul 27, 2023
8e00cf0
회원 가입 성공 / 실패(아이디를 작성하지 않음)구현
KwonJuHwan Jul 27, 2023
abfd5ae
Member 객체를 저장하기 위한 메소드 : save,
KwonJuHwan Jul 27, 2023
fe5a769
Transaction환경에서 회원가입 메소드 구현:join
KwonJuHwan Jul 27, 2023
9cd2ed1
username
KwonJuHwan Jul 27, 2023
c2d8b75
Mock을 이용한 Controller Test
KwonJuHwan Jul 31, 2023
bc4704d
Controller: 회원가입 구현
KwonJuHwan Jul 31, 2023
dc88196
로그인 테스트 성공 / 실패 Test
KwonJuHwan Jul 31, 2023
4062461
로그인용 DTO 생성
KwonJuHwan Jul 31, 2023
d58abb9
equals를 위한 메소드 구현
KwonJuHwan Jul 31, 2023
0aa291c
Vaildation 오류 수정
KwonJuHwan Jul 31, 2023
80a2ab1
기존 Test 통합 및 Servive 테스트와 Controller 테스트 분리
KwonJuHwan Aug 1, 2023
99b4655
Default Constructor 추가
KwonJuHwan Aug 1, 2023
9a56bad
Controller 로직 변경 (Service에서 로직 실행)
KwonJuHwan Aug 1, 2023
443c1d5
비밀번호 재확인, 아이디,비밀번호 확인 로직 추가
KwonJuHwan Aug 1, 2023
da5f9e8
NPE 제거를 위해 Optional 사용
KwonJuHwan Aug 1, 2023
5e28932
Service Test 추가
KwonJuHwan Aug 1, 2023
9820479
등급 업 Test 추가
KwonJuHwan Aug 1, 2023
1a7c45e
Admin 계정 만들기 추가
KwonJuHwan Aug 1, 2023
5cd9521
기존 Test 삭제
KwonJuHwan Aug 1, 2023
b4f779c
사용하지않은 Autowired 삭제
KwonJuHwan Aug 2, 2023
7d82f93
[Day 3-4] 상품 서비스 테스트 추가
KwonJuHwan Aug 2, 2023
0f684c5
[Day 3-4] 상품 리포지토리 추가
KwonJuHwan Aug 2, 2023
0be9d21
[Day 3-4] 상품 등록을 위한 상품 DTO 추가
KwonJuHwan Aug 2, 2023
24b6ca6
[Day 3-4] 상품 등록 메소드, 상품 주문 가능 여부 판단 메소드 추가
KwonJuHwan Aug 2, 2023
f98dc6d
[Day 3-4] 상품 구매-> 재고 -1 메소드 추가 , SellingStatus를 바꾸는 메소드 추가
KwonJuHwan Aug 2, 2023
557eb5d
[Day 3-4] 상품 컨트롤러 테스트 추가
KwonJuHwan Aug 2, 2023
82cc88f
[Day 3-4] 상품 컨트롤러 추가
KwonJuHwan Aug 2, 2023
3e779dc
[Day 3-4] 상품 Validation 추가
KwonJuHwan Aug 2, 2023
747627c
[Day 3-4] 팀원분들의 피드백 반영
KwonJuHwan Aug 7, 2023
61ec120
[Day 3-4] 팀원분들의 피드백 반영
KwonJuHwan Aug 7, 2023
1012a3d
[Day 3-4] 팀원분들의 피드백 반영 3
KwonJuHwan Aug 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}

Expand Down
22 changes: 11 additions & 11 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` 도메인)
* 각 패키지 내부의 클래스들은 예시일 뿐 얼마든지 클래스를 추가로 생성하셔도 됩니다.

### 유저 도메인을 완성해봅시다.
Expand All @@ -49,8 +49,8 @@
| username | 사용자 아이디 | 사용자 로그인 아이디 |
| password | 사용자 비밀번호 | 사용자 비밀번호 |
| nickname | 사용자 닉네임 | 사용자 닉네임 |
| userLevel | 사용자 등급 | 사용자 등급 |
| type | 사용자 유형 | 사용자 유형으로 ADMIN, USER가 존재 |
| MemberLevel | 사용자 등급 | 사용자 등급 |
| type | 사용자 유형 | 사용자 유형으로 ADMIN, Member가 존재 |
| createdAt | 생성 일시 | 사용자 최초 생성 일시 |
| lastModifiedAt | 최종 수정 일시 | 사용자 최종 수정 일시 |
* 사용자는 `회원가입`이 가능합니다.
Expand All @@ -62,7 +62,7 @@
* BRONZE, SILVER, GOLD가 존재하며 추후 주문 시 결제 금액 할인이 가능합니다.
* 5번 구매를 하면 SILVER, 10번 구매를 하면 GOLD로 등급업이 됩니다.
* 사용자 별 `타입(type)`이 존재합니다.
* USER : 일반유저로 상품을 구매는 가능하지만 추가할 수 없습니다.
* Member : 일반유저로 상품을 구매는 가능하지만 추가할 수 없습니다.
* ADMIN : 관리자로 상품을 구매와 추가 모두 가능합니다.

<br>
Expand Down Expand Up @@ -93,7 +93,7 @@
| 변수명 | 필드명 | 설명 |
|----------------|----------|------------|
| id | 주문 아이디 | 주문 엔티티 식별자 |
| userId | 유저 아이디 | 유저 엔티티 식별자 |
| MemberId | 유저 아이디 | 유저 엔티티 식별자 |
| orderProducts | 주문 상품 정보 | 주문의 상품의 정보 |
| price | 총 주문 가격 | 총 주문 가격 |
| orderStatus | 주문 상태 | 주문 상태 |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
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 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) throws Exception{
if (bindingResult.hasErrors()) throw new BindException(bindingResult);
memberService.SignIn(memberSignInDTO);
return "LogInOK";
}

}
25 changes: 25 additions & 0 deletions src/main/java/com/swger/tddstudy/member/domain/DTO/MemberDTO.java
Original file line number Diff line number Diff line change
@@ -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(){}
}
Original file line number Diff line number Diff line change
@@ -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(){}
}
61 changes: 61 additions & 0 deletions src/main/java/com/swger/tddstudy/member/domain/Member.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

}
Original file line number Diff line number Diff line change
@@ -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("골드");

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/swger/tddstudy/member/domain/MemberType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.swger.tddstudy.member.domain;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public enum MemberType {

Member("일반회원"), ADMIN("관리자");

private final String text;

}
Original file line number Diff line number Diff line change
@@ -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<Member,Long> {
Optional<Member> findByUsername(String username);

@Override
<S extends Member> S save(S entity);
}
48 changes: 48 additions & 0 deletions src/main/java/com/swger/tddstudy/member/service/MemberService.java
Original file line number Diff line number Diff line change
@@ -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;
}

}
6 changes: 3 additions & 3 deletions src/main/java/com/swger/tddstudy/order/domain/Order.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<OrderProduct> orderProducts;

private int price;

@Enum태erated(EnumType.STRING)
@Enumerated(EnumType.STRING)
private OrderStatus orderStatus;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.swger.tddstudy.product.controller;

import com.swger.tddstudy.product.domain.DTO.ProductRegisterDTO;
import com.swger.tddstudy.product.service.ProductService;
import lombok.RequiredArgsConstructor;
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 {
@Autowired
ProductService productService;

@PostMapping("/productRegister")
public String productRegister(@Validated @RequestBody ProductRegisterDTO DTO, BindingResult br) throws BindException {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

관리자만 상품 등록 및 재고 추가가 가능하도록 세션을 통해 확인해보는 건 어떨까요? 😀

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

첫번째 유저 질문을 까먹고 있었네요. 좋은 지적 감사드립니다!

if (br.hasErrors()) throw new BindException(br);
productService.register(DTO);
return "Register OK";
}
}
Original file line number Diff line number Diff line change
@@ -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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상품 명에 빈칸이 필요할 수도 있지 않을까 생각해봤습니다! @NotNull로 변경하면 띄어쓰기를 허용할 수 있습니다 ㅎㅎ

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

상품명에 빈칸이 필요한 경우가 구체적으로 어떤 것이 있을까요? 상품명이 빈칸 = " "인 경우는 상품명이 없다고 판단하여 묶어서 테스트를 진행하였는데 의견 부탁드립니다!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 생각했던 빈칸이 필요한 경우는 예를 들어, "탈모 방지 샴푸" 와 같이 상품명에 띄어쓰기가 들어있는 경우였습니다! 😊

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@notblank는 글자 없이 " " 이렇게 띄어쓰기만 사용자가 입력하는 경우에만 예외를 터트리는 걸로 알고 있어요! 글자 사이에 있는 블랭크는 예외를 터트리지 않는 걸로 알고 있슴다

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 그렇군요! 제가 잘못 이해했나 보네요😅 알려주셔서 감사합니다! 제 코드를 수정해야겠네요 하하 👍🏻

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(){}

}
Loading