Completed
Push — master ( 7c7881...78efce )
by Michał
26:17 queued 05:58
created

CartContext::myCartSTotalShouldBe()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 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
namespace Sylius\Behat\Context\Ui\Shop;
13
14
use Behat\Behat\Context\Context;
15
use Behat\Mink\Exception\ElementNotFoundException;
16
use Sylius\Behat\NotificationType;
17
use Sylius\Behat\Page\Shop\Cart\SummaryPageInterface;
18
use Sylius\Behat\Page\Shop\Product\ShowPageInterface;
19
use Sylius\Behat\Service\NotificationCheckerInterface;
20
use Sylius\Behat\Service\SharedSecurityServiceInterface;
21
use Sylius\Component\Core\Model\ShopUserInterface;
22
use Sylius\Behat\Service\SharedStorageInterface;
23
use Sylius\Component\Product\Model\OptionInterface;
24
use Sylius\Component\Product\Model\ProductInterface;
25
use Webmozart\Assert\Assert;
26
27
/**
28
 * @author Mateusz Zalewski <[email protected]>
29
 * @author Anna Walasek <[email protected]>
30
 * @author Paweł Jędrzejewski <[email protected]>
31
 */
32
final class CartContext implements Context
33
{
34
    /**
35
     * @var SharedStorageInterface
36
     */
37
    private $sharedStorage;
38
39
    /**
40
     * @var SummaryPageInterface
41
     */
42
    private $summaryPage;
43
44
    /**
45
     * @var ShowPageInterface
46
     */
47
    private $productShowPage;
48
49
    /**
50
     * @var NotificationCheckerInterface
51
     */
52
    private $notificationChecker;
53
54
    /**
55
     * @var SharedSecurityServiceInterface
56
     */
57
    private $sharedSecurityService;
58
59
    /**
60
     * @param SharedStorageInterface $sharedStorage
61
     * @param SummaryPageInterface $summaryPage
62
     * @param ShowPageInterface $productShowPage
63
     * @param NotificationCheckerInterface $notificationChecker
64
     * @param SharedSecurityServiceInterface $sharedSecurityService
65
     */
66
    public function __construct(
67
        SharedStorageInterface $sharedStorage,
68
        SummaryPageInterface $summaryPage,
69
        ShowPageInterface $productShowPage,
70
        NotificationCheckerInterface $notificationChecker,
71
        SharedSecurityServiceInterface $sharedSecurityService
72
    ) {
73
        $this->sharedStorage = $sharedStorage;
74
        $this->summaryPage = $summaryPage;
75
        $this->productShowPage = $productShowPage;
76
        $this->notificationChecker = $notificationChecker;
77
        $this->sharedSecurityService = $sharedSecurityService;
78
    }
79
80
    /**
81
     * @Given I am at the summary of my cart
82
     * @When I see the summary of my cart
83
     */
84
    public function iOpenCartSummaryPage()
85
    {
86
        $this->summaryPage->open();
87
    }
88
89
    /**
90
     * @When I save my changes
91
     */
92
    public function iSaveMyChanges()
93
    {
94
        $this->summaryPage->updateCart();
95
    }
96
97
    /**
98
     * @Then my cart should be empty
99
     * @Then cart should be empty with no value
100
     */
101
    public function iShouldBeNotifiedThatMyCartIsEmpty()
102
    {
103
        $this->summaryPage->open();
104
105
        Assert::true(
106
             $this->summaryPage->isEmpty(),
107
            'There should appear information about empty cart, but it does not.'
108
        );
109
    }
110
111
    /**
112
     * @Given /^I (?:remove|removed) product "([^"]+)" from the cart$/
113
     */
114
    public function iRemoveProductFromTheCart($productName)
115
    {
116
        $this->summaryPage->open();
117
        $this->summaryPage->removeProduct($productName);
118
    }
119
120
    /**
121
     * @Given I change :productName quantity to :quantity
122
     */
123
    public function iChangeQuantityTo($productName, $quantity)
124
    {
125
        $this->summaryPage->open();
126
        $this->summaryPage->changeQuantity($productName, $quantity);
127
    }
128
129
    /**
130
     * @Then grand total value should be :total
131
     * @Then my cart total should be :total
132
     */
133
    public function myCartTotalShouldBe($total)
134
    {
135
        $this->summaryPage->open();
136
        Assert::same(
137
            $this->summaryPage->getGrandTotal(),
138
            $total,
139
            'Grand total should be %2$s, but it is %s.'
140
        );
141
    }
142
143
    /**
144
     * @Then tax total value should be :taxTotal
145
     * @Then my cart taxes should be :taxTotal
146
     */
147
    public function myCartTaxesShouldBe($taxTotal)
148
    {
149
        $this->summaryPage->open();
150
151
        Assert::same(
152
            $this->summaryPage->getTaxTotal(),
153
            $taxTotal,
154
            'Tax total value should be %2$s, but it is %s.'
155
        );
156
    }
157
158
    /**
159
     * @Then shipping total value should be :shippingTotal
160
     * @Then my cart shipping total should be :shippingTotal
161
     * @Then my cart shipping should be for free
162
     */
163
    public function myCartShippingFeeShouldBe($shippingTotal = '$0.00')
164
    {
165
        $this->summaryPage->open();
166
167
        Assert::same(
168
            $this->summaryPage->getShippingTotal(),
169
            $shippingTotal,
170
            'Shipping total value should be %2$s, but it is %s.'
171
        );
172
    }
173
174
    /**
175
     * @Then my cart promotions should be :promotionsTotal
176
     * @Then my discount should be :promotionsTotal
177
     */
178
    public function myDiscountShouldBe($promotionsTotal)
179
    {
180
        $this->summaryPage->open();
181
182
        Assert::same(
183
            $this->summaryPage->getPromotionTotal(),
184
            $promotionsTotal,
185
            'Promotion total value should be %2$s, but it is %s.'
186
        );
187
    }
188
189
    /**
190
     * @Given /^there should be no shipping fee$/
191
     */
192
    public function thereShouldBeNoShippingFee()
193
    {
194
        $this->summaryPage->open();
195
196
        try {
197
            $this->summaryPage->getShippingTotal();
198
        } catch (ElementNotFoundException $exception) {
199
            return;
200
        }
201
202
        throw new \DomainException('Get shipping total should throw an exception!');
203
    }
204
205
    /**
206
     * @Given /^there should be no discount$/
207
     */
208
    public function thereShouldBeNoDiscount()
209
    {
210
        $this->summaryPage->open();
211
212
        try {
213
            $this->summaryPage->getPromotionTotal();
214
        } catch (ElementNotFoundException $exception) {
215
            return;
216
        }
217
218
        throw new \DomainException('Get promotion total should throw an exception!');
219
    }
220
221
    /**
222
     * @Then /^(its|theirs) price should be decreased by ("[^"]+")$/
223
     * @Then /^(product "[^"]+") price should be decreased by ("[^"]+")$/
224
     */
225
    public function itsPriceShouldBeDecreasedBy(ProductInterface $product, $amount)
226
    {
227
        $this->summaryPage->open();
228
229
        $quantity = $this->summaryPage->getQuantity($product->getName());
230
        $unitPrice = $this->summaryPage->getItemUnitPrice($product->getName());
231
        $regularUnitPrice = $this->summaryPage->getItemUnitRegularPrice($product->getName());
232
233
        Assert::same(
234
            $quantity * $unitPrice,
235
            ($quantity * $regularUnitPrice) - $amount,
236
            'Price after discount should be %s, but it is %2$s.'
237
        );
238
    }
239
240
    /**
241
     * @Then /^(product "[^"]+") price should not be decreased$/
242
     * @Then /^(its|theirs) price should not be decreased$/
243
     */
244
    public function productPriceShouldNotBeDecreased(ProductInterface $product)
245
    {
246
        $this->summaryPage->open();
247
248
        Assert::false(
249
            $this->summaryPage->isItemDiscounted($product->getName()),
250
            'The price should not be decreased, but it is.'
251
        );
252
    }
253
254
    /**
255
     * @Given /^I (?:add|added) (this product) to the cart$/
256
     * @Given I added product :product to the cart
257
     * @Given /^I (?:have|had) (product "[^"]+") in the cart$/
258
     * @When I add product :product to the cart
259
     */
260
    public function iAddProductToTheCart(ProductInterface $product)
261
    {
262
        $this->productShowPage->open(['slug' => $product->getSlug()]);
263
        $this->productShowPage->addToCart();
264
265
        $this->sharedStorage->set('product', $product);
266
    }
267
268
    /**
269
     * @Given /^(this user) has ("[^"]+" product) in the cart$/
270
     */
271
    public function thisUserHasProductInTheCart(ShopUserInterface $user, ProductInterface $product)
272
    {
273
        $this->sharedSecurityService->performActionAsShopUser($user, function () use ($product) {
274
            $this->iAddProductToTheCart($product);
275
        });
276
    }
277
278
    /**
279
     * @Given /^I added (products "([^"]+)" and "([^"]+)") to the cart$/
280
     * @When /^I add (products "([^"]+)" and "([^"]+)") to the cart$/
281
     * @Given /^I added (products "([^"]+)", "([^"]+)" and "([^"]+)") to the cart$/
282
     * @When /^I add (products "([^"]+)", "([^"]+)" and "([^"]+)") to the cart$/
283
     */
284
    public function iAddMultipleProductsToTheCart(array $products)
285
    {
286
        foreach ($products as $product) {
287
            $this->iAddProductToTheCart($product);
288
        }
289
    }
290
291
    /**
292
     * @Given I added :variant variant of product :product to the cart
293
     * @When I add :variant variant of product :product to the cart
294
     * @When I have :variant variant of product :product in the cart
295
     * @When /^I add "([^"]+)" variant of (this product) to the cart$/
296
     */
297
    public function iAddProductToTheCartSelectingVariant($variant, ProductInterface $product)
298
    {
299
        $this->productShowPage->open(['slug' => $product->getSlug()]);
300
        $this->productShowPage->addToCartWithVariant($variant);
301
302
        $this->sharedStorage->set('product', $product);
303
    }
304
305
    /**
306
     * @When /^I add (\d+) of (them) to (?:the|my) cart$/
307
     */
308
    public function iAddQuantityOfProductsToTheCart($quantity, ProductInterface $product)
309
    {
310
        $this->productShowPage->open(['slug' => $product->getSlug()]);
311
        $this->productShowPage->addToCartWithQuantity($quantity);
312
    }
313
314
    /**
315
     * @Given /^I have(?:| added) (\d+) (products "([^"]+)") (?:to|in) the cart$/
316
     * @When /^I add(?:|ed) (\d+) (products "([^"]+)") to the cart$/
317
     */
318
    public function iAddProductsToTheCart($quantity, ProductInterface $product)
319
    {
320
        $this->productShowPage->open(['slug' => $product->getSlug()]);
321
        $this->productShowPage->addToCartWithQuantity($quantity);
322
323
        $this->sharedStorage->set('product', $product);
324
    }
325
326
    /**
327
     * @Then I should be on my cart summary page
328
     */
329
    public function shouldBeOnMyCartSummaryPage()
330
    {
331
        Assert::true(
332
            $this->summaryPage->isOpen(),
333
            'Cart summary page should be open, but it does not.'
334
        );
335
    }
336
337
    /**
338
     * @Then I should be notified that the product has been successfully added
339
     */
340
    public function iShouldBeNotifiedThatItHasBeenSuccessfullyAdded()
341
    {
342
        $this->notificationChecker->checkNotification('Item has been added to cart.', NotificationType::success());
343
    }
344
345
    /**
346
     * @Then there should be one item in my cart
347
     */
348
    public function thereShouldBeOneItemInMyCart()
349
    {
350
        Assert::true(
351
            $this->summaryPage->isSingleItemOnPage(),
352
            'There should be only one item on list, but it does not.'
353
        );
354
    }
355
356
    /**
357
     * @Then this item should have name :itemName
358
     */
359
    public function thisProductShouldHaveName($itemName)
360
    {
361
        Assert::true(
362
            $this->summaryPage->hasItemNamed($itemName),
363
            sprintf('The product with name %s should appear on the list, but it does not.', $itemName)
364
        );
365
    }
366
367
    /**
368
     * @Then this item should have variant :variantName
369
     */
370
    public function thisItemShouldHaveVariant($variantName)
371
    {
372
        Assert::true(
373
            $this->summaryPage->hasItemWithVariantNamed($variantName),
374
            sprintf('The product with variant %s should appear on the list, but it does not.', $variantName)
375
        );
376
    }
377
378
    /**
379
     * @When I add :product with :productOption :productOptionValue to the cart
380
     */
381
    public function iAddThisProductWithToTheCart(ProductInterface $product, OptionInterface $productOption, $productOptionValue)
382
    {
383
        $this->productShowPage->open(['slug' => $product->getSlug()]);
384
385
        $this->productShowPage->addToCartWithOption($productOption, $productOptionValue);
386
    }
387
388
    /**
389
     * @Given /^(this product) should have ([^"]+) "([^"]+)"$/
390
     */
391
    public function thisItemShouldHaveOptionValue(ProductInterface $product, $optionName, $optionValue)
392
    {
393
        Assert::true(
394
            $this->summaryPage->hasItemWithOptionValue($product->getName(), $optionName, $optionValue),
395
            sprintf('Product in cart "%s" should have option %s with value %s, but it has not.', $product->getName(), $optionName, $optionValue)
396
        );
397
    }
398
399
    /**
400
     * @When I clear my cart
401
     */
402
    public function iClearMyCart()
403
    {
404
        $this->summaryPage->clearCart();
405
    }
406
407
    /**
408
     * @Then /^I should see "([^"]+)" with quantity (\d+) in my cart$/
409
     */
410
    public function iShouldSeeWithQuantityInMyCart($productName, $quantity)
411
    {
412
        Assert::same(
413
            $this->summaryPage->getQuantity($productName),
414
            $quantity,
415
            'The quantity of product should be %2$s, but it is %s'
416
        );
417
    }
418
419
    /**
420
     * @Given I use coupon with code :couponCode
421
     */
422
    public function iUseCouponWithCode($couponCode)
423
    {
424
        $this->summaryPage->applyCoupon($couponCode);
425
    }
426
427
    /**
428
     * @Then I should be notified that promotion coupon has been added to the cart
429
     */
430
    public function iShouldBeNotifiedThatPromotionCouponHasBeenAddedToTheCart()
431
    {
432
        $this->notificationChecker->checkNotification(
433
            'Your promotion coupon has been added to the cart.',
434
            NotificationType::success()
435
        );
436
    }
437
438
    /**
439
     * @Then I should be notified that promotion coupon is not valid
440
     */
441
    public function iShouldBeNotifiedThatPromotionCouponIsNotValid()
442
    {
443
        $this->notificationChecker->checkNotification(
444
            'Your promotion coupon is not valid.',
445
            NotificationType::failure()
446
        );
447
    }
448
449
    /**
450
     * @Then total price of :productName item should be :productPrice
451
     */
452
    public function thisItemPriceShouldBe($productName, $productPrice)
453
    {
454
        $this->summaryPage->open();
455
456
        Assert::same(
457
            $this->summaryPage->getItemTotal($productName),
458
            $productPrice
459
        );
460
    }
461
462
    /**
463
     * @Then /^I should be notified that (this product) cannot be updated$/
464
     */
465
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
466
    {
467
        Assert::true(
468
            $this->summaryPage->hasProductOutOfStockValidationMessage($product),
0 ignored issues
show
Compatibility introduced by
$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...
469
            sprintf('I should see validation message for %s product', $product->getName())
470
        );
471
    }
472
473
    /**
474
     * @Then /^I should not be notified that (this product) cannot be updated$/
475
     */
476
    public function iShouldNotBeNotifiedThatThisProductCannotBeUpdated(ProductInterface $product)
477
    {
478
        Assert::false(
479
            $this->summaryPage->hasProductOutOfStockValidationMessage($product),
0 ignored issues
show
Compatibility introduced by
$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...
480
            sprintf('I should see validation message for %s product', $product->getName())
481
        );
482
    }
483
484
    /**
485
     * @Then my cart's total should be :total
486
     */
487
    public function myCartSTotalShouldBe($total)
488
    {
489
        Assert::same(
490
            $total,
491
            $this->summaryPage->getCartTotal(),
492
            'Cart should have %s total, but it has %2$s.'
493
        );
494
    }
495
}
496