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

OP-559 - Change flashbags in AddSelectedProductsToCartHandler to exceptions #269

Merged
merged 2 commits into from
Sep 30, 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
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,27 +73,16 @@ 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);
$this->shouldNotThrow()->during('__invoke', [$addSelectedProductsToCart]);
}

public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_processed(
public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_processed_but_throws_exception(
WishlistItemInterface $wishlistProduct,
OrderModifierInterface $orderModifier,
OrderRepositoryInterface $orderRepository,
OrderInterface $order,
OrderItemInterface $orderItem,
AddToCartCommandInterface $addToCartCommand,
RequestStack $requestStack,
Session $session,
FlashBagInterface $flashBag,
TranslatorInterface $translator,
AvailabilityCheckerInterface $availabilityChecker,
ProductVariantInterface $productVariant,
): void {
Expand All @@ -123,12 +99,6 @@ 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);

$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();

$this->__invoke($addSelectedProductsToCart);
$this->shouldThrow(InvalidProductQuantityException::class)->during('__invoke', [$addSelectedProductsToCart]);
}
}
28 changes: 4 additions & 24 deletions src/CommandHandler/Wishlist/AddSelectedProductsToCartHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCart;
use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use Doctrine\Common\Collections\Collection;
use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface;
use Sylius\Component\Core\Model\OrderItemInterface;
Expand All @@ -21,18 +23,13 @@
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\Session;
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Contracts\Translation\TranslatorInterface;

#[AsMessageHandler]
final class AddSelectedProductsToCartHandler
{
public function __construct(
private RequestStack $requestStack,
private TranslatorInterface $translator,
private OrderItemQuantityModifierInterface $itemQuantityModifier,
private OrderModifierInterface $orderModifier,
private OrderRepositoryInterface $orderRepository,
Expand Down Expand Up @@ -87,25 +84,16 @@ private function productIsStockSufficient(OrderItemInterface $product): bool
return true;
}

$message = sprintf('%s does not have sufficient stock.', $product->getProductName());

/** @var Session $session */
$session = $this->requestStack->getSession();
$session->getFlashBag()->add('error', $this->translator->trans($message));

return false;
throw new InsufficientProductStockException((string) $product->getProductName());
}

private function productHasPositiveQuantity(OrderItemInterface $product): bool
{
if (0 < $product->getQuantity()) {
return true;
}
/** @var Session $session */
$session = $this->requestStack->getSession();
$session->getFlashBag()->add('error', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity'));

return false;
throw new InvalidProductQuantityException();
}

private function addProductToWishlist(WishlistItemInterface $wishlistProduct): void
Expand All @@ -126,13 +114,5 @@ private function addProductToWishlist(WishlistItemInterface $wishlistProduct): v

$this->orderModifier->addToOrder($cart, $cartItem);
$this->orderRepository->add($cart);

/** @var Session $session */
$session = $this->requestStack->getSession();
$flashBag = $session->getFlashBag();

if (false === $flashBag->has('success')) {
$flashBag->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart'));
}
}
}
37 changes: 35 additions & 2 deletions src/Controller/Action/AddSelectedProductsToCartAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,17 @@
namespace BitBag\SyliusWishlistPlugin\Controller\Action;

use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCart;
use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException;
use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException;
use BitBag\SyliusWishlistPlugin\Processor\WishlistCommandProcessorInterface;
use BitBag\SyliusWishlistPlugin\Repository\WishlistRepositoryInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\Messenger\Exception\HandlerFailedException;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
Expand Down Expand Up @@ -48,7 +53,35 @@ public function __construct(

protected function handleCommand(FormInterface $form): void
{
$command = new AddSelectedProductsToCart($form->getData());
$this->messageBus->dispatch($command);
try {
$command = new AddSelectedProductsToCart($form->getData());
$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();
}

private function getFlashBag(): FlashBagInterface
{
/** @var Session $session */
$session = $this->requestStack->getSession();

return $session->getFlashBag();
}
}
25 changes: 25 additions & 0 deletions src/Exception/InsufficientProductStockException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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 [email protected].
*/

declare(strict_types=1);

namespace BitBag\SyliusWishlistPlugin\Exception;

final class InsufficientProductStockException extends \Exception
{
public function __construct(private string $productName)
{
parent::__construct();
}

public function getProductName(): string
{
return $this->productName;
}
}
16 changes: 16 additions & 0 deletions src/Exception/InvalidProductQuantityException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?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 [email protected].
*/

declare(strict_types=1);

namespace BitBag\SyliusWishlistPlugin\Exception;

final class InvalidProductQuantityException extends \Exception
{
}
2 changes: 0 additions & 2 deletions src/Resources/config/services/message_handler.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@
</service>

<service id="bitbag_sylius_wishlist_plugin.command_handler.wishlist.add_selected_products_to_cart" class="BitBag\SyliusWishlistPlugin\CommandHandler\Wishlist\AddSelectedProductsToCartHandler">
<argument type="service" id="request_stack"/>
<argument type="service" id="translator"/>
<argument type="service" id="sylius.order_item_quantity_modifier"/>
<argument type="service" id="sylius.order_modifier"/>
<argument type="service" id="sylius.repository.order"/>
Expand Down
1 change: 1 addition & 0 deletions src/Resources/translations/messages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ bitbag_sylius_wishlist_plugin:
added_to_cart: Wishlist items have been added to your cart.
save_wishlist: Save wishlist
variant_not_unique: You already have this variant on your wishlist
insufficient_stock: '%productName% does not have sufficient stock.'
increase_quantity: Increase the quantity of at least one item.
select_products: Select at least one item.
added_selected_wishlist_items_to_cart: Selected wishlist items have been added to your cart.
Expand Down
1 change: 1 addition & 0 deletions src/Resources/translations/messages.pl.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ bitbag_sylius_wishlist_plugin:
added_to_cart: Produkty z listy życzeń zostały dodane do koszyka.
save_wishlist: Zapisz listę życzeń
variant_not_unique: Ten wariant jest już na Twojej liście życzeń
insufficient_stock: '%productName% nie ma wystarczającego stanu magazynowego.'
increase_quantity: Zwiększ ilość przynajmniej jednego z produktów.
select_products: Wybierz przynajmniej jeden produkt.
added_selected_wishlist_items_to_cart: Wybrane produkty zostały dodane do koszyka.
Expand Down
Loading