From a8e62d65601fb0575570f7b71eb50b066254e897 Mon Sep 17 00:00:00 2001 From: hs12 Date: Fri, 16 Feb 2024 20:16:29 +0900 Subject: [PATCH 01/25] =?UTF-8?q?[feat]=20:=20=EA=B1=B0=EB=9E=98=ED=9D=AC?= =?UTF-8?q?=EB=A7=9D=20=EC=9E=A5=EC=86=8C=20=ED=95=84=EB=93=9C=20nullable?= =?UTF-8?q?=20true=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auction/domain/auction_field/TradingLocation.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java index 9fa96956..15203c95 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java @@ -13,13 +13,13 @@ @NoArgsConstructor(access = PROTECTED) public class TradingLocation { - @Column(name = "si", nullable = false) + @Column(name = "si") private String si; - @Column(name = "gu", nullable = false) + @Column(name = "gu") private String gu; - @Column(name = "dong", nullable = false) + @Column(name = "dong") private String dong; @Builder From b989776ff9a6e93b9978abd735d07fa552758bf5 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 00:21:51 +0900 Subject: [PATCH 02/25] =?UTF-8?q?[feat]=20:=20Enum=20<->=20String=20?= =?UTF-8?q?=EA=B0=84=20=EB=B3=80=ED=99=98=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/auction_field/ProductStatus.java | 15 --------- .../domain/auction_field/PurchaseTime.java | 16 ++++++++++ .../domain/auction_field/TradeMethod.java | 16 ++++++++++ .../auction/domain/product/ProductStatus.java | 31 +++++++++++++++++++ .../product/product_category/Category.java | 31 +++++++++++++++++++ .../ProductCategoryValue.java | 14 --------- .../exception/CommonValidationError.java | 20 ------------ .../java/dev/handsup/exception/ErrorCode.java | 8 ----- .../handsup/exception/NotFoundException.java | 14 --------- .../exception/ValidationException.java | 14 --------- 10 files changed, 94 insertions(+), 85 deletions(-) delete mode 100644 core/src/main/java/dev/handsup/auction/domain/auction_field/ProductStatus.java create mode 100644 core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java create mode 100644 core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java delete mode 100644 core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategoryValue.java delete mode 100644 core/src/main/java/dev/handsup/exception/CommonValidationError.java delete mode 100644 core/src/main/java/dev/handsup/exception/ErrorCode.java delete mode 100644 core/src/main/java/dev/handsup/exception/NotFoundException.java delete mode 100644 core/src/main/java/dev/handsup/exception/ValidationException.java diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/ProductStatus.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/ProductStatus.java deleted file mode 100644 index c484fb5b..00000000 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/ProductStatus.java +++ /dev/null @@ -1,15 +0,0 @@ -package dev.handsup.auction.domain.auction_field; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public enum ProductStatus { - - NEW("미개봉"), - CLEAN("깨끗함"), - DIRTY("더러움"); - - private final String description; -} diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java index 68ecf32c..197eb5fb 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java @@ -1,5 +1,10 @@ package dev.handsup.auction.domain.auction_field; +import static dev.handsup.auction.exception.AuctionErrorCode.*; + +import java.util.Arrays; + +import dev.handsup.common.exception.ValidationException; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -15,4 +20,15 @@ public enum PurchaseTime { UNKNOWN("모름"); private final String description; + + public static PurchaseTime of(String input){ + return Arrays.stream(values()) + .filter(time -> time.isEqual(input)) + .findAny() + .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + } + + private boolean isEqual(String input) { + return input.equalsIgnoreCase(this.description); + } } diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java index 51d39d30..cb942772 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java @@ -1,5 +1,10 @@ package dev.handsup.auction.domain.auction_field; +import static dev.handsup.auction.exception.AuctionErrorCode.*; + +import java.util.Arrays; + +import dev.handsup.common.exception.ValidationException; import lombok.Getter; import lombok.RequiredArgsConstructor; @@ -11,4 +16,15 @@ public enum TradeMethod { DELIVER("택배"); private final String description; + + public static TradeMethod of(String input){ + return Arrays.stream(values()) + .filter(method -> method.isEqual(input)) + .findAny() + .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + } + + private boolean isEqual(String input) { + return input.equalsIgnoreCase(this.description); + } } diff --git a/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java b/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java new file mode 100644 index 00000000..c72dfe0a --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java @@ -0,0 +1,31 @@ +package dev.handsup.auction.domain.product; + +import static dev.handsup.auction.exception.AuctionErrorCode.*; + +import java.util.Arrays; + +import dev.handsup.common.exception.ValidationException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum ProductStatus { + + NEW("미개봉"), + CLEAN("깨끗함"), + DIRTY("더러움"); + + private final String description; + + public static ProductStatus of(String input){ + return Arrays.stream(values()) + .filter(status -> status.isEqual(input)) + .findAny() + .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + } + + private boolean isEqual(String input) { + return input.equalsIgnoreCase(this.description); + } +} diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java new file mode 100644 index 00000000..a966c728 --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java @@ -0,0 +1,31 @@ +package dev.handsup.auction.domain.product.product_category; + +import static dev.handsup.auction.exception.AuctionErrorCode.*; + +import java.util.Arrays; + +import dev.handsup.common.exception.ValidationException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum Category { + + DIGITAL("디지털 기기"), + FURNITURE("가구"), + FASHION("패션"); + + private final String description; + + public static Category of(String input){ + return Arrays.stream(values()) + .filter(value -> value.isEqual(input)) + .findAny() + .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + } + + private boolean isEqual(String input) { + return input.equalsIgnoreCase(this.description); + } +} diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategoryValue.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategoryValue.java deleted file mode 100644 index 5a9130f0..00000000 --- a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategoryValue.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.handsup.auction.domain.product.product_category; - -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public enum ProductCategoryValue { - DIGITAL("디지털 기기"), - FURNITURE("가구"), - FASHION("패션"); - - private final String description; -} diff --git a/core/src/main/java/dev/handsup/exception/CommonValidationError.java b/core/src/main/java/dev/handsup/exception/CommonValidationError.java deleted file mode 100644 index 664696d8..00000000 --- a/core/src/main/java/dev/handsup/exception/CommonValidationError.java +++ /dev/null @@ -1,20 +0,0 @@ -package dev.handsup.exception; - -import static lombok.AccessLevel.*; - -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = PRIVATE) -public final class CommonValidationError { - - private static final String NOT_NULL_POSTFIX = " 는 Null 이 될 수 없습니다"; - private static final String NOT_EMPTY_POSTFIX = " 는 Empty 가 될 수 없습니다"; - - public static String getNotNullMessage(String object, String variable) { - return object + "_" + variable + NOT_NULL_POSTFIX; - } - - public static String getNotEmptyPostfix(String object, String variable) { - return object + "_" + variable + NOT_EMPTY_POSTFIX; - } -} diff --git a/core/src/main/java/dev/handsup/exception/ErrorCode.java b/core/src/main/java/dev/handsup/exception/ErrorCode.java deleted file mode 100644 index dff9e208..00000000 --- a/core/src/main/java/dev/handsup/exception/ErrorCode.java +++ /dev/null @@ -1,8 +0,0 @@ -package dev.handsup.exception; - -public interface ErrorCode { - - String getMessage(); - - String getCode(); -} diff --git a/core/src/main/java/dev/handsup/exception/NotFoundException.java b/core/src/main/java/dev/handsup/exception/NotFoundException.java deleted file mode 100644 index 1736b90b..00000000 --- a/core/src/main/java/dev/handsup/exception/NotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.handsup.exception; - -import lombok.Getter; - -@Getter -public class NotFoundException extends RuntimeException { - - private final String code; - - public NotFoundException(ErrorCode errorCode) { - super(errorCode.getMessage()); - this.code = errorCode.getCode(); - } -} diff --git a/core/src/main/java/dev/handsup/exception/ValidationException.java b/core/src/main/java/dev/handsup/exception/ValidationException.java deleted file mode 100644 index dc872575..00000000 --- a/core/src/main/java/dev/handsup/exception/ValidationException.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.handsup.exception; - -import lombok.Getter; - -@Getter -public class ValidationException extends RuntimeException { - - private final String code; - - public ValidationException(ErrorCode errorCode) { - super(errorCode.getMessage()); - this.code = errorCode.getCode(); - } -} From f07469f74100990c54cae8957652ae4ed66066b4 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 00:23:41 +0900 Subject: [PATCH 03/25] =?UTF-8?q?[feat]=20:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dev/handsup/auction/domain/product/Product.java | 1 - .../domain/product/product_category/ProductCategory.java | 6 +++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/dev/handsup/auction/domain/product/Product.java b/core/src/main/java/dev/handsup/auction/domain/product/Product.java index 826e57e4..f54e1fd5 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/Product.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/Product.java @@ -6,7 +6,6 @@ import static jakarta.persistence.GenerationType.*; import static lombok.AccessLevel.*; -import dev.handsup.auction.domain.auction_field.ProductStatus; import dev.handsup.auction.domain.auction_field.PurchaseTime; import dev.handsup.auction.domain.product.product_category.ProductCategory; import dev.handsup.common.entity.TimeBaseEntity; diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java index 7170f94a..71641126 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java @@ -20,5 +20,9 @@ public class ProductCategory { private Long id; @Column(name = "product_category_value", nullable = false) - private ProductCategoryValue value; + private Category category; + + public ProductCategory(Category category) { + this.category = category; + } } From 8cf6dcd7aa76a7c39918f8cf64153004ed95e608 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 00:25:49 +0900 Subject: [PATCH 04/25] =?UTF-8?q?[feat]=20:=20=EA=B2=BD=EB=A7=A4=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/exception/GlobalExceptionHandler.java | 1 - .../auction/exception/AuctionErrorCode.java | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java diff --git a/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java b/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java index 72edd20c..9f8efec1 100644 --- a/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java +++ b/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java @@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestControllerAdvice; -import dev.handsup.exception.ValidationException; import lombok.extern.slf4j.Slf4j; @Slf4j diff --git a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java new file mode 100644 index 00000000..9510af0a --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java @@ -0,0 +1,15 @@ +package dev.handsup.auction.exception; + +import dev.handsup.common.exception.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum AuctionErrorCode implements ErrorCode { + + NOT_FOUND_PRODUCT_STATUS("올바른 상품 상태를 입력해주세요", "P_001"); + + private final String message; + private final String code; +} From 607813fa7e4dcd754b4c06236f23c4ba1adc4cbc Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 00:31:26 +0900 Subject: [PATCH 05/25] =?UTF-8?q?[feat]=20:=20=EA=B2=BD=EB=A7=A4=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20controller=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=20=EB=B0=8F=20request=20=EC=B6=94=EA=B0=80"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auction/controller/AuctionController.java | 31 +++++++++++++++++++ .../handsup/auction/dto/ApiAuctionMapper.java | 24 ++++++++++++++ .../dto/RegisterAuctionApiRequest.java | 25 +++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 api/src/main/java/dev/handsup/auction/controller/AuctionController.java create mode 100644 api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java create mode 100644 api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java diff --git a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java new file mode 100644 index 00000000..8c4f10b6 --- /dev/null +++ b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java @@ -0,0 +1,31 @@ +package dev.handsup.auction.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import dev.handsup.auction.dto.ApiAuctionMapper; +import dev.handsup.auction.dto.AuctionResponse; +import dev.handsup.auction.dto.RegisterAuctionRequest; +import dev.handsup.auction.service.AuctionService; +import dev.handsup.auction.dto.RegisterAuctionApiRequest; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/auctions") +public class AuctionController { + private final AuctionService auctionService; + + @Operation(summary = "경매 등록 API", description = "경매를 등록한다") + @PostMapping + public ResponseEntity registerAuction(@RequestBody RegisterAuctionApiRequest request){ + RegisterAuctionRequest registerAuctionRequest = ApiAuctionMapper.toRegisterAuctionRequest(request); + AuctionResponse response = auctionService.registerAuction(registerAuctionRequest); + return ResponseEntity.ok(response); + } + +} diff --git a/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java b/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java new file mode 100644 index 00000000..e8acad87 --- /dev/null +++ b/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java @@ -0,0 +1,24 @@ +package dev.handsup.auction.dto; + +import static lombok.AccessLevel.*; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PRIVATE) +public class ApiAuctionMapper { + public static RegisterAuctionRequest toRegisterAuctionRequest(RegisterAuctionApiRequest request){ + return new RegisterAuctionRequest( + request.title(), + request.category(), + request.initPrice(), + request.endDate(), + request.productStatus(), + request.purchaseTime(), + request.description(), + request.tradeMethod(), + request.si(), + request.gu(), + request.dong() + ); + } +} diff --git a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java new file mode 100644 index 00000000..1cd9fcce --- /dev/null +++ b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java @@ -0,0 +1,25 @@ +package dev.handsup.auction.dto; + +import java.time.LocalDate; + +public record RegisterAuctionApiRequest( + String title, + + String category, + + int initPrice, + + LocalDate endDate, + + String productStatus, + + String purchaseTime, + + String description, + + String tradeMethod, + + String si, + String gu, + String dong +){} From 5f0bc831ef20c0e38d88121dfd0b520cf0729d47 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 19:32:02 +0900 Subject: [PATCH 06/25] =?UTF-8?q?[feat]=20:=20Enum=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handsup/auction/domain/auction_field/PurchaseTime.java | 2 +- .../handsup/auction/domain/auction_field/TradeMethod.java | 2 +- .../auction/domain/auction_field/TradingLocation.java | 1 + .../auction/domain/product/product_category/Category.java | 2 +- .../java/dev/handsup/auction/exception/AuctionErrorCode.java | 5 ++++- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java index 197eb5fb..339563da 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java @@ -25,7 +25,7 @@ public static PurchaseTime of(String input){ return Arrays.stream(values()) .filter(time -> time.isEqual(input)) .findAny() - .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + .orElseThrow(() -> new ValidationException(NOT_FOUND_PURCHASE_TIME)); } private boolean isEqual(String input) { diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java index cb942772..cfde570e 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java @@ -21,7 +21,7 @@ public static TradeMethod of(String input){ return Arrays.stream(values()) .filter(method -> method.isEqual(input)) .findAny() - .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + .orElseThrow(() -> new ValidationException(NOT_FOUND_TADE_METHOD)); } private boolean isEqual(String input) { diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java index 15203c95..01ea21d3 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradingLocation.java @@ -12,6 +12,7 @@ @Getter @NoArgsConstructor(access = PROTECTED) public class TradingLocation { + private static final String TRADING_LOCATION = "TradingLocation"; @Column(name = "si") private String si; diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java index a966c728..d9ec082c 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java @@ -22,7 +22,7 @@ public static Category of(String input){ return Arrays.stream(values()) .filter(value -> value.isEqual(input)) .findAny() - .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_STATUS)); + .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_CATEGORY)); } private boolean isEqual(String input) { diff --git a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java index 9510af0a..4ccf2b4b 100644 --- a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java +++ b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java @@ -8,7 +8,10 @@ @RequiredArgsConstructor public enum AuctionErrorCode implements ErrorCode { - NOT_FOUND_PRODUCT_STATUS("올바른 상품 상태를 입력해주세요", "P_001"); + NOT_FOUND_PRODUCT_STATUS("올바른 상품 상태를 입력해주세요", "P_001"), + NOT_FOUND_PURCHASE_TIME("올바른 구매 시기를 입력해주세요", "P_002" ), + NOT_FOUND_TADE_METHOD("올바른 거래 방법을 입력해주세요","P_003" ), + NOT_FOUND_PRODUCT_CATEGORY("올바른 상품 카테고리를 입력해주세요","P_004" ); private final String message; private final String code; From 0fb83399659517127e8b4dbe894a31febd4f983c Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:36:00 +0900 Subject: [PATCH 07/25] =?UTF-8?q?[Style]=20:=20Enum=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handsup/auction/domain/auction_field/AuctionStatus.java | 2 +- .../handsup/auction/domain/auction_field/PurchaseTime.java | 4 ++-- .../dev/handsup/auction/domain/auction_field/TradeMethod.java | 4 ++-- .../dev/handsup/auction/domain/product/ProductStatus.java | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/AuctionStatus.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/AuctionStatus.java index ebd6c7a4..2a0a7297 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/AuctionStatus.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/AuctionStatus.java @@ -12,5 +12,5 @@ public enum AuctionStatus { COMPLETED("완료"), CANCELED("취소"); - private final String description; + private final String label; } diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java index 339563da..31d39165 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java @@ -19,7 +19,7 @@ public enum PurchaseTime { ABOVE_ONE_YEAR("1년 이상"), UNKNOWN("모름"); - private final String description; + private final String label; public static PurchaseTime of(String input){ return Arrays.stream(values()) @@ -29,6 +29,6 @@ public static PurchaseTime of(String input){ } private boolean isEqual(String input) { - return input.equalsIgnoreCase(this.description); + return input.equalsIgnoreCase(this.label); } } diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java index cfde570e..30f0b95d 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java @@ -15,7 +15,7 @@ public enum TradeMethod { DIRECT("직거래"), DELIVER("택배"); - private final String description; + private final String label; public static TradeMethod of(String input){ return Arrays.stream(values()) @@ -25,6 +25,6 @@ public static TradeMethod of(String input){ } private boolean isEqual(String input) { - return input.equalsIgnoreCase(this.description); + return input.equalsIgnoreCase(this.label); } } diff --git a/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java b/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java index c72dfe0a..5fe00568 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java @@ -16,7 +16,7 @@ public enum ProductStatus { CLEAN("깨끗함"), DIRTY("더러움"); - private final String description; + private final String label; public static ProductStatus of(String input){ return Arrays.stream(values()) @@ -26,6 +26,6 @@ public static ProductStatus of(String input){ } private boolean isEqual(String input) { - return input.equalsIgnoreCase(this.description); + return input.equalsIgnoreCase(this.label); } } From 2cd47879515e5c0687d7923751ef084efdeadde9 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:38:03 +0900 Subject: [PATCH 08/25] =?UTF-8?q?[feat]=20:=20service=20dto=20=EB=B0=8F=20?= =?UTF-8?q?mapper=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/handsup/auction/domain/Auction.java | 50 +++++++++++++++-- .../handsup/auction/dto/AuctionResponse.java | 32 +++++++++++ .../auction/dto/RegisterAuctionRequest.java | 22 ++++++++ .../auction/dto/mapper/AuctionMapper.java | 54 +++++++++++++++++++ 4 files changed, 154 insertions(+), 4 deletions(-) create mode 100644 core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java create mode 100644 core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java create mode 100644 core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java diff --git a/core/src/main/java/dev/handsup/auction/domain/Auction.java b/core/src/main/java/dev/handsup/auction/domain/Auction.java index faba5a4b..484b2769 100644 --- a/core/src/main/java/dev/handsup/auction/domain/Auction.java +++ b/core/src/main/java/dev/handsup/auction/domain/Auction.java @@ -1,6 +1,8 @@ package dev.handsup.auction.domain; import static dev.handsup.auction.domain.auction_field.AuctionStatus.*; +import static dev.handsup.common.exception.CommonValidationError.*; +import static jakarta.persistence.CascadeType.*; import static jakarta.persistence.ConstraintMode.*; import static jakarta.persistence.EnumType.*; import static jakarta.persistence.FetchType.*; @@ -9,10 +11,15 @@ import java.time.LocalDate; +import org.springframework.util.Assert; + import dev.handsup.auction.domain.auction_field.AuctionStatus; +import dev.handsup.auction.domain.auction_field.PurchaseTime; import dev.handsup.auction.domain.auction_field.TradeMethod; import dev.handsup.auction.domain.auction_field.TradingLocation; import dev.handsup.auction.domain.product.Product; +import dev.handsup.auction.domain.product.ProductStatus; +import dev.handsup.auction.domain.product.product_category.ProductCategory; import dev.handsup.common.entity.TimeBaseEntity; import dev.handsup.user.domain.User; import jakarta.persistence.Column; @@ -34,6 +41,9 @@ @NoArgsConstructor(access = PROTECTED) public class Auction extends TimeBaseEntity { + private static final String AUCTION = "auction"; + + @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "auction_id") @@ -41,7 +51,7 @@ public class Auction extends TimeBaseEntity { @ManyToOne(fetch = LAZY) @JoinColumn(name = "seller_id", - nullable = false, + // nullable = false, foreignKey = @ForeignKey(NO_CONSTRAINT)) private User seller; @@ -52,7 +62,7 @@ public class Auction extends TimeBaseEntity { @Column(name = "title", nullable = false) private String title; - @OneToOne(fetch = LAZY) + @OneToOne(fetch = LAZY, cascade = ALL) @JoinColumn(name = "product_id", foreignKey = @ForeignKey(NO_CONSTRAINT)) private Product product; @@ -81,9 +91,10 @@ public class Auction extends TimeBaseEntity { private int bookmarkCount; @Builder - public Auction(User seller, String title, Product product, int initPrice, LocalDate endDate, + public Auction(String title, Product product, int initPrice, LocalDate endDate, TradingLocation tradingLocation, TradeMethod tradeMethod) { - this.seller = seller; + Assert.hasText(title, getNotEmptyMessage(AUCTION, "title")); + Assert.notNull(title, getNotEmptyMessage(AUCTION, "initPrice")); this.title = title; this.product = product; this.initPrice = initPrice; @@ -94,4 +105,35 @@ public Auction(User seller, String title, Product product, int initPrice, LocalD bookmarkCount = 0; status = PROGRESS; } + public static Auction of( + String title, + ProductCategory productCategory, + int initPrice, + LocalDate endDate, + ProductStatus status, + PurchaseTime purchaseTime, + String description, + TradeMethod tradeMethod, + String si, + String gu, + String dong + ) { + return Auction.builder() + .title(title) + .product(Product.builder() + .productCategory(productCategory) + .status(status) + .description(description) + .purchaseTime(purchaseTime) + .build()) + .initPrice(initPrice) + .endDate(endDate) + .tradingLocation(TradingLocation.builder() + .si(si) + .gu(gu) + .dong(dong) + .build()) + .tradeMethod(tradeMethod) + .build(); + } } diff --git a/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java b/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java new file mode 100644 index 00000000..bbc4e1b7 --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java @@ -0,0 +1,32 @@ +package dev.handsup.auction.dto; + +import java.time.LocalDate; + +import lombok.Builder; + +@Builder +public record AuctionResponse( + + Long auctionId, + + String title, + + String category, + + int initPrice, + + LocalDate endDate, + + String productStatus, + + String purchaseTime, + + String description, + + String tradeMethod, + + String si, + String gu, + String dong +) { +} diff --git a/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java b/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java new file mode 100644 index 00000000..a47e3e54 --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java @@ -0,0 +1,22 @@ +package dev.handsup.auction.dto; + +import java.time.LocalDate; + +import lombok.Builder; + +@Builder +public record RegisterAuctionRequest( + String title, + String productCategory, + int initPrice, + LocalDate endDate, + String productStatus, + String purchaseTime, + String description, + String tradeMethod, + + String si, + String gu, + String dong +) { +} diff --git a/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java b/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java new file mode 100644 index 00000000..4f3dbe02 --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java @@ -0,0 +1,54 @@ +package dev.handsup.auction.dto.mapper; + +import static lombok.AccessLevel.*; + +import dev.handsup.auction.domain.Auction; +import dev.handsup.auction.domain.auction_field.PurchaseTime; +import dev.handsup.auction.domain.auction_field.TradeMethod; +import dev.handsup.auction.domain.product.ProductStatus; +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import dev.handsup.auction.dto.AuctionResponse; +import dev.handsup.auction.dto.RegisterAuctionRequest; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PRIVATE) +public class AuctionMapper { + + public static Auction toAuction(RegisterAuctionRequest request, ProductCategory productCategory) { + + ProductStatus productStatus = ProductStatus.of(request.productStatus()); + PurchaseTime purchaseTime = PurchaseTime.of(request.purchaseTime()); + TradeMethod tradeMethod = TradeMethod.of(request.tradeMethod()); + + return Auction.of( + request.title(), + productCategory, + request.initPrice(), + request.endDate(), + productStatus, + purchaseTime, + request.description(), + tradeMethod, + request.si(), + request.gu(), + request.dong() + ); + } + public static AuctionResponse toAuctionResponse(Auction auction) { + return AuctionResponse.builder() + .auctionId(auction.getId()) + .title(auction.getTitle()) + .category(auction.getProduct().getProductCategory().getCategoryValue()) + .initPrice(auction.getInitPrice()) + .endDate(auction.getEndDate()) + .productStatus(auction.getProduct().getStatus().getLabel()) + .purchaseTime(auction.getProduct().getPurchaseTime().getLabel()) + .description(auction.getProduct().getDescription()) + .tradeMethod(auction.getTradeMethod().getLabel()) + .si(auction.getTradingLocation().getSi()) + .gu(auction.getTradingLocation().getGu()) + .dong(auction.getTradingLocation().getDong()) + .build(); + } + +} From 4405285c3d42c7078c059ba1b6f97641e844065d Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:39:24 +0900 Subject: [PATCH 09/25] =?UTF-8?q?[feat]=20:=20=EC=A0=84=EC=97=AD=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC=20NotFoundException=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handsup/common/exception/GlobalExceptionHandler.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java b/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java index 9f8efec1..40c92d03 100644 --- a/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java +++ b/api/src/main/java/dev/handsup/common/exception/GlobalExceptionHandler.java @@ -40,4 +40,11 @@ public ErrorResponseTemplate handleValidationException(ValidationException e) { log.error("ValidationException : ", e); return new ErrorResponseTemplate(e.getMessage(), e.getCode()); } + + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(NotFoundException.class) + public ErrorResponseTemplate handleNotFoundException(NotFoundException e) { + log.error("NotFoundException : ", e); + return new ErrorResponseTemplate(e.getMessage(), e.getCode()); + } } From 128bc55f63c3cb9a673e11804901bd83e0b385af Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:41:44 +0900 Subject: [PATCH 10/25] =?UTF-8?q?[feat]=20auctionService=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EA=B4=80=EB=A0=A8=20repository=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auction/repository/AuctionRepository.java | 8 +++++ .../repository/ProductCategoryRepository.java | 11 +++++++ .../auction/service/AuctionService.java | 32 +++++++++++++++++++ 3 files changed, 51 insertions(+) create mode 100644 core/src/main/java/dev/handsup/auction/repository/AuctionRepository.java create mode 100644 core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java create mode 100644 core/src/main/java/dev/handsup/auction/service/AuctionService.java diff --git a/core/src/main/java/dev/handsup/auction/repository/AuctionRepository.java b/core/src/main/java/dev/handsup/auction/repository/AuctionRepository.java new file mode 100644 index 00000000..54311014 --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/repository/AuctionRepository.java @@ -0,0 +1,8 @@ +package dev.handsup.auction.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import dev.handsup.auction.domain.Auction; + +public interface AuctionRepository extends JpaRepository { +} diff --git a/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java b/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java new file mode 100644 index 00000000..94eae14b --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java @@ -0,0 +1,11 @@ +package dev.handsup.auction.repository; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import dev.handsup.auction.domain.product.product_category.ProductCategory; + +public interface ProductCategoryRepository extends JpaRepository { + Optional findByCategoryValue(String categoryValue); +} diff --git a/core/src/main/java/dev/handsup/auction/service/AuctionService.java b/core/src/main/java/dev/handsup/auction/service/AuctionService.java new file mode 100644 index 00000000..51a0de22 --- /dev/null +++ b/core/src/main/java/dev/handsup/auction/service/AuctionService.java @@ -0,0 +1,32 @@ +package dev.handsup.auction.service; + +import org.springframework.stereotype.Service; + +import dev.handsup.auction.domain.Auction; +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import dev.handsup.auction.dto.AuctionResponse; +import dev.handsup.auction.dto.RegisterAuctionRequest; +import dev.handsup.auction.dto.mapper.AuctionMapper; +import dev.handsup.auction.exception.AuctionErrorCode; +import dev.handsup.auction.repository.AuctionRepository; +import dev.handsup.auction.repository.ProductCategoryRepository; +import dev.handsup.common.exception.NotFoundException; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class AuctionService { + private final AuctionRepository auctionRepository; + private final ProductCategoryRepository productCategoryRepository; + + public AuctionResponse registerAuction(RegisterAuctionRequest request) { + ProductCategory productCategory = findProductCategoryEntity(request); + Auction auction = AuctionMapper.toAuction(request, productCategory); + return AuctionMapper.toAuctionResponse(auctionRepository.save(auction)); + } + + private ProductCategory findProductCategoryEntity(RegisterAuctionRequest request) { + return productCategoryRepository.findByCategoryValue(request.productCategory()). + orElseThrow(()-> new NotFoundException(AuctionErrorCode.NOT_FOUND_PRODUCT_CATEGORY)); + } +} From 76de873470c47bb0c28ae7a87a0a8f2a41728504 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:43:03 +0900 Subject: [PATCH 11/25] =?UTF-8?q?[feat]=20:=20auctionErrorCode=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dev/handsup/auction/exception/AuctionErrorCode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java index 4ccf2b4b..47bdd672 100644 --- a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java +++ b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java @@ -11,7 +11,7 @@ public enum AuctionErrorCode implements ErrorCode { NOT_FOUND_PRODUCT_STATUS("올바른 상품 상태를 입력해주세요", "P_001"), NOT_FOUND_PURCHASE_TIME("올바른 구매 시기를 입력해주세요", "P_002" ), NOT_FOUND_TADE_METHOD("올바른 거래 방법을 입력해주세요","P_003" ), - NOT_FOUND_PRODUCT_CATEGORY("올바른 상품 카테고리를 입력해주세요","P_004" ); + NOT_FOUND_PRODUCT_CATEGORY("DB에 해당 상품 카테고리가 존재하지 않습니다.", "P_005"); private final String message; private final String code; From 177382fcd89c603dfadaa5172772dbc54d160483 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:44:03 +0900 Subject: [PATCH 12/25] =?UTF-8?q?[feat]=20:=20@=20valid,=20@=20EnableJpaAu?= =?UTF-8?q?diting=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/src/main/java/dev/handsup/HandsUpApplication.java | 2 ++ .../dev/handsup/auction/controller/AuctionController.java | 5 +++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/api/src/main/java/dev/handsup/HandsUpApplication.java b/api/src/main/java/dev/handsup/HandsUpApplication.java index 4317731c..511849f1 100644 --- a/api/src/main/java/dev/handsup/HandsUpApplication.java +++ b/api/src/main/java/dev/handsup/HandsUpApplication.java @@ -2,7 +2,9 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +@EnableJpaAuditing @SpringBootApplication public class HandsUpApplication { diff --git a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java index 8c4f10b6..c3118bbd 100644 --- a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java +++ b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java @@ -8,10 +8,11 @@ import dev.handsup.auction.dto.ApiAuctionMapper; import dev.handsup.auction.dto.AuctionResponse; +import dev.handsup.auction.dto.RegisterAuctionApiRequest; import dev.handsup.auction.dto.RegisterAuctionRequest; import dev.handsup.auction.service.AuctionService; -import dev.handsup.auction.dto.RegisterAuctionApiRequest; import io.swagger.v3.oas.annotations.Operation; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @RestController @@ -22,7 +23,7 @@ public class AuctionController { @Operation(summary = "경매 등록 API", description = "경매를 등록한다") @PostMapping - public ResponseEntity registerAuction(@RequestBody RegisterAuctionApiRequest request){ + public ResponseEntity registerAuction(@Valid @RequestBody RegisterAuctionApiRequest request){ RegisterAuctionRequest registerAuctionRequest = ApiAuctionMapper.toRegisterAuctionRequest(request); AuctionResponse response = auctionService.registerAuction(registerAuctionRequest); return ResponseEntity.ok(response); From 3e0406fe1eb71824a4d0403acde8a0253761694a Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:48:42 +0900 Subject: [PATCH 13/25] =?UTF-8?q?[feat]=20:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EA=B0=92=20Enum=20->=20String=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/product_category/ProductCategory.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java index 71641126..009f9fed 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java @@ -20,9 +20,9 @@ public class ProductCategory { private Long id; @Column(name = "product_category_value", nullable = false) - private Category category; + private String categoryValue; - public ProductCategory(Category category) { - this.category = category; + public ProductCategory(String categoryValue) { + this.categoryValue = categoryValue; } } From 76fc96110960da1a40ab0ed289eb9addba090aca Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 21:52:14 +0900 Subject: [PATCH 14/25] =?UTF-8?q?[refactor]=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8F=AC=EB=A9=A7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/handsup/auction/domain/Auction.java | 2 +- .../domain/auction_field/PurchaseTime.java | 2 +- .../domain/auction_field/TradeMethod.java | 2 +- .../auction/domain/product/Product.java | 12 +++++-- .../auction/domain/product/ProductStatus.java | 2 +- .../product/product_category/Category.java | 31 ------------------- .../auction/dto/RegisterAuctionRequest.java | 1 + .../auction/dto/mapper/AuctionMapper.java | 1 + .../auction/exception/AuctionErrorCode.java | 4 +-- .../repository/ProductCategoryRepository.java | 1 + .../auction/service/AuctionService.java | 3 +- 11 files changed, 20 insertions(+), 41 deletions(-) delete mode 100644 core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java diff --git a/core/src/main/java/dev/handsup/auction/domain/Auction.java b/core/src/main/java/dev/handsup/auction/domain/Auction.java index 484b2769..c2b91cd2 100644 --- a/core/src/main/java/dev/handsup/auction/domain/Auction.java +++ b/core/src/main/java/dev/handsup/auction/domain/Auction.java @@ -43,7 +43,6 @@ public class Auction extends TimeBaseEntity { private static final String AUCTION = "auction"; - @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "auction_id") @@ -105,6 +104,7 @@ public Auction(String title, Product product, int initPrice, LocalDate endDate, bookmarkCount = 0; status = PROGRESS; } + public static Auction of( String title, ProductCategory productCategory, diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java index 31d39165..15a8beaf 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/PurchaseTime.java @@ -21,7 +21,7 @@ public enum PurchaseTime { private final String label; - public static PurchaseTime of(String input){ + public static PurchaseTime of(String input) { return Arrays.stream(values()) .filter(time -> time.isEqual(input)) .findAny() diff --git a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java index 30f0b95d..e55f7130 100644 --- a/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java +++ b/core/src/main/java/dev/handsup/auction/domain/auction_field/TradeMethod.java @@ -17,7 +17,7 @@ public enum TradeMethod { private final String label; - public static TradeMethod of(String input){ + public static TradeMethod of(String input) { return Arrays.stream(values()) .filter(method -> method.isEqual(input)) .findAny() diff --git a/core/src/main/java/dev/handsup/auction/domain/product/Product.java b/core/src/main/java/dev/handsup/auction/domain/product/Product.java index f54e1fd5..3c6facf0 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/Product.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/Product.java @@ -1,11 +1,14 @@ package dev.handsup.auction.domain.product; +import static dev.handsup.common.exception.CommonValidationError.*; import static jakarta.persistence.ConstraintMode.*; import static jakarta.persistence.EnumType.*; import static jakarta.persistence.FetchType.*; import static jakarta.persistence.GenerationType.*; import static lombok.AccessLevel.*; +import org.springframework.util.Assert; + import dev.handsup.auction.domain.auction_field.PurchaseTime; import dev.handsup.auction.domain.product.product_category.ProductCategory; import dev.handsup.common.entity.TimeBaseEntity; @@ -25,6 +28,7 @@ @Getter @NoArgsConstructor(access = PROTECTED) public class Product extends TimeBaseEntity { + private static final String PRODUCT = "product"; @Id @GeneratedValue(strategy = IDENTITY) @@ -46,13 +50,15 @@ public class Product extends TimeBaseEntity { @JoinColumn(name = "product_category_id", nullable = false, foreignKey = @ForeignKey(NO_CONSTRAINT)) - private ProductCategory category; + private ProductCategory productCategory; @Builder - public Product(ProductStatus status, String description, PurchaseTime purchaseTime, ProductCategory category) { + public Product(ProductStatus status, String description, PurchaseTime purchaseTime, + ProductCategory productCategory) { + Assert.hasText(description, getNotEmptyMessage(PRODUCT, "description")); this.status = status; this.description = description; this.purchaseTime = purchaseTime; - this.category = category; + this.productCategory = productCategory; } } \ No newline at end of file diff --git a/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java b/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java index 5fe00568..a197520c 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/ProductStatus.java @@ -18,7 +18,7 @@ public enum ProductStatus { private final String label; - public static ProductStatus of(String input){ + public static ProductStatus of(String input) { return Arrays.stream(values()) .filter(status -> status.isEqual(input)) .findAny() diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java deleted file mode 100644 index d9ec082c..00000000 --- a/core/src/main/java/dev/handsup/auction/domain/product/product_category/Category.java +++ /dev/null @@ -1,31 +0,0 @@ -package dev.handsup.auction.domain.product.product_category; - -import static dev.handsup.auction.exception.AuctionErrorCode.*; - -import java.util.Arrays; - -import dev.handsup.common.exception.ValidationException; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor -public enum Category { - - DIGITAL("디지털 기기"), - FURNITURE("가구"), - FASHION("패션"); - - private final String description; - - public static Category of(String input){ - return Arrays.stream(values()) - .filter(value -> value.isEqual(input)) - .findAny() - .orElseThrow(() -> new ValidationException(NOT_FOUND_PRODUCT_CATEGORY)); - } - - private boolean isEqual(String input) { - return input.equalsIgnoreCase(this.description); - } -} diff --git a/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java b/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java index a47e3e54..69ec4014 100644 --- a/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java +++ b/core/src/main/java/dev/handsup/auction/dto/RegisterAuctionRequest.java @@ -6,6 +6,7 @@ @Builder public record RegisterAuctionRequest( + String title, String productCategory, int initPrice, diff --git a/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java b/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java index 4f3dbe02..db7bb74b 100644 --- a/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java +++ b/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java @@ -34,6 +34,7 @@ public static Auction toAuction(RegisterAuctionRequest request, ProductCategory request.dong() ); } + public static AuctionResponse toAuctionResponse(Auction auction) { return AuctionResponse.builder() .auctionId(auction.getId()) diff --git a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java index 47bdd672..f8b1effa 100644 --- a/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java +++ b/core/src/main/java/dev/handsup/auction/exception/AuctionErrorCode.java @@ -9,8 +9,8 @@ public enum AuctionErrorCode implements ErrorCode { NOT_FOUND_PRODUCT_STATUS("올바른 상품 상태를 입력해주세요", "P_001"), - NOT_FOUND_PURCHASE_TIME("올바른 구매 시기를 입력해주세요", "P_002" ), - NOT_FOUND_TADE_METHOD("올바른 거래 방법을 입력해주세요","P_003" ), + NOT_FOUND_PURCHASE_TIME("올바른 구매 시기를 입력해주세요", "P_002"), + NOT_FOUND_TADE_METHOD("올바른 거래 방법을 입력해주세요", "P_003"), NOT_FOUND_PRODUCT_CATEGORY("DB에 해당 상품 카테고리가 존재하지 않습니다.", "P_005"); private final String message; diff --git a/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java b/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java index 94eae14b..5cc1b816 100644 --- a/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java +++ b/core/src/main/java/dev/handsup/auction/repository/ProductCategoryRepository.java @@ -7,5 +7,6 @@ import dev.handsup.auction.domain.product.product_category.ProductCategory; public interface ProductCategoryRepository extends JpaRepository { + Optional findByCategoryValue(String categoryValue); } diff --git a/core/src/main/java/dev/handsup/auction/service/AuctionService.java b/core/src/main/java/dev/handsup/auction/service/AuctionService.java index 51a0de22..5dad29d4 100644 --- a/core/src/main/java/dev/handsup/auction/service/AuctionService.java +++ b/core/src/main/java/dev/handsup/auction/service/AuctionService.java @@ -16,6 +16,7 @@ @Service @RequiredArgsConstructor public class AuctionService { + private final AuctionRepository auctionRepository; private final ProductCategoryRepository productCategoryRepository; @@ -27,6 +28,6 @@ public AuctionResponse registerAuction(RegisterAuctionRequest request) { private ProductCategory findProductCategoryEntity(RegisterAuctionRequest request) { return productCategoryRepository.findByCategoryValue(request.productCategory()). - orElseThrow(()-> new NotFoundException(AuctionErrorCode.NOT_FOUND_PRODUCT_CATEGORY)); + orElseThrow(() -> new NotFoundException(AuctionErrorCode.NOT_FOUND_PRODUCT_CATEGORY)); } } From a7389ae43a8aac522d6c3cf1e7986caab641b35c Mon Sep 17 00:00:00 2001 From: hs12 Date: Sat, 17 Feb 2024 22:01:05 +0900 Subject: [PATCH 15/25] =?UTF-8?q?[feat]=20:=20dto=20validation=20=EC=96=B4?= =?UTF-8?q?=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/RegisterAuctionApiRequest.java | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java index 1cd9fcce..1b55b39e 100644 --- a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java +++ b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java @@ -2,24 +2,42 @@ import java.time.LocalDate; +import com.fasterxml.jackson.annotation.JsonFormat; + +import jakarta.validation.constraints.Max; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + public record RegisterAuctionApiRequest( - String title, + @NotBlank(message = "title 값이 공백입니다.") + String title, + @NotBlank(message = "category 값이 공백입니다.") String category, - + @NotNull(message = "initPrice 값이 공백입니다.") + @Min(value = 1000, message = "최소 금액은 1000원입니다.") + @Max(value = 100000000, message = "최대 금액은 1억입니다.") int initPrice, + @NotNull(message = "endDate 값이 공백입니다.") + @JsonFormat(pattern = "yyyy-MM-dd") //localDate 형식으로 받음 LocalDate endDate, + @NotBlank(message = "productStatus가 공백입니다.") String productStatus, + @NotBlank(message = "purchaseTime이 공백입니다.") String purchaseTime, + @NotBlank(message = "description이 공백입니다.") String description, + @NotBlank(message = "tradeMethod가 공백입니다.") String tradeMethod, String si, String gu, String dong -){} +) { +} From 92d604f2dbe03c2404917b8b4df341463beff9e5 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 16:53:26 +0900 Subject: [PATCH 16/25] =?UTF-8?q?[feat]=20auction,=20product=20test=20fixt?= =?UTF-8?q?ure=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/handsup/fixture/AuctionFixture.java | 32 +++++++++++++++++++ .../dev/handsup/fixture/ProductFixture.java | 14 ++++++++ 2 files changed, 46 insertions(+) create mode 100644 core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java create mode 100644 core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java diff --git a/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java new file mode 100644 index 00000000..1e8be611 --- /dev/null +++ b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java @@ -0,0 +1,32 @@ +package dev.handsup.fixture; + +import static lombok.AccessLevel.*; + +import java.time.LocalDate; + +import dev.handsup.auction.domain.Auction; +import dev.handsup.auction.domain.auction_field.PurchaseTime; +import dev.handsup.auction.domain.auction_field.TradeMethod; +import dev.handsup.auction.domain.product.ProductStatus; +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PRIVATE) +public class AuctionFixture { + + public static Auction auction(){ + return Auction.of( + "거의 새상품 버즈 팔아요", + ProductCategory.of("디지털 기기"), + 10000, + LocalDate.parse("2022-10-18"), + ProductStatus.NEW, + PurchaseTime.UNDER_ONE_MONTH, + "거의 새상품이에요", + TradeMethod.DIRECT, + "서울시", + "성북구", + "동선동" + ); + } +} diff --git a/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java new file mode 100644 index 00000000..5d5689a0 --- /dev/null +++ b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java @@ -0,0 +1,14 @@ +package dev.handsup.fixture; + +import static lombok.AccessLevel.*; + +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PRIVATE) +public class ProductFixture { + + public static ProductCategory productCategory(String categoryValue){ + return ProductCategory.of(categoryValue); + } +} From 443efd8e512c363cabd56465103eda62b785ef0b Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 16:56:39 +0900 Subject: [PATCH 17/25] =?UTF-8?q?[chore]=20:=20testFixtures=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=B4=20=EB=AA=A8=EB=93=88=EA=B0=84=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=A4=91=EB=B3=B5=20?= =?UTF-8?q?=EC=A4=84=EC=9D=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/build.gradle | 1 + build.gradle | 1 + core/build.gradle | 13 +++-- .../handsup/support/TestContainerSupport.java | 49 +++++++++++++++++++ 4 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java diff --git a/api/build.gradle b/api/build.gradle index 4a9d58bc..3dfd7111 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,5 +1,6 @@ dependencies { implementation project(path: ':core') + testImplementation(testFixtures(project(':core'))) implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' diff --git a/build.gradle b/build.gradle index efef14d4..eae6851e 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,7 @@ subprojects { apply { plugin('java') } apply { plugin('org.springframework.boot') } apply { plugin('io.spring.dependency-management') } + apply { plugin('java-test-fixtures')} dependencies { compileOnly 'org.projectlombok:lombok' diff --git a/core/build.gradle b/core/build.gradle index 1c15dbe3..d0603cc7 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -17,8 +17,13 @@ dependencies { runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5' - // test container - testImplementation "org.testcontainers:junit-jupiter:1.19.5" - testImplementation "org.testcontainers:testcontainers:1.19.5" - testImplementation "org.testcontainers:mysql:1.19.2" //mysql test container + // testFixtures 의존성 + testFixturesImplementation 'org.springframework.boot:spring-boot-starter-test' + testFixturesImplementation "org.testcontainers:junit-jupiter:1.19.5" + testFixturesImplementation "org.testcontainers:testcontainers:1.19.5" + testFixturesImplementation "org.testcontainers:mysql:1.19.2" //mysql test container + + testFixturesCompileOnly 'org.projectlombok:lombok' + testFixturesAnnotationProcessor 'org.projectlombok:lombok' + testFixturesCompileOnly 'org.springframework.boot:spring-boot-starter-security' } diff --git a/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java b/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java new file mode 100644 index 00000000..d04f0d84 --- /dev/null +++ b/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java @@ -0,0 +1,49 @@ +package dev.handsup.support; + +import static lombok.AccessLevel.*; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.utility.DockerImageName; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PROTECTED) +public abstract class TestContainerSupport { + + private static final String REDIS_IMAGE = "redis:latest"; + private static final String MYSQL_IMAGE = "mysql:8.0"; + private static final int REDIS_PORT = 6379; + private static final int MYSQL_PORT = 3306; + + private static final GenericContainer REDIS; + private static final JdbcDatabaseContainer MYSQL; + + // 컨테이너 싱글톤으로 생성 + static { + REDIS = new GenericContainer<>(DockerImageName.parse(REDIS_IMAGE)) + .withExposedPorts(REDIS_PORT) + .withReuse(true); + MYSQL = new MySQLContainer<>(DockerImageName.parse(MYSQL_IMAGE)) + .withExposedPorts(MYSQL_PORT) + .withReuse(true); + + REDIS.start(); + MYSQL.start(); + } + + // 동적으로 속성 할당 + @DynamicPropertySource + public static void setUp(DynamicPropertyRegistry registry) { + registry.add("spring.data.redis.host", REDIS::getHost); + registry.add("spring.data.redis.port", () -> String.valueOf(REDIS.getMappedPort(REDIS_PORT))); + + registry.add("spring.datasource.driver-class-name", MYSQL::getDriverClassName); + registry.add("spring.datasource.url", MYSQL::getJdbcUrl); + registry.add("spring.datasource.username", MYSQL::getUsername); + registry.add("spring.datasource.password", MYSQL::getPassword); + } +} \ No newline at end of file From 9857e4099c81b3dc1d38770bca19e88714714d25 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 16:57:39 +0900 Subject: [PATCH 18/25] =?UTF-8?q?[feat]=20:=20=EA=B2=BD=EB=A7=A4=EA=B8=80?= =?UTF-8?q?=20=EB=93=B1=EB=A1=9D=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auction/service/AuctionServiceTest.java | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java diff --git a/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java b/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java new file mode 100644 index 00000000..fac8bc69 --- /dev/null +++ b/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java @@ -0,0 +1,78 @@ +package dev.handsup.auction.service; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.*; + +import java.time.LocalDate; +import java.util.Optional; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import dev.handsup.auction.domain.Auction; +import dev.handsup.auction.domain.auction_field.PurchaseTime; +import dev.handsup.auction.domain.auction_field.TradeMethod; +import dev.handsup.auction.domain.product.ProductStatus; +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import dev.handsup.auction.dto.AuctionResponse; +import dev.handsup.auction.dto.RegisterAuctionRequest; +import dev.handsup.auction.repository.AuctionRepository; +import dev.handsup.auction.repository.ProductCategoryRepository; +import dev.handsup.fixture.AuctionFixture; +import dev.handsup.fixture.ProductFixture; + +@ExtendWith(MockitoExtension.class) +class AuctionServiceTest { + + private final String DIGITAL_DEVICE = "디지털 기기"; + @Mock + private AuctionRepository auctionRepository; + @Mock + private ProductCategoryRepository productCategoryRepository; + + @InjectMocks + private AuctionService auctionService; + + @Test + @DisplayName("경매글을 등록할 수 있다.") + void registerAuction() { + // given + ProductCategory productCategory = ProductFixture.productCategory(DIGITAL_DEVICE); + Auction auction = AuctionFixture.auction(); + RegisterAuctionRequest registerAuctionRequest = + RegisterAuctionRequest.builder() + .title("거의 새상품 버즈 팔아요") + .tradeMethod(TradeMethod.DIRECT.getLabel()) + .purchaseTime(PurchaseTime.UNDER_ONE_MONTH.getLabel()) + .productCategory(DIGITAL_DEVICE) + .productStatus(ProductStatus.NEW.getLabel()) + .endDate(LocalDate.parse("2022-10-18")) + .description("거의 새상품이에요") + .initPrice(10000) + .si("서울시") + .gu("성북구") + .dong("동선동") + .build(); + + given(productCategoryRepository.findByCategoryValue(DIGITAL_DEVICE)) + .willReturn(Optional.of(productCategory)); + given(auctionRepository.save(any(Auction.class))).willReturn(auction); + + // when + AuctionResponse auctionResponse = auctionService.registerAuction(registerAuctionRequest); + + // then + assertAll( + () -> assertThat(auctionResponse.title()).isEqualTo(registerAuctionRequest.title()), + () -> assertThat(auctionResponse.tradeMethod()).isEqualTo(registerAuctionRequest.tradeMethod()), + () -> assertThat(auctionResponse.endDate()).isEqualTo(registerAuctionRequest.endDate()), + () -> assertThat(auctionResponse.purchaseTime()).isEqualTo(registerAuctionRequest.purchaseTime()), + () -> assertThat(auctionResponse.productCategory()).isEqualTo(registerAuctionRequest.productCategory()) + ); + } +} From 7945f68695cef6e0a79ffbfdbe444d97f8c6e7e0 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 20:09:42 +0900 Subject: [PATCH 19/25] =?UTF-8?q?[fix]=20:=20springboottest=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=8A=A4=EC=BA=94=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/build.gradle | 8 --- .../java/dev/handsup/HandsUpApplication.java | 6 +-- .../handsup/auction/dto/ApiAuctionMapper.java | 5 +- .../dto/RegisterAuctionApiRequest.java | 8 +-- .../handsup/support/DataJpaTestSupport.java | 2 +- .../handsup/support/TestContainerSupport.java | 44 ----------------- .../dev/handsup/fixture/AuctionFixture.java | 32 ------------ .../dev/handsup/fixture/ProductFixture.java | 14 ------ .../handsup/support/TestContainerSupport.java | 49 ------------------- 9 files changed, 12 insertions(+), 156 deletions(-) delete mode 100644 core/src/test/java/dev/handsup/support/TestContainerSupport.java delete mode 100644 core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java delete mode 100644 core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java delete mode 100644 core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java diff --git a/api/build.gradle b/api/build.gradle index 3dfd7111..131074e6 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -7,12 +7,4 @@ dependencies { //swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' - - tasks.named('bootJar') { - enabled = true - } - - tasks.named('jar') { - enabled = false - } } diff --git a/api/src/main/java/dev/handsup/HandsUpApplication.java b/api/src/main/java/dev/handsup/HandsUpApplication.java index 511849f1..bc756341 100644 --- a/api/src/main/java/dev/handsup/HandsUpApplication.java +++ b/api/src/main/java/dev/handsup/HandsUpApplication.java @@ -6,11 +6,11 @@ @EnableJpaAuditing @SpringBootApplication -public class HandsUpApplication { +public class ApiApplication { public static void main(String[] args) { // 타 모듈 yml 가져오기 - System.setProperty("spring.config.name", "application,application-core"); - SpringApplication.run(HandsUpApplication.class, args); + System.setProperty("spring.config.name", "application, application-core"); + SpringApplication.run(ApiApplication.class, args); } } diff --git a/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java b/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java index e8acad87..ea1fc8ad 100644 --- a/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java +++ b/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java @@ -1,7 +1,8 @@ -package dev.handsup.auction.dto; +package dev.handsup.auction.dtos; import static lombok.AccessLevel.*; +import dev.handsup.auction.dto.RegisterAuctionRequest; import lombok.NoArgsConstructor; @NoArgsConstructor(access = PRIVATE) @@ -9,7 +10,7 @@ public class ApiAuctionMapper { public static RegisterAuctionRequest toRegisterAuctionRequest(RegisterAuctionApiRequest request){ return new RegisterAuctionRequest( request.title(), - request.category(), + request.productCategory(), request.initPrice(), request.endDate(), request.productStatus(), diff --git a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java index 1b55b39e..fc9d9468 100644 --- a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java +++ b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java @@ -1,4 +1,4 @@ -package dev.handsup.auction.dto; +package dev.handsup.auction.dtos; import java.time.LocalDate; @@ -8,13 +8,15 @@ import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import lombok.Builder; +@Builder public record RegisterAuctionApiRequest( @NotBlank(message = "title 값이 공백입니다.") String title, - @NotBlank(message = "category 값이 공백입니다.") - String category, + @NotBlank(message = "productCategory 값이 공백입니다.") + String productCategory, @NotNull(message = "initPrice 값이 공백입니다.") @Min(value = 1000, message = "최소 금액은 1000원입니다.") @Max(value = 100000000, message = "최대 금액은 1억입니다.") diff --git a/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java b/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java index f20f9ba8..7b9f558b 100644 --- a/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java +++ b/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java @@ -1,4 +1,4 @@ -package dev.handsup.support; +package dev.handsup.common.support; import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.*; diff --git a/core/src/test/java/dev/handsup/support/TestContainerSupport.java b/core/src/test/java/dev/handsup/support/TestContainerSupport.java deleted file mode 100644 index 1f06b3d2..00000000 --- a/core/src/test/java/dev/handsup/support/TestContainerSupport.java +++ /dev/null @@ -1,44 +0,0 @@ -package dev.handsup.support; - -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.JdbcDatabaseContainer; -import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.utility.DockerImageName; - -public abstract class TestContainerSupport { - - private static final String REDIS_IMAGE = "redis:latest"; - private static final String MYSQL_IMAGE = "mysql:8.0"; - private static final int REDIS_PORT = 6379; - private static final int MYSQL_PORT = 3306; - - private static final GenericContainer REDIS; - private static final JdbcDatabaseContainer MYSQL; - - // 컨테이너 싱글톤으로 생성 - static { - REDIS = new GenericContainer<>(DockerImageName.parse(REDIS_IMAGE)) - .withExposedPorts(REDIS_PORT) - .withReuse(true); - MYSQL = new MySQLContainer<>(DockerImageName.parse(MYSQL_IMAGE)) - .withExposedPorts(MYSQL_PORT) - .withReuse(true); - - REDIS.start(); - MYSQL.start(); - } - - // 동적으로 속성 할당 - @DynamicPropertySource - public static void setUp(DynamicPropertyRegistry registry) { - registry.add("spring.data.redis.host", REDIS::getHost); - registry.add("spring.data.redis.port", () -> String.valueOf(REDIS.getMappedPort(REDIS_PORT))); - - registry.add("spring.datasource.driver-class-name", MYSQL::getDriverClassName); - registry.add("spring.datasource.url", MYSQL::getJdbcUrl); - registry.add("spring.datasource.username", MYSQL::getUsername); - registry.add("spring.datasource.password", MYSQL::getPassword); - } -} \ No newline at end of file diff --git a/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java deleted file mode 100644 index 1e8be611..00000000 --- a/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.handsup.fixture; - -import static lombok.AccessLevel.*; - -import java.time.LocalDate; - -import dev.handsup.auction.domain.Auction; -import dev.handsup.auction.domain.auction_field.PurchaseTime; -import dev.handsup.auction.domain.auction_field.TradeMethod; -import dev.handsup.auction.domain.product.ProductStatus; -import dev.handsup.auction.domain.product.product_category.ProductCategory; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = PRIVATE) -public class AuctionFixture { - - public static Auction auction(){ - return Auction.of( - "거의 새상품 버즈 팔아요", - ProductCategory.of("디지털 기기"), - 10000, - LocalDate.parse("2022-10-18"), - ProductStatus.NEW, - PurchaseTime.UNDER_ONE_MONTH, - "거의 새상품이에요", - TradeMethod.DIRECT, - "서울시", - "성북구", - "동선동" - ); - } -} diff --git a/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java deleted file mode 100644 index 5d5689a0..00000000 --- a/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.handsup.fixture; - -import static lombok.AccessLevel.*; - -import dev.handsup.auction.domain.product.product_category.ProductCategory; -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = PRIVATE) -public class ProductFixture { - - public static ProductCategory productCategory(String categoryValue){ - return ProductCategory.of(categoryValue); - } -} diff --git a/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java b/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java deleted file mode 100644 index d04f0d84..00000000 --- a/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java +++ /dev/null @@ -1,49 +0,0 @@ -package dev.handsup.support; - -import static lombok.AccessLevel.*; - -import org.springframework.test.context.DynamicPropertyRegistry; -import org.springframework.test.context.DynamicPropertySource; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.JdbcDatabaseContainer; -import org.testcontainers.containers.MySQLContainer; -import org.testcontainers.utility.DockerImageName; - -import lombok.NoArgsConstructor; - -@NoArgsConstructor(access = PROTECTED) -public abstract class TestContainerSupport { - - private static final String REDIS_IMAGE = "redis:latest"; - private static final String MYSQL_IMAGE = "mysql:8.0"; - private static final int REDIS_PORT = 6379; - private static final int MYSQL_PORT = 3306; - - private static final GenericContainer REDIS; - private static final JdbcDatabaseContainer MYSQL; - - // 컨테이너 싱글톤으로 생성 - static { - REDIS = new GenericContainer<>(DockerImageName.parse(REDIS_IMAGE)) - .withExposedPorts(REDIS_PORT) - .withReuse(true); - MYSQL = new MySQLContainer<>(DockerImageName.parse(MYSQL_IMAGE)) - .withExposedPorts(MYSQL_PORT) - .withReuse(true); - - REDIS.start(); - MYSQL.start(); - } - - // 동적으로 속성 할당 - @DynamicPropertySource - public static void setUp(DynamicPropertyRegistry registry) { - registry.add("spring.data.redis.host", REDIS::getHost); - registry.add("spring.data.redis.port", () -> String.valueOf(REDIS.getMappedPort(REDIS_PORT))); - - registry.add("spring.datasource.driver-class-name", MYSQL::getDriverClassName); - registry.add("spring.datasource.url", MYSQL::getJdbcUrl); - registry.add("spring.datasource.username", MYSQL::getUsername); - registry.add("spring.datasource.password", MYSQL::getPassword); - } -} \ No newline at end of file From 9622d47806ac0f8fb1e8fd6d81edfc3c2284adf3 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 20:13:26 +0900 Subject: [PATCH 20/25] =?UTF-8?q?[feat]=20controller=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=EC=9A=A9=20support=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dev/handsup/HandsUpApplication.java | 4 +-- .../auction/controller/AuctionController.java | 1 + .../common/support/ApiTestSupport.java | 26 +++++++++++++++++++ api/src/test/resources/application.yml | 11 ++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 api/src/test/java/dev/handsup/common/support/ApiTestSupport.java create mode 100644 api/src/test/resources/application.yml diff --git a/api/src/main/java/dev/handsup/HandsUpApplication.java b/api/src/main/java/dev/handsup/HandsUpApplication.java index bc756341..c1be1152 100644 --- a/api/src/main/java/dev/handsup/HandsUpApplication.java +++ b/api/src/main/java/dev/handsup/HandsUpApplication.java @@ -6,11 +6,11 @@ @EnableJpaAuditing @SpringBootApplication -public class ApiApplication { +public class HandsUpApplication { public static void main(String[] args) { // 타 모듈 yml 가져오기 System.setProperty("spring.config.name", "application, application-core"); - SpringApplication.run(ApiApplication.class, args); + SpringApplication.run(HandsUpApplication.class, args); } } diff --git a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java index c3118bbd..b5d078cf 100644 --- a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java +++ b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java @@ -19,6 +19,7 @@ @RequiredArgsConstructor @RequestMapping("/api/auctions") public class AuctionController { + private final AuctionService auctionService; @Operation(summary = "경매 등록 API", description = "경매를 등록한다") diff --git a/api/src/test/java/dev/handsup/common/support/ApiTestSupport.java b/api/src/test/java/dev/handsup/common/support/ApiTestSupport.java new file mode 100644 index 00000000..343eac39 --- /dev/null +++ b/api/src/test/java/dev/handsup/common/support/ApiTestSupport.java @@ -0,0 +1,26 @@ +package dev.handsup.common.support; + +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.test.web.servlet.MockMvc; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import dev.handsup.support.TestContainerSupport; + +@SpringBootTest +@AutoConfigureMockMvc +public abstract class ApiTestSupport extends TestContainerSupport { + + @Autowired + protected MockMvc mockMvc; + + @Autowired + protected ObjectMapper objectMapper; + + protected String toJson(Object object) throws JsonProcessingException { + return objectMapper.writeValueAsString(object); + } +} diff --git a/api/src/test/resources/application.yml b/api/src/test/resources/application.yml new file mode 100644 index 00000000..3ed86d6c --- /dev/null +++ b/api/src/test/resources/application.yml @@ -0,0 +1,11 @@ +spring: + jpa: + hibernate: + ddl-auto: create + properties: + hibernate: + format_sql: true + default_batch_fetch_size: 10 +logging.level: + org.hibernate.SQL: debug + org.hibernate.orm.jdbc.bind: trace \ No newline at end of file From d514c4f6819f1a8bd9cee3984583dd6b2409974d Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 20:41:58 +0900 Subject: [PATCH 21/25] =?UTF-8?q?[style]=20dto=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20enum=20=EA=B0=92?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../handsup/auction/dto/AuctionResponse.java | 3 +- .../auction/service/AuctionServiceTest.java | 2 +- .../dev/handsup/fixture/AuctionFixture.java | 32 ++++++++++++ .../dev/handsup/fixture/ProductFixture.java | 15 ++++++ .../handsup/support/TestContainerSupport.java | 49 +++++++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java create mode 100644 core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java create mode 100644 core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java diff --git a/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java b/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java index bbc4e1b7..bcdbf955 100644 --- a/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java +++ b/core/src/main/java/dev/handsup/auction/dto/AuctionResponse.java @@ -8,10 +8,9 @@ public record AuctionResponse( Long auctionId, - String title, - String category, + String productCategory, int initPrice, diff --git a/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java b/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java index fac8bc69..36bf934c 100644 --- a/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java +++ b/core/src/test/java/dev/handsup/auction/service/AuctionServiceTest.java @@ -47,7 +47,7 @@ void registerAuction() { RegisterAuctionRequest registerAuctionRequest = RegisterAuctionRequest.builder() .title("거의 새상품 버즈 팔아요") - .tradeMethod(TradeMethod.DIRECT.getLabel()) + .tradeMethod(TradeMethod.DELIVER.getLabel()) .purchaseTime(PurchaseTime.UNDER_ONE_MONTH.getLabel()) .productCategory(DIGITAL_DEVICE) .productStatus(ProductStatus.NEW.getLabel()) diff --git a/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java new file mode 100644 index 00000000..d19c6311 --- /dev/null +++ b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java @@ -0,0 +1,32 @@ +package dev.handsup.fixture; + +import static lombok.AccessLevel.*; + +import java.time.LocalDate; + +import dev.handsup.auction.domain.Auction; +import dev.handsup.auction.domain.auction_field.PurchaseTime; +import dev.handsup.auction.domain.auction_field.TradeMethod; +import dev.handsup.auction.domain.product.ProductStatus; +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PRIVATE) +public class AuctionFixture { + + public static Auction auction(){ + return Auction.of( + "거의 새상품 버즈 팔아요", + ProductCategory.of("디지털 기기"), + 10000, + LocalDate.parse("2022-10-18"), + ProductStatus.NEW, + PurchaseTime.UNDER_ONE_MONTH, + "거의 새상품이에요", + TradeMethod.DELIVER, + "서울시", + "성북구", + "동선동" + ); + } +} diff --git a/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java new file mode 100644 index 00000000..a25fc19b --- /dev/null +++ b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java @@ -0,0 +1,15 @@ +package dev.handsup.fixture; + +import static lombok.AccessLevel.*; + +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PRIVATE) +public class ProductFixture { + + public static ProductCategory productCategory(String productCategory){ + return ProductCategory.of(productCategory); + } +} + diff --git a/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java b/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java new file mode 100644 index 00000000..79990c5f --- /dev/null +++ b/core/src/testFixtures/java/dev/handsup/support/TestContainerSupport.java @@ -0,0 +1,49 @@ +package dev.handsup.support; + +import static lombok.AccessLevel.*; + +import org.springframework.test.context.DynamicPropertyRegistry; +import org.springframework.test.context.DynamicPropertySource; +import org.testcontainers.containers.GenericContainer; +import org.testcontainers.containers.JdbcDatabaseContainer; +import org.testcontainers.containers.MySQLContainer; +import org.testcontainers.utility.DockerImageName; + +import lombok.NoArgsConstructor; + +@NoArgsConstructor(access = PROTECTED) +public abstract class TestContainerSupport { + + private static final String REDIS_IMAGE = "redis:latest"; + private static final String MYSQL_IMAGE = "mysql:8.0"; + private static final int REDIS_PORT = 6379; + private static final int MYSQL_PORT = 3306; + + private static final GenericContainer REDIS; + private static final JdbcDatabaseContainer MYSQL; + + // 컨테이너 싱글톤으로 생성 + static { + REDIS = new GenericContainer<>(DockerImageName.parse(REDIS_IMAGE)) + .withExposedPorts(REDIS_PORT) + .withReuse(true); + MYSQL = new MySQLContainer<>(DockerImageName.parse(MYSQL_IMAGE)) + .withExposedPorts(MYSQL_PORT) + .withReuse(true); + + REDIS.start(); + MYSQL.start(); + } + + // 동적으로 속성 할당 + @DynamicPropertySource + public static void setUp(DynamicPropertyRegistry registry) { + registry.add("spring.data.redis.host", REDIS::getHost); + registry.add("spring.data.redis.port", () -> String.valueOf(REDIS.getMappedPort(REDIS_PORT))); + + registry.add("spring.datasource.driver-class-name", MYSQL::getDriverClassName); + registry.add("spring.datasource.url", MYSQL::getJdbcUrl); + registry.add("spring.datasource.username", MYSQL::getUsername); + registry.add("spring.datasource.password", MYSQL::getPassword); + } +} From f65ea076076f4fe789e1e2ad4e839e46919fa2f1 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 20:42:34 +0900 Subject: [PATCH 22/25] =?UTF-8?q?[feat]=20:=20=EA=B2=BD=EB=A7=A4=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AuctionControllerTest.java | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java diff --git a/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java b/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java new file mode 100644 index 00000000..5b18d82b --- /dev/null +++ b/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java @@ -0,0 +1,68 @@ +package dev.handsup.auction.controller; + +import static org.springframework.http.MediaType.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.time.LocalDate; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import dev.handsup.auction.domain.auction_field.PurchaseTime; +import dev.handsup.auction.domain.auction_field.TradeMethod; +import dev.handsup.auction.domain.product.ProductStatus; +import dev.handsup.auction.domain.product.product_category.ProductCategory; +import dev.handsup.auction.dto.RegisterAuctionApiRequest; +import dev.handsup.auction.repository.AuctionRepository; +import dev.handsup.auction.repository.ProductCategoryRepository; +import dev.handsup.common.support.ApiTestSupport; +import dev.handsup.fixture.ProductFixture; + +class AuctionControllerTest extends ApiTestSupport { + + @Autowired + private AuctionRepository auctionRepository; + @Autowired + private ProductCategoryRepository productCategoryRepository; + private final String DIGITAL_DEVICE = "디지털 기기"; + + @BeforeEach + void setUp() { + ProductCategory productCategory = ProductFixture.productCategory(DIGITAL_DEVICE); + productCategoryRepository.save(productCategory); + } + + @DisplayName("경매를 등록할 수 있다.") + @Test + void registerAuction() throws Exception { + RegisterAuctionApiRequest request = RegisterAuctionApiRequest.builder() + .title("아이패드 팔아요") + .description("아이패드 팔아요. 오래 되어서 싸게 팔아요") + .productStatus(ProductStatus.DIRTY.getLabel()) + .tradeMethod(TradeMethod.DIRECT.getLabel()) + .endDate(LocalDate.parse("2023-02-19")) + .initPrice(300000) + .purchaseTime(PurchaseTime.ABOVE_ONE_YEAR.getLabel()) + .productCategory(DIGITAL_DEVICE) + .build(); + + mockMvc.perform(post("/api/auctions") + .contentType(APPLICATION_JSON) + .content(toJson(request))) + .andExpect(status().isOk()) + .andExpect(jsonPath("$.title").value(request.title())) + .andExpect(jsonPath("$.description").value(request.description())) + .andExpect(jsonPath("$.productStatus").value(request.productStatus())) + .andExpect(jsonPath("$.tradeMethod").value(request.tradeMethod())) + .andExpect(jsonPath("$.endDate").value(request.endDate().toString())) + .andExpect(jsonPath("$.initPrice").value(request.initPrice())) + .andExpect(jsonPath("$.purchaseTime").value(request.purchaseTime())) + .andExpect(jsonPath("$.productCategory").value(request.productCategory())) + .andExpect(jsonPath("$.si").isEmpty()) + .andExpect(jsonPath("$.gu").isEmpty()) + .andExpect(jsonPath("$.dong").isEmpty()); + } +} \ No newline at end of file From 2a1169b2cdc98e7049909c5d7277913bcbe06bba Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 20:46:00 +0900 Subject: [PATCH 23/25] =?UTF-8?q?[refactor]=20:=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=ED=8F=AC=EB=A9=A7=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dev/handsup/auction/controller/AuctionController.java | 2 +- .../java/dev/handsup/auction/dto/ApiAuctionMapper.java | 6 +++--- .../handsup/auction/dto/RegisterAuctionApiRequest.java | 2 +- .../handsup/auction/controller/AuctionControllerTest.java | 2 +- .../domain/product/product_category/ProductCategory.java | 8 ++++++++ .../dev/handsup/auction/dto/mapper/AuctionMapper.java | 2 +- .../dev/handsup/user/dto/response/UserJoinResponse.java | 3 ++- .../test/java/dev/handsup/support/DataJpaTestSupport.java | 2 +- .../java/dev/handsup/fixture/AuctionFixture.java | 2 +- .../java/dev/handsup/fixture/ProductFixture.java | 2 +- 10 files changed, 20 insertions(+), 11 deletions(-) diff --git a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java index b5d078cf..7da3849c 100644 --- a/api/src/main/java/dev/handsup/auction/controller/AuctionController.java +++ b/api/src/main/java/dev/handsup/auction/controller/AuctionController.java @@ -24,7 +24,7 @@ public class AuctionController { @Operation(summary = "경매 등록 API", description = "경매를 등록한다") @PostMapping - public ResponseEntity registerAuction(@Valid @RequestBody RegisterAuctionApiRequest request){ + public ResponseEntity registerAuction(@Valid @RequestBody RegisterAuctionApiRequest request) { RegisterAuctionRequest registerAuctionRequest = ApiAuctionMapper.toRegisterAuctionRequest(request); AuctionResponse response = auctionService.registerAuction(registerAuctionRequest); return ResponseEntity.ok(response); diff --git a/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java b/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java index ea1fc8ad..94e88560 100644 --- a/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java +++ b/api/src/main/java/dev/handsup/auction/dto/ApiAuctionMapper.java @@ -1,13 +1,13 @@ -package dev.handsup.auction.dtos; +package dev.handsup.auction.dto; import static lombok.AccessLevel.*; -import dev.handsup.auction.dto.RegisterAuctionRequest; import lombok.NoArgsConstructor; @NoArgsConstructor(access = PRIVATE) public class ApiAuctionMapper { - public static RegisterAuctionRequest toRegisterAuctionRequest(RegisterAuctionApiRequest request){ + + public static RegisterAuctionRequest toRegisterAuctionRequest(RegisterAuctionApiRequest request) { return new RegisterAuctionRequest( request.title(), request.productCategory(), diff --git a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java index fc9d9468..bc014bc4 100644 --- a/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java +++ b/api/src/main/java/dev/handsup/auction/dto/RegisterAuctionApiRequest.java @@ -1,4 +1,4 @@ -package dev.handsup.auction.dtos; +package dev.handsup.auction.dto; import java.time.LocalDate; diff --git a/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java b/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java index 5b18d82b..0c1e0e06 100644 --- a/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java +++ b/api/src/test/java/dev/handsup/auction/controller/AuctionControllerTest.java @@ -23,11 +23,11 @@ class AuctionControllerTest extends ApiTestSupport { + private final String DIGITAL_DEVICE = "디지털 기기"; @Autowired private AuctionRepository auctionRepository; @Autowired private ProductCategoryRepository productCategoryRepository; - private final String DIGITAL_DEVICE = "디지털 기기"; @BeforeEach void setUp() { diff --git a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java index 009f9fed..534f767a 100644 --- a/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java +++ b/core/src/main/java/dev/handsup/auction/domain/product/product_category/ProductCategory.java @@ -7,6 +7,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -22,7 +23,14 @@ public class ProductCategory { @Column(name = "product_category_value", nullable = false) private String categoryValue; + @Builder(access = PRIVATE) public ProductCategory(String categoryValue) { this.categoryValue = categoryValue; } + + public static ProductCategory of(String categoryValue) { + return ProductCategory.builder() + .categoryValue(categoryValue) + .build(); + } } diff --git a/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java b/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java index db7bb74b..22cf96a3 100644 --- a/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java +++ b/core/src/main/java/dev/handsup/auction/dto/mapper/AuctionMapper.java @@ -39,7 +39,7 @@ public static AuctionResponse toAuctionResponse(Auction auction) { return AuctionResponse.builder() .auctionId(auction.getId()) .title(auction.getTitle()) - .category(auction.getProduct().getProductCategory().getCategoryValue()) + .productCategory(auction.getProduct().getProductCategory().getCategoryValue()) .initPrice(auction.getInitPrice()) .endDate(auction.getEndDate()) .productStatus(auction.getProduct().getStatus().getLabel()) diff --git a/core/src/main/java/dev/handsup/user/dto/response/UserJoinResponse.java b/core/src/main/java/dev/handsup/user/dto/response/UserJoinResponse.java index 1f614183..6900733b 100644 --- a/core/src/main/java/dev/handsup/user/dto/response/UserJoinResponse.java +++ b/core/src/main/java/dev/handsup/user/dto/response/UserJoinResponse.java @@ -3,4 +3,5 @@ public record UserJoinResponse( Long userId -) {} +) { +} diff --git a/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java b/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java index 7b9f558b..f20f9ba8 100644 --- a/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java +++ b/core/src/test/java/dev/handsup/support/DataJpaTestSupport.java @@ -1,4 +1,4 @@ -package dev.handsup.common.support; +package dev.handsup.support; import static org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase.Replace.*; diff --git a/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java index d19c6311..882b7179 100644 --- a/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java +++ b/core/src/testFixtures/java/dev/handsup/fixture/AuctionFixture.java @@ -14,7 +14,7 @@ @NoArgsConstructor(access = PRIVATE) public class AuctionFixture { - public static Auction auction(){ + public static Auction auction() { return Auction.of( "거의 새상품 버즈 팔아요", ProductCategory.of("디지털 기기"), diff --git a/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java index a25fc19b..c7f3600b 100644 --- a/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java +++ b/core/src/testFixtures/java/dev/handsup/fixture/ProductFixture.java @@ -8,7 +8,7 @@ @NoArgsConstructor(access = PRIVATE) public class ProductFixture { - public static ProductCategory productCategory(String productCategory){ + public static ProductCategory productCategory(String productCategory) { return ProductCategory.of(productCategory); } } From 0de31e709a7a9d94f6a1676013409de16b61db31 Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 20:50:02 +0900 Subject: [PATCH 24/25] =?UTF-8?q?[fix]=20:=20403=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=ED=95=B4=EA=B2=B0=20=EC=9C=84=ED=95=B4=20security=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/build.gradle b/core/build.gradle index d0603cc7..0cafbdfe 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,11 +1,11 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' - implementation 'org.springframework.boot:spring-boot-starter-security' +// implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' +// implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-validation' runtimeOnly 'com.mysql:mysql-connector-j' - testImplementation 'org.springframework.security:spring-security-test' +// testImplementation 'org.springframework.security:spring-security-test' testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2' //redis From a8f15aed753db4ca6402b77ebe8e71a6e0731e5b Mon Sep 17 00:00:00 2001 From: hs12 Date: Sun, 18 Feb 2024 21:45:05 +0900 Subject: [PATCH 25/25] =?UTF-8?q?[fix]=20:=20jar=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EC=95=88=EB=90=98=EB=8A=94=20=EC=97=90?= =?UTF-8?q?=EB=9F=AC=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/build.gradle | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/build.gradle b/api/build.gradle index 131074e6..a7d37ba1 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -7,4 +7,12 @@ dependencies { //swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0' + + tasks.named('bootJar') { + enabled = true + } + + tasks.named('jar') { + enabled = true + } }