Skip to content

Commit

Permalink
OP-291: Extract abstraction to prevent code repetition
Browse files Browse the repository at this point in the history
  • Loading branch information
hmfilar committed Jul 25, 2024
1 parent 6b74600 commit 248fb6d
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 107 deletions.
4 changes: 2 additions & 2 deletions spec/CommandHandler/Wishlist/AddProductsToCartHandlerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface;
use BitBag\SyliusWishlistPlugin\CommandHandler\Wishlist\AddProductsToCartHandler;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantity;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface;
Expand Down Expand Up @@ -113,6 +113,6 @@ public function it_throws_exception_when_quantity_is_not_positive(

$availabilityChecker->isStockSufficient($productVariant, 0)->willReturn(true);

$this->shouldThrow(InvalidProductQuantity::class)->during('__invoke', [$addProductsToCart]);
$this->shouldThrow(InvalidProductQuantityException::class)->during('__invoke', [$addProductsToCart]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItem;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface;
use BitBag\SyliusWishlistPlugin\CommandHandler\Wishlist\AddSelectedProductsToCartHandler;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use Doctrine\Common\Collections\ArrayCollection;
use PhpSpec\ObjectBehavior;
use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface;
Expand All @@ -25,25 +26,16 @@
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
use Sylius\Component\Order\Modifier\OrderModifierInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Translation\Translator;
use Symfony\Contracts\Translation\TranslatorInterface;

final class AddSelectedProductsToCartHandlerSpec extends ObjectBehavior
{
public function let(
RequestStack $requestStack,
Translator $translator,
OrderItemQuantityModifierInterface $itemQuantityModifier,
OrderModifierInterface $orderModifier,
OrderRepositoryInterface $orderRepository,
AvailabilityCheckerInterface $availabilityChecker,
): void {
$this->beConstructedWith(
$requestStack,
$translator,
$itemQuantityModifier,
$orderModifier,
$orderRepository,
Expand All @@ -60,14 +52,9 @@ public function it_adds_selected_products_to_cart(
WishlistItem $wishlistProduct,
OrderModifierInterface $orderModifier,
OrderRepositoryInterface $orderRepository,
OrderItemQuantityModifierInterface $itemQuantityModifier,
OrderInterface $order,
OrderItemInterface $orderItem,
AddToCartCommandInterface $addToCartCommand,
RequestStack $requestStack,
Session $session,
FlashBagInterface $flashBag,
TranslatorInterface $translator,
AvailabilityCheckerInterface $availabilityChecker,
ProductVariantInterface $productVariant,
): void {
Expand All @@ -86,13 +73,6 @@ public function it_adds_selected_products_to_cart(

$availabilityChecker->isStockSufficient($productVariant, 1)->willReturn(true);

$requestStack->getSession()->willReturn($session);
$session->getFlashBag()->willReturn($flashBag);
$flashBag->has('success')->willReturn(false);

$translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart')->willReturn('Test translation');
$flashBag->add('success', 'Test translation')->shouldBeCalled();

$this->__invoke($addSelectedProductsToCart);
}

Expand All @@ -103,10 +83,6 @@ public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_pro
OrderInterface $order,
OrderItemInterface $orderItem,
AddToCartCommandInterface $addToCartCommand,
RequestStack $requestStack,
Session $session,
FlashBagInterface $flashBag,
TranslatorInterface $translator,
AvailabilityCheckerInterface $availabilityChecker,
ProductVariantInterface $productVariant,
): void {
Expand All @@ -123,12 +99,26 @@ public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_pro
$orderModifier->addToOrder($order, $orderItem)->shouldNotBeCalled();
$orderRepository->add($order)->shouldNotBeCalled();

$requestStack->getSession()->willReturn($session);
$session->getFlashBag()->willReturn($flashBag);
$this->shouldThrow(InvalidProductQuantityException::class)->during('__invoke', [$addSelectedProductsToCart]);
}

public function it_throws_exception_when_quantity_is_not_positive(
AvailabilityCheckerInterface $availabilityChecker,
ProductVariantInterface $productVariant,
OrderItemInterface $orderItem,
WishlistItemInterface $wishlistProduct,
AddToCartCommandInterface $addToCartCommand,
): void {
$collection = new ArrayCollection([$wishlistProduct->getWrappedObject()]);
$addSelectedProductsToCart = new AddSelectedProductsToCart($collection);

$wishlistProduct->getCartItem()->willReturn($addToCartCommand);
$addToCartCommand->getCartItem()->willReturn($orderItem);
$orderItem->getVariant()->willReturn($productVariant);
$orderItem->getQuantity()->willReturn(0);

$translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity')->willReturn('Increase the quantity of at least one item.');
$flashBag->add('error', 'Increase the quantity of at least one item.')->shouldBeCalled();
$availabilityChecker->isStockSufficient($productVariant, 0)->willReturn(true);

$this->__invoke($addSelectedProductsToCart);
$this->shouldThrow(InvalidProductQuantityException::class)->during('__invoke', [$addSelectedProductsToCart]);
}
}
2 changes: 1 addition & 1 deletion src/Command/Wishlist/AddSelectedProductsToCart.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use Doctrine\Common\Collections\Collection;

final class AddSelectedProductsToCart implements WishlistSyncCommandInterface
final class AddSelectedProductsToCart implements AddSelectedProductsToCartInterface
{
public function __construct(private readonly Collection $wishlistProducts)
{
Expand Down
19 changes: 19 additions & 0 deletions src/Command/Wishlist/AddSelectedProductsToCartInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?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 BitBag\SyliusWishlistPlugin\Command\Wishlist;

use Doctrine\Common\Collections\Collection;

interface AddSelectedProductsToCartInterface extends WishlistSyncCommandInterface
{
public function getWishlistProducts(): Collection;
}
6 changes: 3 additions & 3 deletions src/CommandHandler/Wishlist/AddProductsToCartHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddProductsToCartInterface;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantity;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use Doctrine\Common\Collections\Collection;
use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
Expand Down Expand Up @@ -89,15 +89,15 @@ private function productIsStockSufficient(OrderItemInterface $product): bool
}

/**
* @throws InvalidProductQuantity
* @throws InvalidProductQuantityException
*/
private function productHasPositiveQuantity(OrderItemInterface $product): bool
{
if (0 < $product->getQuantity()) {
return true;
}

throw new InvalidProductQuantity();
throw new InvalidProductQuantityException();
}

private function addProductToWishlist(WishlistItemInterface $wishlistProduct): void
Expand Down
11 changes: 5 additions & 6 deletions src/CommandHandler/Wishlist/AddSelectedProductsToCartHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@

namespace BitBag\SyliusWishlistPlugin\CommandHandler\Wishlist;

use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCart;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCartInterface;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantity;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use Doctrine\Common\Collections\Collection;
use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
Expand All @@ -23,7 +23,6 @@
use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface;
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
use Sylius\Component\Order\Modifier\OrderModifierInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;

Expand All @@ -38,7 +37,7 @@ public function __construct(
) {
}

public function __invoke(AddSelectedProductsToCart $addSelectedProductsToCartCommand): void
public function __invoke(AddSelectedProductsToCartInterface $addSelectedProductsToCartCommand): void
{
$this->addSelectedProductsToCart($addSelectedProductsToCartCommand->getWishlistProducts());
}
Expand Down Expand Up @@ -93,8 +92,8 @@ private function productHasPositiveQuantity(OrderItemInterface $product): bool
if (0 < $product->getQuantity()) {
return true;
}
/** @var Session $session */
throw new InvalidProductQuantity();

throw new InvalidProductQuantityException();
}

private function addProductToWishlist(WishlistItemInterface $wishlistProduct): void
Expand Down
37 changes: 4 additions & 33 deletions src/Controller/Action/AddProductsToCartAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,42 +12,13 @@
namespace BitBag\SyliusWishlistPlugin\Controller\Action;

use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddProductsToCart;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantity;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistSyncCommandInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Messenger\Exception\HandlerFailedException;

final class AddProductsToCartAction extends BaseWishlistProductsAction
final class AddProductsToCartAction extends BaseAddWishlistProductsAction
{
protected function handleCommand(FormInterface $form): void
protected function getCommand(FormInterface $form): WishlistSyncCommandInterface
{
/** @var Session $session */
$session = $this->requestStack->getSession();
$flashBag = $session->getFlashBag();

$command = new AddProductsToCart($form->get('items')->getData());

try {
$this->messageBus->dispatch($command);
if (false === $flashBag->has('success')) {
$flashBag->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart'));
}
} catch (HandlerFailedException $exception) {
$flashBag->add('error', $this->getExceptionMessage($exception));
}
}

private function getExceptionMessage(HandlerFailedException $exception): string
{
$previous = $exception->getPrevious();
if ($previous instanceof InsufficientProductStockException) {
return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.insufficient_stock', ['%productName%' => $previous->getProductName()]);
}
if ($previous instanceof InvalidProductQuantity) {
return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity');
}

return $exception->getMessage();
return new AddProductsToCart($form->get('items')->getData());
}
}
35 changes: 4 additions & 31 deletions src/Controller/Action/AddSelectedProductsToCartAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,13 @@
namespace BitBag\SyliusWishlistPlugin\Controller\Action;

use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCart;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantity;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistSyncCommandInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Messenger\Exception\HandlerFailedException;

final class AddSelectedProductsToCartAction extends BaseWishlistProductsAction
final class AddSelectedProductsToCartAction extends BaseAddWishlistProductsAction
{
protected function handleCommand(FormInterface $form): void
protected function getCommand(FormInterface $form): WishlistSyncCommandInterface
{
$session = $this->requestStack->getSession();
$flashBag = $session->getFlashBag();

$command = new AddSelectedProductsToCart($form->getData());

try {
$this->messageBus->dispatch($command);
if (false === $flashBag->has('success')) {
$flashBag->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart'));
}
} catch (HandlerFailedException $exception) {
$flashBag->add('error', $this->getExceptionMessage($exception));
}
}

private function getExceptionMessage(HandlerFailedException $exception): string
{
$previous = $exception->getPrevious();
if ($previous instanceof InsufficientProductStockException) {
return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.insufficient_stock', ['%productName%' => $previous->getProductName()]);
}
if ($previous instanceof InvalidProductQuantity) {
return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity');
}

return $exception->getMessage();
return new AddSelectedProductsToCart($form->getData());
}
}
50 changes: 50 additions & 0 deletions src/Controller/Action/BaseAddWishlistProductsAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?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 BitBag\SyliusWishlistPlugin\Controller\Action;

use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistSyncCommandInterface;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Messenger\Exception\HandlerFailedException;

abstract class BaseAddWishlistProductsAction extends BaseWishlistProductsAction
{
abstract protected function getCommand(FormInterface $form): WishlistSyncCommandInterface;

protected function handleCommand(FormInterface $form): void
{
$command = $this->getCommand($form);

try {
$this->messageBus->dispatch($command);
if (false === $this->getFlashBag()->has('success')) {
$this->getFlashBag()->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart'));
}
} catch (HandlerFailedException $exception) {
$this->getFlashBag()->add('error', $this->getExceptionMessage($exception));
}
}

private function getExceptionMessage(HandlerFailedException $exception): string
{
$previous = $exception->getPrevious();
if ($previous instanceof InsufficientProductStockException) {
return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.insufficient_stock', ['%productName%' => $previous->getProductName()]);
}
if ($previous instanceof InvalidProductQuantityException) {
return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity');
}

return $exception->getMessage();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@

namespace BitBag\SyliusWishlistPlugin\Exception;

final class InvalidProductQuantity extends \Exception
final class InvalidProductQuantityException extends \Exception
{
}
7 changes: 7 additions & 0 deletions src/Exception/WishlistProductNotFoundException.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<?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 BitBag\SyliusWishlistPlugin\Exception;
Expand Down

0 comments on commit 248fb6d

Please sign in to comment.