-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: 키오스크 상품 기능 테스트(Presentation Layer)
- Loading branch information
Showing
20 changed files
with
683 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
Testing/cafekiosk/src/main/java/sample/cafekiosk/spring/api/ApiControllerAdvice.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package sample.cafekiosk.spring.api; | ||
|
||
import org.springframework.http.HttpStatus; | ||
import org.springframework.validation.BindException; | ||
import org.springframework.web.bind.annotation.ExceptionHandler; | ||
import org.springframework.web.bind.annotation.ResponseStatus; | ||
import org.springframework.web.bind.annotation.RestControllerAdvice; | ||
|
||
@RestControllerAdvice | ||
public class ApiControllerAdvice { | ||
|
||
@ResponseStatus(HttpStatus.BAD_REQUEST) | ||
@ExceptionHandler(BindException.class) | ||
public ApiResponse<Object> bindException(BindException e) { | ||
return ApiResponse.of( | ||
HttpStatus.BAD_REQUEST, | ||
e.getBindingResult().getAllErrors().get(0).getDefaultMessage(), | ||
null | ||
); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
Testing/cafekiosk/src/main/java/sample/cafekiosk/spring/api/ApiResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package sample.cafekiosk.spring.api; | ||
|
||
import org.springframework.http.HttpStatus; | ||
|
||
import lombok.Getter; | ||
import sample.cafekiosk.spring.api.service.product.response.ProductResponse; | ||
|
||
@Getter | ||
public class ApiResponse<T> { | ||
|
||
private int code; | ||
private HttpStatus status; | ||
private String message; | ||
private T data; | ||
|
||
public ApiResponse(HttpStatus status, String message, T data) { | ||
this.code = status.value(); | ||
this.status = status; | ||
this.message = message; | ||
this.data = data; | ||
} | ||
|
||
public static <T> ApiResponse<T> of(HttpStatus httpStatus, String message, T data) { | ||
return new ApiResponse<>(httpStatus, message, data); | ||
} | ||
|
||
public static <T> ApiResponse<T> of(HttpStatus httpStatus, T data) { | ||
return of(httpStatus, httpStatus.name(), data); | ||
} | ||
|
||
public static <T> ApiResponse<T> ok(T data) { | ||
return of(HttpStatus.OK, HttpStatus.OK.name(), data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...java/sample/cafekiosk/spring/api/controller/product/dto/request/ProductCreateRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package sample.cafekiosk.spring.api.controller.product.dto.request; | ||
|
||
import jakarta.validation.constraints.Max; | ||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Positive; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import sample.cafekiosk.spring.api.service.product.request.ProductCreateServiceRequest; | ||
import sample.cafekiosk.spring.domain.product.Product; | ||
import sample.cafekiosk.spring.domain.product.ProductSellingStatus; | ||
import sample.cafekiosk.spring.domain.product.ProductType; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class ProductCreateRequest { | ||
|
||
@NotNull(message = "상품 타입은 필수입니다.") | ||
private ProductType type; | ||
|
||
@NotNull(message = "상품 판매상태는 필수입니다.") | ||
private ProductSellingStatus sellingStatus; | ||
|
||
@NotBlank(message = "상품 이름은 필수입니다.") | ||
private String name; | ||
|
||
@Positive(message = "상품 가격은 양수여야 합니다.") | ||
private int price; | ||
|
||
@Builder | ||
private ProductCreateRequest(ProductType type, ProductSellingStatus sellingStatus, String name, int price) { | ||
this.type = type; | ||
this.sellingStatus = sellingStatus; | ||
this.name = name; | ||
this.price = price; | ||
} | ||
|
||
public Product toEntity(String nextProductNumber) { | ||
return Product.builder() | ||
.productNumber(nextProductNumber) | ||
.type(type) | ||
.sellingStatus(sellingStatus) | ||
.name(name) | ||
.price(price) | ||
.build(); | ||
} | ||
|
||
public ProductCreateServiceRequest toServiceRequest() { | ||
return ProductCreateServiceRequest.builder() | ||
.type(type) | ||
.sellingStatus(sellingStatus) | ||
.name(name) | ||
.price(price) | ||
.build(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
...ain/java/sample/cafekiosk/spring/api/service/order/request/OrderCreateServiceRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package sample.cafekiosk.spring.api.service.order.request; | ||
|
||
import java.util.List; | ||
|
||
import jakarta.validation.constraints.NotEmpty; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class OrderCreateServiceRequest { | ||
|
||
@NotEmpty(message = "상품 번호 리스트는 필수입니다.") | ||
private List<String> productNumbers; | ||
|
||
@Builder | ||
public OrderCreateServiceRequest(List<String> productNumbers) { | ||
this.productNumbers = productNumbers; | ||
} | ||
} |
39 changes: 37 additions & 2 deletions
39
...g/cafekiosk/src/main/java/sample/cafekiosk/spring/api/service/product/ProductService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,63 @@ | ||
package sample.cafekiosk.spring.api.service.product; | ||
|
||
import static sample.cafekiosk.spring.domain.product.ProductSellingStatus.*; | ||
import static sample.cafekiosk.spring.domain.product.ProductType.*; | ||
|
||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import sample.cafekiosk.spring.api.controller.product.dto.request.ProductCreateRequest; | ||
import sample.cafekiosk.spring.api.service.product.request.ProductCreateServiceRequest; | ||
import sample.cafekiosk.spring.api.service.product.response.ProductResponse; | ||
import sample.cafekiosk.spring.domain.product.Product; | ||
import sample.cafekiosk.spring.domain.product.ProductRepository; | ||
import sample.cafekiosk.spring.domain.product.ProductSellingStatus; | ||
|
||
/** | ||
* readOnly = true : 읽기전용 | ||
* CRUD 에서 CUD 동작 x, only Read | ||
* JPA : CUD 스냅샷 저장, 변경감지 x (성능 향상) | ||
* | ||
* CQRS - Command와 Query를 분리하자 | ||
*/ | ||
@Transactional(readOnly = true) | ||
@RequiredArgsConstructor | ||
@Service | ||
public class ProductService { | ||
|
||
private final ProductRepository productRepository; | ||
|
||
@Transactional | ||
public ProductResponse createProduct(ProductCreateServiceRequest request) { | ||
// nextProductNumber -> DB에서 마지막 저장된 Product의 상품 번호를 읽어와서 +1 | ||
String nextProductNumber = createNextProductNumber(); | ||
|
||
Product product = request.toEntity(nextProductNumber); | ||
Product savedProduct = productRepository.save(product); | ||
|
||
return ProductResponse.of(savedProduct); | ||
} | ||
|
||
public List<ProductResponse> getSellingProducts() { | ||
List<Product> products = productRepository.findAllBySellingStatusIn(ProductSellingStatus.forDisplay()); | ||
List<Product> products = productRepository.findAllBySellingStatusIn(forDisplay()); | ||
|
||
return products.stream() | ||
.map(ProductResponse::of) | ||
.collect(Collectors.toList()); | ||
} | ||
|
||
private String createNextProductNumber() { | ||
String latestProductNumber = productRepository.findLatestProductNumber(); | ||
if(latestProductNumber == null) { | ||
return "001"; | ||
} | ||
|
||
int latestProductNumberInt = Integer.parseInt(latestProductNumber); | ||
int nextProductNumberInt = latestProductNumberInt + 1; | ||
|
||
return String.format("%03d", nextProductNumberInt); | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
...java/sample/cafekiosk/spring/api/service/product/request/ProductCreateServiceRequest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package sample.cafekiosk.spring.api.service.product.request; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Positive; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import sample.cafekiosk.spring.domain.product.Product; | ||
import sample.cafekiosk.spring.domain.product.ProductSellingStatus; | ||
import sample.cafekiosk.spring.domain.product.ProductType; | ||
|
||
@Getter | ||
@NoArgsConstructor | ||
public class ProductCreateServiceRequest { | ||
|
||
@NotNull(message = "상품 타입은 필수입니다.") | ||
private ProductType type; | ||
|
||
@NotNull(message = "상품 판매상태는 필수입니다.") | ||
private ProductSellingStatus sellingStatus; | ||
|
||
@NotBlank(message = "상품 이름은 필수입니다.") | ||
private String name; | ||
|
||
@Positive(message = "상품 가격은 양수여야 합니다.") | ||
private int price; | ||
|
||
@Builder | ||
private ProductCreateServiceRequest(ProductType type, ProductSellingStatus sellingStatus, String name, int price) { | ||
this.type = type; | ||
this.sellingStatus = sellingStatus; | ||
this.name = name; | ||
this.price = price; | ||
} | ||
|
||
public Product toEntity(String nextProductNumber) { | ||
return Product.builder() | ||
.productNumber(nextProductNumber) | ||
.type(type) | ||
.sellingStatus(sellingStatus) | ||
.name(name) | ||
.price(price) | ||
.build(); | ||
} | ||
} |
Oops, something went wrong.