diff --git a/features/cart/shopping_cart/allowing_access_only_for_correctly_logged_in_users.feature b/features/cart/shopping_cart/allowing_access_only_for_correctly_logged_in_users.feature index 4abb45bed35..3bc5572ac46 100644 --- a/features/cart/shopping_cart/allowing_access_only_for_correctly_logged_in_users.feature +++ b/features/cart/shopping_cart/allowing_access_only_for_correctly_logged_in_users.feature @@ -143,8 +143,7 @@ Feature: Allowing access only for correctly logged in users And the customer has specified address as "Ankh Morpork", "Frost Alley", "90210", "United States" for "Jon Snow" And the customer has completed the addressing step And the customer logged out - When the visitor try to proceed with "UPS" shipping method in the customer cart - Then the visitor has no access to customer's cart + Then the visitor has no access to proceed with "UPS" shipping method in the customer cart @api Scenario: Denying access to add payment method to the customer cart by the visitor @@ -154,8 +153,7 @@ Feature: Allowing access only for correctly logged in users And the customer has completed the addressing step And the customer has proceeded "UPS" shipping method And the customer logged out - When the visitor try to proceed with "offline" payment in the customer cart - Then the visitor has no access to customer's cart + Then the visitor has no access to proceed with "offline" payment in the customer cart @api Scenario: Denying access to complete the customer cart by the visitor @@ -166,16 +164,14 @@ Feature: Allowing access only for correctly logged in users And the customer has proceeded "UPS" shipping method And the customer has proceeded "offline" payment And the customer logged out - When the visitor try to confirm the customer order - Then the visitor has no access to customer's cart + Then the visitor has no access to confirm the customer order @api Scenario: Denying to increase quantity of an item in the customer cart by the visitor Given the customer logged in And the customer has product "Stark T-Shirt" in the cart And the customer logged out - When the visitor try to change product "Stark T-Shirt" quantity to 2 in the customer cart - Then the visitor has no access to customer's cart + Then the visitor has no access to change product "Stark T-Shirt" quantity to 2 in the customer cart @api Scenario: Accessing to the customers cart by the admin diff --git a/features/cart/shopping_cart/clearing_cart_after_logging_out.feature b/features/cart/shopping_cart/clearing_cart_after_logging_out.feature index 74aee9ce483..21af2b9bb30 100644 --- a/features/cart/shopping_cart/clearing_cart_after_logging_out.feature +++ b/features/cart/shopping_cart/clearing_cart_after_logging_out.feature @@ -10,8 +10,13 @@ Feature: Clearing cart after logging out And I am a logged in customer And I have product "Stark T-Shirt" in the cart - @ui @api + @ui Scenario: Clearing cart after logging out When I log out And I see the summary of my cart Then my cart should be empty + + @api + Scenario: Clearing cart after logging out + When I log out + Then I don't have access to see the summary of my cart diff --git a/features/checkout/ability_to_checkout_as_guest_with_a_registered_email.feature b/features/checkout/ability_to_checkout_as_guest_with_a_registered_email.feature index 67b04eaee0c..705fbc8255a 100644 --- a/features/checkout/ability_to_checkout_as_guest_with_a_registered_email.feature +++ b/features/checkout/ability_to_checkout_as_guest_with_a_registered_email.feature @@ -11,7 +11,7 @@ Feature: Checking out as guest with a registered email And the store allows paying offline And there is a customer account "john@example.com" - @ui @api + @ui Scenario: Successfully placing an order Given I have product "PHP T-Shirt" in the cart When I complete addressing step with email "john@example.com" and "United States" based billing address diff --git a/src/Sylius/Behat/Context/Api/Shop/CartContext.php b/src/Sylius/Behat/Context/Api/Shop/CartContext.php index 6195df8797d..c9610360be9 100644 --- a/src/Sylius/Behat/Context/Api/Shop/CartContext.php +++ b/src/Sylius/Behat/Context/Api/Shop/CartContext.php @@ -36,6 +36,9 @@ final class CartContext implements Context /** @var ApiClientInterface */ private $productsClient; + /** @var ApiClientInterface */ + private $ordersAdminClient; + /** @var ResponseCheckerInterface */ private $responseChecker; @@ -51,6 +54,7 @@ final class CartContext implements Context public function __construct( ApiClientInterface $cartsClient, ApiClientInterface $productsClient, + ApiClientInterface $ordersAdminClient, ResponseCheckerInterface $responseChecker, AdminToShopIriConverterInterface $adminToShopIriConverter, SharedStorageInterface $sharedStorage, @@ -58,6 +62,7 @@ public function __construct( ) { $this->cartsClient = $cartsClient; $this->productsClient = $productsClient; + $this->ordersAdminClient = $ordersAdminClient; $this->responseChecker = $responseChecker; $this->adminToShopIriConverter = $adminToShopIriConverter; $this->sharedStorage = $sharedStorage; @@ -74,7 +79,7 @@ public function iClearMyCart(string $tokenValue): void /** * @When /^I see the summary of my (cart)$/ - * @When /^the (?:visitor|administrator) try to see the summary of (?:customer|visitor)'s (cart)$/ + * @When /^the visitor try to see the summary of (?:customer|visitor)'s (cart)$/ * @When /^the (?:visitor|customer) see the summary of (?:their) (cart)$/ */ public function iSeeTheSummaryOfMyCart(string $tokenValue): void @@ -82,6 +87,14 @@ public function iSeeTheSummaryOfMyCart(string $tokenValue): void $this->cartsClient->show($tokenValue); } + /** + * @When /^the administrator try to see the summary of (?:customer|visitor)'s (cart)$/ + */ + public function theAdministratorTryToSeeTheSummaryOfCart(string $tokenValue): void + { + $this->ordersAdminClient->show($tokenValue); + } + /** * @When /^I (?:add|added) (this product) to the (cart)$/ * @When /^I (?:add|added) ("[^"]+" product) to the (cart)$/ @@ -130,6 +143,14 @@ public function iRemoveProductFromTheCart(ProductInterface $product, string $tok $this->removeOrderItemFromCart($itemId, $tokenValue); } + /** + * @Then I don't have access to see the summary of my cart + */ + public function iDoNotHaveAccessToSeeTheSummaryOfMyCart(): void + { + Assert::same($this->getCart()['code'], 404); + } + /** * @Then my cart should be cleared */ @@ -156,7 +177,6 @@ public function myCartSTotalShouldBe(string $tokenValue, int $total): void /** * @Then /^my (cart) should be empty$/ - * @Then /^the visitor has no access to customer's (cart)$/ */ public function myCartShouldBeEmpty(string $tokenValue): void { @@ -168,6 +188,19 @@ public function myCartShouldBeEmpty(string $tokenValue): void ); } + /** + * @Then /^the visitor has no access to customer's (cart)$/ + */ + public function theVisitorHasNoAccessToCustomer(string $tokenValue): void + { + $response = $this->cartsClient->show($tokenValue); + + Assert::false( + $this->responseChecker->isShowSuccessful($response), + SprintfResponseEscaper::provideMessageWithEscapedResponseContent('Cart has not been created.', $response) + ); + } + /** * @Then I should be on my cart summary page */ @@ -242,28 +275,19 @@ public function thisItemShouldHaveCode(array $item, string $variantCode): void /** * @Then I should see :productName with quantity :quantity in my cart - * @Then /^the administrator should see ("[^"]+" product) with quantity ([^"]+) in the (?:customer|visitor) cart$/ - * @Then /^the (?:customer|visitor) should see (product "[^"]+") with quantity (\d+) in his cart$/ + * @Then /^the (?:customer|visitor) should see product "([^"]+)" with quantity (\d+) in his cart$/ */ public function iShouldSeeWithQuantityInMyCart(string $productName, int $quantity): void { - $cartResponse = $this->cartsClient->getLastResponse(); - $items = $this->responseChecker->getValue($cartResponse, 'items'); - - foreach ($items as $item) { - $productResponse = $this->getProductForItem($item); + $this->checkProductQuantity($this->cartsClient->getLastResponse(), $productName, $quantity); + } - if ($this->responseChecker->hasTranslation($productResponse, 'en_US', 'name', $productName)) { - Assert::same( - $item['quantity'], - $quantity, - SprintfResponseEscaper::provideMessageWithEscapedResponseContent( - sprintf('Quantity did not match. Expected %s.', $quantity), - $cartResponse - ) - ); - } - } + /** + * @Then /^the administrator should see "([^"]+)" product with quantity (\d+) in the (?:customer|visitor) cart$/ + */ + public function theAdministratorShouldSeeProductWithQuantityInTheCart(string $productName, int $quantity): void + { + $this->checkProductQuantity($this->ordersAdminClient->getLastResponse(), $productName, $quantity); } /** @@ -414,4 +438,31 @@ private function hasItemWithNameAndQuantity(Response $response, string $productN return false; } + + private function checkProductQuantity(Response $cartResponse, string $productName, int $quantity): void + { + $items = $this->responseChecker->getValue($cartResponse, 'items'); + + foreach ($items as $item) { + $productResponse = $this->getProductForItem($item); + + if ($this->responseChecker->hasTranslation($productResponse, 'en_US', 'name', $productName)) { + Assert::same( + $item['quantity'], + $quantity, + SprintfResponseEscaper::provideMessageWithEscapedResponseContent( + sprintf('Quantity did not match. Expected %s.', $quantity), + $cartResponse + ) + ); + } + } + } + + private function getCart(): array + { + $response = $this->cartsClient->show($this->sharedStorage->get('cart_token')); + + return $this->responseChecker->getResponseContent($response); + } } diff --git a/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php b/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php index 808221af3b2..b9d6196de8a 100644 --- a/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php +++ b/src/Sylius/Behat/Context/Api/Shop/CheckoutContext.php @@ -215,7 +215,6 @@ public function iProvideAdditionalNotesLike(string $notes): void * @When I confirm my order * @When I try to confirm my order * @When /^the (?:visitor|customer) confirm his order$/ - * @When /^the visitor try to confirm the customer order$/ */ public function iConfirmMyOrder(): void { @@ -250,7 +249,6 @@ public function iConfirmMyOrder(): void * @When I select :shippingMethod shipping method * @When /^the (?:visitor|customer) proceed with ("[^"]+" shipping method)$/ * @Given /^the (?:visitor|customer) has proceeded ("[^"]+" shipping method)$/ - * @When /^the visitor try to proceed with ("[^"]+" shipping method) in the customer cart$/ */ public function iProceededWithShippingMethod(ShippingMethodInterface $shippingMethod): void { @@ -270,6 +268,17 @@ public function iProceededWithShippingMethod(ShippingMethodInterface $shippingMe ); } + /** + * @Then the visitor has no access to proceed with :shippingMethod shipping method in the customer cart + * @Then the visitor has no access to proceed with :paymentMethod payment in the customer cart + * @Then the visitor has no access to confirm the customer order + * @Then the visitor has no access to change product :product quantity to :quantity in the customer cart + */ + public function theVisitorHasNoProceedWithShippingMethodInTheCustomerCart(): void + { + Assert::same($this->getCart()['code'], 404); + } + /** * @When I complete the shipping step with first shipping method */ @@ -286,7 +295,6 @@ public function iCompleteTheShippingStepWithFirstShippingMethod(): void * @When I select :paymentMethod payment method * @When /^the (?:customer|visitor) proceed with ("[^"]+" payment)$/ * @Given /^the (?:customer|visitor) has proceeded ("[^"]+" payment)$/ - * @Given /^the visitor try to proceed with ("[^"]+" payment) in the customer cart$/ */ public function iChoosePaymentMethod(PaymentMethodInterface $paymentMethod): void { diff --git a/src/Sylius/Behat/Resources/config/services/contexts/api/shop.xml b/src/Sylius/Behat/Resources/config/services/contexts/api/shop.xml index ff4471bfef4..e5f98f19b76 100644 --- a/src/Sylius/Behat/Resources/config/services/contexts/api/shop.xml +++ b/src/Sylius/Behat/Resources/config/services/contexts/api/shop.xml @@ -21,6 +21,7 @@ + diff --git a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php index 91b2bc3549a..276af597074 100644 --- a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php +++ b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderGetMethodItemExtension.php @@ -17,6 +17,7 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use Doctrine\ORM\QueryBuilder; use Sylius\Bundle\ApiBundle\Context\UserContextInterface; +use Sylius\Bundle\ApiBundle\Serializer\ContextKeys; use Sylius\Component\Core\Model\AdminUserInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\ShopUserInterface; @@ -43,35 +44,37 @@ public function applyToItem( string $operationName = null, array $context = [] ) { - $operationName = strtoupper($operationName); - if (!is_a($resourceClass, OrderInterface::class, true)) { return; } - if ($operationName !== Request::METHOD_GET) { + if ($context[ContextKeys::HTTP_REQUEST_METHOD_TYPE] !== Request::METHOD_GET) { return; } $rootAlias = $queryBuilder->getRootAliases()[0]; $user = $this->userContext->getUser(); - $this->applyToItemForGetMethod($user, $queryBuilder, $operationName, $rootAlias); + $this->applyToItemForGetMethod($user, $queryBuilder, $rootAlias); } private function applyToItemForGetMethod( ?UserInterface $user, QueryBuilder $queryBuilder, - string $operationName, string $rootAlias ): void { if ($user === null) { - $queryBuilder->andWhere(sprintf('%s.customer IS NULL', $rootAlias)); + $queryBuilder + ->leftJoin(sprintf('%s.customer', $rootAlias), 'customer') + ->leftJoin('customer.user', 'user') + ->andWhere('user IS NULL') + ->orWhere(sprintf('%s.customer IS NULL', $rootAlias)) + ; return; } - if ($user instanceof ShopUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles(), true)) { + if ($user instanceof ShopUserInterface && in_array('ROLE_USER', $user->getRoles(), true)) { $queryBuilder ->andWhere(sprintf('%s.customer = :customer', $rootAlias)) ->setParameter('customer', $user->getCustomer()->getId()) diff --git a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderDeleteMethodItemExtension.php b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php similarity index 67% rename from src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderDeleteMethodItemExtension.php rename to src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php index 80c4359fbee..1f919de3db1 100644 --- a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderDeleteMethodItemExtension.php +++ b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderMethodsItemExtension.php @@ -17,6 +17,7 @@ use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use Doctrine\ORM\QueryBuilder; use Sylius\Bundle\ApiBundle\Context\UserContextInterface; +use Sylius\Bundle\ApiBundle\Serializer\ContextKeys; use Sylius\Component\Core\Model\AdminUserInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\ShopUserInterface; @@ -25,7 +26,7 @@ use Symfony\Component\Security\Core\User\UserInterface; /** @experimental */ -final class OrderDeleteMethodItemExtension implements QueryItemExtensionInterface +final class OrderMethodsItemExtension implements QueryItemExtensionInterface { /** @var UserContextInterface */ private $userContext; @@ -43,31 +44,34 @@ public function applyToItem( string $operationName = null, array $context = [] ) { - $operationName = strtoupper($operationName); - if (!is_a($resourceClass, OrderInterface::class, true)) { return; } - if ($operationName !== Request::METHOD_DELETE) { + $httpRequestMethodType = $context[ContextKeys::HTTP_REQUEST_METHOD_TYPE]; + + if ($httpRequestMethodType === Request::METHOD_GET) { return; } $rootAlias = $queryBuilder->getRootAliases()[0]; $user = $this->userContext->getUser(); - $this->applyToItemForDeleteMethod($user, $queryBuilder, $operationName, $rootAlias); + $this->applyUserRulesToItem($user, $queryBuilder, $rootAlias, $httpRequestMethodType); } - private function applyToItemForDeleteMethod( + private function applyUserRulesToItem( ?UserInterface $user, QueryBuilder $queryBuilder, - string $operationName, - string $rootAlias + string $rootAlias, + string $httpRequestMethodType ): void { if ($user === null) { $queryBuilder - ->andWhere(sprintf('%s.customer IS NULL', $rootAlias)) + ->leftJoin(sprintf('%s.customer', $rootAlias), 'customer') + ->leftJoin('customer.user', 'user') + ->andWhere('user IS NULL') + ->orWhere(sprintf('%s.customer IS NULL', $rootAlias)) ->andWhere(sprintf('%s.state = :state', $rootAlias)) ->setParameter('state', OrderInterface::STATE_CART) ; @@ -75,7 +79,7 @@ private function applyToItemForDeleteMethod( return; } - if ($user instanceof ShopUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles(), true)) { + if ($user instanceof ShopUserInterface && in_array('ROLE_USER', $user->getRoles(), true)) { $queryBuilder ->andWhere(sprintf('%s.customer = :customer', $rootAlias)) ->setParameter('customer', $user->getCustomer()->getId()) @@ -86,7 +90,11 @@ private function applyToItemForDeleteMethod( return; } - if ($user instanceof AdminUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles(), true)) { + if ( + $user instanceof AdminUserInterface && + in_array('ROLE_API_ACCESS', $user->getRoles(), true) && + $httpRequestMethodType === Request::METHOD_DELETE + ) { $queryBuilder ->andWhere(sprintf('%s.state = :state', $rootAlias)) ->setParameter('state', OrderInterface::STATE_CART) @@ -95,6 +103,16 @@ private function applyToItemForDeleteMethod( return; } + if ( + $user instanceof AdminUserInterface && + in_array('ROLE_API_ACCESS', $user->getRoles(), true) && + $httpRequestMethodType !== Request::METHOD_DELETE + ) { + //admin has also access to modified orders in states other than cart + + return; + } + throw new AccessDeniedHttpException('Requested method is not allowed.'); } } diff --git a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderPatchMethodItemExtension.php b/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderPatchMethodItemExtension.php deleted file mode 100644 index 2e5b1152d06..00000000000 --- a/src/Sylius/Bundle/ApiBundle/Doctrine/QueryItemExtension/OrderPatchMethodItemExtension.php +++ /dev/null @@ -1,100 +0,0 @@ -userContext = $userContext; - } - - public function applyToItem( - QueryBuilder $queryBuilder, - QueryNameGeneratorInterface $queryNameGenerator, - string $resourceClass, - array $identifiers, - string $operationName = null, - array $context = [] - ) { - $operationName = strtoupper($operationName); - - if (!is_a($resourceClass, OrderInterface::class, true)) { - return; - } - - if ($operationName !== Request::METHOD_PATCH) { - return; - } - - $rootAlias = $queryBuilder->getRootAliases()[0]; - $user = $this->userContext->getUser(); - - $this->applyToItemForPatchMethod($user, $queryBuilder, $operationName, $rootAlias); - } - - private function applyToItemForPatchMethod( - ?UserInterface $user, - QueryBuilder $queryBuilder, - string $operationName, - string $rootAlias - ): void { - if ($user === null) { - $queryBuilder - ->andWhere(sprintf('%s.customer IS NULL', $rootAlias)) - ->andWhere(sprintf('%s.state = :state', $rootAlias)) - ->setParameter('state', OrderInterface::STATE_CART) - ; - - return; - } - - if ($user instanceof ShopUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles(), true)) { - $queryBuilder - ->andWhere(sprintf('%s.customer = :customer', $rootAlias)) - ->setParameter('customer', $user->getCustomer()->getId()) - ->andWhere(sprintf('%s.state = :state', $rootAlias)) - ->setParameter('state', OrderInterface::STATE_CART) - ; - - return; - } - - if ($user instanceof AdminUserInterface && in_array('ROLE_API_ACCESS', $user->getRoles(), true)) { - $queryBuilder - ->andWhere(sprintf('%s.state = :state', $rootAlias)) - ->setParameter('state', OrderInterface::STATE_CART) - ; - - return; - } - - throw new AccessDeniedHttpException('Requested method is not allowed.'); - } -} diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/services/context_builders.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/services/context_builders.xml index e62ed9a9920..bfe6a7d07e4 100644 --- a/src/Sylius/Bundle/ApiBundle/Resources/config/services/context_builders.xml +++ b/src/Sylius/Bundle/ApiBundle/Resources/config/services/context_builders.xml @@ -37,5 +37,14 @@ + + + + diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/services/extensions.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/services/extensions.xml index 7502ef90c20..d1e7f424d41 100644 --- a/src/Sylius/Bundle/ApiBundle/Resources/config/services/extensions.xml +++ b/src/Sylius/Bundle/ApiBundle/Resources/config/services/extensions.xml @@ -45,16 +45,7 @@ - - - - - diff --git a/src/Sylius/Bundle/ApiBundle/Serializer/ContextKeys.php b/src/Sylius/Bundle/ApiBundle/Serializer/ContextKeys.php index ad3f2a6564a..527e48c2512 100644 --- a/src/Sylius/Bundle/ApiBundle/Serializer/ContextKeys.php +++ b/src/Sylius/Bundle/ApiBundle/Serializer/ContextKeys.php @@ -20,6 +20,8 @@ class ContextKeys public const LOCALE_CODE = 'sylius_api_locale_code'; + public const HTTP_REQUEST_METHOD_TYPE = 'sylius_api_http_method_request_type'; + private function __construct() { } diff --git a/src/Sylius/Bundle/ApiBundle/SerializerContextBuilder/HttpRequestMethodTypeContextBuilder.php b/src/Sylius/Bundle/ApiBundle/SerializerContextBuilder/HttpRequestMethodTypeContextBuilder.php new file mode 100644 index 00000000000..8e865f458d3 --- /dev/null +++ b/src/Sylius/Bundle/ApiBundle/SerializerContextBuilder/HttpRequestMethodTypeContextBuilder.php @@ -0,0 +1,39 @@ +decoratedLocaleBuilder = $decoratedLocaleBuilder; + } + + public function createFromRequest(Request $request, bool $normalization, array $extractedAttributes = null): array + { + $context = $this->decoratedLocaleBuilder->createFromRequest($request, $normalization, $extractedAttributes); + + $context[ContextKeys::HTTP_REQUEST_METHOD_TYPE] = strtoupper($request->getMethod()); + + return $context; + } +} diff --git a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Checkout/AddressOrderHandlerSpec.php b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Checkout/AddressOrderHandlerSpec.php index fa87a9efeb4..e797dcc99af 100644 --- a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Checkout/AddressOrderHandlerSpec.php +++ b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/Checkout/AddressOrderHandlerSpec.php @@ -36,7 +36,13 @@ function let( ObjectManager $manager, StateMachineFactoryInterface $stateMachineFactory ): void { - $this->beConstructedWith($orderRepository, $customerRepository, $customerFactory, $manager, $stateMachineFactory); + $this->beConstructedWith( + $orderRepository, + $customerRepository, + $customerFactory, + $manager, + $stateMachineFactory + ); } function it_handles_addressing_an_order_without_provided_shipping_address( @@ -91,7 +97,6 @@ function it_handles_addressing_an_order_for_visitor( $customer->setEmail('r2d2@droid.com')->shouldBeCalled(); $manager->persist($customer)->shouldBeCalled(); $order->setCustomer($customer)->shouldBeCalled(); - $order->setBillingAddress($billingAddress)->shouldBeCalled(); $order->setShippingAddress($shippingAddress)->shouldBeCalled(); diff --git a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php index ea9a9345e03..5abcb90f83a 100644 --- a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php +++ b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php @@ -36,8 +36,15 @@ function let( UserContextInterface $userContext, ObjectManager $orderManager, RandomnessGeneratorInterface $generator + ): void { - $this->beConstructedWith($cartFactory, $channelContext, $userContext, $orderManager, $generator); + $this->beConstructedWith( + $cartFactory, + $channelContext, + $userContext, + $orderManager, + $generator + ); } function it_is_a_message_handler(): void diff --git a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderDeleteMethodItemExtensionSpec.php b/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderDeleteMethodItemExtensionSpec.php deleted file mode 100644 index 934092ec5a6..00000000000 --- a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderDeleteMethodItemExtensionSpec.php +++ /dev/null @@ -1,207 +0,0 @@ -beConstructedWith($userContext); - } - - function it_applies_conditions_to_delete_order_with_state_cart_and_with_null_user_if_present_user_is_null( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn(null); - - $queryBuilder - ->andWhere(sprintf('%s.customer IS NULL', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->andWhere(sprintf('%s.state = :state', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->setParameter('state', OrderInterface::STATE_CART) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $this->applyToItem( - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_DELETE, - [] - ); - } - - function it_applies_conditions_to_delete_order_with_state_cart_by_authorized_shop_user_that_is_assigns_to_this_order( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - ShopUserInterface $shopUser, - CustomerInterface $customer, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($shopUser); - $shopUser->getCustomer()->willReturn($customer); - $customer->getId()->willReturn(1); - $shopUser->getRoles()->willReturn(['ROLE_API_ACCESS']); - - $queryBuilder - ->andWhere(sprintf('%s.customer = :customer', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - $queryBuilder - ->setParameter('customer', 1) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->andWhere(sprintf('%s.state = :state', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->setParameter('state', OrderInterface::STATE_CART) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $this->applyToItem( - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_DELETE, - [] - ); - } - - function it_throws_an_exception_when_unauthorized_shop_user_try_to_delete_order_with_state_cart( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - ShopUserInterface $shopUser, - CustomerInterface $customer, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($shopUser); - $shopUser->getCustomer()->willReturn($customer); - $customer->getId()->willReturn(1); - $shopUser->getRoles()->willReturn([]); - - $this - ->shouldThrow(AccessDeniedHttpException::class) - ->during( - 'applyToItem', - [ - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_DELETE, - [], - ] - ) - ; - } - - function it_applies_conditions_to_delete_order_with_state_cart_by_authorized_admin_user( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - AdminUserInterface $adminUser, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($adminUser); - $adminUser->getRoles()->willReturn(['ROLE_API_ACCESS']); - - $queryBuilder - ->andWhere(sprintf('%s.state = :state', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->setParameter('state', OrderInterface::STATE_CART) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $this->applyToItem( - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_DELETE, - [] - ); - } - - function it_throws_an_exception_when_unauthorized_admin_user_try_to_delete_order_with_state_cart( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - AdminUserInterface $adminUser, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($adminUser); - $adminUser->getRoles()->willReturn([]); - - $this - ->shouldThrow(AccessDeniedHttpException::class) - ->during( - 'applyToItem', - [ - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_DELETE, - [], - ] - ) - ; - } -} diff --git a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php b/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php index fd8662d33fe..efd920b5ab6 100644 --- a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php +++ b/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderGetMethodItemExtensionSpec.php @@ -17,6 +17,7 @@ use Doctrine\ORM\QueryBuilder; use PhpSpec\ObjectBehavior; use Sylius\Bundle\ApiBundle\Context\UserContextInterface; +use Sylius\Bundle\ApiBundle\Serializer\ContextKeys; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Component\Core\Model\OrderInterface; use Sylius\Component\Core\Model\ShopUserInterface; @@ -39,7 +40,29 @@ function it_applies_conditions_to_get_order_with_state_cart_and_without_user_if_ $userContext->getUser()->willReturn(null); - $queryBuilder->andWhere(sprintf('%s.customer IS NULL', 'o'))->shouldBeCalled(); + $queryBuilder + ->leftJoin(sprintf('%s.customer', 'o'), 'customer') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->leftJoin('customer.user', 'user') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere('user IS NULL') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->orWhere(sprintf('%s.customer IS NULL', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; $this->applyToItem( $queryBuilder, @@ -47,7 +70,7 @@ function it_applies_conditions_to_get_order_with_state_cart_and_without_user_if_ OrderInterface::class, ['tokenValue' => 'xaza-tt_fee'], Request::METHOD_GET, - [] + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_GET], ); } @@ -61,9 +84,10 @@ function it_applies_conditions_to_get_order_with_state_cart_by_authorized_shop_u $queryBuilder->getRootAliases()->willReturn(['o']); $userContext->getUser()->willReturn($shopUser); + $shopUser->getCustomer()->willReturn($customer); $customer->getId()->willReturn(1); - $shopUser->getRoles()->willReturn(['ROLE_API_ACCESS']); + $shopUser->getRoles()->willReturn(['ROLE_USER']); $queryBuilder ->andWhere(sprintf('%s.customer = :customer', 'o')) @@ -82,7 +106,7 @@ function it_applies_conditions_to_get_order_with_state_cart_by_authorized_shop_u OrderInterface::class, ['tokenValue' => 'xaza-tt_fee'], Request::METHOD_GET, - [] + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_GET], ); } @@ -110,7 +134,7 @@ function it_throws_an_exception_when_unauthorized_shop_user_try_to_get_order_wit OrderInterface::class, ['tokenValue' => 'xaza-tt_fee'], Request::METHOD_GET, - [], + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_GET] ] ) ; diff --git a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderMethodsItemExtensionSpec.php b/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderMethodsItemExtensionSpec.php new file mode 100644 index 00000000000..9de00494b28 --- /dev/null +++ b/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderMethodsItemExtensionSpec.php @@ -0,0 +1,623 @@ +beConstructedWith($userContext); + } + + function it_applies_conditions_to_delete_order_with_state_cart_and_with_null_user_and_customer_if_present_user_and_customer_are_null( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn(null); + + $queryBuilder + ->leftJoin(sprintf('%s.customer', 'o'), 'customer') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->leftJoin('customer.user', 'user') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere('user IS NULL') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->orWhere(sprintf('%s.customer IS NULL', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_DELETE, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_DELETE], + ); + } + + function it_applies_conditions_to_patch_order_with_state_cart_and_with_null_user_and_customer_if_present_user_and_customer_are_null( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn(null); + + $queryBuilder + ->leftJoin(sprintf('%s.customer', 'o'), 'customer') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->leftJoin('customer.user', 'user') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere('user IS NULL') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->orWhere(sprintf('%s.customer IS NULL', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PATCH, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PATCH], + ); + } + + function it_applies_conditions_to_put_order_with_state_cart_and_with_null_user_and_customer_if_present_user_and_customer_are_null( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn(null); + + $queryBuilder + ->leftJoin(sprintf('%s.customer', 'o'), 'customer') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->leftJoin('customer.user', 'user') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere('user IS NULL') + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->orWhere(sprintf('%s.customer IS NULL', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PUT, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PUT], + ); + } + + function it_applies_conditions_to_put_order_with_state_cart_and_with_null_user_and_not_null_customer_if_present_user_is_null_and_present_customer_is_not_null( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn(['ROLE_USER']); + + $queryBuilder + ->andWhere(sprintf('%s.customer = :customer', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + $queryBuilder + ->setParameter('customer', 1) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PUT, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PUT], + ); + } + + function it_applies_conditions_to_patch_order_with_state_cart_and_with_null_user_and_not_null_customer_if_present_user_is_null_and_present_customer_is_not_null( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn(['ROLE_USER']); + + $queryBuilder + ->andWhere(sprintf('%s.customer = :customer', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + $queryBuilder + ->setParameter('customer', 1) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PATCH, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PATCH], + ); + } + + function it_applies_conditions_to_delete_order_with_state_cart_and_with_null_user_and_not_null_customer_if_present_user_is_null_and_present_customer_is_not_null( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn(['ROLE_USER']); + + $queryBuilder + ->andWhere(sprintf('%s.customer = :customer', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + $queryBuilder + ->setParameter('customer', 1) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_DELETE, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_DELETE], + ); + } + + function it_applies_conditions_to_delete_order_with_state_cart_by_authorized_shop_user_that_is_assigns_to_this_order( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn(['ROLE_USER']); + + $queryBuilder + ->andWhere(sprintf('%s.customer = :customer', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + $queryBuilder + ->setParameter('customer', 1) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_DELETE, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_DELETE], + ); + } + + function it_applies_conditions_to_patch_order_with_state_cart_by_authorized_shop_user_that_is_assigns_to_this_order( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn(['ROLE_USER']); + + $queryBuilder + ->andWhere(sprintf('%s.customer = :customer', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + $queryBuilder + ->setParameter('customer', 1) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PATCH, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PATCH], + ); + } + + function it_applies_conditions_to_put_order_with_state_cart_by_authorized_shop_user_that_is_assigns_to_this_order( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn(['ROLE_USER']); + + $queryBuilder + ->andWhere(sprintf('%s.customer = :customer', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + $queryBuilder + ->setParameter('customer', 1) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PUT, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PUT], + ); + } + + function it_throws_an_exception_when_unauthorized_shop_user_try_to_delete_order_with_state_cart( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + ShopUserInterface $shopUser, + CustomerInterface $customer, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($shopUser); + + $shopUser->getCustomer()->willReturn($customer); + $customer->getId()->willReturn(1); + $shopUser->getRoles()->willReturn([]); + + $this + ->shouldThrow(AccessDeniedHttpException::class) + ->during( + 'applyToItem', + [ + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_DELETE, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_POST], + ] + ) + ; + } + + function it_applies_conditions_to_delete_order_with_state_cart_by_authorized_admin_user( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + AdminUserInterface $adminUser, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($adminUser); + + $adminUser->getRoles()->willReturn(['ROLE_API_ACCESS']); + + $queryBuilder + ->andWhere(sprintf('%s.state = :state', 'o')) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $queryBuilder + ->setParameter('state', OrderInterface::STATE_CART) + ->shouldBeCalled() + ->willReturn($queryBuilder) + ; + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_DELETE, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_DELETE], + ); + } + + function it_applies_conditions_to_patch_order_with_state_cart_by_authorized_admin_user( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + AdminUserInterface $adminUser, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($adminUser); + + $adminUser->getRoles()->willReturn(['ROLE_API_ACCESS']); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PATCH, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PATCH], + ); + } + + function it_applies_conditions_to_put_order_with_state_cart_by_authorized_admin_user( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + AdminUserInterface $adminUser, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($adminUser); + + $adminUser->getRoles()->willReturn(['ROLE_API_ACCESS']); + + $this->applyToItem( + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_PUT, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_PUT], + ); + } + + function it_throws_an_exception_when_unauthorized_admin_user_try_to_delete_order_with_state_cart( + UserContextInterface $userContext, + QueryBuilder $queryBuilder, + AdminUserInterface $adminUser, + QueryNameGeneratorInterface $queryNameGenerator + ): void { + $queryBuilder->getRootAliases()->willReturn(['o']); + + $userContext->getUser()->willReturn($adminUser); + $adminUser->getRoles()->willReturn([]); + + $this + ->shouldThrow(AccessDeniedHttpException::class) + ->during( + 'applyToItem', + [ + $queryBuilder, + $queryNameGenerator, + OrderInterface::class, + ['tokenValue' => 'xaza-tt_fee'], + Request::METHOD_DELETE, + [ContextKeys::HTTP_REQUEST_METHOD_TYPE => Request::METHOD_DELETE], + ] + ) + ; + } +} diff --git a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderPatchMethodItemExtensionSpec.php b/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderPatchMethodItemExtensionSpec.php deleted file mode 100644 index 9e59af605c5..00000000000 --- a/src/Sylius/Bundle/ApiBundle/spec/Doctrine/QueryItemExtension/OrderPatchMethodItemExtensionSpec.php +++ /dev/null @@ -1,207 +0,0 @@ -beConstructedWith($userContext); - } - - function it_applies_conditions_to_patch_order_with_state_cart_and_with_null_user_if_present_user_is_null( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn(null); - - $queryBuilder - ->andWhere(sprintf('%s.customer IS NULL', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->andWhere(sprintf('%s.state = :state', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->setParameter('state', OrderInterface::STATE_CART) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $this->applyToItem( - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_PATCH, - [] - ); - } - - function it_applies_conditions_to_patch_order_with_state_cart_by_authorized_shop_user_that_is_assigns_to_this_order( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - ShopUserInterface $shopUser, - CustomerInterface $customer, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($shopUser); - $shopUser->getCustomer()->willReturn($customer); - $customer->getId()->willReturn(1); - $shopUser->getRoles()->willReturn(['ROLE_API_ACCESS']); - - $queryBuilder - ->andWhere(sprintf('%s.customer = :customer', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - $queryBuilder - ->setParameter('customer', 1) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->andWhere(sprintf('%s.state = :state', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->setParameter('state', OrderInterface::STATE_CART) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $this->applyToItem( - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_PATCH, - [] - ); - } - - function it_throws_an_exception_when_unauthorized_shop_user_try_to_patch_order_with_state_cart( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - ShopUserInterface $shopUser, - CustomerInterface $customer, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($shopUser); - $shopUser->getCustomer()->willReturn($customer); - $customer->getId()->willReturn(1); - $shopUser->getRoles()->willReturn([]); - - $this - ->shouldThrow(AccessDeniedHttpException::class) - ->during( - 'applyToItem', - [ - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_PATCH, - [], - ] - ) - ; - } - - function it_applies_conditions_to_patch_order_with_state_cart_by_authorized_admin_user( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - AdminUserInterface $adminUser, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($adminUser); - $adminUser->getRoles()->willReturn(['ROLE_API_ACCESS']); - - $queryBuilder - ->andWhere(sprintf('%s.state = :state', 'o')) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $queryBuilder - ->setParameter('state', OrderInterface::STATE_CART) - ->shouldBeCalled() - ->willReturn($queryBuilder) - ; - - $this->applyToItem( - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_PATCH, - [] - ); - } - - function it_throws_an_exception_when_unauthorized_admin_user_try_to_patch_order_with_state_cart( - UserContextInterface $userContext, - QueryBuilder $queryBuilder, - AdminUserInterface $adminUser, - QueryNameGeneratorInterface $queryNameGenerator - ): void { - $queryBuilder->getRootAliases()->willReturn(['o']); - - $userContext->getUser()->willReturn($adminUser); - $adminUser->getRoles()->willReturn([]); - - $this - ->shouldThrow(AccessDeniedHttpException::class) - ->during( - 'applyToItem', - [ - $queryBuilder, - $queryNameGenerator, - OrderInterface::class, - ['tokenValue' => 'xaza-tt_fee'], - Request::METHOD_PATCH, - [], - ] - ) - ; - } -}