rest 개발
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.github.sejoung.product.rest.constants;
|
||||
|
||||
public enum ProductStatus {
|
||||
CREATE, DELETE, TEMPORARY, PERMANENTLY_DELETE
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package io.github.sejoung.product.rest.constants;
|
||||
|
||||
public enum ProductType {
|
||||
ROUND, PERIOD
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
2
adapters/rest/src/main/resources/application.yml
Normal file
2
adapters/rest/src/main/resources/application.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
server:
|
||||
port: 8080
|
||||
10
adapters/rest/src/main/resources/logback-spring.xml
Normal file
10
adapters/rest/src/main/resources/logback-spring.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
|
||||
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
|
||||
<logger name="org.springframework" level="INFO" />
|
||||
<logger name="io.github.sejoung" level="DEBUG" />
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<SaveRoundProductCommand> {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user