diff --git a/features/shipping/managing_shipments/browsing_shipments.feature b/features/shipping/managing_shipments/browsing_shipments.feature
index 00cd386ac3c..2e92aeb6b52 100644
--- a/features/shipping/managing_shipments/browsing_shipments.feature
+++ b/features/shipping/managing_shipments/browsing_shipments.feature
@@ -21,21 +21,21 @@ Feature: Browsing shipments
And the customer chose "UPS" shipping method with "Cash on Delivery" payment
And I am logged in as an administrator
- @ui
+ @ui @api
Scenario: Browsing shipments and their states in one channel
When I browse shipments
Then I should see 2 shipments in the list
And I should see the shipment of order "#00000001" as "Shipped"
And I should see the shipment of order "#00000002" as "Ready"
- @ui
+ @ui @api
Scenario: Shipments are sorted by newest as default
When I browse shipments
Then I should see shipment for the "#00000002" order as 1st in the list
And I should see shipment for the "#00000001" order as 2nd in the list
- @ui
+ @ui @api
Scenario: Not seeing shipments in cart state
- Given the customer added "Banana" product to the cart
+ Given the customer "customer@example.com" added "Banana" product to the cart
When I browse shipments
Then I should see only 2 shipments in the list
diff --git a/features/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature b/features/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature
index 104e31f94a2..b7eb58897e7 100644
--- a/features/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature
+++ b/features/shipping/managing_shipments/browsing_shipments_from_multiple_channels.feature
@@ -27,7 +27,7 @@ Feature: Browsing shipments from multiple channels
And the customer chose "FEDEX" shipping method with "bank transfer" payment
And I am logged in as an administrator
- @ui
+ @ui @api
Scenario: Browsing shipments and their states from multiple channels
When I browse shipments
And I should see 2 shipments in the list
diff --git a/src/Sylius/Behat/Client/ResponseChecker.php b/src/Sylius/Behat/Client/ResponseChecker.php
index abe132480be..48ee7d1c2bd 100644
--- a/src/Sylius/Behat/Client/ResponseChecker.php
+++ b/src/Sylius/Behat/Client/ResponseChecker.php
@@ -100,6 +100,17 @@ public function hasItemWithTranslation(Response $response, string $locale, strin
return false;
}
+ public function hasItemWithValues(Response $response, array $parameters): bool
+ {
+ foreach ($this->getCollection($response) as $item) {
+ if ($this->itemHasValues($item, $parameters)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
private function getResponseContentValue(Response $response, string $key)
{
$content = json_decode($response->getContent(), true);
@@ -108,4 +119,14 @@ private function getResponseContentValue(Response $response, string $key)
return $content[$key];
}
+
+ private function itemHasValues(array $element, array $parameters): bool {
+ foreach ($parameters as $key => $value) {
+ if ($element[$key] !== $value) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/src/Sylius/Behat/Client/ResponseCheckerInterface.php b/src/Sylius/Behat/Client/ResponseCheckerInterface.php
index b845b5c69c2..eb9d86da406 100644
--- a/src/Sylius/Behat/Client/ResponseCheckerInterface.php
+++ b/src/Sylius/Behat/Client/ResponseCheckerInterface.php
@@ -42,4 +42,6 @@ public function hasItemWithValue(Response $response, string $key, $value): bool;
public function hasItemOnPositionWithValue(Response $response, int $position, string $key, string $value): bool;
public function hasItemWithTranslation(Response $response, string $locale, string $key, string $translation): bool;
+
+ public function hasItemWithValues(Response $response, array $parameters): bool;
}
diff --git a/src/Sylius/Behat/Context/Api/Admin/ManagingShipmentsContext.php b/src/Sylius/Behat/Context/Api/Admin/ManagingShipmentsContext.php
new file mode 100644
index 00000000000..6342957cb7d
--- /dev/null
+++ b/src/Sylius/Behat/Context/Api/Admin/ManagingShipmentsContext.php
@@ -0,0 +1,127 @@
+client = $client;
+ $this->responseChecker = $responseChecker;
+ $this->iriConverter = $iriConverter;
+ }
+
+ /**
+ * @When I browse shipments
+ */
+ public function iBrowseShipments(): void
+ {
+ $this->client->index();
+ }
+
+ /**
+ * @Then I should see( only) :count shipment(s) in the list
+ * @Then I should see a single shipment in the list
+ */
+ public function iShouldSeeCountShipmentsInList(int $count = 1): void
+ {
+ Assert::same($this->responseChecker->countCollectionItems($this->client->getLastResponse()), $count);
+ }
+
+ /**
+ * @Then /^I should see the shipment of (order "[^"]+") as "([^"]+)"$/
+ */
+ public function iShouldSeeTheShipmentOfOrderAs(OrderInterface $order, string $shippingState): void
+ {
+ Assert::true(
+ $this->responseChecker->hasItemWithValues($this->client->getLastResponse(), [
+ 'order' => $this->iriConverter->getIriFromItem($order),
+ 'state' => strtolower($shippingState)
+ ]),
+ sprintf('Shipment for order %s with state %s does not exist', $order->getNumber(), $shippingState)
+ );
+ }
+
+ /**
+ * @Then /^I should see shipment for the ("[^"]+" order) as (\d+)(?:|st|nd|rd|th) in the list$/
+ */
+ public function iShouldSeeShipmentForTheOrderInTheList(OrderInterface $order, int $position): void
+ {
+ Assert::true(
+ $this->responseChecker->hasItemOnPositionWithValue(
+ $this->client->getLastResponse(),
+ --$position,
+ 'order',
+ $this->iriConverter->getIriFromItem($order)
+ ),
+ sprintf('On position %s there is no shipment for order %s', $position, $order->getNumber())
+ );
+ }
+
+ /**
+ * @Then the shipment of the :orderNumber order should be :shippingState for :customer
+ * @Then the shipment of the :orderNumber order should be :shippingState for :customer in :channel channel
+ */
+ public function shipmentOfOrderShouldBe(
+ string $orderNumber,
+ string $shippingState,
+ CustomerInterface $customer,
+ ChannelInterface $channel = null
+ ): void {
+ $this->client->index();
+
+ foreach ($this->responseChecker->getCollectionItemsWithValue($this->client->getLastResponse(), 'state',
+ StringInflector::nameToLowercaseCode($shippingState)) as $shipment) {
+ $orderIri = $shipment['order'];
+ $orderShowResponse = $this->client->showByIri($orderIri);
+
+ if (!$this->responseChecker->HasValue($orderShowResponse, 'number', $orderNumber)) {
+ continue;
+ }
+
+ $this->client->showByIri($this->responseChecker->getValue($orderShowResponse, 'customer'));
+ if (!$this->responseChecker->HasValue($this->client->getLastResponse(), 'email', $customer->getEmail())) {
+ continue;
+ }
+ $this->client->showByIri($this->responseChecker->getValue($orderShowResponse, 'channel'));
+ if ($this->responseChecker->HasValue($this->client->getLastResponse(), 'name', $channel->getName())) {
+ return;
+ }
+ }
+
+ throw new \InvalidArgumentException('There is no shipment with given data');
+ }
+}
diff --git a/src/Sylius/Behat/Context/Transform/OrderContext.php b/src/Sylius/Behat/Context/Transform/OrderContext.php
index f80288a0bf4..44d4b2a728a 100644
--- a/src/Sylius/Behat/Context/Transform/OrderContext.php
+++ b/src/Sylius/Behat/Context/Transform/OrderContext.php
@@ -37,6 +37,8 @@ public function __construct(
/**
* @Transform :order
+ * @Transform /^"([^"]+)" order$/
+ * @Transform /^order "([^"]+)"$/
*/
public function getOrderByNumber(string $orderNumber): OrderInterface
{
@@ -51,7 +53,7 @@ public function getOrderByNumber(string $orderNumber): OrderInterface
/**
* @Transform /^latest order$/
*/
- public function getLatestOrder()
+ public function getLatestOrder(): OrderInterface
{
$orders = $this->orderRepository->findLatest(1);
@@ -65,7 +67,7 @@ public function getLatestOrder()
* @Transform /^order placed by "([^"]+)"$/
* @Transform /^the order of "([^"]+)"$/
*/
- public function getOrderByCustomer($email)
+ public function getOrderByCustomer(string $email): OrderInterface
{
$customer = $this->customerRepository->findOneBy(['email' => $email]);
Assert::notNull($customer, sprintf('Cannot find customer with email %s.', $email));
@@ -82,7 +84,7 @@ public function getOrderByCustomer($email)
* @Transform /^the order "([^"]+)"$/
* @Transform /^the "([^"]+)" order$/
*/
- public function getOrderNumber($orderNumber)
+ public function getOrderNumber(string $orderNumber): string
{
return str_replace('#', '', $orderNumber);
}
diff --git a/src/Sylius/Behat/Resources/config/services/api.xml b/src/Sylius/Behat/Resources/config/services/api.xml
index 6b98d46b3cd..9248a349129 100644
--- a/src/Sylius/Behat/Resources/config/services/api.xml
+++ b/src/Sylius/Behat/Resources/config/services/api.xml
@@ -67,6 +67,12 @@
tax_categories
+
+
+
+ shipments
+
+
diff --git a/src/Sylius/Behat/Resources/config/services/contexts/api.xml b/src/Sylius/Behat/Resources/config/services/contexts/api.xml
index ad996b76ee6..09383e6520b 100644
--- a/src/Sylius/Behat/Resources/config/services/contexts/api.xml
+++ b/src/Sylius/Behat/Resources/config/services/contexts/api.xml
@@ -77,5 +77,11 @@
+
+
+
+
+
+
diff --git a/src/Sylius/Behat/Resources/config/suites.yml b/src/Sylius/Behat/Resources/config/suites.yml
index 86cfb0e714b..5e02e2d56bd 100644
--- a/src/Sylius/Behat/Resources/config/suites.yml
+++ b/src/Sylius/Behat/Resources/config/suites.yml
@@ -10,6 +10,7 @@ imports:
- suites/api/product/managing_product_reviews.yml
- suites/api/product/managing_product_variants.yml
- suites/api/product/managing_products.yml
+ - suites/api/shipping/managing_shipments.yml
- suites/api/shipping/managing_shipping_categories.yml
- suites/api/taxation/managing_tax_categories.yml
- suites/api/taxon/managing_taxons.yml
diff --git a/src/Sylius/Behat/Resources/config/suites/api/shipping/managing_shipments.yml b/src/Sylius/Behat/Resources/config/suites/api/shipping/managing_shipments.yml
new file mode 100644
index 00000000000..7708d94274c
--- /dev/null
+++ b/src/Sylius/Behat/Resources/config/suites/api/shipping/managing_shipments.yml
@@ -0,0 +1,34 @@
+# This file is part of the Sylius package.
+# (c) Paweł Jędrzejewski
+
+default:
+ suites:
+ api_managing_shipments:
+ contexts:
+ - sylius.behat.context.hook.doctrine_orm
+
+ - sylius.behat.context.transform.address
+ - sylius.behat.context.transform.channel
+ - sylius.behat.context.transform.country
+ - sylius.behat.context.transform.customer
+ - sylius.behat.context.transform.order
+ - sylius.behat.context.transform.payment
+ - sylius.behat.context.transform.product
+ - sylius.behat.context.transform.shared_storage
+ - sylius.behat.context.transform.shipping_method
+ - sylius.behat.context.transform.zone
+
+ - sylius.behat.context.setup.admin_api_security
+ - sylius.behat.context.setup.calendar
+ - sylius.behat.context.setup.channel
+ - sylius.behat.context.setup.geographical
+ - sylius.behat.context.setup.order
+ - sylius.behat.context.setup.payment
+ - sylius.behat.context.setup.product
+ - sylius.behat.context.setup.shipping
+ - sylius.behat.context.setup.zone
+
+ - sylius.behat.context.api.admin.managing_shipments
+ filters:
+ tags: "@managing_shipments && @api"
+ javascript: false
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Channel.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Channel.xml
new file mode 100644
index 00000000000..47694679421
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Channel.xml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ channel:read
+
+
+
+
+
+
+
+
+ channel:read
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Customer.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Customer.xml
index 9b776d98917..7d03cc8f7bf 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Customer.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Customer.xml
@@ -25,7 +25,11 @@
-
+
+
+ customer:read
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml
index 077c00fcd0f..32d10af7fbd 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml
@@ -22,6 +22,8 @@
+ sylius
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Shipment.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Shipment.xml
new file mode 100644
index 00000000000..647a606a746
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Shipment.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+ shipment:read
+
+
+
+
+
+ shipment:update
+
+
+
+ sylius
+
+
+ DESC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ShipmentUnit.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ShipmentUnit.xml
new file mode 100644
index 00000000000..244e7d19472
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ShipmentUnit.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+ shipment_unit:read
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ShippingMethod.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ShippingMethod.xml
new file mode 100644
index 00000000000..9d22dbcbd38
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/ShippingMethod.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+ shipping_method:read
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Channel.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Channel.xml
new file mode 100644
index 00000000000..3ac0fa80f35
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Channel.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+ channel:read
+
+
+
+ channel:read
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Customer.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Customer.xml
index 753cf8d8c09..099ef2c71de 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Customer.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Customer.xml
@@ -19,6 +19,7 @@
customer:read
+
customer:read
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Order.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Order.xml
index eff0ff13737..e07af0ea531 100644
--- a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Order.xml
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Order.xml
@@ -19,12 +19,15 @@
order:read
+
order:read
+
order:read
+
order:read
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Shipment.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Shipment.xml
new file mode 100644
index 00000000000..893f515308d
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/Shipment.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
+ shipment:read
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/ShipmentUnit.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/ShipmentUnit.xml
new file mode 100644
index 00000000000..8b458859b92
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/ShipmentUnit.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ shipment_unit:read
+
+
+
diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/ShippingMethod.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/ShippingMethod.xml
new file mode 100644
index 00000000000..2a4df3b1dfe
--- /dev/null
+++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serializer/ShippingMethod.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+ shipping_method:read
+
+
+