Completed
Push — master ( 3ff7e6...cf5edc )
by Kamil
96:30 queued 63:14
created

ProductContext::iOpenProductPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
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 Sylius\Behat\Page\Shop\Product\ShowPageInterface;
16
use Sylius\Behat\Page\Shop\ProductReview\IndexPageInterface;
17
use Sylius\Behat\Page\Shop\Taxon\ShowPageInterface as TaxonShowPageInterface;
18
use Sylius\Component\Core\Model\ProductInterface;
19
use Sylius\Component\Core\Model\TaxonInterface;
20
use Webmozart\Assert\Assert;
21
22
/**
23
 * @author Kamil Kokot <[email protected]>
24
 * @author Magdalena Banasiak <[email protected]>
25
 * @author Anna Walasek <[email protected]>
26
 */
27
final class ProductContext implements Context
28
{
29
    /**
30
     * @var ShowPageInterface
31
     */
32
    private $showPage;
33
34
    /**
35
     * @var TaxonShowPageInterface
36
     */
37
    private $taxonShowPage;
38
39
    /**
40
     * @var IndexPageInterface
41
     */
42
    private $productReviewsIndexPage;
43
44
    /**
45
     * @param ShowPageInterface $showPage
46
     * @param TaxonShowPageInterface $taxonShowPage
47
     * @param IndexPageInterface $productReviewsIndexPage
48
     */
49
    public function __construct(
50
        ShowPageInterface $showPage,
51
        TaxonShowPageInterface $taxonShowPage,
52
        IndexPageInterface $productReviewsIndexPage
53
    ) {
54
        $this->showPage = $showPage;
55
        $this->taxonShowPage = $taxonShowPage;
56
        $this->productReviewsIndexPage = $productReviewsIndexPage;
57
    }
58
59
    /**
60
     * @Then I should be able to access product :product
61
     */
62
    public function iShouldBeAbleToAccessProduct(ProductInterface $product)
63
    {
64
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
65
66
        Assert::true(
67
            $this->showPage->isOpen(['slug' => $product->getSlug()]),
68
            'Product show page should be open, but it does not.'
69
        );
70
    }
71
72
    /**
73
     * @Then I should not be able to access product :product
74
     */
75
    public function iShouldNotBeAbleToAccessProduct(ProductInterface $product)
76
    {
77
        $this->showPage->tryToOpen(['slug' => $product->getSlug()]);
78
79
        Assert::false(
80
            $this->showPage->isOpen(['slug' => $product->getSlug()]),
81
            'Product show page should not be open, but it does.'
82
        );
83
    }
84
85
    /**
86
     * @When /^I check (this product)'s details/
87
     * @When I view product :product
88
     */
89
    public function iOpenProductPage(ProductInterface $product)
90
    {
91
        $this->showPage->open(['slug' => $product->getSlug()]);
92
    }
93
94
    /**
95
     * @Given I should see the product name :name
96
     */
97
    public function iShouldSeeProductName($name)
98
    {
99
        Assert::same(
100
            $name,
101
            $this->showPage->getName(),
102
            'Product should have name %2$s, but it has %s'
103
        );
104
    }
105
106
    /**
107
     * @When I open page :url
108
     */
109
    public function iOpenPage($url)
110
    {
111
        $this->showPage->visit($url);
112
    }
113
114
    /**
115
     * @Then I should be on :product product detailed page
116
     * @Then I should still be on product :product page
117
     */
118
    public function iShouldBeOnProductDetailedPage(ProductInterface $product)
119
    {
120
        Assert::true(
121
            $this->showPage->isOpen(['slug' => $product->getSlug()]),
122
            sprintf('Product %s show page should be open, but it does not.', $product->getName())
123
        );
124
    }
125
126
    /**
127
     * @Then I should see the product attribute :attributeName with value :AttributeValue
128
     */
129
    public function iShouldSeeTheProductAttributeWithValue($attributeName, $AttributeValue)
0 ignored issues
show
Coding Style introduced by
$AttributeValue does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
130
    {
131
        Assert::true(
132
            $this->showPage->hasAttributeWithValue($attributeName, $AttributeValue),
0 ignored issues
show
Coding Style introduced by
$AttributeValue does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
133
            sprintf('Product should have attribute %s with value %s, but it does not.', $attributeName, $AttributeValue)
0 ignored issues
show
Coding Style introduced by
$AttributeValue does not seem to conform to the naming convention (^[a-z][a-zA-Z0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
134
        );
135
    }
136
137
    /**
138
     * @When /^I browse products from (taxon "([^"]+)")$/
139
     */
140
    public function iCheckListOfProductsForTaxon(TaxonInterface $taxon)
141
    {
142
        $this->taxonShowPage->open(['permalink' => $taxon->getPermalink()]);
143
    }
144
145
    /**
146
     * @When I search for products with name :name
147
     */
148
    public function iSearchForProductsWithName($name)
149
    {
150
        $this->taxonShowPage->search($name);
151
    }
152
153
    /**
154
     * @When I clear filter
155
     */
156
    public function iClearFilter()
157
    {
158
        $this->taxonShowPage->clearFilter();
159
    }
160
161
    /**
162
     * @Then I should see the product :productName
163
     */
164
    public function iShouldSeeProduct($productName)
165
    {
166
        Assert::true(
167
            $this->taxonShowPage->isProductOnList($productName),
168
            sprintf("The product %s should appear on page, but it does not.", $productName)
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal The product %s should ap... page, but it does not. does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
169
        );
170
    }
171
172
    /**
173
     * @Then I should not see the product :productName
174
     */
175
    public function iShouldNotSeeProduct($productName)
176
    {
177
        Assert::false(
178
            $this->taxonShowPage->isProductOnList($productName),
179
            sprintf("The product %s should not appear on page, but it does.", $productName)
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal The product %s should no...r on page, but it does. does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
180
        );
181
    }
182
183
    /**
184
     * @Then I should see empty list of products
185
     */
186
    public function iShouldSeeEmptyListOfProducts()
187
    {
188
        Assert::true(
189
            $this->taxonShowPage->isEmpty(),
190
            'There should appear information about empty list of products, but it does not.'
191
        );
192
    }
193
194
    /**
195
     * @Then I should see that it is out of stock
196
     */
197
    public function iShouldSeeItIsOutOfStock()
198
    {
199
        Assert::true(
200
            $this->showPage->isOutOfStock(),
201
            'Out of stock label should be visible.'
202
        );
203
    }
204
205
    /**
206
     * @Then I should be unable to add it to the cart
207
     */
208
    public function iShouldBeUnableToAddItToTheCart()
209
    {
210
        Assert::false(
211
            $this->showPage->hasAddToCartButton(),
212
            'Add to cart button should not be visible.'
213
        );
214
    }
215
216
    /**
217
     * @Then the product price should be :price
218
     * @Then I should see the product price :price
219
     */
220
    public function iShouldSeeTheProductPrice($price)
221
    {
222
        Assert::same(
223
            $price,
224
            $this->showPage->getPrice(),
225
            'Product should have price %2$s, but it has %s'
226
        );
227
    }
228
229
    /**
230
     * @When I set its :optionName to :optionValue
231
     */
232
    public function iSetItsOptionTo($optionName, $optionValue)
233
    {
234
        $this->showPage->selectOption($optionName, $optionValue);
235
    }
236
237
    /**
238
     * @When I select :variantName variant
239
     */
240
    public function iSelectVariant($variantName)
241
    {
242
        $this->showPage->selectVariant($variantName);
243
    }
244
245
    /**
246
     * @Then I should see the product :productName with price :productPrice
247
     */
248
    public function iShouldSeeTheProductWithPrice($productName, $productPrice)
249
    {
250
        Assert::true(
251
            $this->taxonShowPage->isProductWithPriceOnList($productName, $productPrice),
252
            sprintf("The product %s with price %s should appear on page, but it does not.", $productName, $productPrice)
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal The product %s with pric... page, but it does not. does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
253
        );
254
    }
255
256
    /**
257
     * @Then /^I should be notified that (this product) does not have sufficient stock$/
258
     */
259
    public function iShouldBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
260
    {
261
       $this->showPage->waitForValidationErrors(3);
262
263
        Assert::true(
264
            $this->showPage->hasProductOutOfStockValidationMessage($product),
265
            sprintf('I should see validation message for %s product', $product->getName())
266
        );
267
    }
268
269
    /**
270
     * @Then /^I should not be notified that (this product) does not have sufficient stock$/
271
     */
272
    public function iShouldNotBeNotifiedThatThisProductDoesNotHaveSufficientStock(ProductInterface $product)
273
    {
274
        Assert::false(
275
            $this->showPage->hasProductOutOfStockValidationMessage($product),
276
            sprintf('I should see validation message for %s product', $product->getName())
277
        );
278
    }
279
280
    /**
281
     * @Then I should see a main image
282
     */
283
    public function iShouldSeeAMainImage()
284
    {
285
        Assert::true(
286
            $this->showPage->isMainImageDisplayed(),
287
            'The main image should have been displayed.'
288
        );
289
    }
290
291
    /**
292
     * @When /^I view (oldest|newest) products from (taxon "([^"]+)")$/
293
     */
294
    public function iViewSortedProductsFromTaxon($sortDirection, TaxonInterface $taxon)
295
    {
296
        $sorting = ['createdAt' => 'oldest' === $sortDirection ? 'asc' : 'desc'];
297
298
        $this->taxonShowPage->open(['permalink' => $taxon->getPermalink(), 'sorting' => $sorting]);
299
    }
300
301
    /**
302
     * @Then I should see :numberOfProducts products in the list
303
     */
304
    public function iShouldSeeProductsInTheList($numberOfProducts)
305
    {
306
        $foundRows = $this->taxonShowPage->countProductsItems();
307
308
        Assert::same(
309
            (int) $numberOfProducts,
310
            $foundRows,
311
            '%s rows with products should appear on page, %s rows has been found'
312
        );
313
    }
314
315
    /**
316
     * @Then I should see a product with name :name
317
     */
318
    public function iShouldSeeProductWithName($name)
319
    {
320
        Assert::true(
321
            $this->taxonShowPage->isProductOnPageWithName($name),
322
            sprintf('The product with name "%s" has not been found.', $name)
323
        );
324
    }
325
326
    /**
327
     * @Then the first product on the list should have name :name
328
     */
329
    public function theFirstProductOnTheListShouldHaveName($name)
330
    {
331
        $actualName = $this->taxonShowPage->getFirstProductNameFromList();
332
333
        Assert::same(
334
            $actualName,
335
            $name,
336
            sprintf('Expected first product\'s name to be "%s", but it is "%s".', $name, $actualName)
337
        );
338
    }
339
340
    /**
341
     * @Then I should see :count product reviews
342
     */
343
    public function iShouldSeeProductReviews($count)
344
    {
345
        Assert::same(
346
            (int) $count,
347
            $this->showPage->countReviews(),
348
            'Product has %2$s reviews, but should have %s.'
349
        );
350
    }
351
352
    /**
353
     * @Then I should see reviews titled :firstReview, :secondReview and :thirdReview
354
     */
355
    public function iShouldSeeReviewsTitled(...$reviews)
356
    {
357
        foreach ($reviews as $review) {
358
            Assert::true(
359
                $this->showPage->hasReviewTitled($review),
360
                sprintf('Product should have review titled "%s" but it does not.', $review)
361
            );
362
        }
363
    }
364
365
    /**
366
     * @Then I should not see review titled :title
367
     */
368
    public function iShouldNotSeeReviewTitled($title)
369
    {
370
        Assert::false(
371
            $this->showPage->hasReviewTitled($title),
372
            sprintf('Product should not have review titled "%s" but it does.', $title)
373
        );
374
    }
375
376
    /**
377
     * @When /^I check (this product)'s reviews$/
378
     */
379
    public function iCheckThisProductSReviews(ProductInterface $product)
380
    {
381
        $this->productReviewsIndexPage->open(['slug' => $product->getSlug()]);
382
    }
383
384
    /**
385
     * @Then I should see :count product reviews in the list
386
     */
387
    public function iShouldSeeProductReviewsInTheList($count)
388
    {
389
        Assert::same(
390
            (int) $count,
391
            $this->productReviewsIndexPage->countReviews(),
392
            'Product has %2$s reviews in the list, but should have %s.'
393
        );
394
    }
395
396
    /**
397
     * @Then I should not see review titled :title in the list
398
     */
399
    public function iShouldNotSeeReviewTitledInTheList($title)
400
    {
401
        Assert::false(
402
            $this->productReviewsIndexPage->hasReviewTitled($title),
403
            sprintf('Product should not have review titled "%s" but it does.', $title)
404
        );
405
    }
406
407
    /**
408
     * @Then /^I should be notified that there are no reviews$/
409
     */
410
    public function iShouldBeNotifiedThatThereAreNoReviews()
411
    {
412
        Assert::true(
413
            $this->productReviewsIndexPage->hasNoReviewMessage(),
414
            'There should be message about no reviews but there is not.'
415
        );
416
    }
417
418
    /**
419
     * @Then I should see :rating as its average rating
420
     */
421
    public function iShouldSeeAsItsAverageRating($rating)
422
    {
423
        Assert::same(
424
            (float) $rating,
425
            $this->showPage->getAverageRating(),
426
            'Product should have average rating %2$s but has %s.'
427
        );
428
    }
429
430
    /**
431
     * @Then /^I should(?:| also) see the product association "([^"]+)" with (products "[^"]+" and "[^"]+")$/
432
     */
433
    public function iShouldSeeTheProductAssociationWithProducts($productAssociationName, array $products)
434
    {
435
        Assert::true(
436
            $this->showPage->hasAssociation($productAssociationName),
437
            sprintf('There should be an association named "%s" but it does not.', $productAssociationName)
438
        );
439
440
        foreach ($products as $product) {
441
            $this->assertIsProductIsInAssociation($product->getName(), $productAssociationName);
442
        }
443
    }
444
445
    /**
446
     * @param string $productName
447
     * @param string $productAssociationName
448
     *
449
     * @throws \InvalidArgumentException
450
     */
451
    private function assertIsProductIsInAssociation($productName, $productAssociationName)
452
    {
453
        Assert::true(
454
            $this->showPage->hasProductInAssociation($productName, $productAssociationName),
455
            sprintf(
456
                'There should be an associated product "%s" under association "%s" but it does not.',
457
                $productName,
458
                $productAssociationName
459
            )
460
        );
461
    }
462
}
463