From 248fb6d94e96d9026bcd39872dabb20dd2a18610 Mon Sep 17 00:00:00 2001 From: Hubert Filar Date: Thu, 25 Jul 2024 15:12:47 +0200 Subject: [PATCH] OP-291: Extract abstraction to prevent code repetition --- .../Wishlist/AddProductsToCartHandlerSpec.php | 4 +- .../AddSelectedProductsToCartHandlerSpec.php | 50 ++++++++----------- .../Wishlist/AddSelectedProductsToCart.php | 2 +- .../AddSelectedProductsToCartInterface.php | 19 +++++++ .../Wishlist/AddProductsToCartHandler.php | 6 +-- .../AddSelectedProductsToCartHandler.php | 11 ++-- .../Action/AddProductsToCartAction.php | 37 ++------------ .../AddSelectedProductsToCartAction.php | 35 ++----------- .../Action/BaseAddWishlistProductsAction.php | 50 +++++++++++++++++++ ...hp => InvalidProductQuantityException.php} | 2 +- .../WishlistProductNotFoundException.php | 7 +++ 11 files changed, 116 insertions(+), 107 deletions(-) create mode 100644 src/Command/Wishlist/AddSelectedProductsToCartInterface.php create mode 100644 src/Controller/Action/BaseAddWishlistProductsAction.php rename src/Exception/{InvalidProductQuantity.php => InvalidProductQuantityException.php} (83%) diff --git a/spec/CommandHandler/Wishlist/AddProductsToCartHandlerSpec.php b/spec/CommandHandler/Wishlist/AddProductsToCartHandlerSpec.php index 3ded2a92..4b0e27df 100644 --- a/spec/CommandHandler/Wishlist/AddProductsToCartHandlerSpec.php +++ b/spec/CommandHandler/Wishlist/AddProductsToCartHandlerSpec.php @@ -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; @@ -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]); } } diff --git a/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php b/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php index adb47989..dad54c26 100644 --- a/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php +++ b/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php @@ -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; @@ -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, @@ -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 { @@ -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); } @@ -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 { @@ -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]); } } diff --git a/src/Command/Wishlist/AddSelectedProductsToCart.php b/src/Command/Wishlist/AddSelectedProductsToCart.php index f1134351..b6d8f024 100644 --- a/src/Command/Wishlist/AddSelectedProductsToCart.php +++ b/src/Command/Wishlist/AddSelectedProductsToCart.php @@ -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) { diff --git a/src/Command/Wishlist/AddSelectedProductsToCartInterface.php b/src/Command/Wishlist/AddSelectedProductsToCartInterface.php new file mode 100644 index 00000000..9d5fc3b7 --- /dev/null +++ b/src/Command/Wishlist/AddSelectedProductsToCartInterface.php @@ -0,0 +1,19 @@ +addSelectedProductsToCart($addSelectedProductsToCartCommand->getWishlistProducts()); } @@ -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 diff --git a/src/Controller/Action/AddProductsToCartAction.php b/src/Controller/Action/AddProductsToCartAction.php index 312d0eab..873c8450 100644 --- a/src/Controller/Action/AddProductsToCartAction.php +++ b/src/Controller/Action/AddProductsToCartAction.php @@ -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()); } } diff --git a/src/Controller/Action/AddSelectedProductsToCartAction.php b/src/Controller/Action/AddSelectedProductsToCartAction.php index e47d6471..f67fa8cd 100644 --- a/src/Controller/Action/AddSelectedProductsToCartAction.php +++ b/src/Controller/Action/AddSelectedProductsToCartAction.php @@ -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()); } } diff --git a/src/Controller/Action/BaseAddWishlistProductsAction.php b/src/Controller/Action/BaseAddWishlistProductsAction.php new file mode 100644 index 00000000..b6d3cf30 --- /dev/null +++ b/src/Controller/Action/BaseAddWishlistProductsAction.php @@ -0,0 +1,50 @@ +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(); + } +} diff --git a/src/Exception/InvalidProductQuantity.php b/src/Exception/InvalidProductQuantityException.php similarity index 83% rename from src/Exception/InvalidProductQuantity.php rename to src/Exception/InvalidProductQuantityException.php index fa18dab2..0ba2d523 100644 --- a/src/Exception/InvalidProductQuantity.php +++ b/src/Exception/InvalidProductQuantityException.php @@ -11,6 +11,6 @@ namespace BitBag\SyliusWishlistPlugin\Exception; -final class InvalidProductQuantity extends \Exception +final class InvalidProductQuantityException extends \Exception { } diff --git a/src/Exception/WishlistProductNotFoundException.php b/src/Exception/WishlistProductNotFoundException.php index 99ed3beb..44484194 100644 --- a/src/Exception/WishlistProductNotFoundException.php +++ b/src/Exception/WishlistProductNotFoundException.php @@ -1,5 +1,12 @@