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;
+ }
+}