Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1064 [BACKOFFICE] [Bugs] Product Variations - delete variant #1072

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
package com.yas.product.service;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;

import com.yas.commonlibrary.exception.NotFoundException;
import com.yas.product.ProductApplication;
import com.yas.product.config.IntegrationTestConfiguration;
import com.yas.product.model.Brand;
import com.yas.product.model.Category;
import com.yas.product.model.Product;
import com.yas.product.model.ProductCategory;
import com.yas.product.model.ProductOption;
import com.yas.product.model.ProductOptionCombination;
import com.yas.product.model.ProductOptionValue;
import com.yas.product.repository.BrandRepository;
import com.yas.product.repository.CategoryRepository;
import com.yas.product.repository.ProductCategoryRepository;
import com.yas.product.repository.ProductOptionCombinationRepository;
import com.yas.product.repository.ProductOptionRepository;
import com.yas.product.repository.ProductOptionValueRepository;
import com.yas.product.repository.ProductRepository;
import com.yas.product.viewmodel.NoFileMediaVm;
import com.yas.product.viewmodel.product.ProductFeatureGetVm;
Expand All @@ -17,31 +32,26 @@
import com.yas.product.viewmodel.product.ProductThumbnailGetVm;
import com.yas.product.viewmodel.product.ProductThumbnailVm;
import com.yas.product.viewmodel.product.ProductsGetVm;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.junit.jupiter.api.AfterEach;
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 org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.when;

@SpringBootTest(classes = ProductApplication.class)
class ProductServiceTest {
@SpringBootTest
@Import(IntegrationTestConfiguration.class)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class ProductServiceIT {
private final ZonedDateTime CREATED_ON = ZonedDateTime.now();
@Autowired
private ProductRepository productRepository;
Expand All @@ -51,6 +61,12 @@ class ProductServiceTest {
private CategoryRepository categoryRepository;
@Autowired
private ProductCategoryRepository productCategoryRepository;
@Autowired
private ProductOptionCombinationRepository productOptionCombinationRepository;
@Autowired
private ProductOptionValueRepository productOptionValueRepository;
@Autowired
private ProductOptionRepository productOptionRepository;
@MockBean
private MediaService mediaService;
@Autowired
Expand Down Expand Up @@ -117,13 +133,13 @@ private void generateTestData() {
product.setCreatedOn(CREATED_ON);
products.add(product);
}
List<Product> productsDB = productRepository.saveAll(products);
List<Product> productsDb = productRepository.saveAll(products);

productCategoryList = new ArrayList<>();
for (int i = 1; i <= productsDB.size(); i++) {
Product productDB = productsDB.get(i - 1);
for (int i = 1; i <= productsDb.size(); i++) {
Product productDb = productsDb.get(i - 1);
ProductCategory productCategory = new ProductCategory();
productCategory.setProduct(productDB);
productCategory.setProduct(productDb);
if (i % 2 == 0) {
productCategory.setCategory(category2);
} else {
Expand All @@ -134,8 +150,26 @@ private void generateTestData() {
productCategoryRepository.saveAll(productCategoryList);
}

private Product getVariant(Product parent) {
return Product.builder()
.name("product variant name")
.slug("product variant slug")
.isAllowedToOrder(true)
.isPublished(true)
.isFeatured(true)
.isVisibleIndividually(true)
.stockTrackingEnabled(true)
.thumbnailMediaId(1L)
.taxClassId(1L)
.parent(parent)
.build();
}

@AfterEach
void tearDown() {
productOptionCombinationRepository.deleteAll();
productOptionValueRepository.deleteAll();
productOptionRepository.deleteAll();
productCategoryRepository.deleteAll();
categoryRepository.deleteAll();
productRepository.deleteAll();
Expand All @@ -148,8 +182,9 @@ void getFeaturedProducts_WhenEverythingIsOkay_Success() {
generateTestData();
ProductFeatureGetVm actualResponse = productService.getListFeaturedProducts(pageNo, pageSize);
assertThat(actualResponse.totalPage()).isEqualTo(totalPage);
assertThat(actualResponse.productList().size()).isEqualTo(5);
Map<String, Product> productMap = products.stream().collect(Collectors.toMap(Product::getSlug, product -> product));
assertThat(actualResponse.productList()).hasSize(5);
Map<String, Product> productMap
= products.stream().collect(Collectors.toMap(Product::getSlug, product -> product));
for (int i = 0; i < actualResponse.productList().size(); i++) {
ProductThumbnailGetVm productThumbnailGetVm = actualResponse.productList().get(i);
Product product = productMap.get(productThumbnailGetVm.slug());
Expand All @@ -169,7 +204,8 @@ void getProductsByBrand_BrandSlugIsValid_Success() {
@DisplayName("Get products by brand when brand is non exist then throws exception")
@Test
void getProductsByBrand_BrandIsNonExist_ThrowsNotFoundException() {
NotFoundException exception = assertThrows(NotFoundException.class, () -> productService.getProductsByBrand("brandSlug1"));
NotFoundException exception = assertThrows(NotFoundException.class,
() -> productService.getProductsByBrand("brandSlug1"));
assertEquals(String.format("Brand %s is not found", "brandSlug1"), exception.getMessage());
}

Expand Down Expand Up @@ -198,7 +234,8 @@ void getListFeaturedProductsByListProductIds_whenAllProductIdsValid_shouldSucces
@Test
void getProductsWithFilter_WhenFilterByBrandNameAndProductName_ThenSuccess() {
generateTestData();
ProductListGetVm actualResponse = productService.getProductsWithFilter(pageNo, pageSize, "product1", brand1.getName());
ProductListGetVm actualResponse
= productService.getProductsWithFilter(pageNo, pageSize, "product1", brand1.getName());
assertEquals(1, actualResponse.productContent().size());
}

Expand All @@ -219,28 +256,31 @@ void getProductsWithFilter_WhenFilterByProductName_ThenSuccess() {
@Test
void getProductsWithFilter_whenFindAll_thenSuccess() {
generateTestData();
ProductListGetVm actualResponse = productService.getProductsWithFilter(pageNo, pageSize, "product", brand2.getName());
ProductListGetVm actualResponse
= productService.getProductsWithFilter(pageNo, pageSize, "product", brand2.getName());
assertEquals(5, actualResponse.productContent().size());

}

@Test
void getProductsFromCategory_WhenFindAllByCategory_ThenSuccess() {
generateTestData();
ProductListGetFromCategoryVm actualResponse = productService.getProductsFromCategory(pageNo, pageSize, "categorySlug1");
ProductListGetFromCategoryVm actualResponse
= productService.getProductsFromCategory(pageNo, pageSize, "categorySlug1");
assertEquals(5, actualResponse.productContent().size());
}

@Test
void getProductsFromCategory_CategoryIsNonExist_ThrowsNotFoundException() {
generateTestData();
String categorySlug = "laptop-macbook";
NotFoundException exception = assertThrows(NotFoundException.class, () -> productService.getProductsFromCategory(pageNo, pageSize, categorySlug));
NotFoundException exception = assertThrows(NotFoundException.class,
() -> productService.getProductsFromCategory(pageNo, pageSize, categorySlug));
assertThat(exception.getMessage()).isEqualTo(String.format("Category %s is not found", categorySlug));
}

@Test
void deleteProduct_givenProductIdValid_thenSuccess() {
void deleteProduct_givenParentProduct_thenSuccess() {
generateTestData();
Long id = productRepository.findAll().getFirst().getId();
productService.deleteProduct(id);
Expand All @@ -251,6 +291,49 @@ void deleteProduct_givenProductIdValid_thenSuccess() {

}

@Test
void deleteProduct_givenVariant_thenSuccess() {

generateTestData();

String value = "red";
ProductOption productOption = new ProductOption();
productOption.setName(value);
productOption.setCreatedOn(CREATED_ON);
ProductOption afterProductOption = productOptionRepository.save(productOption);

ProductOptionCombination productOptionCombination = new ProductOptionCombination();
productOptionCombination.setValue(value);
productOptionCombination.setDisplayOrder(1);

Product parent = productRepository.findAll().getFirst();
Product product = getVariant(parent);
Product afterProduct = productRepository.save(product);

productOptionCombination.setProduct(afterProduct);
productOptionCombination.setProductOption(afterProductOption);
ProductOptionCombination productOptionCombinationSaved
= productOptionCombinationRepository.save(productOptionCombination);
assertTrue(productOptionCombinationRepository.findById(productOptionCombinationSaved.getId()).isPresent());

ProductOptionValue productOptionValue = new ProductOptionValue();
productOptionValue.setProduct(parent);
productOptionValue.setValue(value);
productOptionValue.setDisplayOrder(1);
productOptionValue.setProductOption(afterProductOption);
ProductOptionValue productOptionValueSaved = productOptionValueRepository.save(productOptionValue);
assertTrue(productOptionValueRepository.findById(productOptionValueSaved.getId()).isPresent());

productService.deleteProduct(afterProduct.getId());
Optional<Product> result = productRepository.findById(afterProduct.getId());

assertTrue(result.isPresent());
assertFalse(result.get().isPublished());
assertFalse(productOptionCombinationRepository.findById(productOptionCombinationSaved.getId()).isPresent());
assertFalse(productOptionValueRepository.findById(productOptionValueSaved.getId()).isPresent());

}

@Test
void deleteProduct_givenProductIdInvalid_thenThrowNotFoundException() {
Long productId = 99999L;
Expand All @@ -263,7 +346,8 @@ void getProductsByMultiQuery_WhenFilterByBrandNameAndProductName_ThenSuccess() {
Double startPrice = 1.0;
Double endPrice = 10.0;
String productName = "product2";
ProductsGetVm result = productService.getProductsByMultiQuery(pageNo, pageSize, productName, category2.getSlug(), startPrice, endPrice);
ProductsGetVm result
= productService.getProductsByMultiQuery(pageNo, pageSize, productName, category2.getSlug(), startPrice, endPrice);

// Assert result
assertEquals(1, result.productContent().size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
import com.yas.product.model.Product;
import com.yas.product.model.ProductOptionCombination;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface ProductOptionCombinationRepository extends JpaRepository<ProductOptionCombination, Long> {
List<ProductOptionCombination> findAllByProduct(Product product);

Optional<ProductOptionCombination> findByProductId(Long productId);

void deleteByProductId(Long productId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@
@Repository
public interface ProductOptionValueRepository extends JpaRepository<ProductOptionValue, Long> {
List<ProductOptionValue> findAllByProduct(Product product);

void deleteByProductIdAndValue(Long productId, String value);

}
12 changes: 12 additions & 0 deletions product/src/main/java/com/yas/product/service/ProductService.java
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,18 @@ public void deleteProduct(Long id) {
.findById(id)
.orElseThrow(() -> new NotFoundException(Constants.ErrorCode.PRODUCT_NOT_FOUND, id));
product.setPublished(false);

if (!Objects.isNull(product.getParent())) {

Optional<ProductOptionCombination> productOptionCombination = productOptionCombinationRepository
.findByProductId(id);

productOptionCombination.ifPresent(poc -> {
productOptionCombinationRepository.deleteByProductId(id);
productOptionValueRepository.deleteByProductIdAndValue(product.getParent().getId(), poc.getValue());
});
}

productRepository.save(product);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,5 @@
package com.yas.product.service;

import com.yas.commonlibrary.exception.DuplicatedException;
import com.yas.product.model.attribute.ProductAttributeGroup;
import com.yas.product.repository.ProductAttributeGroupRepository;
import com.yas.product.viewmodel.productattribute.ProductAttributeGroupListGetVm;
import com.yas.product.viewmodel.productattribute.ProductAttributeGroupVm;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
Expand All @@ -28,9 +11,24 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
class ProductAttributeGroupServiceTest {
import com.yas.commonlibrary.exception.DuplicatedException;
import com.yas.product.model.attribute.ProductAttributeGroup;
import com.yas.product.repository.ProductAttributeGroupRepository;
import com.yas.product.viewmodel.productattribute.ProductAttributeGroupListGetVm;
import com.yas.product.viewmodel.productattribute.ProductAttributeGroupVm;
import java.util.ArrayList;
import java.util.List;
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 org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

@ExtendWith(MockitoExtension.class)
class ProductAttributeGroupServiceTest {

@Mock
private ProductAttributeGroupRepository repository;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
package com.yas.product.service;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import com.yas.commonlibrary.exception.DuplicatedException;
import com.yas.product.model.attribute.ProductAttribute;
import com.yas.product.model.attribute.ProductAttributeGroup;
import com.yas.product.repository.ProductAttributeGroupRepository;
import com.yas.product.repository.ProductAttributeRepository;
import com.yas.product.viewmodel.productattribute.ProductAttributeListGetVm;
import com.yas.product.viewmodel.productattribute.ProductAttributePostVm;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
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.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
@ExtendWith(MockitoExtension.class)
class ProductAttributeServiceTest {

@Mock
Expand Down
Loading
Loading