Completed
Push — master ( b4619a...ab6ee6 )
by Kamil
12:06 queued 06:35
created

ManagingShipmentsContext   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 236
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 0
loc 236
c 0
b 0
f 0
wmc 24
lcom 1
cbo 7
rs 10

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A iBrowseShipments() 0 4 1
A iChooseShipmentState() 0 4 1
A iChooseChannelAsAChannelFilter() 0 4 1
A iFilter() 0 4 1
A iViewTheShipmentOfTheOrder() 0 4 1
A iShouldSeeCountShipmentsInList() 0 4 1
A iShipShipmentOfOrder() 0 4 1
A iShipTheShipmentOfOrderWithTrackingCode() 0 8 1
A iShouldBeNotifiedThatTheShipmentHasBeenSuccessfullyShipped() 0 4 1
A iShouldSeeTheShipmentOfOrderAs() 0 10 1
A iShouldSeeShipmentForTheOrderInTheList() 0 12 1
A iShouldSeeTheShippingDateAs() 0 8 1
A shipmentOfOrderShouldBe() 0 28 5
A iShouldSeeShipmentWithOrderNumber() 0 7 1
A iShouldNotSeeShipmentWithOrderNumber() 0 7 1
A iShouldSeeUnitsInTheList() 0 23 3
A isShipmentForOrder() 0 8 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Api\Admin;
15
16
use ApiPlatform\Core\Api\IriConverterInterface;
17
use Behat\Behat\Context\Context;
18
use Sylius\Behat\Client\ApiClientInterface;
19
use Sylius\Behat\Client\ApiIriClientInterface;
20
use Sylius\Behat\Client\ResponseCheckerInterface;
21
use Sylius\Component\Channel\Model\ChannelInterface;
22
use Sylius\Component\Core\Formatter\StringInflector;
23
use Sylius\Component\Core\Model\OrderInterface;
24
use Sylius\Component\Core\Model\ProductInterface;
25
use Sylius\Component\Customer\Model\CustomerInterface;
26
use Sylius\Component\Shipping\Model\ShipmentUnitInterface;
27
use Sylius\Component\Shipping\ShipmentTransitions;
28
use Webmozart\Assert\Assert;
29
30
final class ManagingShipmentsContext implements Context
31
{
32
    /** @var ApiClientInterface */
33
    private $client;
34
35
    /** @var ApiIriClientInterface */
36
    private $iriClient;
37
38
    /** @var ResponseCheckerInterface */
39
    private $responseChecker;
40
41
    /** @var IriConverterInterface */
42
    private $iriConverter;
43
44
    public function __construct(
45
        ApiClientInterface $client,
46
        ApiIriClientInterface $iriClient,
47
        ResponseCheckerInterface $responseChecker,
48
        IriConverterInterface $iriConverter
49
    ) {
50
        $this->client = $client;
51
        $this->iriClient = $iriClient;
52
        $this->responseChecker = $responseChecker;
53
        $this->iriConverter = $iriConverter;
54
    }
55
56
    /**
57
     * @When I browse shipments
58
     */
59
    public function iBrowseShipments(): void
60
    {
61
        $this->client->index();
62
    }
63
64
    /**
65
     * @When I choose :state as a shipment state
66
     */
67
    public function iChooseShipmentState(string $state): void
68
    {
69
        $this->client->addFilter('state', $state);
70
    }
71
72
    /**
73
     * @When I choose :channel as a channel filter
74
     */
75
    public function iChooseChannelAsAChannelFilter(ChannelInterface $channel): void
76
    {
77
        $this->client->addFilter('order.channel.code', $channel->getCode());
78
    }
79
80
    /**
81
     * @When I filter
82
     */
83
    public function iFilter(): void
84
    {
85
        $this->client->filter();
86
    }
87
88
    /**
89
     * @When I view the first shipment of the order :order
90
     */
91
    public function iViewTheShipmentOfTheOrder(OrderInterface $order): void
92
    {
93
        $this->client->show((string) $order->getShipments()->first()->getId());
94
    }
95
96
    /**
97
     * @Then I should see( only) :count shipment(s) in the list
98
     * @Then I should see a single shipment in the list
99
     */
100
    public function iShouldSeeCountShipmentsInList(int $count = 1): void
101
    {
102
        Assert::same($this->responseChecker->countCollectionItems($this->client->getLastResponse()), $count);
103
    }
104
105
    /**
106
     * @When I ship the shipment of order :order
107
     */
108
    public function iShipShipmentOfOrder(OrderInterface $order): void
109
    {
110
        $this->client->applyTransition((string) $order->getShipments()->first()->getId(), ShipmentTransitions::TRANSITION_SHIP);
111
    }
112
113
    /**
114
     * @When I ship the shipment of order :order with :trackingCode tracking code
115
     */
116
    public function iShipTheShipmentOfOrderWithTrackingCode(OrderInterface $order, string $trackingCode): void
117
    {
118
        $this->client->applyTransition(
119
            (string) $order->getShipments()->first()->getId(),
120
            ShipmentTransitions::TRANSITION_SHIP,
121
            ['tracking' => $trackingCode]
122
        );
123
    }
124
125
    /**
126
     * @Then I should be notified that the shipment has been successfully shipped
127
     */
128
    public function iShouldBeNotifiedThatTheShipmentHasBeenSuccessfullyShipped(): void
129
    {
130
        Assert::same($this->responseChecker->getValue($this->client->getLastResponse(), 'state'), 'shipped', 'Shipment is not shipped');
131
    }
132
133
    /**
134
     * @Then /^I should see the shipment of (order "[^"]+") as "([^"]+)"$/
135
     */
136
    public function iShouldSeeTheShipmentOfOrderAs(OrderInterface $order, string $shippingState): void
137
    {
138
        Assert::true(
139
            $this->responseChecker->hasItemWithValues($this->client->index(), [
140
                'order' => $this->iriConverter->getIriFromItem($order),
141
                'state' => strtolower($shippingState),
142
            ]),
143
            sprintf('Shipment for order %s with state %s does not exist', $order->getNumber(), $shippingState)
144
        );
145
    }
146
147
    /**
148
     * @Then /^I should see shipment for the ("[^"]+" order) as (\d+)(?:|st|nd|rd|th) in the list$/
149
     */
150
    public function iShouldSeeShipmentForTheOrderInTheList(OrderInterface $order, int $position): void
151
    {
152
        Assert::true(
153
            $this->responseChecker->hasItemOnPositionWithValue(
154
                $this->client->getLastResponse(),
155
                --$position,
156
                'order',
157
                $this->iriConverter->getIriFromItem($order)
158
            ),
159
            sprintf('On position %s there is no shipment for order %s', $position, $order->getNumber())
160
        );
161
    }
162
163
    /**
164
     * @Then I should see the shipment of order :order shipped at :dateTime
165
     */
166
    public function iShouldSeeTheShippingDateAs(OrderInterface $order, string $dateTime): void
167
    {
168
        Assert::eq(
169
             new \DateTime($this->responseChecker->getValue($this->client->show((string) $order->getShipments()->first()->getId()), 'shippedAt')),
170
             new \DateTime($dateTime),
171
             'Shipment was shipped in different date'
172
         );
173
    }
174
175
    /**
176
     * @Then the shipment of the :orderNumber order should be :shippingState for :customer
177
     * @Then the shipment of the :orderNumber order should be :shippingState for :customer in :channel channel
178
     */
179
    public function shipmentOfOrderShouldBe(
180
        string $orderNumber,
181
        string $shippingState,
182
        CustomerInterface $customer,
183
        ChannelInterface $channel = null
184
    ): void {
185
        $this->client->index();
186
187
        foreach ($this->responseChecker->getCollectionItemsWithValue($this->client->getLastResponse(), 'state',
188
            StringInflector::nameToLowercaseCode($shippingState)) as $shipment) {
189
            $orderShowResponse = $this->client->showByIri($shipment['order']);
190
191
            if (!$this->responseChecker->HasValue($orderShowResponse, 'number', $orderNumber)) {
192
                continue;
193
            }
194
195
            $this->client->showByIri($this->responseChecker->getValue($orderShowResponse, 'customer'));
196
            if (!$this->responseChecker->HasValue($this->client->getLastResponse(), 'email', $customer->getEmail())) {
197
                continue;
198
            }
199
            $this->client->showByIri($this->responseChecker->getValue($orderShowResponse, 'channel'));
200
            if ($this->responseChecker->HasValue($this->client->getLastResponse(), 'name', $channel->getName())) {
0 ignored issues
show
Bug introduced by
It seems like $channel is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
201
                return;
202
            }
203
        }
204
205
        throw new \InvalidArgumentException('There is no shipment with given data');
206
    }
207
208
    /**
209
     * @Then I should see a shipment of order :order
210
     */
211
    public function iShouldSeeShipmentWithOrderNumber(OrderInterface $order): void
212
    {
213
        Assert::true(
214
            $this->isShipmentForOrder($order),
215
            sprintf('There is no shipment for order %s', $order->getNumber())
216
        );
217
    }
218
219
    /**
220
     * @Then I should not see a shipment of order :order
221
     */
222
    public function iShouldNotSeeShipmentWithOrderNumber(OrderInterface $order): void
223
    {
224
        Assert::false(
225
            $this->isShipmentForOrder($order),
226
            sprintf('There is shipment for order %s', $order->getNumber())
227
        );
228
    }
229
230
    /**
231
     * @Then I should see :amount :product units in the list
232
     */
233
    public function iShouldSeeUnitsInTheList(int $amount, ProductInterface $product): void
234
    {
235
        $shipmentUnitsFromResponse = $this->responseChecker->getValue($this->client->getLastResponse(), 'units');
236
237
        $productUnitsCounter = 0;
238
        foreach ($shipmentUnitsFromResponse as $shipmentUnitFromResponse) {
239
            $shipmentUnitResponse = $this->iriClient->showByIri($shipmentUnitFromResponse);
240
            $productVariantResponse = $this->iriClient->showByIri(
241
                $this->responseChecker->getValue($shipmentUnitResponse, 'shippable')['@id']
242
            );
243
            $productResponse = $this->iriClient->showByIri(
244
                $this->responseChecker->getValue($productVariantResponse, 'product')
245
            );
246
247
            $productName = $this->responseChecker->getValue($productResponse, 'translations')['en_US']['name'];
248
249
            if ($productName === $product->getName()) {
250
                ++$productUnitsCounter;
251
            }
252
        }
253
254
        Assert::same($productUnitsCounter, $amount);
255
    }
256
257
    private function isShipmentForOrder(OrderInterface $order): bool
258
    {
259
        return $this->responseChecker->hasItemWithValue(
260
            $this->client->getLastResponse(),
261
            'order',
262
            $this->iriConverter->getIriFromItem($order)
263
        );
264
    }
265
}
266