From 366cac89e010366dae414885e0ba722e005a235e Mon Sep 17 00:00:00 2001 From: Bartosz Pietrzak Date: Fri, 21 Sep 2018 13:57:44 +0200 Subject: [PATCH 1/4] OrderCustomerRelationChecker class + test --- .../OrderCustomerRelationCheckerSpec.php | 52 +++++++++++++++++++ src/Checker/OrderCustomerRelationChecker.php | 30 +++++++++++ .../OrderCustomerRelationCheckerInterface.php | 12 +++++ 3 files changed, 94 insertions(+) create mode 100644 spec/Checker/OrderCustomerRelationCheckerSpec.php create mode 100644 src/Checker/OrderCustomerRelationChecker.php create mode 100644 src/Checker/OrderCustomerRelationCheckerInterface.php diff --git a/spec/Checker/OrderCustomerRelationCheckerSpec.php b/spec/Checker/OrderCustomerRelationCheckerSpec.php new file mode 100644 index 0000000..3f915cc --- /dev/null +++ b/spec/Checker/OrderCustomerRelationCheckerSpec.php @@ -0,0 +1,52 @@ +beConstructedWith($customerContext); + } + + function it_implements_order_customer_relation_checker_interface(): void + { + $this->shouldImplement(OrderCustomerRelationCheckerInterface::class); + } + + function it_returns_true_when_order_was_placed_by_customer( + CustomerContextInterface $customerContext, + CustomerInterface $customer, + OrderInterface $order + ): void { + $customer->getId()->willReturn('1'); + + $customerContext->getCustomer()->willReturn($customer); + $order->getCustomer()->willReturn($customer); + + $this->wasOrderPlacedByCurrentCustomer($order)->shouldReturn(true); + } + + function it_returns_false_when_order_was_not_placed_by_customer( + CustomerContextInterface $customerContext, + CustomerInterface $firstCustomer, + CustomerInterface $secondCustomer, + OrderInterface $order + ): void { + $firstCustomer->getId()->willReturn('1'); + $secondCustomer->getId()->willReturn('2'); + + $customerContext->getCustomer()->willReturn($firstCustomer); + $order->getCustomer()->willReturn($secondCustomer); + + $this->wasOrderPlacedByCurrentCustomer($order)->shouldReturn(false); + } +} diff --git a/src/Checker/OrderCustomerRelationChecker.php b/src/Checker/OrderCustomerRelationChecker.php new file mode 100644 index 0000000..1f43461 --- /dev/null +++ b/src/Checker/OrderCustomerRelationChecker.php @@ -0,0 +1,30 @@ +customerContext = $customerContext; + } + + public function wasOrderPlacedByCurrentCustomer(OrderInterface $order): bool + { + $customer = $this->customerContext->getCustomer(); + + return + null !== $customer && + null !g== $order->getCustomer() && + $order->getCustomer()->getId() === $customer->getId() + ; + } +} diff --git a/src/Checker/OrderCustomerRelationCheckerInterface.php b/src/Checker/OrderCustomerRelationCheckerInterface.php new file mode 100644 index 0000000..9857909 --- /dev/null +++ b/src/Checker/OrderCustomerRelationCheckerInterface.php @@ -0,0 +1,12 @@ + Date: Mon, 24 Sep 2018 12:08:23 +0200 Subject: [PATCH 2/4] First steps of reimplementing behat test --- ...e_order_placed_by_another_customer.feature | 18 ++++++ .../OrderCustomerRelationCheckerSpec.php | 14 +---- spec/Reorder/ReordererSpec.php | 56 ++++++++++++++--- src/Checker/OrderCustomerRelationChecker.php | 16 +---- .../OrderCustomerRelationCheckerInterface.php | 3 +- src/Controller/CustomerReorderAction.php | 12 +++- src/Reorder/Reorderer.php | 20 +++++- src/Reorder/ReordererInterface.php | 7 ++- src/Resources/config/services.xml | 4 ++ .../Reorder/Application/ReorderContext.php | 63 +++++++++++++++++++ .../Reorder/{ => Ui}/ReorderContext.php | 2 +- tests/Behat/Resources/services.xml | 10 ++- tests/Behat/Resources/suites.yml | 33 +++++++++- 13 files changed, 216 insertions(+), 42 deletions(-) create mode 100644 features/being_unable_to_reorder_the_order_placed_by_another_customer.feature create mode 100644 tests/Behat/Context/Reorder/Application/ReorderContext.php rename tests/Behat/Context/Reorder/{ => Ui}/ReorderContext.php (99%) diff --git a/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature b/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature new file mode 100644 index 0000000..620d498 --- /dev/null +++ b/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature @@ -0,0 +1,18 @@ +@reordering +Feature: Being unable to reorder the order placed by another customer + In order to maintain shop security + As a Store Owner + I want Customer to be the only person allowed to reorder their previously placed order + + Background: + Given the store operates on a single channel in "United States" + And the store has a product "Angel T-Shirt" + And the store ships everywhere for free + And the store allows paying with "Cash on Delivery" + And there is a customer "Rick Sanchez" identified by an email "rick.sanchez@wubba-lubba-dub-dub.com" and a password "Morty" + And there is another customer "Morty Smith" that placed an order "#00000666" + + @application + Scenario: Being unable to reorder the order placed by another customer + When the customer "rick.sanchez@wubba-lubba-dub-dub.com" tries to reorder the order "#00000666" + Then the order "#000001" should not be reordered diff --git a/spec/Checker/OrderCustomerRelationCheckerSpec.php b/spec/Checker/OrderCustomerRelationCheckerSpec.php index 3f915cc..58abe7a 100644 --- a/spec/Checker/OrderCustomerRelationCheckerSpec.php +++ b/spec/Checker/OrderCustomerRelationCheckerSpec.php @@ -7,36 +7,27 @@ use PhpSpec\ObjectBehavior; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; -use Sylius\Component\Customer\Context\CustomerContextInterface; use Sylius\CustomerReorderPlugin\Checker\OrderCustomerRelationCheckerInterface; final class OrderCustomerRelationCheckerSpec extends ObjectBehavior { - function let(CustomerContextInterface $customerContext): void - { - $this->beConstructedWith($customerContext); - } - function it_implements_order_customer_relation_checker_interface(): void { $this->shouldImplement(OrderCustomerRelationCheckerInterface::class); } function it_returns_true_when_order_was_placed_by_customer( - CustomerContextInterface $customerContext, CustomerInterface $customer, OrderInterface $order ): void { $customer->getId()->willReturn('1'); - $customerContext->getCustomer()->willReturn($customer); $order->getCustomer()->willReturn($customer); - $this->wasOrderPlacedByCurrentCustomer($order)->shouldReturn(true); + $this->wasOrderPlacedByCustomer($order, $customer)->shouldReturn(true); } function it_returns_false_when_order_was_not_placed_by_customer( - CustomerContextInterface $customerContext, CustomerInterface $firstCustomer, CustomerInterface $secondCustomer, OrderInterface $order @@ -44,9 +35,8 @@ function it_returns_false_when_order_was_not_placed_by_customer( $firstCustomer->getId()->willReturn('1'); $secondCustomer->getId()->willReturn('2'); - $customerContext->getCustomer()->willReturn($firstCustomer); $order->getCustomer()->willReturn($secondCustomer); - $this->wasOrderPlacedByCurrentCustomer($order)->shouldReturn(false); + $this->wasOrderPlacedByCustomer($order, $firstCustomer)->shouldReturn(false); } } diff --git a/spec/Reorder/ReordererSpec.php b/spec/Reorder/ReordererSpec.php index 9daedd6..a76bd4b 100644 --- a/spec/Reorder/ReordererSpec.php +++ b/spec/Reorder/ReordererSpec.php @@ -6,14 +6,17 @@ use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; +use Nette\InvalidStateException; use PhpSpec\ObjectBehavior; use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\OrderItemInterface; use Sylius\Component\Core\Model\ProductVariantInterface; use Sylius\Component\Core\Model\PromotionInterface; use Sylius\Component\Order\Processor\OrderProcessorInterface; +use Sylius\CustomerReorderPlugin\Checker\OrderCustomerRelationCheckerInterface; use Sylius\CustomerReorderPlugin\Factory\OrderFactoryInterface; use Sylius\CustomerReorderPlugin\Reorder\Reorderer; use Sylius\CustomerReorderPlugin\Reorder\ReordererInterface; @@ -32,7 +35,8 @@ function let( MoneyFormatterInterface $moneyFormatter, Session $session, ReorderEligibilityChecker $reorderEligibilityChecker, - ReorderEligibilityCheckerResponseProcessorInterface $reorderEligibilityCheckerResponseProcessor + ReorderEligibilityCheckerResponseProcessorInterface $reorderEligibilityCheckerResponseProcessor, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker ): void { $this->beConstructedWith( $orderFactory, @@ -41,7 +45,8 @@ function let( $moneyFormatter, $session, $reorderEligibilityChecker, - $reorderEligibilityCheckerResponseProcessor + $reorderEligibilityCheckerResponseProcessor, + $orderCustomerRelationChecker ); } @@ -59,7 +64,9 @@ function it_creates_and_persists_reorder_from_existing_order( OrderFactoryInterface $orderFactory, EntityManagerInterface $entityManager, ReorderEligibilityChecker $reorderEligibilityChecker, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker, ChannelInterface $channel, + CustomerInterface $customer, OrderInterface $order, OrderInterface $reorder, OrderItemInterface $firstOrderItem, @@ -68,6 +75,8 @@ function it_creates_and_persists_reorder_from_existing_order( $order->getTotal()->willReturn(100); $order->getCurrencyCode()->willReturn('USD'); + $orderCustomerRelationChecker->wasOrderPlacedByCustomer($order, $customer)->willReturn(true); + $reorder->getTotal()->willReturn(100); $orderFactory->createFromExistingOrder($order, $channel)->willReturn($reorder); @@ -81,14 +90,16 @@ function it_creates_and_persists_reorder_from_existing_order( $secondOrderItem->getWrappedObject() ])); - $this->reorder($order, $channel); + $this->reorder($order, $channel, $customer); } function it_checks_if_orders_totals_differ( OrderFactoryInterface $orderFactory, EntityManagerInterface $entityManager, ReorderEligibilityChecker $reorderEligibilityChecker, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker, ChannelInterface $channel, + CustomerInterface $customer, OrderInterface $order, OrderInterface $reorder, MoneyFormatterInterface $moneyFormatter, @@ -101,6 +112,8 @@ function it_checks_if_orders_totals_differ( $order->getCurrencyCode()->willReturn('USD'); $order->getPromotions()->willReturn($promotions); + $orderCustomerRelationChecker->wasOrderPlacedByCustomer($order, $customer)->willReturn(true); + $reorder->getTotal()->willReturn(150); $reorder->getPromotions()->willReturn($promotions); @@ -122,14 +135,16 @@ function it_checks_if_orders_totals_differ( $entityManager->persist($reorder)->shouldBeCalled(); $entityManager->flush()->shouldBeCalled(); - $this->reorder($order, $channel); + $this->reorder($order, $channel, $customer); } function it_checks_if_promotion_is_no_longer_available( OrderFactoryInterface $orderFactory, EntityManagerInterface $entityManager, ReorderEligibilityChecker $reorderEligibilityChecker, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker, ChannelInterface $channel, + CustomerInterface $customer, OrderInterface $order, OrderInterface $reorder, MoneyFormatterInterface $moneyFormatter, @@ -144,6 +159,8 @@ function it_checks_if_promotion_is_no_longer_available( $secondPromotion->getWrappedObject() ])); + $orderCustomerRelationChecker->wasOrderPlacedByCustomer($order, $customer)->willReturn(true); + $firstPromotion->getName()->willReturn('test_promotion_01'); $secondPromotion->getName()->willReturn('test_promotion_02'); @@ -169,14 +186,16 @@ function it_checks_if_promotion_is_no_longer_available( $entityManager->persist($reorder)->shouldBeCalled(); $entityManager->flush()->shouldBeCalled(); - $this->reorder($order, $channel); + $this->reorder($order, $channel, $customer); } function it_checks_if_price_of_any_item_has_changed( OrderFactoryInterface $orderFactory, EntityManagerInterface $entityManager, ReorderEligibilityChecker $reorderEligibilityChecker, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker, ChannelInterface $channel, + CustomerInterface $customer, OrderInterface $order, OrderInterface $reorder, OrderItemInterface $firstOrderItem, @@ -194,6 +213,8 @@ function it_checks_if_price_of_any_item_has_changed( $secondOrderItem->getWrappedObject() ])); + $orderCustomerRelationChecker->wasOrderPlacedByCustomer($order, $customer)->willReturn(true); + $reorder->getItems()->willReturn(new ArrayCollection([ $firstOrderItem->getWrappedObject(), $secondOrderItem->getWrappedObject() @@ -213,14 +234,16 @@ function it_checks_if_price_of_any_item_has_changed( $entityManager->persist($reorder)->shouldBeCalled(); $entityManager->flush()->shouldBeCalled(); - $this->reorder($order, $channel); + $this->reorder($order, $channel, $customer); } function it_checks_if_any_item_is_out_of_stock( OrderFactoryInterface $orderFactory, EntityManagerInterface $entityManager, ReorderEligibilityChecker $reorderEligibilityChecker, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker, ChannelInterface $channel, + CustomerInterface $customer, OrderInterface $order, OrderInterface $reorder, OrderItemInterface $firstOrderItem, @@ -244,6 +267,8 @@ function it_checks_if_any_item_is_out_of_stock( $secondOrderItem->getWrappedObject() ])); + $orderCustomerRelationChecker->wasOrderPlacedByCustomer($order, $customer)->willReturn(true); + $reorder->getItems()->willReturn(new ArrayCollection([ $firstOrderItem->getWrappedObject() ])); @@ -261,6 +286,23 @@ function it_checks_if_any_item_is_out_of_stock( $entityManager->persist($reorder)->shouldBeCalled(); $entityManager->flush()->shouldBeCalled(); - $this->reorder($order, $channel); + $this->reorder($order, $channel, $customer); + } + + function it_does_not_create_reorder_when_order_does_not_belong_to_given_customer( + OrderInterface $order, + ChannelInterface $channel, + CustomerInterface $firstCustomer, + CustomerInterface $secondCustomer + ): void { + $firstCustomer->getId()->willReturn('1'); + $secondCustomer->getId()->willReturn('2'); + + $order->getCustomer()->willReturn($firstCustomer); + + $this + ->shouldThrow(InvalidStateException::class) + ->during('reorder', [$order, $channel, $secondCustomer]) + ; } } diff --git a/src/Checker/OrderCustomerRelationChecker.php b/src/Checker/OrderCustomerRelationChecker.php index 1f43461..5c17f33 100644 --- a/src/Checker/OrderCustomerRelationChecker.php +++ b/src/Checker/OrderCustomerRelationChecker.php @@ -4,26 +4,16 @@ namespace Sylius\CustomerReorderPlugin\Checker; +use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; -use Sylius\Component\Customer\Context\CustomerContextInterface; final class OrderCustomerRelationChecker implements OrderCustomerRelationCheckerInterface { - /** @var CustomerContextInterface */ - private $customerContext; - - public function __construct(CustomerContextInterface $customerContext) + public function wasOrderPlacedByCustomer(OrderInterface $order, CustomerInterface $customer): bool { - $this->customerContext = $customerContext; - } - - public function wasOrderPlacedByCurrentCustomer(OrderInterface $order): bool - { - $customer = $this->customerContext->getCustomer(); - return null !== $customer && - null !g== $order->getCustomer() && + null !== $order->getCustomer() && $order->getCustomer()->getId() === $customer->getId() ; } diff --git a/src/Checker/OrderCustomerRelationCheckerInterface.php b/src/Checker/OrderCustomerRelationCheckerInterface.php index 9857909..d3d997e 100644 --- a/src/Checker/OrderCustomerRelationCheckerInterface.php +++ b/src/Checker/OrderCustomerRelationCheckerInterface.php @@ -4,9 +4,10 @@ namespace Sylius\CustomerReorderPlugin\Checker; +use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; interface OrderCustomerRelationCheckerInterface { - public function wasOrderPlacedByCurrentCustomer(OrderInterface $order): bool; + public function wasOrderPlacedByCustomer(OrderInterface $order, CustomerInterface $customer): bool; } diff --git a/src/Controller/CustomerReorderAction.php b/src/Controller/CustomerReorderAction.php index bac422f..b96e968 100644 --- a/src/Controller/CustomerReorderAction.php +++ b/src/Controller/CustomerReorderAction.php @@ -10,12 +10,15 @@ use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Repository\OrderRepositoryInterface; +use Sylius\Component\Customer\Context\CustomerContextInterface; use Sylius\Component\Order\Context\CartContextInterface; +use Sylius\CustomerReorderPlugin\Checker\OrderCustomerRelationCheckerInterface; use Sylius\CustomerReorderPlugin\Reorder\ReordererInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; final class CustomerReorderAction @@ -29,6 +32,9 @@ final class CustomerReorderAction /** @var CartContextInterface */ private $cartContext; + /** @var CustomerContextInterface */ + private $customerContext; + /** @var OrderRepositoryInterface */ private $orderRepository; @@ -45,6 +51,7 @@ public function __construct( CartSessionStorage $cartSessionStorage, ChannelContextInterface $channelContext, CartContextInterface $cartContext, + CustomerContextInterface $customerContext, OrderRepositoryInterface $orderRepository, ReordererInterface $reorderService, UrlGeneratorInterface $urlGenerator, @@ -53,6 +60,7 @@ public function __construct( $this->cartSessionStorage = $cartSessionStorage; $this->channelContext = $channelContext; $this->cartContext = $cartContext; + $this->customerContext = $customerContext; $this->orderRepository = $orderRepository; $this->reorderer = $reorderService; $this->urlGenerator = $urlGenerator; @@ -67,10 +75,12 @@ public function __invoke(Request $request): Response $channel = $this->channelContext->getChannel(); assert($channel instanceof ChannelInterface); + $customer = $this->customerContext->getCustomer(); + $reorder = null; try { - $reorder = $this->reorderer->reorder($order, $channel); + $reorder = $this->reorderer->reorder($order, $channel, $customer); } catch (InvalidStateException $exception) { $this->session->getFlashBag()->add('info', $exception->getMessage()); diff --git a/src/Reorder/Reorderer.php b/src/Reorder/Reorderer.php index cd0bfab..21439bb 100644 --- a/src/Reorder/Reorderer.php +++ b/src/Reorder/Reorderer.php @@ -8,8 +8,10 @@ use Nette\InvalidStateException; use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Order\Processor\OrderProcessorInterface; +use Sylius\CustomerReorderPlugin\Checker\OrderCustomerRelationCheckerInterface; use Sylius\CustomerReorderPlugin\Factory\OrderFactoryInterface; use Sylius\CustomerReorderPlugin\ReorderEligibility\ReorderEligibilityChecker; use Sylius\CustomerReorderPlugin\ReorderEligibility\ResponseProcessing\ReorderEligibilityCheckerResponseProcessorInterface; @@ -38,6 +40,9 @@ final class Reorderer implements ReordererInterface /** @var ReorderEligibilityCheckerResponseProcessorInterface */ private $reorderEligibilityCheckerResponseProcessor; + /** @var OrderCustomerRelationCheckerInterface */ + private $orderCustomerRelationCheckerInterface; + public function __construct( OrderFactoryInterface $orderFactory, EntityManagerInterface $entityManager, @@ -45,7 +50,8 @@ public function __construct( MoneyFormatterInterface $moneyFormatter, Session $session, ReorderEligibilityChecker $reorderEligibilityChecker, - ReorderEligibilityCheckerResponseProcessorInterface $reorderEligibilityCheckerResponseProcessor + ReorderEligibilityCheckerResponseProcessorInterface $reorderEligibilityCheckerResponseProcessor, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker ) { $this->orderFactory = $orderFactory; $this->entityManager = $entityManager; @@ -54,10 +60,18 @@ public function __construct( $this->session = $session; $this->reorderEligibilityChecker = $reorderEligibilityChecker; $this->reorderEligibilityCheckerResponseProcessor = $reorderEligibilityCheckerResponseProcessor; + $this->orderCustomerRelationCheckerInterface = $orderCustomerRelationChecker; } - public function reorder(OrderInterface $order, ChannelInterface $channel): OrderInterface - { + public function reorder( + OrderInterface $order, + ChannelInterface $channel, + CustomerInterface $customer + ): OrderInterface { + if (!$this->orderCustomerRelationCheckerInterface->wasOrderPlacedByCustomer($order, $customer)) { + throw new InvalidStateException("The customer is not the order's owner."); + } + $reorder = $this->orderFactory->createFromExistingOrder($order, $channel); assert($reorder instanceof OrderInterface); diff --git a/src/Reorder/ReordererInterface.php b/src/Reorder/ReordererInterface.php index 13fe0d0..d78c439 100644 --- a/src/Reorder/ReordererInterface.php +++ b/src/Reorder/ReordererInterface.php @@ -5,9 +5,14 @@ namespace Sylius\CustomerReorderPlugin\Reorder; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; interface ReordererInterface { - public function reorder(OrderInterface $order, ChannelInterface $channel): OrderInterface; + public function reorder( + OrderInterface $order, + ChannelInterface $channel, + CustomerInterface $customer + ): OrderInterface; } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index 03b092b..b25650d 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -8,6 +8,7 @@ + @@ -21,6 +22,7 @@ + @@ -66,5 +68,7 @@ + + diff --git a/tests/Behat/Context/Reorder/Application/ReorderContext.php b/tests/Behat/Context/Reorder/Application/ReorderContext.php new file mode 100644 index 0000000..75d9dde --- /dev/null +++ b/tests/Behat/Context/Reorder/Application/ReorderContext.php @@ -0,0 +1,63 @@ +orderRepository = $orderRepository; + $this->customerRepository = $customerRepository; + $this->reorderer = $reorderer; + } + + /** + * @When the customer :customerEmail tries to reorder the order :orderNumber + */ + public function theCustomerTriesToReorderTheOrder(string $customerEmail, string $orderNumber): void + { + /** @var OrderInterface $order */ + $order = $this->orderRepository->findOneByNumber($orderNumber); + + /** @var CustomerInterface $customer */ + $customer = $this->customerRepository->findOneBy(['email' => $customerEmail]); + + try { + $this->reorderer->reorder($order, $order->getChannel(), $customer); + } catch (InvalidStateException $exception) { + return; + } + + throw new \Exception("Reorder should fail"); + } + + /** + * @Then the order :orderNumber should not be reordered + */ + public function theOrderShouldNotBeReordered(string $orderNumber): void + { + // skipped intentionally - not relevant as the condition was checked in previous step + } +} diff --git a/tests/Behat/Context/Reorder/ReorderContext.php b/tests/Behat/Context/Reorder/Ui/ReorderContext.php similarity index 99% rename from tests/Behat/Context/Reorder/ReorderContext.php rename to tests/Behat/Context/Reorder/Ui/ReorderContext.php index 0fff470..22b2456 100644 --- a/tests/Behat/Context/Reorder/ReorderContext.php +++ b/tests/Behat/Context/Reorder/Ui/ReorderContext.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Tests\Sylius\CustomerReorderPlugin\Behat\Context\Reorder; +namespace Tests\Sylius\CustomerReorderPlugin\Behat\Context\Reorder\Ui; use Behat\Behat\Context\Context; use Behat\Mink\Session; diff --git a/tests/Behat/Resources/services.xml b/tests/Behat/Resources/services.xml index 173f55c..a87d110 100644 --- a/tests/Behat/Resources/services.xml +++ b/tests/Behat/Resources/services.xml @@ -2,7 +2,7 @@ - + @@ -14,6 +14,14 @@ + + + + + + + + diff --git a/tests/Behat/Resources/suites.yml b/tests/Behat/Resources/suites.yml index 845776a..8205932 100644 --- a/tests/Behat/Resources/suites.yml +++ b/tests/Behat/Resources/suites.yml @@ -1,8 +1,8 @@ default: suites: - reorders: + reorders_ui: contexts_services: - - sylius_customer_reorder.behat.context.setup.reorder + - sylius_customer_reorder.behat.context.ui.reorder - sylius.behat.context.setup.channel - sylius.behat.context.setup.product @@ -29,3 +29,32 @@ default: - sylius.behat.context.ui.shop.checkout.addressing filters: tags: "@reordering && @ui" + reorders_application: + context_services: + - sylius_customer_reorder.behat.context.application.reorder + + - sylius.behat.context.setup.channel + - sylius.behat.context.setup.product + - sylius.behat.context.setup.shipping + - sylius.behat.context.setup.payment + - sylius.behat.context.setup.order + - sylius.behat.context.setup.shop_security + - sylius.behat.context.setup.promotion + + - sylius.behat.context.transform.address + - sylius.behat.context.transform.channel + - sylius.behat.context.transform.lexical + - sylius.behat.context.transform.payment + - sylius.behat.context.transform.product + - sylius.behat.context.transform.promotion + - sylius.behat.context.transform.shared_storage + - sylius.behat.context.transform.shipping_method + - sylius.behat.context.transform.user + + - sylius.behat.context.hook.doctrine_orm + - sylius.behat.context.ui.shop.checkout.complete + - sylius.behat.context.ui.shop.account + - sylius.behat.context.ui.shop.cart + - sylius.behat.context.ui.shop.checkout.addressing + filters: + tags: "@reordering && @application" From f6fc51e088f15ebf906504d1e7c0fa9b5daf965e Mon Sep 17 00:00:00 2001 From: Bartosz Pietrzak Date: Mon, 24 Sep 2018 15:38:15 +0200 Subject: [PATCH 3/4] Tests fixes --- ..._reorder_the_order_placed_by_another_customer.feature | 5 ++++- spec/Checker/OrderCustomerRelationCheckerSpec.php | 2 +- spec/Reorder/ReordererSpec.php | 5 ++++- src/Checker/OrderCustomerRelationChecker.php | 9 ++++++--- src/Controller/CustomerReorderAction.php | 4 ++-- tests/Behat/Resources/suites.yml | 4 +++- 6 files changed, 20 insertions(+), 9 deletions(-) diff --git a/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature b/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature index 620d498..8fdf8ac 100644 --- a/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature +++ b/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature @@ -10,7 +10,10 @@ Feature: Being unable to reorder the order placed by another customer And the store ships everywhere for free And the store allows paying with "Cash on Delivery" And there is a customer "Rick Sanchez" identified by an email "rick.sanchez@wubba-lubba-dub-dub.com" and a password "Morty" - And there is another customer "Morty Smith" that placed an order "#00000666" + And there is a customer "Morty Smith" identified by an email "morty.smith@wubba-lubba-dub-dub.com" and a password "Rick" + And a customer "Morty Smith" placed an order "#00000666" + And the customer bought a single "Angel T-Shirt" + And the customer chose "Free" shipping method to "United States" with "Cash on Delivery" payment @application Scenario: Being unable to reorder the order placed by another customer diff --git a/spec/Checker/OrderCustomerRelationCheckerSpec.php b/spec/Checker/OrderCustomerRelationCheckerSpec.php index 58abe7a..0bda572 100644 --- a/spec/Checker/OrderCustomerRelationCheckerSpec.php +++ b/spec/Checker/OrderCustomerRelationCheckerSpec.php @@ -37,6 +37,6 @@ function it_returns_false_when_order_was_not_placed_by_customer( $order->getCustomer()->willReturn($secondCustomer); - $this->wasOrderPlacedByCustomer($order, $firstCustomer)->shouldReturn(false); + $this->wasOrderPlacedByCustomer($order, $firstCustomer)->shouldReturn(false); } } diff --git a/spec/Reorder/ReordererSpec.php b/spec/Reorder/ReordererSpec.php index a76bd4b..511dac7 100644 --- a/spec/Reorder/ReordererSpec.php +++ b/spec/Reorder/ReordererSpec.php @@ -293,13 +293,16 @@ function it_does_not_create_reorder_when_order_does_not_belong_to_given_customer OrderInterface $order, ChannelInterface $channel, CustomerInterface $firstCustomer, - CustomerInterface $secondCustomer + CustomerInterface $secondCustomer, + OrderCustomerRelationCheckerInterface $orderCustomerRelationChecker ): void { $firstCustomer->getId()->willReturn('1'); $secondCustomer->getId()->willReturn('2'); $order->getCustomer()->willReturn($firstCustomer); + $orderCustomerRelationChecker->wasOrderPlacedByCustomer($order, $secondCustomer)->shouldBeCalled(); + $this ->shouldThrow(InvalidStateException::class) ->during('reorder', [$order, $channel, $secondCustomer]) diff --git a/src/Checker/OrderCustomerRelationChecker.php b/src/Checker/OrderCustomerRelationChecker.php index 5c17f33..ef0b8b1 100644 --- a/src/Checker/OrderCustomerRelationChecker.php +++ b/src/Checker/OrderCustomerRelationChecker.php @@ -11,10 +11,13 @@ final class OrderCustomerRelationChecker implements OrderCustomerRelationChecker { public function wasOrderPlacedByCustomer(OrderInterface $order, CustomerInterface $customer): bool { + /** @var CustomerInterface $orderCustomer */ + $orderCustomer = $order->getCustomer(); + return - null !== $customer && - null !== $order->getCustomer() && - $order->getCustomer()->getId() === $customer->getId() + null != $customer && + null != $orderCustomer && + $orderCustomer->getId() === $customer->getId() ; } } diff --git a/src/Controller/CustomerReorderAction.php b/src/Controller/CustomerReorderAction.php index b96e968..1301eaa 100644 --- a/src/Controller/CustomerReorderAction.php +++ b/src/Controller/CustomerReorderAction.php @@ -8,17 +8,16 @@ use Sylius\Bundle\CoreBundle\Storage\CartSessionStorage; use Sylius\Component\Channel\Context\ChannelContextInterface; use Sylius\Component\Core\Model\ChannelInterface; +use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Repository\OrderRepositoryInterface; use Sylius\Component\Customer\Context\CustomerContextInterface; use Sylius\Component\Order\Context\CartContextInterface; -use Sylius\CustomerReorderPlugin\Checker\OrderCustomerRelationCheckerInterface; use Sylius\CustomerReorderPlugin\Reorder\ReordererInterface; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\Session; -use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; final class CustomerReorderAction @@ -75,6 +74,7 @@ public function __invoke(Request $request): Response $channel = $this->channelContext->getChannel(); assert($channel instanceof ChannelInterface); + /** @var CustomerInterface $customer */ $customer = $this->customerContext->getCustomer(); $reorder = null; diff --git a/tests/Behat/Resources/suites.yml b/tests/Behat/Resources/suites.yml index 8205932..5a078f8 100644 --- a/tests/Behat/Resources/suites.yml +++ b/tests/Behat/Resources/suites.yml @@ -30,10 +30,11 @@ default: filters: tags: "@reordering && @ui" reorders_application: - context_services: + contexts_services: - sylius_customer_reorder.behat.context.application.reorder - sylius.behat.context.setup.channel + - sylius.behat.context.setup.customer - sylius.behat.context.setup.product - sylius.behat.context.setup.shipping - sylius.behat.context.setup.payment @@ -43,6 +44,7 @@ default: - sylius.behat.context.transform.address - sylius.behat.context.transform.channel + - sylius.behat.context.transform.customer - sylius.behat.context.transform.lexical - sylius.behat.context.transform.payment - sylius.behat.context.transform.product From 62779ddb9e98a5ce13cb91bffb960fbe6e063286 Mon Sep 17 00:00:00 2001 From: Bartosz Pietrzak Date: Thu, 27 Sep 2018 11:53:35 +0200 Subject: [PATCH 4/4] Review fixes --- ...e_order_placed_by_another_customer.feature | 2 +- .../OrderCustomerRelationCheckerSpec.php | 27 +++++++++++++------ src/Checker/OrderCustomerRelationChecker.php | 5 ++-- src/Resources/config/services.xml | 1 - 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature b/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature index 8fdf8ac..3501d71 100644 --- a/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature +++ b/features/being_unable_to_reorder_the_order_placed_by_another_customer.feature @@ -18,4 +18,4 @@ Feature: Being unable to reorder the order placed by another customer @application Scenario: Being unable to reorder the order placed by another customer When the customer "rick.sanchez@wubba-lubba-dub-dub.com" tries to reorder the order "#00000666" - Then the order "#000001" should not be reordered + Then the order "#00000666" should not be reordered diff --git a/spec/Checker/OrderCustomerRelationCheckerSpec.php b/spec/Checker/OrderCustomerRelationCheckerSpec.php index 0bda572..df1e624 100644 --- a/spec/Checker/OrderCustomerRelationCheckerSpec.php +++ b/spec/Checker/OrderCustomerRelationCheckerSpec.php @@ -17,26 +17,37 @@ function it_implements_order_customer_relation_checker_interface(): void } function it_returns_true_when_order_was_placed_by_customer( + CustomerInterface $orderCustomer, CustomerInterface $customer, OrderInterface $order ): void { - $customer->getId()->willReturn('1'); + $orderCustomer->getId()->willReturn(1); + $customer->getId()->willReturn(1); - $order->getCustomer()->willReturn($customer); + $order->getCustomer()->willReturn($orderCustomer); $this->wasOrderPlacedByCustomer($order, $customer)->shouldReturn(true); } function it_returns_false_when_order_was_not_placed_by_customer( - CustomerInterface $firstCustomer, - CustomerInterface $secondCustomer, + CustomerInterface $orderCustomer, + CustomerInterface $customer, OrderInterface $order ): void { - $firstCustomer->getId()->willReturn('1'); - $secondCustomer->getId()->willReturn('2'); + $orderCustomer->getId()->willReturn(1); + $customer->getId()->willReturn(2); + + $order->getCustomer()->willReturn($orderCustomer); + + $this->wasOrderPlacedByCustomer($order, $customer)->shouldReturn(false); + } - $order->getCustomer()->willReturn($secondCustomer); + function it_returns_false_when_order_has_no_customer_assigned( + CustomerInterface $customer, + OrderInterface $order + ): void { + $order->getCustomer()->willReturn(null); - $this->wasOrderPlacedByCustomer($order, $firstCustomer)->shouldReturn(false); + $this->wasOrderPlacedByCustomer($order, $customer)->shouldReturn(false); } } diff --git a/src/Checker/OrderCustomerRelationChecker.php b/src/Checker/OrderCustomerRelationChecker.php index ef0b8b1..f8f9048 100644 --- a/src/Checker/OrderCustomerRelationChecker.php +++ b/src/Checker/OrderCustomerRelationChecker.php @@ -11,12 +11,11 @@ final class OrderCustomerRelationChecker implements OrderCustomerRelationChecker { public function wasOrderPlacedByCustomer(OrderInterface $order, CustomerInterface $customer): bool { - /** @var CustomerInterface $orderCustomer */ + /** @var CustomerInterface|null $orderCustomer */ $orderCustomer = $order->getCustomer(); return - null != $customer && - null != $orderCustomer && + null !== $orderCustomer && $orderCustomer->getId() === $customer->getId() ; } diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml index b25650d..83e2d1c 100644 --- a/src/Resources/config/services.xml +++ b/src/Resources/config/services.xml @@ -69,6 +69,5 @@ -