Completed
Push — master ( d81c19...f57266 )
by Kamil
20s
created

src/Sylius/Behat/Context/Ui/Shop/CartContext.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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\Ui\Shop;
15
16
use Behat\Behat\Context\Context;
17
use Behat\Mink\Exception\ElementNotFoundException;
18
use Sylius\Behat\NotificationType;
19
use Sylius\Behat\Page\Shop\Cart\SummaryPageInterface;
20
use Sylius\Behat\Page\Shop\Product\ShowPageInterface;
21
use Sylius\Behat\Service\NotificationCheckerInterface;
22
use Sylius\Behat\Service\SharedStorageInterface;
23
use Sylius\Component\Product\Model\ProductInterface;
24
use Sylius\Component\Product\Model\ProductOptionInterface;
25
use Webmozart\Assert\Assert;
26
27
final class CartContext implements Context
28
{
29
    /**
30
     * @var SharedStorageInterface
31
     */
32
    private $sharedStorage;
33
34
    /**
35
     * @var SummaryPageInterface
36
     */
37
    private $summaryPage;
38
39
    /**
40
     * @var ShowPageInterface
41
     */
42
    private $productShowPage;
43
44
    /**
45
     * @var NotificationCheckerInterface
46
     */
47
    private $notificationChecker;
48
49
    /**
50
     * @param SharedStorageInterface $sharedStorage
51
     * @param SummaryPageInterface $summaryPage
52
     * @param ShowPageInterface $productShowPage
53
     * @param NotificationCheckerInterface $notificationChecker
54
     */
55
    public function __construct(
56
        SharedStorageInterface $sharedStorage,
57
        SummaryPageInterface $summaryPage,
58
        ShowPageInterface $productShowPage,
59
        NotificationCheckerInterface $notificationChecker
60
    ) {
61
        $this->sharedStorage = $sharedStorage;
62
        $this->summaryPage = $summaryPage;
63
        $this->productShowPage = $productShowPage;
64
        $this->notificationChecker = $notificationChecker;
65
    }
66
67
    /**
68
     * @When I see the summary of my cart
69
     */
70
    public function iOpenCartSummaryPage()
71
    {
72
        $this->summaryPage->open();
73
    }
74
75
    /**
76
     * @When I update my cart
77
     */
78
    public function iUpdateMyCart()
79
    {
80
        $this->summaryPage->updateCart();
81
    }
82
83
    /**
84
     * @Then my cart should be empty
85
     * @Then cart should be empty with no value
86
     */
87
    public function iShouldBeNotifiedThatMyCartIsEmpty()
88
    {
89
        $this->summaryPage->open();
90
91
        Assert::true($this->summaryPage->isEmpty());
92
    }
93
94
    /**
95
     * @Given I removed product :productName from the cart
96
     * @When I remove product :productName from the cart
97
     */
98
    public function iRemoveProductFromTheCart(string $productName): void
99
    {
100
        $this->summaryPage->open();
101
        $this->summaryPage->removeProduct($productName);
102
    }
103
104
    /**
105
     * @Given I change :productName quantity to :quantity
106
     */
107
    public function iChangeQuantityTo($productName, $quantity)
108
    {
109
        $this->summaryPage->open();
110
        $this->summaryPage->changeQuantity($productName, $quantity);
111
    }
112
113
    /**
114
     * @Then the grand total value should be :total
115
     * @Then my cart total should be :total
116
     */
117
    public function myCartTotalShouldBe($total)
118
    {
119
        $this->summaryPage->open();
120
121
        Assert::same($this->summaryPage->getGrandTotal(), $total);
122
    }
123
124
    /**
125
     * @Then the grand total value in base currency should be :total
126
     */
127
    public function myBaseCartTotalShouldBe($total)
128
    {
129
        $this->summaryPage->open();
130
131
        Assert::same($this->summaryPage->getBaseGrandTotal(), $total);
132
    }
133
134
    /**
135
     * @Then my cart taxes should be :taxTotal
136
     */
137
    public function myCartTaxesShouldBe($taxTotal)
138
    {
139
        $this->summaryPage->open();
140
141
        Assert::same($this->summaryPage->getTaxTotal(), $taxTotal);
142
    }
143
144
    /**
145
     * @Then my cart shipping total should be :shippingTotal
146
     * @Then my cart shipping should be for free
147
     */
148
    public function myCartShippingFeeShouldBe($shippingTotal = '$0.00')
149
    {
150
        $this->summaryPage->open();
151
152
        Assert::same($this->summaryPage->getShippingTotal(), $shippingTotal);
153
    }
154
155
    /**
156
     * @Then my discount should be :promotionsTotal
157
     */
158
    public function myDiscountShouldBe($promotionsTotal)
159
    {
160
        $this->summaryPage->open();
161
162
        Assert::same($this->summaryPage->getPromotionTotal(), $promotionsTotal);
163
    }
164
165
    /**
166
     * @Given /^there should be no shipping fee$/
167
     */
168
    public function thereShouldBeNoShippingFee()
169
    {
170
        $this->summaryPage->open();
171
172
        try {
173
            $this->summaryPage->getShippingTotal();
174
        } catch (ElementNotFoundException $exception) {
175
            return;
176
        }
177
178
        throw new \DomainException('Get shipping total should throw an exception!');
179
    }
180
181
    /**
182
     * @Given /^there should be no discount$/
183
     */
184
    public function thereShouldBeNoDiscount()
185
    {
186
        $this->summaryPage->open();
187
188
        try {
189
            $this->summaryPage->getPromotionTotal();
190
        } catch (ElementNotFoundException $exception) {
191
            return;
192
        }
193
194
        throw new \DomainException('Get promotion total should throw an exception!');
195
    }
196
197
    /**
198
     * @Then /^(its|theirs) price should be decreased by ("[^"]+")$/
199
     * @Then /^(product "[^"]+") price should be decreased by ("[^"]+")$/
200
     */
201
    public function itsPriceShouldBeDecreasedBy(ProductInterface $product, $amount)
202
    {
203
        $this->summaryPage->open();
204
205
        $quantity = $this->summaryPage->getQuantity($product->getName());
206
        $itemTotal = $this->summaryPage->getItemTotal($product->getName());
207
        $regularUnitPrice = $this->summaryPage->getItemUnitRegularPrice($product->getName());
208
209
        Assert::same($this->getPriceFromString($itemTotal), ($quantity * $regularUnitPrice) - $amount);
210
    }
211
212
    /**
213
     * @Then /^(product "[^"]+") price should not be decreased$/
214
     */
215
    public function productPriceShouldNotBeDecreased(ProductInterface $product)
216
    {
217
        $this->summaryPage->open();
218
219
        Assert::false($this->summaryPage->isItemDiscounted($product->getName()));
220
    }
221
222
    /**
223
     * @Given /^I (?:add|added) (this product) to the cart$/
224
     * @Given I added product :product to the cart
225
     * @Given /^I (?:have|had) (product "[^"]+") in the cart$/
226
     * @When I add product :product to the cart
227
     */
228
    public function iAddProductToTheCart(ProductInterface $product)
229
    {
230
        $this->productShowPage->open(['slug' => $product->getSlug()]);
231
        $this->productShowPage->addToCart();
232
233
        $this->sharedStorage->set('product', $product);
234
    }
235
236
    /**
237
     * @When /^I add (products "([^"]+)" and "([^"]+)") to the cart$/
238
     * @When /^I add (products "([^"]+)", "([^"]+)" and "([^"]+)") to the cart$/
239
     */
240
    public function iAddMultipleProductsToTheCart(array $products)
241
    {
242
        foreach ($products as $product) {
243
            $this->iAddProductToTheCart($product);
244
        }
245
    }
246
247
    /**
248
     * @When I add :variantName variant of product :product to the cart
249
     * @When /^I add "([^"]+)" variant of (this product) to the cart$/
250
     * @Given I have :variantName variant of product :product in the cart
251
     */
252
    public function iAddProductToTheCartSelectingVariant($variantName, ProductInterface $product)
253
    {
254
        $this->productShowPage->open(['slug' => $product->getSlug()]);
255
        $this->productShowPage->addToCartWithVariant($variantName);
256
257
        $this->sharedStorage->set('product', $product);
258
    }
259
260
    /**
261
     * @When /^I add (\d+) of (them) to (?:the|my) cart$/
262
     */
263
    public function iAddQuantityOfProductsToTheCart($quantity, ProductInterface $product)
264
    {
265
        $this->productShowPage->open(['slug' => $product->getSlug()]);
266
        $this->productShowPage->addToCartWithQuantity($quantity);
267
    }
268
269
    /**
270
     * @Given /^I have(?:| added) (\d+) (products "([^"]+)") (?:to|in) the cart$/
271
     * @When /^I add(?:|ed)(?:| again) (\d+) (products "([^"]+)") to the cart$/
272
     */
273
    public function iAddProductsToTheCart($quantity, ProductInterface $product)
274
    {
275
        $this->productShowPage->open(['slug' => $product->getSlug()]);
276
        $this->productShowPage->addToCartWithQuantity($quantity);
277
278
        $this->sharedStorage->set('product', $product);
279
    }
280
281
    /**
282
     * @Then /^I should be(?: on| redirected to) my cart summary page$/
283
     */
284
    public function shouldBeOnMyCartSummaryPage()
285
    {
286
        $this->summaryPage->waitForRedirect(3);
287
288
        $this->summaryPage->verify();
289
    }
290
291
    /**
292
     * @Then I should be notified that the product has been successfully added
293
     */
294
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyAdded()
295
    {
296
        $this->notificationChecker->checkNotification('Item has been added to cart', NotificationType::success());
297
    }
298
299
    /**
300
     * @Then there should be one item in my cart
301
     */
302
    public function thereShouldBeOneItemInMyCart()
303
    {
304
        Assert::true($this->summaryPage->isSingleItemOnPage());
305
    }
306
307
    /**
308
     * @Then this item should have name :itemName
309
     */
310
    public function thisProductShouldHaveName($itemName)
311
    {
312
        Assert::true($this->summaryPage->hasItemNamed($itemName));
313
    }
314
315
    /**
316
     * @Then this item should have variant :variantName
317
     */
318
    public function thisItemShouldHaveVariant($variantName)
319
    {
320
        Assert::true($this->summaryPage->hasItemWithVariantNamed($variantName));
321
    }
322
323
    /**
324
     * @Then this item should have code :variantCode
325
     */
326
    public function thisItemShouldHaveCode($variantCode)
327
    {
328
        Assert::true($this->summaryPage->hasItemWithCode($variantCode));
329
    }
330
331
    /**
332
     * @Given I have :product with :productOption :productOptionValue in the cart
333
     * @When I add :product with :productOption :productOptionValue to the cart
334
     */
335
    public function iAddThisProductWithToTheCart(ProductInterface $product, ProductOptionInterface $productOption, $productOptionValue)
336
    {
337
        $this->productShowPage->open(['slug' => $product->getSlug()]);
338
339
        $this->productShowPage->addToCartWithOption($productOption, $productOptionValue);
340
    }
341
342
    /**
343
     * @Given /^(this product) should have ([^"]+) "([^"]+)"$/
344
     */
345
    public function thisItemShouldHaveOptionValue(ProductInterface $product, $optionName, $optionValue)
346
    {
347
        Assert::true($this->summaryPage->hasItemWithOptionValue($product->getName(), $optionName, $optionValue));
348
    }
349
350
    /**
351
     * @When I clear my cart
352
     */
353
    public function iClearMyCart()
354
    {
355
        $this->summaryPage->clearCart();
356
    }
357
358
    /**
359
     * @Then /^I should see "([^"]+)" with quantity (\d+) in my cart$/
360
     */
361
    public function iShouldSeeWithQuantityInMyCart($productName, $quantity)
362
    {
363
        Assert::same($this->summaryPage->getQuantity($productName), (int) $quantity);
364
    }
365
366
    /**
367
     * @Then /^I should see "([^"]+)" with unit price ("[^"]+") in my cart$/
368
     */
369
    public function iShouldSeeProductWithUnitPriceInMyCart($productName, $unitPrice)
370
    {
371
        Assert::same($this->summaryPage->getItemUnitPrice($productName), $unitPrice);
372
    }
373
374
    /**
375
     * @Given I use coupon with code :couponCode
376
     */
377
    public function iUseCouponWithCode($couponCode)
378
    {
379
        $this->summaryPage->applyCoupon($couponCode);
380
    }
381
382
    /**
383
     * @Then I should be notified that the coupon is invalid
384
     */
385
    public function iShouldBeNotifiedThatCouponIsInvalid()
386
    {
387
        Assert::same($this->summaryPage->getPromotionCouponValidationMessage(), 'Coupon code is invalid.');
388
    }
389
390
    /**
391
     * @Then total price of :productName item should be :productPrice
392
     */
393
    public function thisItemPriceShouldBe($productName, $productPrice)
394
    {
395
        $this->summaryPage->open();
396
397
        Assert::same($this->summaryPage->getItemTotal($productName), $productPrice);
398
    }
399
400
    /**
401
     * @Then /^I should be notified that (this product) cannot be updated$/
402
     */
403
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
404
    {
405
        Assert::true($this->summaryPage->hasProductOutOfStockValidationMessage($product));
0 ignored issues
show
$product of type object<Sylius\Component\...Model\ProductInterface> is not a sub-type of object<Sylius\Component\...Model\ProductInterface>. It seems like you assume a child interface of the interface Sylius\Component\Product\Model\ProductInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
406
    }
407
408
    /**
409
     * @Then /^I should not be notified that (this product) cannot be updated$/
410
     */
411
    public function iShouldNotBeNotifiedThatThisProductCannotBeUpdated(ProductInterface $product)
412
    {
413
        Assert::false($this->summaryPage->hasProductOutOfStockValidationMessage($product));
0 ignored issues
show
$product of type object<Sylius\Component\...Model\ProductInterface> is not a sub-type of object<Sylius\Component\...Model\ProductInterface>. It seems like you assume a child interface of the interface Sylius\Component\Product\Model\ProductInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
414
    }
415
416
    /**
417
     * @Then my cart's total should be :total
418
     */
419
    public function myCartSTotalShouldBe($total)
420
    {
421
        $this->summaryPage->open();
422
423
        Assert::same($this->summaryPage->getCartTotal(), $total);
424
    }
425
426
    /**
427
     * @param string $price
428
     *
429
     * @return int
430
     */
431
    private function getPriceFromString($price)
432
    {
433
        return (int) round(str_replace(['€', '£', '$'], '', $price) * 100, 2);
434
    }
435
}
436