Completed
Push — master ( d581af...d607ef )
by Paweł
148:00 queued 129:07
created

iShouldNotBeNotifiedThatThisProductCannotBeUpdated()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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