Skip to content

Commit

Permalink
OP-289: Add unit tests to command provider
Browse files Browse the repository at this point in the history
  • Loading branch information
hmfilar committed Sep 11, 2024
1 parent 32a5795 commit 0391920
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 17 deletions.
23 changes: 13 additions & 10 deletions src/Provider/AddProductBundleItemToCartCommandProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
) {
Expand All @@ -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);
Expand All @@ -63,25 +64,27 @@ 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);
}
}
}

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();
}
}
1 change: 0 additions & 1 deletion src/Resources/config/services/provider.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
class="BitBag\SyliusProductBundlePlugin\Provider\AddProductBundleItemToCartCommandProvider"
>
<argument type="service" id="bitbag_sylius_product_bundle.factory.add_product_bundle_item_to_cart_command"/>
<argument type="service" id="bitbag_sylius_product_bundle.repository.product_bundle_item"/>
<argument type="service" id="bitbag_sylius_product_bundle.repository.product_bundle"/>
<argument type="service" id="sylius.repository.product_variant"/>
</service>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
189 changes: 189 additions & 0 deletions tests/Unit/Provider/AddProductBundleItemToCartCommandProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* You can find more information about us on https://bitbag.io and write us
* an email on hello@bitbag.io.
*/

declare(strict_types=1);

namespace Tests\BitBag\SyliusProductBundlePlugin\Unit\Provider;

use BitBag\SyliusProductBundlePlugin\Command\AddProductBundleItemToCartCommandInterface;
use BitBag\SyliusProductBundlePlugin\Entity\ProductBundleInterface;
use BitBag\SyliusProductBundlePlugin\Entity\ProductBundleItemInterface;
use BitBag\SyliusProductBundlePlugin\Factory\AddProductBundleItemToCartCommandFactoryInterface;
use BitBag\SyliusProductBundlePlugin\Provider\AddProductBundleItemToCartCommandProvider;
use BitBag\SyliusProductBundlePlugin\Provider\AddProductBundleItemToCartCommandProviderInterface;
use BitBag\SyliusProductBundlePlugin\Repository\ProductBundleRepositoryInterface;
use Doctrine\Common\Collections\ArrayCollection;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Core\Repository\ProductVariantRepositoryInterface;

final class AddProductBundleItemToCartCommandProviderTest extends TestCase
{
private AddProductBundleItemToCartCommandFactoryInterface|MockObject $addProductBundleItemToCartCommandFactory;

private ProductBundleRepositoryInterface|MockObject $productBundleRepository;

private ProductVariantRepositoryInterface|MockObject $productVariantRepository;

private ProductBundleInterface|MockObject $bundle;

private ProductBundleItemInterface|MockObject $bundleItem1;

private ProductBundleItemInterface|MockObject $bundleItem2;

private AddProductBundleItemToCartCommandProviderInterface $provider;

public function setUp(): void
{
$this->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);
}
}

0 comments on commit 0391920

Please sign in to comment.