diff --git a/features/cart/shopping_cart/viewing_cart_summary.feature b/features/cart/shopping_cart/viewing_cart_summary.feature
index 40ef32bfea9..cc056096033 100644
--- a/features/cart/shopping_cart/viewing_cart_summary.feature
+++ b/features/cart/shopping_cart/viewing_cart_summary.feature
@@ -7,7 +7,7 @@ Feature: Viewing a cart summary
Background:
Given the store operates on a single channel in "United States"
- @ui
+ @ui @api
Scenario: Viewing information about empty cart
When I see the summary of my cart
Then my cart should be empty
diff --git a/src/Sylius/Behat/Client/ApiClientInterface.php b/src/Sylius/Behat/Client/ApiClientInterface.php
index 173d175cc73..1fe53c88c80 100644
--- a/src/Sylius/Behat/Client/ApiClientInterface.php
+++ b/src/Sylius/Behat/Client/ApiClientInterface.php
@@ -26,7 +26,7 @@ public function subResourceIndex(string $subResource, string $id): Response;
public function show(string $id): Response;
- public function create(): Response;
+ public function create(?RequestInterface $request = null): Response;
public function update(): Response;
diff --git a/src/Sylius/Behat/Client/ApiPlatformClient.php b/src/Sylius/Behat/Client/ApiPlatformClient.php
index ec58c48bfa4..8bc318c81c8 100644
--- a/src/Sylius/Behat/Client/ApiPlatformClient.php
+++ b/src/Sylius/Behat/Client/ApiPlatformClient.php
@@ -61,9 +61,9 @@ public function show(string $id): Response
return $this->request(Request::show($this->resource, $id, $this->sharedStorage->get('token')));
}
- public function create(): Response
+ public function create(?RequestInterface $request = null): Response
{
- return $this->request($this->request);
+ return $this->request($request ?? $this->request);
}
public function update(): Response
@@ -118,7 +118,8 @@ public function upload(): Response
public function buildCreateRequest(): void
{
- $this->request = Request::create($this->resource, $this->sharedStorage->get('token'));
+ $this->request = Request::create($this->resource);
+ $this->request->authorize($this->sharedStorage->get('token'));
}
public function buildUpdateRequest(string $id): void
diff --git a/src/Sylius/Behat/Client/Request.php b/src/Sylius/Behat/Client/Request.php
index ea3294599e2..6e702be49ef 100644
--- a/src/Sylius/Behat/Client/Request.php
+++ b/src/Sylius/Behat/Client/Request.php
@@ -67,12 +67,12 @@ public static function show(string $resource, string $id, string $token): Reques
);
}
- public static function create(string $resource, string $token): RequestInterface
+ public static function create(string $resource): RequestInterface
{
return new self(
sprintf('/new-api/%s', $resource),
HttpRequest::METHOD_POST,
- ['CONTENT_TYPE' => 'application/json', 'HTTP_Authorization' => 'Bearer ' . $token]
+ ['CONTENT_TYPE' => 'application/ld+json']
);
}
@@ -190,6 +190,11 @@ public function removeSubResource(string $subResource, string $id): void
}
}
+ public function authorize(string $token): void
+ {
+ $this->headers['HTTP_Authorization'] = 'Bearer ' . $token;
+ }
+
private function mergeArraysUniquely(array $firstArray, array $secondArray): array
{
foreach ($secondArray as $key => $value) {
diff --git a/src/Sylius/Behat/Client/RequestInterface.php b/src/Sylius/Behat/Client/RequestInterface.php
index fc7291991e9..596082e0170 100644
--- a/src/Sylius/Behat/Client/RequestInterface.php
+++ b/src/Sylius/Behat/Client/RequestInterface.php
@@ -21,7 +21,7 @@ public static function subResourceIndex(string $resource, string $id, string $su
public static function show(string $resource, string $id, string $token): self;
- public static function create(string $resource, string $token): self;
+ public static function create(string $resource): self;
public static function update(string $resource, string $id, string $token): self;
@@ -56,4 +56,6 @@ public function updateFiles(array $newFiles): void;
public function addSubResource(string $key, array $subResource): void;
public function removeSubResource(string $subResource, string $id): void;
+
+ public function authorize(string $token): void;
}
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingOrdersContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingOrdersContext.php
index 71feb378866..0e05ed6ebaa 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingOrdersContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingOrdersContext.php
@@ -75,7 +75,7 @@ public function iBrowseOrders(): void
*/
public function iSeeTheOrder(OrderInterface $order): void
{
- $this->client->show($order->getNumber());
+ $this->client->show($order->getTokenValue());
}
/**
@@ -84,7 +84,7 @@ public function iSeeTheOrder(OrderInterface $order): void
public function iCancelThisOrder(OrderInterface $order): void
{
$this->client->applyTransition(
- $this->responseChecker->getValue($this->client->show($order->getNumber()), 'number'),
+ $this->responseChecker->getValue($this->client->show($order->getTokenValue()), 'tokenValue'),
OrderTransitions::TRANSITION_CANCEL
);
}
@@ -129,9 +129,10 @@ public function iShouldSeeASingleOrderFromCustomer(CustomerInterface $customer):
*/
public function iShouldBeNotifiedAboutItHasBeenSuccessfullyCanceled(): void
{
+ $response = $this->client->getLastResponse();
Assert::true(
- $this->responseChecker->isUpdateSuccessful($this->client->getLastResponse()),
- 'Resource could not be completed'
+ $this->responseChecker->isUpdateSuccessful($response),
+ 'Resource could not be completed. Reason: ' . $response->getContent()
);
}
@@ -143,7 +144,7 @@ public function itsStateShouldBe(string $state): void
{
/** @var OrderInterface $order */
$order = $this->sharedStorage->get('order');
- $orderState = $this->responseChecker->getValue($this->client->show($order->getNumber()), 'state');
+ $orderState = $this->responseChecker->getValue($this->client->show($order->getTokenValue()), 'state');
Assert::same($orderState, strtolower($state));
}
@@ -154,7 +155,7 @@ public function itsStateShouldBe(string $state): void
public function itShouldHaveShipmentState(string $state): void
{
$shipmentsIri = $this->responseChecker->getValue(
- $this->client->show($this->sharedStorage->get('order')->getNumber()),
+ $this->client->show($this->sharedStorage->get('order')->getTokenValue()),
'shipments'
);
@@ -170,7 +171,7 @@ public function itShouldHaveShipmentState(string $state): void
public function itShouldHavePaymentState($state): void
{
$paymentsIri = $this->responseChecker->getValue(
- $this->client->show($this->sharedStorage->get('order')->getNumber()),
+ $this->client->show($this->sharedStorage->get('order')->getTokenValue()),
'payments'
);
@@ -186,7 +187,7 @@ public function itShouldHavePaymentState($state): void
public function theOrderShouldHaveNumberOfPayments(int $number): void
{
Assert::count(
- $this->responseChecker->getValue($this->client->show($this->sharedStorage->get('order')->getNumber()), 'payments'),
+ $this->responseChecker->getValue($this->client->show($this->sharedStorage->get('order')->getTokenValue()), 'payments'),
$number
);
}
@@ -197,8 +198,8 @@ public function theOrderShouldHaveNumberOfPayments(int $number): void
public function theOrderShouldHavePaymentState(OrderInterface $order, string $paymentState): void
{
Assert::true(
- $this->responseChecker->hasValue($this->client->show($order->getNumber()), 'paymentState', strtolower($paymentState)),
- sprintf('Order %s does not have %s payment state', $order->getNumber(), $paymentState)
+ $this->responseChecker->hasValue($this->client->show($order->getTokenValue()), 'paymentState', strtolower($paymentState)),
+ sprintf('Order %s does not have %s payment state', $order->getTokenValue(), $paymentState)
);
}
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentsContext.php
index 91509b1c977..ba23840a30a 100644
--- a/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentsContext.php
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingPaymentsContext.php
@@ -135,12 +135,12 @@ public function thePaymentOfTheOrderShouldBeFor(
}
/**
- * @Then /^I should see payment for (the "[^"]+" order) as (\d+)(?:|st|nd|rd|th) in the list$/
+ * @Then /^I should see payment for the ("[^"]+" order) as (\d+)(?:|st|nd|rd|th) in the list$/
*/
- public function iShouldSeePaymentForTheOrderInTheList(string $orderNumber, int $position): void
+ public function iShouldSeePaymentForTheOrderInTheList(OrderInterface $order, int $position): void
{
Assert::true($this->responseChecker->hasItemOnPositionWithValue(
- $this->client->getLastResponse(), $position - 1, 'order', sprintf('/new-api/orders/%s', $orderNumber)
+ $this->client->getLastResponse(), $position - 1, 'order', sprintf('/new-api/orders/%s', $order->getTokenValue())
));
}
diff --git a/src/Sylius/Behat/Context/Api/Shop/CartContext.php b/src/Sylius/Behat/Context/Api/Shop/CartContext.php
new file mode 100644
index 00000000000..e3cf890210a
--- /dev/null
+++ b/src/Sylius/Behat/Context/Api/Shop/CartContext.php
@@ -0,0 +1,55 @@
+cartsClient = $cartsClient;
+ $this->responseChecker = $responseChecker;
+ }
+
+ /**
+ * @When I see the summary of my cart
+ */
+ public function iSeeTheSummaryOfMyCart(): void
+ {
+ $this->cartsClient->create(Request::create('orders'));
+ }
+
+ /**
+ * @Then my cart should be empty
+ */
+ public function myCartShouldBeEmpty(): void
+ {
+ $response = $this->cartsClient->getLastResponse();
+ Assert::true(
+ $this->responseChecker->isCreationSuccessful($response),
+ 'Cart has not been created. Reason: ' . $response->getContent()
+ );
+ }
+}
diff --git a/src/Sylius/Behat/Resources/config/services/api.xml b/src/Sylius/Behat/Resources/config/services/api.xml
index 5838547c115..df69a01bb64 100644
--- a/src/Sylius/Behat/Resources/config/services/api.xml
+++ b/src/Sylius/Behat/Resources/config/services/api.xml
@@ -74,6 +74,10 @@
provinces
+
+ carts
+
+
shipping-categories
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 bf4309eff73..56e6a42bfbf 100644
--- a/src/Sylius/Behat/Resources/config/services/contexts/api/shop.xml
+++ b/src/Sylius/Behat/Resources/config/services/contexts/api/shop.xml
@@ -18,6 +18,11 @@
+
+
+
+
+
diff --git a/src/Sylius/Behat/Resources/config/suites.yml b/src/Sylius/Behat/Resources/config/suites.yml
index 9c9dd2e0620..b3d820dc6f1 100644
--- a/src/Sylius/Behat/Resources/config/suites.yml
+++ b/src/Sylius/Behat/Resources/config/suites.yml
@@ -7,6 +7,7 @@ imports:
- suites/api/addressing/managing_countries.yml
- suites/api/addressing/managing_zones.yml
- suites/api/admin/login.yml
+ - suites/api/cart/shopping_cart.yml
- suites/api/channel/managing_channels.yml
- suites/api/currency/managing_currencies.yml
- suites/api/currency/managing_exchange_rates.yml
diff --git a/src/Sylius/Behat/Resources/config/suites/api/cart/shopping_cart.yml b/src/Sylius/Behat/Resources/config/suites/api/cart/shopping_cart.yml
new file mode 100644
index 00000000000..a07e462c9da
--- /dev/null
+++ b/src/Sylius/Behat/Resources/config/suites/api/cart/shopping_cart.yml
@@ -0,0 +1,15 @@
+# This file is part of the Sylius package.
+# (c) Paweł Jędrzejewski
+
+default:
+ suites:
+ api_shopping_cart:
+ contexts:
+ - sylius.behat.context.hook.doctrine_orm
+
+ - sylius.behat.context.setup.channel
+
+ - sylius.behat.context.api.shop.cart
+
+ filters:
+ tags: "@shopping_cart && @api"
diff --git a/src/Sylius/Bundle/ApiBundle/Command/PickupCart.php b/src/Sylius/Bundle/ApiBundle/Command/PickupCart.php
new file mode 100644
index 00000000000..daa83460040
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Command/PickupCart.php
@@ -0,0 +1,21 @@
+cartFactory = $cartFactory;
+ $this->channelContext = $channelContext;
+ $this->orderManager = $orderManager;
+ $this->generator = $generator;
+ }
+
+ public function __invoke(PickupCart $pickupCart)
+ {
+ /** @var OrderInterface $cart */
+ $cart = $this->cartFactory->createNew();
+
+ /** @var ChannelInterface $channel */
+ $channel = $this->channelContext->getChannel();
+ /** @var LocaleInterface $locale */
+ $locale = $channel->getDefaultLocale();
+ /** @var CurrencyInterface $currency */
+ $currency = $channel->getBaseCurrency();
+
+ $cart->setChannel($channel);
+ $cart->setLocaleCode($locale->getCode());
+ $cart->setCurrencyCode($currency->getCode());
+ $cart->setTokenValue($this->generator->generateUriSafeString(10));
+
+ $this->orderManager->persist($cart);
+
+ return $cart;
+ }
+}
diff --git a/src/Sylius/Bundle/ApiBundle/PropertyInfo/Extractor/EmptyPropertyListExtractor.php b/src/Sylius/Bundle/ApiBundle/PropertyInfo/Extractor/EmptyPropertyListExtractor.php
new file mode 100644
index 00000000000..749b699ff96
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/PropertyInfo/Extractor/EmptyPropertyListExtractor.php
@@ -0,0 +1,28 @@
+
is_granted('ROLE_API_ACCESS')
+
+ is_granted('IS_AUTHENTICATED_ANONYMOUSLY')
+
+ Pickup a new cart
+
+ input
+ Sylius\Bundle\ApiBundle\Command\PickupCart
+
@@ -51,7 +59,8 @@
-
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Order.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Order.xml
index 07653d6dde4..dd2bc9ebc82 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Order.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Order.xml
@@ -55,5 +55,9 @@
order:read
+
+
+ order:read
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/services.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/services.xml
index 5ece3e81d67..ccb697727ba 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/services.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/services.xml
@@ -62,5 +62,9 @@
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
index 7df18ffc729..5cc2b2352d8 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml
@@ -22,5 +22,13 @@
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php
new file mode 100644
index 00000000000..ee3af17e7fa
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/spec/CommandHandler/PickupCartHandlerSpec.php
@@ -0,0 +1,79 @@
+beConstructedWith($cartFactory, $channelContext, $orderManager, $generator);
+ }
+
+ function it_is_a_message_handler(): void
+ {
+ $this->shouldImplement(MessageHandlerInterface::class);
+ }
+
+ function it_pick_ups_a_cart(
+ FactoryInterface $cartFactory,
+ ChannelContextInterface $channelContext,
+ ObjectManager $orderManager,
+ RandomnessGeneratorInterface $generator,
+ OrderInterface $cart,
+ ChannelInterface $channel,
+ CurrencyInterface $currency,
+ LocaleInterface $locale
+ ): void {
+ $cartFactory->createNew()->willReturn($cart);
+ $channelContext->getChannel()->willReturn($channel);
+ $generator->generateUriSafeString(10)->willReturn('urisafestr');
+
+ $channel->getBaseCurrency()->willReturn($currency);
+ $channel->getDefaultLocale()->willReturn($locale);
+
+ $currency->getCode()->willReturn('USD');
+
+ $locale->getCode()->willReturn('en_US');
+
+ $cart->setChannel($channel)->shouldBeCalled();
+ $cart->setCurrencyCode('USD')->shouldBeCalled();
+ $cart->setLocaleCode('en_US')->shouldBeCalled();
+ $cart->setTokenValue('urisafestr')->shouldBeCalled();
+
+ $orderManager->persist($cart)->shouldBeCalled();
+
+ $this(new PickupCart());
+ }
+}
diff --git a/src/Sylius/Bundle/ApiBundle/spec/PropertyInfo/Extractor/EmptyPropertyListExtractorSpec.php b/src/Sylius/Bundle/ApiBundle/spec/PropertyInfo/Extractor/EmptyPropertyListExtractorSpec.php
new file mode 100644
index 00000000000..0f1176708e9
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/spec/PropertyInfo/Extractor/EmptyPropertyListExtractorSpec.php
@@ -0,0 +1,36 @@
+shouldImplement(PropertyListExtractorInterface::class);
+ }
+
+ function it_provides_empty_list_if_requested_class_exists(): void
+ {
+ $this->getProperties(PickupCart::class, [])->shouldReturn([]);
+ }
+
+ function it_provides_null_if_requested_class_does_not_exist(): void
+ {
+ $this->getProperties(\Serializable::class, [])->shouldReturn(null);
+ }
+}