Issues (244)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

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

Severity

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
    private function getPriceFromString(string $price): int
427
    {
428
        return (int) round((float) str_replace(['€', '£', '$'], '', $price) * 100, 2);
429
    }
430
}
431