From 3db585e3afbb46990299c2b9177347b973060597 Mon Sep 17 00:00:00 2001 From: Hubert Filar Date: Thu, 25 Jul 2024 15:12:16 +0200 Subject: [PATCH] OP-291: Refactor RemoveSelectedProductsFromWishlistHandler to handle exceptions in controller --- ...electedProductsFromWishlistHandlerSpec.php | 31 +++++++++---------- ...oveSelectedProductsFromWishlistHandler.php | 18 +++-------- .../Action/BaseWishlistProductsAction.php | 9 ++++++ ...moveSelectedProductsFromWishlistAction.php | 9 +++++- .../WishlistProductNotFoundException.php | 9 ++++++ .../config/services/message_handler.xml | 2 -- src/Resources/translations/messages.en.yml | 1 + src/Resources/translations/messages.pl.yml | 1 + 8 files changed, 47 insertions(+), 33 deletions(-) create mode 100644 src/Exception/WishlistProductNotFoundException.php diff --git a/spec/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandlerSpec.php b/spec/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandlerSpec.php index beba66fd..25189071 100644 --- a/spec/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandlerSpec.php +++ b/spec/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandlerSpec.php @@ -15,30 +15,23 @@ use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface; use BitBag\SyliusWishlistPlugin\CommandHandler\Wishlist\RemoveSelectedProductsFromWishlistHandler; use BitBag\SyliusWishlistPlugin\Entity\WishlistProductInterface; +use BitBag\SyliusWishlistPlugin\Exception\ProductNotFoundException; +use BitBag\SyliusWishlistPlugin\Exception\WishlistProductNotFoundException; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; use PhpSpec\ObjectBehavior; use Sylius\Component\Core\Model\ProductVariantInterface; use Sylius\Component\Core\Repository\ProductVariantRepositoryInterface; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; -use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; -use Symfony\Contracts\Translation\TranslatorInterface; final class RemoveSelectedProductsFromWishlistHandlerSpec extends ObjectBehavior { public function let( ProductVariantRepositoryInterface $productVariantRepository, EntityManagerInterface $wishlistProductManager, - RequestStack $requestStack, - TranslatorInterface $translator, ): void { $this->beConstructedWith( $productVariantRepository, $wishlistProductManager, - $requestStack, - $translator, ); } @@ -52,10 +45,6 @@ public function it_removes_selected_products_from_wishlist( WishlistItemInterface $wishlistItem, WishlistProductInterface $wishlistProduct, ProductVariantInterface $productVariant, - RequestStack $requestStack, - Session $session, - FlashBagInterface $flashBag, - TranslatorInterface $translator, ): void { $removeSelectedProductsCommand = new RemoveSelectedProductsFromWishlist(new ArrayCollection([$wishlistItem->getWrappedObject()])); @@ -63,8 +52,6 @@ public function it_removes_selected_products_from_wishlist( $wishlistItem->getWishlistProduct()->willReturn($wishlistProduct); $wishlistProduct->getVariant()->willReturn($productVariant); $productVariantRepository->find($productVariant)->willReturn($productVariant); - $requestStack->getSession()->willReturn($session); - $session->getFlashBag()->willReturn($flashBag); $this->__invoke($removeSelectedProductsCommand); } @@ -80,6 +67,18 @@ public function it_throws_exception_when_variant_not_found( $wishlistProduct->getVariant()->willReturn(null); $productVariantRepository->find(null)->willReturn(null); - $this->shouldThrow(NotFoundHttpException::class)->during('__invoke', [$removeSelectedProductsCommand]); + $this->shouldThrow(ProductNotFoundException::class)->during('__invoke', [$removeSelectedProductsCommand]); + } + + public function it_throws_exception_when_wishlist_product_not_found( + ProductVariantRepositoryInterface $productVariantRepository, + WishlistItemInterface $wishlistItem, + WishlistProductInterface $wishlistProduct, + ): void { + $removeSelectedProductsCommand = new RemoveSelectedProductsFromWishlist(new ArrayCollection([$wishlistItem->getWrappedObject()])); + + $wishlistItem->getWishlistProduct()->willReturn(null); + + $this->shouldThrow(WishlistProductNotFoundException::class)->during('__invoke', [$removeSelectedProductsCommand]); } } diff --git a/src/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandler.php b/src/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandler.php index 9c8fb7f8..4bf89526 100644 --- a/src/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandler.php +++ b/src/CommandHandler/Wishlist/RemoveSelectedProductsFromWishlistHandler.php @@ -15,15 +15,12 @@ use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItem; use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface; use BitBag\SyliusWishlistPlugin\Entity\WishlistProductInterface; +use BitBag\SyliusWishlistPlugin\Exception\ProductNotFoundException; +use BitBag\SyliusWishlistPlugin\Exception\WishlistProductNotFoundException; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\EntityManagerInterface; use Sylius\Component\Core\Repository\ProductVariantRepositoryInterface; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\Messenger\Attribute\AsMessageHandler; -use Symfony\Component\Routing\Exception\ResourceNotFoundException; -use Symfony\Contracts\Translation\TranslatorInterface; #[AsMessageHandler] final class RemoveSelectedProductsFromWishlistHandler @@ -31,19 +28,12 @@ final class RemoveSelectedProductsFromWishlistHandler public function __construct( private ProductVariantRepositoryInterface $productVariantRepository, private EntityManagerInterface $wishlistProductManager, - private RequestStack $requestStack, - private TranslatorInterface $translator, ) { } public function __invoke(RemoveSelectedProductsFromWishlist $removeSelectedProductsFromWishlistCommand): void { $this->removeSelectedProductsFromWishlist($removeSelectedProductsFromWishlistCommand->getWishlistProducts()); - - /** @var Session $session */ - $session = $this->requestStack->getSession(); - - $session->getFlashBag()->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.removed_selected_wishlist_items')); } private function removeSelectedProductsFromWishlist(Collection $wishlistProducts): void @@ -60,13 +50,13 @@ private function removeProductFromWishlist(WishlistItemInterface $wishlistItem): $wishlistProduct = $wishlistItem->getWishlistProduct(); if (null === $wishlistProduct) { - throw new ResourceNotFoundException(); + throw new WishlistProductNotFoundException(); } $productVariant = $this->productVariantRepository->find($wishlistProduct->getVariant()); if (null === $productVariant) { - throw new NotFoundHttpException(); + throw new ProductNotFoundException(); } $this->wishlistProductManager->remove($wishlistProduct); diff --git a/src/Controller/Action/BaseWishlistProductsAction.php b/src/Controller/Action/BaseWishlistProductsAction.php index 8c8e6969..b15aacb8 100644 --- a/src/Controller/Action/BaseWishlistProductsAction.php +++ b/src/Controller/Action/BaseWishlistProductsAction.php @@ -23,6 +23,7 @@ use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -79,6 +80,14 @@ public function __invoke(int $wishlistId, Request $request): Response abstract protected function handleCommand(FormInterface $form): void; + protected function getFlashBag(): FlashBagInterface + { + /** @var Session $session */ + $session = $this->requestStack->getSession(); + + return $session->getFlashBag(); + } + private function createForm(int $wishlistId): ?FormInterface { /** @var ?WishlistInterface $wishlist */ diff --git a/src/Controller/Action/RemoveSelectedProductsFromWishlistAction.php b/src/Controller/Action/RemoveSelectedProductsFromWishlistAction.php index 005836f7..bdd24dfc 100644 --- a/src/Controller/Action/RemoveSelectedProductsFromWishlistAction.php +++ b/src/Controller/Action/RemoveSelectedProductsFromWishlistAction.php @@ -13,12 +13,19 @@ use BitBag\SyliusWishlistPlugin\Command\Wishlist\RemoveSelectedProductsFromWishlist; use Symfony\Component\Form\FormInterface; +use Symfony\Component\Messenger\Exception\HandlerFailedException; final class RemoveSelectedProductsFromWishlistAction extends BaseWishlistProductsAction { protected function handleCommand(FormInterface $form): void { $command = new RemoveSelectedProductsFromWishlist($form->getData()); - $this->messageBus->dispatch($command); + + try { + $this->messageBus->dispatch($command); + $this->getFlashBag()->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.removed_selected_wishlist_items')); + } catch (HandlerFailedException) { + $this->getFlashBag()->add('error', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.wishlist_product_not_found')); + } } } diff --git a/src/Exception/WishlistProductNotFoundException.php b/src/Exception/WishlistProductNotFoundException.php new file mode 100644 index 00000000..99ed3beb --- /dev/null +++ b/src/Exception/WishlistProductNotFoundException.php @@ -0,0 +1,9 @@ + - - diff --git a/src/Resources/translations/messages.en.yml b/src/Resources/translations/messages.en.yml index e1cf837a..3c02617f 100644 --- a/src/Resources/translations/messages.en.yml +++ b/src/Resources/translations/messages.en.yml @@ -39,6 +39,7 @@ bitbag_sylius_wishlist_plugin: copied_selected_wishlist_items: Selected products have been successfully copied. wishlist_not_found: Wishlist not found wishlist_for_channel_not_found: Wishlist for channel not found + wishlist_product_not_found: Wishlist product not found csv_file_contains_incorrect_products: CSV file contains incorrect products. wishlist_name_already_exists: Wishlist name already exists, try another. does_not_have_sufficient_stock: does not have sufficient stock. diff --git a/src/Resources/translations/messages.pl.yml b/src/Resources/translations/messages.pl.yml index 55556167..d3f29d04 100644 --- a/src/Resources/translations/messages.pl.yml +++ b/src/Resources/translations/messages.pl.yml @@ -49,6 +49,7 @@ bitbag_sylius_wishlist_plugin: product_variant_exists_in_another_wishlist: 'istnieje w innej liście życzeń.' create_new_wishlist: 'Nowa lista życzeń została utworzona.' wishlist_for_channel_not_found: 'Nie znaleziono listy życzeń dla aktualnego kanału' + wishlist_product_not_found: Nie znaleziono produktu z listy życzeń clear_wishlist: 'Wyczyść listę życzeń' cleared_wishlist: 'Lista życzeń została wyczyszczona' wishlist_name_already_exists: 'Istnieje już lista życzeń z taką nazwą, proszę podaj inną.'