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 + + +