diff --git a/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/service/SaveRoundProductServiceTest.java b/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/service/SaveRoundProductServiceTest.java
index 9515180..8782b01 100644
--- a/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/service/SaveRoundProductServiceTest.java
+++ b/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/service/SaveRoundProductServiceTest.java
@@ -8,7 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import io.github.sejoung.product.persistence.repository.ProductRepository;
-import io.github.sejoung.product.persistence.util.TestUtil;
+import io.github.sejoung.product.persistence.util.JpaTestUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@@ -27,7 +27,7 @@ class SaveRoundProductServiceTest {
@Test
void saveRoundProduct() {
- var actual = service.saveRoundProduct(TestUtil.defaultRoundProduct());
+ var actual = service.saveRoundProduct(JpaTestUtil.defaultRoundProduct());
log.debug("{}",actual);
assertThat(actual.getProductId()).isNotNull();
diff --git a/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/util/TestUtil.java b/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/util/JpaTestUtil.java
similarity index 92%
rename from adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/util/TestUtil.java
rename to adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/util/JpaTestUtil.java
index 94eb87e..cb26b5f 100644
--- a/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/util/TestUtil.java
+++ b/adapters/jpa-persistence/src/test/java/io/github/sejoung/product/persistence/util/JpaTestUtil.java
@@ -4,7 +4,7 @@ import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
import io.github.sejoung.product.entities.RoundProduct;
-public interface TestUtil {
+public interface JpaTestUtil {
static RoundProduct defaultRoundProduct() {
return new RoundProduct(null, 1L, Category.ProductType.ROUND, Product.ProductStatus.CREATE, "회차권", 2);
}
diff --git a/adapters/rest/src/main/java/io/github/sejoung/product/rest/constants/ProductStatus.java b/adapters/rest/src/main/java/io/github/sejoung/product/rest/constants/ProductStatus.java
new file mode 100644
index 0000000..1e9452c
--- /dev/null
+++ b/adapters/rest/src/main/java/io/github/sejoung/product/rest/constants/ProductStatus.java
@@ -0,0 +1,5 @@
+package io.github.sejoung.product.rest.constants;
+
+public enum ProductStatus {
+ CREATE, DELETE, TEMPORARY, PERMANENTLY_DELETE
+}
diff --git a/adapters/rest/src/main/java/io/github/sejoung/product/rest/constants/ProductType.java b/adapters/rest/src/main/java/io/github/sejoung/product/rest/constants/ProductType.java
new file mode 100644
index 0000000..6c41500
--- /dev/null
+++ b/adapters/rest/src/main/java/io/github/sejoung/product/rest/constants/ProductType.java
@@ -0,0 +1,5 @@
+package io.github.sejoung.product.rest.constants;
+
+public enum ProductType {
+ ROUND, PERIOD
+}
\ No newline at end of file
diff --git a/adapters/rest/src/main/java/io/github/sejoung/product/rest/controller/SaveRoundProductController.java b/adapters/rest/src/main/java/io/github/sejoung/product/rest/controller/SaveRoundProductController.java
new file mode 100644
index 0000000..f9655e3
--- /dev/null
+++ b/adapters/rest/src/main/java/io/github/sejoung/product/rest/controller/SaveRoundProductController.java
@@ -0,0 +1,32 @@
+package io.github.sejoung.product.rest.controller;
+
+import javax.validation.Valid;
+
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import io.github.sejoung.product.rest.dto.SaveRoundProduct;
+import io.github.sejoung.product.rest.mapper.SaveRoundProductMapper;
+import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@RestController
+public class SaveRoundProductController {
+
+ private final SaveRoundProductInUseCase saveRoundProductInUseCase;
+
+ public SaveRoundProductController(
+ SaveRoundProductInUseCase saveRoundProductInUseCase) {
+ this.saveRoundProductInUseCase = saveRoundProductInUseCase;
+ }
+
+ @PostMapping("/product/round")
+ public SaveRoundProduct roundSave(
+ @Valid @RequestBody SaveRoundProduct dto) {
+ log.debug("{}", dto);
+ var command = saveRoundProductInUseCase.save(SaveRoundProductMapper.toEntity(dto));
+ return SaveRoundProductMapper.toDto(command);
+ }
+}
diff --git a/adapters/rest/src/main/java/io/github/sejoung/product/rest/dto/SaveRoundProduct.java b/adapters/rest/src/main/java/io/github/sejoung/product/rest/dto/SaveRoundProduct.java
new file mode 100644
index 0000000..ab5f70d
--- /dev/null
+++ b/adapters/rest/src/main/java/io/github/sejoung/product/rest/dto/SaveRoundProduct.java
@@ -0,0 +1,46 @@
+package io.github.sejoung.product.rest.dto;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+import io.github.sejoung.product.rest.constants.ProductStatus;
+import io.github.sejoung.product.rest.constants.ProductType;
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+
+@Getter
+@ToString
+public class SaveRoundProduct {
+
+ private final Long productId;
+
+ @NotNull
+ private final Long categoryId;
+
+ @NotNull
+ private final ProductType productType;
+
+ @NotNull
+ private final ProductStatus status;
+
+ @NotEmpty
+ private final String productName;
+
+ @Min(1)
+ @Max(99)
+ private final Integer count;
+
+ @Builder
+ private SaveRoundProduct(Long productId, Long categoryId,
+ ProductType productType, ProductStatus status, String productName, Integer count) {
+ this.productId = productId;
+ this.categoryId = categoryId;
+ this.productType = productType;
+ this.status = status;
+ this.productName = productName;
+ this.count = count;
+ }
+}
diff --git a/adapters/rest/src/main/java/io/github/sejoung/product/rest/mapper/SaveRoundProductMapper.java b/adapters/rest/src/main/java/io/github/sejoung/product/rest/mapper/SaveRoundProductMapper.java
new file mode 100644
index 0000000..02c4bdf
--- /dev/null
+++ b/adapters/rest/src/main/java/io/github/sejoung/product/rest/mapper/SaveRoundProductMapper.java
@@ -0,0 +1,28 @@
+package io.github.sejoung.product.rest.mapper;
+
+import io.github.sejoung.product.entities.Product;
+import io.github.sejoung.product.rest.constants.ProductType;
+import io.github.sejoung.product.rest.dto.SaveRoundProduct;
+import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
+
+public interface SaveRoundProductMapper {
+ static SaveRoundProductInUseCase.SaveRoundProductCommand toEntity(SaveRoundProduct dto) {
+ return SaveRoundProductInUseCase.SaveRoundProductCommand.builder()
+ .productName(dto.getProductName())
+ .categoryId(dto.getCategoryId())
+ .productId(dto.getProductId())
+ .status(Product.ProductStatus.valueOf(dto.getStatus().name()))
+ .count(dto.getCount())
+ .build();
+ }
+
+ static SaveRoundProduct toDto(SaveRoundProductInUseCase.SaveRoundProductCommand command) {
+ return SaveRoundProduct.builder()
+ .productType(ProductType.valueOf(command.getProductType().name()))
+ .productId(command.getProductId())
+ .productName(command.getProductName())
+ .categoryId(command.getCategoryId())
+ .count(command.getCount())
+ .build();
+ }
+}
diff --git a/adapters/rest/src/main/resources/application.yml b/adapters/rest/src/main/resources/application.yml
new file mode 100644
index 0000000..47fbb02
--- /dev/null
+++ b/adapters/rest/src/main/resources/application.yml
@@ -0,0 +1,2 @@
+server:
+ port: 8080
\ No newline at end of file
diff --git a/adapters/rest/src/main/resources/logback-spring.xml b/adapters/rest/src/main/resources/logback-spring.xml
new file mode 100644
index 0000000..23f0277
--- /dev/null
+++ b/adapters/rest/src/main/resources/logback-spring.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/adapters/rest/src/test/java/io/github/sejoung/product/rest/TestApplication.java b/adapters/rest/src/test/java/io/github/sejoung/product/rest/TestApplication.java
new file mode 100644
index 0000000..23e8042
--- /dev/null
+++ b/adapters/rest/src/test/java/io/github/sejoung/product/rest/TestApplication.java
@@ -0,0 +1,15 @@
+package io.github.sejoung.product.rest;
+
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+
+import io.github.sejoung.product.rest.util.SaveRoundProductInUseCaseStub;
+import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
+
+@SpringBootApplication
+public class TestApplication {
+ @Bean
+ public SaveRoundProductInUseCase saveRoundProductInUseCase() {
+ return new SaveRoundProductInUseCaseStub();
+ }
+}
diff --git a/adapters/rest/src/test/java/io/github/sejoung/product/rest/constants/ProductTypeTest.java b/adapters/rest/src/test/java/io/github/sejoung/product/rest/constants/ProductTypeTest.java
new file mode 100644
index 0000000..60ecaff
--- /dev/null
+++ b/adapters/rest/src/test/java/io/github/sejoung/product/rest/constants/ProductTypeTest.java
@@ -0,0 +1,18 @@
+package io.github.sejoung.product.rest.constants;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+import io.github.sejoung.product.entities.Category;
+
+class ProductTypeTest {
+
+ @Test
+ void valueOf() {
+ var actal = ProductType.valueOf(Category.ProductType.ROUND.name());
+
+ assertThat(actal).isNotNull();
+ }
+}
\ No newline at end of file
diff --git a/adapters/rest/src/test/java/io/github/sejoung/product/rest/controller/SaveRoundProductControllerTest.java b/adapters/rest/src/test/java/io/github/sejoung/product/rest/controller/SaveRoundProductControllerTest.java
new file mode 100644
index 0000000..9882557
--- /dev/null
+++ b/adapters/rest/src/test/java/io/github/sejoung/product/rest/controller/SaveRoundProductControllerTest.java
@@ -0,0 +1,46 @@
+package io.github.sejoung.product.rest.controller;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.BDDMockito.*;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.web.servlet.MockMvc;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import io.github.sejoung.product.rest.util.RestTestUtil;
+import io.github.sejoung.product.rest.util.SaveRoundProductInUseCaseStub;
+import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
+
+@WebMvcTest(controllers = SaveRoundProductController.class)
+class SaveRoundProductControllerTest {
+
+ private static final String URL = "/product/round";
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @DisplayName("회차권 API 테스트")
+ @Test
+ void saveRoundProduct() throws Exception {
+
+ var objectMapper = new ObjectMapper();
+ var json = objectMapper.writeValueAsString(RestTestUtil.defaultSaveRoundProductCommand(null));
+ mockMvc.perform(post(URL)
+ .contentType(MediaType.APPLICATION_JSON)
+ .accept(MediaType.APPLICATION_JSON)
+ .content(json))
+ .andDo(print())
+ .andExpect(status().isOk());
+
+ }
+}
\ No newline at end of file
diff --git a/adapters/rest/src/test/java/io/github/sejoung/product/rest/util/RestTestUtil.java b/adapters/rest/src/test/java/io/github/sejoung/product/rest/util/RestTestUtil.java
new file mode 100644
index 0000000..a1e5428
--- /dev/null
+++ b/adapters/rest/src/test/java/io/github/sejoung/product/rest/util/RestTestUtil.java
@@ -0,0 +1,18 @@
+package io.github.sejoung.product.rest.util;
+
+import io.github.sejoung.product.entities.Product;
+import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
+
+public interface RestTestUtil {
+
+ static SaveRoundProductInUseCase.SaveRoundProductCommand defaultSaveRoundProductCommand(Long productId) {
+ return SaveRoundProductInUseCase.SaveRoundProductCommand.builder()
+ .count(1)
+ .status(Product.ProductStatus.CREATE)
+ .productId(productId)
+ .productName("회차권")
+ .categoryId(1L)
+ .build();
+ }
+
+}
diff --git a/adapters/rest/src/test/java/io/github/sejoung/product/rest/util/SaveRoundProductInUseCaseStub.java b/adapters/rest/src/test/java/io/github/sejoung/product/rest/util/SaveRoundProductInUseCaseStub.java
new file mode 100644
index 0000000..79e2f99
--- /dev/null
+++ b/adapters/rest/src/test/java/io/github/sejoung/product/rest/util/SaveRoundProductInUseCaseStub.java
@@ -0,0 +1,19 @@
+package io.github.sejoung.product.rest.util;
+
+import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class SaveRoundProductInUseCaseStub implements SaveRoundProductInUseCase {
+ @Override
+ public SaveRoundProductCommand save(SaveRoundProductCommand command) {
+ log.debug("{}", command);
+ return SaveRoundProductCommand.builder()
+ .categoryId(command.getCategoryId())
+ .productName(command.getProductName())
+ .productId(1L)
+ .status(command.getStatus())
+ .count(command.getCount())
+ .build();
+ }
+}
diff --git a/domain/src/main/java/io/github/sejoung/product/mapper/SaveRoundProductCommandMapper.java b/domain/src/main/java/io/github/sejoung/product/mapper/SaveRoundProductCommandMapper.java
index 0350acd..15be8ee 100644
--- a/domain/src/main/java/io/github/sejoung/product/mapper/SaveRoundProductCommandMapper.java
+++ b/domain/src/main/java/io/github/sejoung/product/mapper/SaveRoundProductCommandMapper.java
@@ -1,14 +1,20 @@
package io.github.sejoung.product.mapper;
+import io.github.sejoung.product.entities.Product;
import io.github.sejoung.product.entities.RoundProduct;
import io.github.sejoung.product.usecases.port.in.SaveRoundProductInUseCase;
public interface SaveRoundProductCommandMapper {
static SaveRoundProductInUseCase.SaveRoundProductCommand toDto(RoundProduct roundProduct) {
- return new SaveRoundProductInUseCase.SaveRoundProductCommand(roundProduct.getProductId(),
- roundProduct.getCategory().getCategoryId(), roundProduct.getCategory().getProductType(),
- roundProduct.getStatus(), roundProduct.getProductName(), roundProduct.getCount());
+ return SaveRoundProductInUseCase.SaveRoundProductCommand.builder()
+ .productName(roundProduct.getProductName())
+ .productId(roundProduct.getProductId())
+ .status(
+ Product.ProductStatus.valueOf(roundProduct.getStatus().name()))
+ .categoryId(roundProduct.getCategory().getCategoryId())
+ .count(roundProduct.getCount())
+ .build();
}
static RoundProduct toEntity(SaveRoundProductInUseCase.SaveRoundProductCommand command) {
diff --git a/domain/src/main/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCase.java b/domain/src/main/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCase.java
index ddc3446..7ef43a7 100644
--- a/domain/src/main/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCase.java
+++ b/domain/src/main/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCase.java
@@ -9,14 +9,17 @@ import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
import io.github.sejoung.product.validating.SelfValidating;
+import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
+import lombok.ToString;
public interface SaveRoundProductInUseCase {
SaveRoundProductCommand save(SaveRoundProductCommand command);
@Getter
+ @ToString
@EqualsAndHashCode(callSuper = false)
final class SaveRoundProductCommand extends SelfValidating {
@@ -38,11 +41,12 @@ public interface SaveRoundProductInUseCase {
@Max(99)
private final Integer count;
- public SaveRoundProductCommand(Long productId, Long categoryId, Category.ProductType productType,
+ @Builder
+ private SaveRoundProductCommand(Long productId, Long categoryId,
Product.ProductStatus status, String productName, Integer count) {
this.productId = productId;
this.categoryId = categoryId;
- this.productType = productType;
+ this.productType = Category.ProductType.ROUND;
this.status = status;
this.productName = productName;
this.count = count;
diff --git a/domain/src/test/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCaseTest.java b/domain/src/test/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCaseTest.java
index 2465e59..d0928d1 100644
--- a/domain/src/test/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCaseTest.java
+++ b/domain/src/test/java/io/github/sejoung/product/usecases/port/in/SaveRoundProductInUseCaseTest.java
@@ -10,7 +10,6 @@ import org.junit.jupiter.api.Test;
import io.github.sejoung.product.entities.Category;
import io.github.sejoung.product.entities.Product;
-
class SaveRoundProductInUseCaseTest {
@DisplayName("Commend 회차권 count는 99 이하여야 합니다")
@@ -18,8 +17,13 @@ class SaveRoundProductInUseCaseTest {
void validationSaveRoundProductCommand() {
Throwable exception = assertThrows(ConstraintViolationException.class, () -> {
- var command = new SaveRoundProductInUseCase.SaveRoundProductCommand(null, 1L, Category.ProductType.ROUND,
- Product.ProductStatus.CREATE, "2회권", 999);
+ SaveRoundProductInUseCase.SaveRoundProductCommand.builder()
+ .categoryId(1L)
+ .status(Product.ProductStatus.CREATE)
+ .productName("안녕")
+ .count(999)
+ .build();
+
});
assertEquals("count: 99 이하여야 합니다", exception.getMessage());
diff --git a/domain/src/test/java/io/github/sejoung/product/usecases/service/SaveRoundProductServiceTest.java b/domain/src/test/java/io/github/sejoung/product/usecases/service/SaveRoundProductServiceTest.java
index 563c4e8..3c2c9d5 100644
--- a/domain/src/test/java/io/github/sejoung/product/usecases/service/SaveRoundProductServiceTest.java
+++ b/domain/src/test/java/io/github/sejoung/product/usecases/service/SaveRoundProductServiceTest.java
@@ -22,8 +22,12 @@ class SaveRoundProductServiceTest {
@DisplayName("회차권 저장")
@Test
void saveTest() {
- var command = new SaveRoundProductInUseCase.SaveRoundProductCommand(null, 1L, Category.ProductType.ROUND,
- Product.ProductStatus.CREATE, "2회권", 2);
+ var command = SaveRoundProductInUseCase.SaveRoundProductCommand.builder()
+ .productName("회차권")
+ .count(99)
+ .categoryId(1L)
+ .status(Product.ProductStatus.CREATE)
+ .build();
var actual = service.save(command);
Assertions.assertEquals(99, actual.getProductId());
}