From 0391920d148ff808ee57511d493567a9b8ffa672 Mon Sep 17 00:00:00 2001 From: Hubert Filar Date: Wed, 11 Sep 2024 17:35:41 +0200 Subject: [PATCH] OP-289: Add unit tests to command provider --- ...ProductBundleItemToCartCommandProvider.php | 23 ++- src/Resources/config/services/provider.xml | 1 - ...ductBundleToCartDtoDataTransformerTest.php | 6 - ...uctBundleItemToCartCommandProviderTest.php | 189 ++++++++++++++++++ 4 files changed, 202 insertions(+), 17 deletions(-) create mode 100644 tests/Unit/Provider/AddProductBundleItemToCartCommandProviderTest.php diff --git a/src/Provider/AddProductBundleItemToCartCommandProvider.php b/src/Provider/AddProductBundleItemToCartCommandProvider.php index 11a0ebd2..c6632f54 100644 --- a/src/Provider/AddProductBundleItemToCartCommandProvider.php +++ b/src/Provider/AddProductBundleItemToCartCommandProvider.php @@ -14,7 +14,6 @@ use BitBag\SyliusProductBundlePlugin\Command\AddProductBundleItemToCartCommandInterface; use BitBag\SyliusProductBundlePlugin\Entity\ProductBundleItemInterface; use BitBag\SyliusProductBundlePlugin\Factory\AddProductBundleItemToCartCommandFactoryInterface; -use BitBag\SyliusProductBundlePlugin\Repository\ProductBundleItemRepositoryInterface; use BitBag\SyliusProductBundlePlugin\Repository\ProductBundleRepositoryInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -23,9 +22,12 @@ final class AddProductBundleItemToCartCommandProvider implements AddProductBundleItemToCartCommandProviderInterface { + public const TO = 'to'; + + public const FROM = 'from'; + public function __construct( private readonly AddProductBundleItemToCartCommandFactoryInterface $addProductBundleItemToCartCommandFactory, - private readonly ProductBundleItemRepositoryInterface $productBundleItemRepository, private readonly ProductBundleRepositoryInterface $productBundleRepository, private readonly ProductVariantRepositoryInterface $productVariantRepository, ) { @@ -43,8 +45,7 @@ public function provide(string $bundleCode, array $overwrittenVariants): Collect throw new \Exception('Product bundle not found'); } - $bundleItems = $this->productBundleItemRepository->findByBundleCode($bundleCode); - + $bundleItems = $bundle->getProductBundleItems(); $commands = []; foreach ($bundleItems as $bundleItem) { $command = $this->addProductBundleItemToCartCommandFactory->createNew($bundleItem); @@ -63,12 +64,12 @@ private function overwriteVariant( array $overwrittenVariants, ): void { foreach ($overwrittenVariants as $overwrittenVariant) { - if (null !== $overwrittenVariant['from'] && null !== $overwrittenVariant['to'] && - $bundleItem->getProductVariant()?->getCode() === $overwrittenVariant['from'] && - $this->shouldOverwriteVariant($overwrittenVariant['from'], $overwrittenVariant['to']) + if (null !== $overwrittenVariant[self::FROM] && null !== $overwrittenVariant[self::TO] && + $bundleItem->getProductVariant()?->getCode() === $overwrittenVariant[self::FROM] && + $this->shouldOverwriteVariant($overwrittenVariant[self::FROM], $overwrittenVariant[self::TO]) ) { /** @var ProductVariantInterface $newVariant */ - $newVariant = $this->productVariantRepository->findOneBy(['code' => $overwrittenVariant['to']]); + $newVariant = $this->productVariantRepository->findOneBy(['code' => $overwrittenVariant[self::TO]]); $command->setProductVariant($newVariant); } } @@ -76,12 +77,14 @@ private function overwriteVariant( private function shouldOverwriteVariant(string $oldVariantCode, string $newVariantCode): bool { + /** @var ?ProductVariantInterface $oldVariant */ $oldVariant = $this->productVariantRepository->findOneBy(['code' => $oldVariantCode]); + /** @var ?ProductVariantInterface $oldVariant */ $newVariant = $this->productVariantRepository->findOneBy(['code' => $newVariantCode]); return - $oldVariant instanceof ProductVariantInterface && - $newVariant instanceof ProductVariantInterface && + null !== $oldVariant && + null !== $newVariant && $oldVariant->getProduct() === $newVariant->getProduct(); } } diff --git a/src/Resources/config/services/provider.xml b/src/Resources/config/services/provider.xml index 2d70958a..e04757ca 100644 --- a/src/Resources/config/services/provider.xml +++ b/src/Resources/config/services/provider.xml @@ -8,7 +8,6 @@ class="BitBag\SyliusProductBundlePlugin\Provider\AddProductBundleItemToCartCommandProvider" > - diff --git a/tests/Unit/DataTransformer/AddProductBundleToCartDtoDataTransformerTest.php b/tests/Unit/DataTransformer/AddProductBundleToCartDtoDataTransformerTest.php index 4b592b18..a7fc87ec 100644 --- a/tests/Unit/DataTransformer/AddProductBundleToCartDtoDataTransformerTest.php +++ b/tests/Unit/DataTransformer/AddProductBundleToCartDtoDataTransformerTest.php @@ -7,12 +7,6 @@ * an email on hello@bitbag.io. */ -/* - * This file was created by developers working at BitBag - * Do you need more information about us and what we do? Visit our https://bitbag.io website! - * We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career - */ - declare(strict_types=1); namespace Tests\BitBag\SyliusProductBundlePlugin\Unit\DataTransformer; diff --git a/tests/Unit/Provider/AddProductBundleItemToCartCommandProviderTest.php b/tests/Unit/Provider/AddProductBundleItemToCartCommandProviderTest.php new file mode 100644 index 00000000..de5b8492 --- /dev/null +++ b/tests/Unit/Provider/AddProductBundleItemToCartCommandProviderTest.php @@ -0,0 +1,189 @@ +addProductBundleItemToCartCommandFactory = $this->createMock(AddProductBundleItemToCartCommandFactoryInterface::class); + $this->productBundleRepository = $this->createMock(ProductBundleRepositoryInterface::class); + $this->productVariantRepository = $this->createMock(ProductVariantRepositoryInterface::class); + + $this->bundleItem1 = $this->createMock(ProductBundleItemInterface::class); + $this->bundleItem2 = $this->createMock(ProductBundleItemInterface::class); + $this->bundle = $this->createMock(ProductBundleInterface::class); + $this->bundle + ->expects(self::any()) + ->method('getProductBundleItems') + ->willReturn(new ArrayCollection([$this->bundleItem1, $this->bundleItem2])); + + $this->provider = new AddProductBundleItemToCartCommandProvider( + $this->addProductBundleItemToCartCommandFactory, + $this->productBundleRepository, + $this->productVariantRepository, + ); + } + + public function testItThrowsExceptionIfBundleIsNotFound(): void + { + self::expectException(\Exception::class); + self::expectExceptionMessage('Product bundle not found'); + + $this->productBundleRepository + ->expects(self::once()) + ->method('findOneByProductCode') + ->with('BUNDLE_CODE') + ->willReturn(null); + + $this->provider->provide('BUNDLE_CODE', []); + } + + public function testItWillNotOverwriteIfBundleIsPacked(): void + { + $this->bundle + ->expects(self::exactly(2)) + ->method('isPackedProduct') + ->willReturn(true); + + $this->productBundleRepository + ->expects(self::once()) + ->method('findOneByProductCode') + ->with('BUNDLE_CODE') + ->willReturn($this->bundle); + + $addProductBundleItemToCartCommand = $this->createMock(AddProductBundleItemToCartCommandInterface::class); + + $this->addProductBundleItemToCartCommandFactory + ->expects(self::exactly(2)) + ->method('createNew') + ->withConsecutive([$this->bundleItem1], [$this->bundleItem2]) + ->willReturn($addProductBundleItemToCartCommand); + + $this->productVariantRepository->expects(self::never())->method(self::anything()); + + $this->provider->provide('BUNDLE_CODE', []); + } + + public function testItWillNotOverwriteIfOverwrittenVariantsIsEmpty(): void + { + $this->bundle + ->expects(self::exactly(2)) + ->method('isPackedProduct') + ->willReturn(false); + + $this->productBundleRepository + ->expects(self::once()) + ->method('findOneByProductCode') + ->with('BUNDLE_CODE') + ->willReturn($this->bundle); + + $addProductBundleItemToCartCommand = $this->createMock(AddProductBundleItemToCartCommandInterface::class); + + $this->addProductBundleItemToCartCommandFactory + ->expects(self::exactly(2)) + ->method('createNew') + ->withConsecutive([$this->bundleItem1], [$this->bundleItem2]) + ->willReturn($addProductBundleItemToCartCommand); + + $this->productVariantRepository->expects(self::never())->method(self::anything()); + + $this->provider->provide('BUNDLE_CODE', []); + } + + public function testItOverwrites(): void + { + $this->bundle + ->expects(self::exactly(2)) + ->method('isPackedProduct') + ->willReturn(false); + + $this->productBundleRepository + ->expects(self::once()) + ->method('findOneByProductCode') + ->with('BUNDLE_CODE') + ->willReturn($this->bundle); + + $product = $this->createMock(ProductInterface::class); + + $oldProductVariant = $this->createMock(ProductVariantInterface::class); + $oldProductVariant + ->expects(self::once()) + ->method('getCode') + ->willReturn('OLD_VARIANT_CODE'); + $oldProductVariant + ->expects(self::once()) + ->method('getProduct') + ->willReturn($product); + + $newProductVariant = $this->createMock(ProductVariantInterface::class); + $newProductVariant + ->expects(self::once()) + ->method('getProduct') + ->willReturn($product); + + $this->bundleItem1 + ->expects(self::once()) + ->method('getProductVariant') + ->willReturn($oldProductVariant); + + $this->productVariantRepository + ->expects(self::exactly(3)) + ->method('findOneBy') + ->willReturnOnConsecutiveCalls($oldProductVariant, $newProductVariant, $newProductVariant); + + $addProductBundleItemToCartCommand = $this->createMock(AddProductBundleItemToCartCommandInterface::class); + + $this->addProductBundleItemToCartCommandFactory + ->expects(self::exactly(2)) + ->method('createNew') + ->withConsecutive([$this->bundleItem1], [$this->bundleItem2]) + ->willReturn($addProductBundleItemToCartCommand); + + $overwrittenVariants = [ + [ + 'from' => 'OLD_VARIANT_CODE', + 'to' => 'NEW_VARIANT_CODE', + ], + ]; + + $this->provider->provide('BUNDLE_CODE', $overwrittenVariants); + } +}