From 1bc380f64ea78788d35da44e11aaebfa0043e2ff Mon Sep 17 00:00:00 2001 From: jhonatanaraujo1 Date: Thu, 9 Feb 2023 14:07:13 +0000 Subject: [PATCH] No pom XML coloquei Loombok e mapping strutucs para me ajudar com o mapeamento dos dtos para entidades. Estou utilizando o Banco de Dados H2 para fazer persistencia dos dados. Fiz alguns testes unitarios porem nao consegui fazer cobertura completa por falta de tempo, mas inseri alguns. --- pom.xml | 63 +++++++- .../blz/testjava/api/enums/TypeWarehouse.java | 5 + .../api/inventory/entity/InventoryEntity.java | 28 ++++ .../blz/testjava/api/mapper/MapperUtil.java | 142 ++++++++++++++++++ .../product/controller/ProductController.java | 51 +++++++ .../controller/domain/ProductRequest.java | 17 +++ .../controller/domain/ProductResponse.java | 14 ++ .../api/product/dto/InventoryDto.java | 16 ++ .../api/product/dto/WarehousesDto.java | 18 +++ .../api/product/entity/ProductEntity.java | 40 +++++ .../product/repository/ProductRepository.java | 12 ++ .../api/product/service/ProductService.java | 55 +++++++ .../api/werehouse/entity/WarehouseEntity.java | 29 ++++ .../ProductAlreadyExistsException.java | 7 + .../exceptions/ProductNotFoundException.java | 9 ++ src/main/resources/application.properties | 7 + src/main/resources/application.yml | 0 .../api/product/ProductServiceTest.java | 79 ++++++++++ .../com/blz/testjava/testUtils/TestUtils.java | 77 ++++++++++ 19 files changed, 668 insertions(+), 1 deletion(-) create mode 100644 src/main/java/br/com/blz/testjava/api/enums/TypeWarehouse.java create mode 100644 src/main/java/br/com/blz/testjava/api/inventory/entity/InventoryEntity.java create mode 100644 src/main/java/br/com/blz/testjava/api/mapper/MapperUtil.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/controller/ProductController.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductRequest.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductResponse.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/dto/InventoryDto.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/dto/WarehousesDto.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/entity/ProductEntity.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/repository/ProductRepository.java create mode 100644 src/main/java/br/com/blz/testjava/api/product/service/ProductService.java create mode 100644 src/main/java/br/com/blz/testjava/api/werehouse/entity/WarehouseEntity.java create mode 100644 src/main/java/br/com/blz/testjava/common/exceptions/ProductAlreadyExistsException.java create mode 100644 src/main/java/br/com/blz/testjava/common/exceptions/ProductNotFoundException.java create mode 100644 src/main/resources/application.properties delete mode 100644 src/main/resources/application.yml create mode 100644 src/test/java/br/com/blz/testjava/api/product/ProductServiceTest.java create mode 100644 src/test/java/br/com/blz/testjava/testUtils/TestUtils.java diff --git a/pom.xml b/pom.xml index 0c508267..6a93abb8 100644 --- a/pom.xml +++ b/pom.xml @@ -23,6 +23,7 @@ UTF-8 UTF-8 1.8 + 1.18.24 @@ -36,7 +37,33 @@ spring-boot-starter-test test - + + org.springframework.boot + spring-boot-starter-data-jpa + + + com.h2database + h2 + runtime + + + + org.mapstruct + mapstruct + 1.5.2.Final + + + org.projectlombok + lombok + 1.18.24 + + + junit + junit + test + + + @@ -44,6 +71,40 @@ org.springframework.boot spring-boot-maven-plugin + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + + + org.projectlombok + lombok + ${lombok.version} + + + org.mapstruct + mapstruct-processor + 1.5.2.Final + + + + -Amapstruct.defaultComponentModel=spring + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + org.projectlombok + lombok + + + + diff --git a/src/main/java/br/com/blz/testjava/api/enums/TypeWarehouse.java b/src/main/java/br/com/blz/testjava/api/enums/TypeWarehouse.java new file mode 100644 index 00000000..c7cbb016 --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/enums/TypeWarehouse.java @@ -0,0 +1,5 @@ +package br.com.blz.testjava.api.enums; + +public enum TypeWarehouse { + ECOMMERCE, PHYSICAL_STORE +} diff --git a/src/main/java/br/com/blz/testjava/api/inventory/entity/InventoryEntity.java b/src/main/java/br/com/blz/testjava/api/inventory/entity/InventoryEntity.java new file mode 100644 index 00000000..e2baec9e --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/inventory/entity/InventoryEntity.java @@ -0,0 +1,28 @@ +package br.com.blz.testjava.api.inventory.entity; + +import br.com.blz.testjava.api.werehouse.entity.WarehouseEntity; +import lombok.Data; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import java.io.Serializable; +import java.util.List; + +@Data +@Entity +@Table(name = "inventory") +public class InventoryEntity implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) + private List werehouses; +} diff --git a/src/main/java/br/com/blz/testjava/api/mapper/MapperUtil.java b/src/main/java/br/com/blz/testjava/api/mapper/MapperUtil.java new file mode 100644 index 00000000..e0b0ad4f --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/mapper/MapperUtil.java @@ -0,0 +1,142 @@ +package br.com.blz.testjava.api.mapper; + +import br.com.blz.testjava.api.inventory.entity.InventoryEntity; +import br.com.blz.testjava.api.product.controller.domain.ProductRequest; +import br.com.blz.testjava.api.product.controller.domain.ProductResponse; +import br.com.blz.testjava.api.product.dto.InventoryDto; +import br.com.blz.testjava.api.product.dto.WarehousesDto; +import br.com.blz.testjava.api.product.entity.ProductEntity; +import br.com.blz.testjava.api.werehouse.entity.WarehouseEntity; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@org.mapstruct.Mapper(componentModel = "spring") +@Configuration +public interface MapperUtil { + + default ProductEntity productRequestToEntity(ProductRequest productRequest) { + + if (productRequest == null) { + return null; + } else { + ProductEntity productEntity = new ProductEntity(); + productEntity.setSku(productRequest.getSku()); + productEntity.setName(productRequest.getName()); + productEntity.setInventory(this.inventoryDtoToInventoryEntity(productRequest.getInventory())); + + return productEntity; + } + } + + default InventoryEntity inventoryDtoToInventoryEntity(InventoryDto inventoryDto) { + if (inventoryDto == null) { + return null; + } else { + final List warehouseEntityList = new ArrayList<>(); + InventoryEntity inventoryEntity = new InventoryEntity(); + for (WarehousesDto wh : inventoryDto.getWarehouses()) { + warehouseEntityList.add(toEntityWareHouse(wh)); + } + + inventoryEntity.setWerehouses(warehouseEntityList); + return inventoryEntity; + } + } + + default InventoryDto inventoryEntityToInventoryDto(InventoryEntity inventoryEntity) { + if (inventoryEntity == null) { + return null; + } else { + + final List warehouseDtoList = new ArrayList<>(); + InventoryDto inventoryDto = new InventoryDto(); + + for (WarehouseEntity wh : inventoryEntity.getWerehouses()) { + + inventoryDto.setQuantity( + Optional.ofNullable(inventoryDto.getQuantity()).orElse(0) + + Optional.ofNullable(wh.getQuantity()).orElse(0)); + + warehouseDtoList.add(warehousesEntityToDto(wh)); + } + inventoryDto.setWarehouses(warehouseDtoList); + return inventoryDto; + } + } + + WarehouseEntity toEntityWareHouse(WarehousesDto warehousesDto); + + WarehousesDto warehousesEntityToDto(WarehouseEntity warehousesEntity); + + default ProductResponse productEntitytoResponse(ProductEntity productEntity) { + if (productEntity == null) { + return null; + } else { + ProductResponse productResponse = new ProductResponse(); + if (productEntity.getSku() != null) { + productResponse.setSku(productEntity.getSku().longValue()); + } + productResponse.setName(productEntity.getName()); + + productResponse.setInventory(inventoryEntityToInventoryDto(productEntity.getInventory())); + productResponse.setIsMarketable((productResponse.getInventory().getQuantity() > 0)); + + return productResponse; + } + } + + default ProductEntity productEntitytoEntityAtualizar( + ProductRequest productRequest, ProductEntity productEntity) { + if (productRequest == null) { + return null; + } else { + + if (productRequest.getSku() != null) { + productEntity.setSku(productRequest.getSku()); + } + productEntity.setName(productRequest.getName()); + + productEntity.setInventory( + inventoryDtoToInventoryEntityAtualizar( + productRequest.getInventory(), productEntity.getInventory())); + + return productEntity; + } + } + + default InventoryEntity inventoryDtoToInventoryEntityAtualizar( + InventoryDto inventoryDto, InventoryEntity inventoryEntity) { + if (inventoryDto == null) { + return null; + } else { + + final List warehouseEntityList = new ArrayList<>(); + + int size = + Math.min(inventoryDto.getWarehouses().size(), inventoryEntity.getWerehouses().size()); + for (int i = 0; i < size; i++) { + warehouseEntityList.add( + toEntityWareHouseAtualizar( + inventoryDto.getWarehouses().get(i), inventoryEntity.getWerehouses().get(i))); + } + + inventoryEntity.setWerehouses(warehouseEntityList); + return inventoryEntity; + } + } + + default WarehouseEntity toEntityWareHouseAtualizar( + WarehousesDto warehousesDto, WarehouseEntity warehouseEntity) { + if (warehousesDto == null) { + return null; + } else { + warehouseEntity.setLocality(warehousesDto.getLocality()); + warehouseEntity.setQuantity(warehousesDto.getQuantity()); + warehouseEntity.setType(warehousesDto.getType()); + return warehouseEntity; + } + } +} diff --git a/src/main/java/br/com/blz/testjava/api/product/controller/ProductController.java b/src/main/java/br/com/blz/testjava/api/product/controller/ProductController.java new file mode 100644 index 00000000..18001d8e --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/controller/ProductController.java @@ -0,0 +1,51 @@ +package br.com.blz.testjava.api.product.controller; + +import br.com.blz.testjava.api.product.controller.domain.ProductRequest; +import br.com.blz.testjava.api.product.controller.domain.ProductResponse; +import br.com.blz.testjava.api.product.service.ProductService; +import br.com.blz.testjava.common.exceptions.ProductAlreadyExistsException; +import br.com.blz.testjava.common.exceptions.ProductNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("product") +public class ProductController { + + private final ProductService service; + + @PostMapping + public ResponseEntity createProduct(@RequestBody ProductRequest product) + throws ProductAlreadyExistsException { + return ResponseEntity.status(HttpStatus.CREATED).body(service.create(product)); + } + + @GetMapping("{id}") + public ResponseEntity getProduct(@PathVariable("id") final Integer id) + throws ProductNotFoundException { + return ResponseEntity.status(HttpStatus.CREATED).body(service.getProduct(id)); + } + + @PutMapping + public ResponseEntity update(@RequestBody final ProductRequest request) + throws ProductNotFoundException { + return ResponseEntity.status(HttpStatus.CREATED).body(service.update(request)); + } + + @DeleteMapping("{id}") + public ResponseEntity delete(@PathVariable("id") final Integer id) + throws ProductNotFoundException { + service.delete(id); + return ResponseEntity.noContent().build(); + } +} diff --git a/src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductRequest.java b/src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductRequest.java new file mode 100644 index 00000000..8dd457ce --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductRequest.java @@ -0,0 +1,17 @@ +package br.com.blz.testjava.api.product.controller.domain; + +import br.com.blz.testjava.api.product.dto.InventoryDto; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class ProductRequest { + private Integer sku; + private String name; + private InventoryDto inventory; +} diff --git a/src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductResponse.java b/src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductResponse.java new file mode 100644 index 00000000..517f1528 --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/controller/domain/ProductResponse.java @@ -0,0 +1,14 @@ +package br.com.blz.testjava.api.product.controller.domain; + +import br.com.blz.testjava.api.product.dto.InventoryDto; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ProductResponse { + private Long sku; + private String name; + private InventoryDto inventory; + private Boolean isMarketable; +} diff --git a/src/main/java/br/com/blz/testjava/api/product/dto/InventoryDto.java b/src/main/java/br/com/blz/testjava/api/product/dto/InventoryDto.java new file mode 100644 index 00000000..c7335409 --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/dto/InventoryDto.java @@ -0,0 +1,16 @@ +package br.com.blz.testjava.api.product.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class InventoryDto { + private Integer quantity; + private List warehouses; +} diff --git a/src/main/java/br/com/blz/testjava/api/product/dto/WarehousesDto.java b/src/main/java/br/com/blz/testjava/api/product/dto/WarehousesDto.java new file mode 100644 index 00000000..b9182df3 --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/dto/WarehousesDto.java @@ -0,0 +1,18 @@ +package br.com.blz.testjava.api.product.dto; + +import br.com.blz.testjava.api.enums.TypeWarehouse; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class WarehousesDto { + + private String locality; + private Integer quantity; + private TypeWarehouse type; +} diff --git a/src/main/java/br/com/blz/testjava/api/product/entity/ProductEntity.java b/src/main/java/br/com/blz/testjava/api/product/entity/ProductEntity.java new file mode 100644 index 00000000..80dfd38e --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/entity/ProductEntity.java @@ -0,0 +1,40 @@ +package br.com.blz.testjava.api.product.entity; + +import br.com.blz.testjava.api.inventory.entity.InventoryEntity; +import lombok.Data; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import java.io.Serializable; + +@Data +@Entity +@Table(name = "product") +public class ProductEntity implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", nullable = false, updatable = false) + private Integer id; + + @Column(name = "sku", nullable = false, updatable = false) + private Integer sku; + + @Column(name = "name") + private String name; + + @OneToOne(cascade = CascadeType.ALL) + @JoinColumn(name = "inventory") + @OnDelete(action = OnDeleteAction.CASCADE) + private InventoryEntity inventory; + +} diff --git a/src/main/java/br/com/blz/testjava/api/product/repository/ProductRepository.java b/src/main/java/br/com/blz/testjava/api/product/repository/ProductRepository.java new file mode 100644 index 00000000..af03dc62 --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/repository/ProductRepository.java @@ -0,0 +1,12 @@ +package br.com.blz.testjava.api.product.repository; + +import br.com.blz.testjava.api.product.entity.ProductEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface ProductRepository extends JpaRepository { + Optional findBySku(Integer integer); +} diff --git a/src/main/java/br/com/blz/testjava/api/product/service/ProductService.java b/src/main/java/br/com/blz/testjava/api/product/service/ProductService.java new file mode 100644 index 00000000..f9c1573c --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/product/service/ProductService.java @@ -0,0 +1,55 @@ +package br.com.blz.testjava.api.product.service; + +import br.com.blz.testjava.api.mapper.MapperUtil; +import br.com.blz.testjava.api.product.controller.domain.ProductRequest; +import br.com.blz.testjava.api.product.controller.domain.ProductResponse; +import br.com.blz.testjava.api.product.entity.ProductEntity; +import br.com.blz.testjava.api.product.repository.ProductRepository; +import br.com.blz.testjava.common.exceptions.ProductAlreadyExistsException; +import br.com.blz.testjava.common.exceptions.ProductNotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class ProductService { + + private final ProductRepository repository; + private final MapperUtil mapperUtil; + + public ProductResponse create(final ProductRequest product) throws ProductAlreadyExistsException { + if (repository.findBySku(product.getSku()).isPresent()) { + throw new ProductAlreadyExistsException( + "Dois produtos são considerados iguais se os seus skus forem iguais"); + } + return mapperUtil.productEntitytoResponse(repository.save(mapperUtil.productRequestToEntity(product))); + } + + public ProductResponse getProduct(final Integer sku) throws ProductNotFoundException { + + return mapperUtil.productEntitytoResponse( + repository + .findBySku(sku) + .orElseThrow( + () -> new ProductNotFoundException("Não foi Possivel encontrar o Produto"))); + } + + public ProductResponse update(final ProductRequest product) throws ProductNotFoundException { + ProductEntity productEntity = + repository + .findBySku(product.getSku()) + .orElseThrow( + () -> new ProductNotFoundException("Não foi Possivel encontrar o Produto")); + + return mapperUtil.productEntitytoResponse( + repository.save(mapperUtil.productEntitytoEntityAtualizar(product, productEntity))); + } + + public void delete(final Integer id) throws ProductNotFoundException { + repository.delete( + repository + .findBySku(id) + .orElseThrow( + () -> new ProductNotFoundException("Não foi Possivel encontrar o Produto"))); + } +} diff --git a/src/main/java/br/com/blz/testjava/api/werehouse/entity/WarehouseEntity.java b/src/main/java/br/com/blz/testjava/api/werehouse/entity/WarehouseEntity.java new file mode 100644 index 00000000..5c6278ee --- /dev/null +++ b/src/main/java/br/com/blz/testjava/api/werehouse/entity/WarehouseEntity.java @@ -0,0 +1,29 @@ +package br.com.blz.testjava.api.werehouse.entity; + +import br.com.blz.testjava.api.enums.TypeWarehouse; +import lombok.Data; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Data +@Entity +@Table(name = "werehouse") +public class WarehouseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "locality") + private String locality; + + @Column(name = "quantity") + private Integer quantity; + + @Column(name = "typeWarehouse") + private TypeWarehouse type; +} diff --git a/src/main/java/br/com/blz/testjava/common/exceptions/ProductAlreadyExistsException.java b/src/main/java/br/com/blz/testjava/common/exceptions/ProductAlreadyExistsException.java new file mode 100644 index 00000000..a6ba81c8 --- /dev/null +++ b/src/main/java/br/com/blz/testjava/common/exceptions/ProductAlreadyExistsException.java @@ -0,0 +1,7 @@ +package br.com.blz.testjava.common.exceptions; + +public class ProductAlreadyExistsException extends Exception { + public ProductAlreadyExistsException(String message) { + super(message); + } +} diff --git a/src/main/java/br/com/blz/testjava/common/exceptions/ProductNotFoundException.java b/src/main/java/br/com/blz/testjava/common/exceptions/ProductNotFoundException.java new file mode 100644 index 00000000..4b34166b --- /dev/null +++ b/src/main/java/br/com/blz/testjava/common/exceptions/ProductNotFoundException.java @@ -0,0 +1,9 @@ +package br.com.blz.testjava.common.exceptions; + +import javassist.NotFoundException; + +public class ProductNotFoundException extends NotFoundException { + public ProductNotFoundException(String message) { + super(message); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 00000000..b47daf47 --- /dev/null +++ b/src/main/resources/application.properties @@ -0,0 +1,7 @@ +spring.datasource.url=jdbc:h2:mem:testdb +spring.datasource.driverClassName=org.h2.Driver +spring.datasource.username=sa +spring.datasource.password=password +spring.jpa.database-platform=org.hibernate.dialect.H2Dialect +spring.h2.console.enabled=true +logging.level.com.microsoft.sqlserver.jdbc.internals.SQLServerStatement: TRACE diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/java/br/com/blz/testjava/api/product/ProductServiceTest.java b/src/test/java/br/com/blz/testjava/api/product/ProductServiceTest.java new file mode 100644 index 00000000..ef634597 --- /dev/null +++ b/src/test/java/br/com/blz/testjava/api/product/ProductServiceTest.java @@ -0,0 +1,79 @@ +package br.com.blz.testjava.api.product; + +import br.com.blz.testjava.api.mapper.MapperUtil; +import br.com.blz.testjava.api.product.controller.domain.ProductRequest; +import br.com.blz.testjava.api.product.controller.domain.ProductResponse; +import br.com.blz.testjava.api.product.entity.ProductEntity; +import br.com.blz.testjava.api.product.repository.ProductRepository; +import br.com.blz.testjava.api.product.service.ProductService; +import br.com.blz.testjava.common.exceptions.ProductAlreadyExistsException; +import br.com.blz.testjava.common.exceptions.ProductNotFoundException; +import br.com.blz.testjava.testUtils.TestUtils; +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 java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class ProductServiceTest { + @Mock private ProductRepository repository; + @Mock private MapperUtil mapper; + @InjectMocks private ProductService productService; + + @Test + void create_product_should_succeed() throws ProductAlreadyExistsException { + ProductRequest productRequest = TestUtils.getProductRequest(); + ProductEntity productEntity = new ProductEntity(); + ProductResponse productResponse = TestUtils.getProductResponse(); + when(repository.save(productEntity)).thenReturn(productEntity); + when(mapper.productRequestToEntity(productRequest)).thenReturn(productEntity); + when(mapper.productEntitytoResponse(productEntity)).thenReturn(productResponse); + + ProductResponse response = productService.create(productRequest); + + assertEquals(response, productResponse); + } + + @Test + void get_product_should_succeed() throws ProductNotFoundException { + ProductEntity productEntity = TestUtils.getProductEntity(); + ProductResponse productResponse = TestUtils.getProductResponse(); + when(repository.findBySku(1)).thenReturn(Optional.of(productEntity)); + when(mapper.productEntitytoResponse(productEntity)).thenReturn(productResponse); + + ProductResponse response = productService.getProduct(1); + + assertEquals(response, productResponse); + } + + @Test + void getProduct_whenProductExists_shouldReturnProduct() throws ProductNotFoundException { + // Arrange + ProductEntity productEntity = new ProductEntity(); + ProductResponse expectedProductResponse = new ProductResponse(); + when(repository.findBySku(anyInt())).thenReturn(Optional.of(productEntity)); + when(mapper.productEntitytoResponse(productEntity)).thenReturn(expectedProductResponse); + + // Act + ProductResponse actualProductResponse = productService.getProduct(123); + + // Assert + assertEquals(expectedProductResponse, actualProductResponse); + } + + @Test + void getProduct_whenProductDoesNotExist_shouldThrowProductNotFoundException() { + // Arrange + when(repository.findBySku(anyInt())).thenReturn(Optional.empty()); + // Act & Assert + assertThrows(ProductNotFoundException.class, () -> productService.getProduct(123)); + } +} diff --git a/src/test/java/br/com/blz/testjava/testUtils/TestUtils.java b/src/test/java/br/com/blz/testjava/testUtils/TestUtils.java new file mode 100644 index 00000000..ccf57881 --- /dev/null +++ b/src/test/java/br/com/blz/testjava/testUtils/TestUtils.java @@ -0,0 +1,77 @@ +package br.com.blz.testjava.testUtils; + +import br.com.blz.testjava.api.enums.TypeWarehouse; +import br.com.blz.testjava.api.inventory.entity.InventoryEntity; +import br.com.blz.testjava.api.product.controller.domain.ProductRequest; +import br.com.blz.testjava.api.product.controller.domain.ProductResponse; +import br.com.blz.testjava.api.product.dto.InventoryDto; +import br.com.blz.testjava.api.product.dto.WarehousesDto; +import br.com.blz.testjava.api.product.entity.ProductEntity; +import br.com.blz.testjava.api.werehouse.entity.WarehouseEntity; + +import java.util.ArrayList; +import java.util.List; + +public class TestUtils { + + public static ProductRequest getProductRequest() { + ProductRequest productResponse = new ProductRequest(); + productResponse.setInventory(getInventory()); + productResponse.setName("product"); + + return productResponse; + } + + public static ProductResponse getProductResponse() { + ProductResponse productResponse = new ProductResponse(); + productResponse.setInventory(getInventory()); + productResponse.setName("product"); + + return productResponse; + } + + public static InventoryDto getInventory() { + InventoryDto inventoryDto = new InventoryDto(); + inventoryDto.setQuantity(10); + inventoryDto.setWarehouses(getWarehouses()); + return inventoryDto; + } + + public static List getWarehouses() { + List warehousesDtos = new ArrayList<>(); + WarehousesDto warehouses = new WarehousesDto(); + warehouses.setLocality("SP"); + warehouses.setQuantity(2); + warehouses.setType(TypeWarehouse.ECOMMERCE); + warehousesDtos.add(warehouses); + return warehousesDtos; + } + + public static ProductEntity getProductEntity() { + ProductEntity productResponse = new ProductEntity(); + productResponse.setInventory(getInventoryEntity()); + productResponse.setName("product"); + productResponse.setSku(1); + productResponse.setId(1); + + return productResponse; + } + + public static InventoryEntity getInventoryEntity() { + InventoryEntity inventoryDto = new InventoryEntity(); + inventoryDto.setId(10); + inventoryDto.setWerehouses(getWarehouseEntity()); + return inventoryDto; + } + + public static List getWarehouseEntity() { + List warehousesDtos = new ArrayList<>(); + WarehouseEntity warehouses = new WarehouseEntity(); + warehouses.setId(1L); + warehouses.setLocality("SP"); + warehouses.setQuantity(2); + warehouses.setType(TypeWarehouse.ECOMMERCE); + warehousesDtos.add(warehouses); + return warehousesDtos; + } +}