Completed
Push — to-be-a-hat-or-not-to-be-kuhwa ( 7c7f7b...b72886 )
by Kamil
20:35
created

ManagingProductsContext   F

Complexity

Total Complexity 65

Size/Duplication

Total Lines 843
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 14

Importance

Changes 0
Metric Value
wmc 65
lcom 3
cbo 14
dl 0
loc 843
rs 3.2
c 0
b 0
f 0

62 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 1
A iWantToCreateANewSimpleProduct() 0 4 1
A iWantToCreateANewConfigurableProduct() 0 4 1
A iSpecifyItsCodeAs() 0 9 1
A iNameItIn() 0 9 1
A iRenameItToIn() 0 9 1
A iAddIt() 0 12 1
A iDisableItsTracking() 0 4 1
A iEnableItsTracking() 0 4 1
A iSetItsPriceTo() 0 4 1
A iSetItsSlugTo() 0 4 1
A iEnableSlugModification() 0 4 1
A theProductShouldAppearInTheShop() 0 9 1
A iWantToBrowseProducts() 0 4 1
A iFilterThemByTaxon() 0 4 1
A iShouldSeeProductWith() 0 7 1
A iShouldNotSeeAnyProductWith() 0 7 1
A theFirstProductOnTheListShouldHave() 0 10 1
A iSortProductsBy() 0 4 1
A iShouldSeeProductsInTheList() 0 10 1
A iDeleteProduct() 0 7 1
A productShouldNotExist() 0 9 1
A iShouldBeNotifiedOfFailure() 0 7 1
A productShouldExistInTheProductCatalog() 0 4 1
A iWantToModifyAProduct() 0 11 2
A theCodeFieldShouldBeDisabled() 0 13 1
A theSlugFieldShouldNotBeEditable() 0 7 1
A thisProductPriceShouldBeEqualTo() 0 4 1
A thisProductElementShouldBe() 0 4 1
A iShouldBeNotifiedThatIsRequired() 0 4 1
A iShouldBeNotifiedThatPriceIsRequired() 0 4 1
A iSaveMyChanges() 0 12 1
A iChangeItsPriceTo() 0 4 1
A iAddTheOptionToIt() 0 4 1
A iSetItsAttributeTo() 0 4 1
A iRemoveItsAttribute() 0 4 1
A itsAttributeShouldBe() 0 10 1
A productShouldNotHaveAttribute() 0 9 1
A productWithNameShouldNotBeAdded() 0 9 1
A iRemoveItsNameFromTranslation() 0 9 1
A thisProductShouldHaveOption() 0 4 1
A theOptionFieldShouldBeDisabled() 0 7 1
A iChooseMainTaxon() 0 9 1
A productSlugShouldBe() 0 9 1
A thisProductMainTaxonShouldBe() 0 15 1
A thisProductShouldNotBeTracked() 0 9 1
A thisProductShouldBeTracked() 0 9 1
A iAttachImageWithACode() 0 12 2
A iAttachImageWithoutACode() 0 10 1
A thisProductShouldHaveAnImageWithCode() 0 15 1
A thisProductShouldNotHaveAnImageWithCode() 0 13 1
A iChangeItsImageToPathForTheCode() 0 10 1
A iRemoveAnImageWithACode() 0 10 1
A iRemoveTheFirstImage() 0 10 1
A thisProductShouldNotHaveImages() 0 16 1
A theImageCodeFieldShouldBeDisabled() 0 13 1
A iShouldBeNotifiedThatTheImageWithThisCodeAlreadyExists() 0 4 1
A iShouldBeNotifiedThatAnImageCodeIsRequired() 0 13 1
A thereShouldStillBeOnlyOneImageInThisTaxon() 0 16 1
A thereAreNoProductReviews() 0 9 1
A assertElementValue() 0 17 1
A assertValidationMessage() 0 14 2

How to fix   Complexity   

Complex Class

Complex classes like ManagingProductsContext often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ManagingProductsContext, and based on these observations, apply Extract Interface, too.

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\Admin;
13
14
use Behat\Behat\Context\Context;
15
use Sylius\Behat\NotificationType;
16
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
17
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
18
use Sylius\Behat\Page\Admin\Product\CreateConfigurableProductPageInterface;
19
use Sylius\Behat\Page\Admin\Product\CreateSimpleProductPageInterface;
20
use Sylius\Behat\Page\Admin\Product\IndexPageInterface;
21
use Sylius\Behat\Page\Admin\Product\UpdateConfigurableProductPageInterface;
22
use Sylius\Behat\Page\Admin\Product\UpdateSimpleProductPageInterface;
23
use Sylius\Behat\Page\Admin\ProductReview\IndexPageInterface as ProductReviewIndexPageInterface;
24
use Sylius\Behat\Service\NotificationCheckerInterface;
25
use Sylius\Behat\Service\Resolver\CurrentProductPageResolverInterface;
26
use Sylius\Component\Core\Model\ProductInterface;
27
use Sylius\Behat\Service\SharedStorageInterface;
28
use Sylius\Component\Taxonomy\Model\TaxonInterface;
29
use Webmozart\Assert\Assert;
30
31
/**
32
 * @author Kamil Kokot <[email protected]>
33
 * @author Magdalena Banasiak <[email protected]>
34
 * @author Łukasz Chruściel <[email protected]>
35
 */
36
final class ManagingProductsContext implements Context
37
{
38
    /**
39
     * @var SharedStorageInterface
40
     */
41
    private $sharedStorage;
42
43
    /**x
44
     * @var CreateSimpleProductPageInterface
45
     */
46
    private $createSimpleProductPage;
47
48
    /**
49
     * @var CreateConfigurableProductPageInterface
50
     */
51
    private $createConfigurableProductPage;
52
53
    /**
54
     * @var IndexPageInterface
55
     */
56
    private $indexPage;
57
58
    /**
59
     * @var UpdateSimpleProductPageInterface
60
     */
61
    private $updateSimpleProductPage;
62
63
    /**
64
     * @var UpdateConfigurableProductPageInterface
65
     */
66
    private $updateConfigurableProductPage;
67
68
    /**
69
     * @var ProductReviewIndexPageInterface
70
     */
71
    private $productReviewIndexPage;
72
73
    /**
74
     * @var CurrentProductPageResolverInterface
75
     */
76
    private $currentPageResolver;
77
78
    /**
79
     * @var NotificationCheckerInterface
80
     */
81
    private $notificationChecker;
82
83
    /**
84
     * @param SharedStorageInterface $sharedStorage
85
     * @param CreateSimpleProductPageInterface $createSimpleProductPage
86
     * @param CreateConfigurableProductPageInterface $createConfigurableProductPage
87
     * @param IndexPageInterface $indexPage
88
     * @param UpdateSimpleProductPageInterface $updateSimpleProductPage
89
     * @param UpdateConfigurableProductPageInterface $updateConfigurableProductPage
90
     * @param ProductReviewIndexPageInterface $productReviewIndexPage
91
     * @param CurrentProductPageResolverInterface $currentPageResolver
92
     * @param NotificationCheckerInterface $notificationChecker
93
     */
94
    public function __construct(
95
        SharedStorageInterface $sharedStorage,
96
        CreateSimpleProductPageInterface $createSimpleProductPage,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $createSimpleProductPage exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
97
        CreateConfigurableProductPageInterface $createConfigurableProductPage,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $createConfigurableProductPage exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
98
        IndexPageInterface $indexPage,
99
        UpdateSimpleProductPageInterface $updateSimpleProductPage,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $updateSimpleProductPage exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
100
        UpdateConfigurableProductPageInterface $updateConfigurableProductPage,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $updateConfigurableProductPage exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
101
        ProductReviewIndexPageInterface $productReviewIndexPage,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $productReviewIndexPage exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
102
        CurrentProductPageResolverInterface $currentPageResolver,
103
        NotificationCheckerInterface $notificationChecker
104
    ) {
105
        $this->sharedStorage = $sharedStorage;
106
        $this->createSimpleProductPage = $createSimpleProductPage;
107
        $this->createConfigurableProductPage = $createConfigurableProductPage;
108
        $this->indexPage = $indexPage;
109
        $this->updateSimpleProductPage = $updateSimpleProductPage;
110
        $this->updateConfigurableProductPage = $updateConfigurableProductPage;
111
        $this->productReviewIndexPage = $productReviewIndexPage;
112
        $this->currentPageResolver = $currentPageResolver;
113
        $this->notificationChecker = $notificationChecker;
114
    }
115
116
    /**
117
     * @Given I want to create a new simple product
118
     */
119
    public function iWantToCreateANewSimpleProduct()
120
    {
121
        $this->createSimpleProductPage->open();
122
    }
123
124
    /**
125
     * @Given I want to create a new configurable product
126
     */
127
    public function iWantToCreateANewConfigurableProduct()
128
    {
129
        $this->createConfigurableProductPage->open();
130
    }
131
132
    /**
133
     * @When I specify its code as :code
134
     * @When I do not specify its code
135
     */
136
    public function iSpecifyItsCodeAs($code = null)
137
    {
138
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
139
            $this->createSimpleProductPage,
140
            $this->createConfigurableProductPage,
141
        ]);
142
143
        $currentPage->specifyCode($code);
144
    }
145
146
    /**
147
     * @When I name it :name in :language
148
     */
149
    public function iNameItIn($name, $language)
150
    {
151
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
152
            $this->createSimpleProductPage,
153
            $this->createConfigurableProductPage,
154
        ]);
155
156
        $currentPage->nameItIn($name, $language);
157
    }
158
159
    /**
160
     * @When I rename it to :name in :language
161
     */
162
    public function iRenameItToIn($name, $language)
163
    {
164
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
165
            $this->updateSimpleProductPage,
166
            $this->updateConfigurableProductPage,
167
        ], $this->sharedStorage->get('product'));
168
169
        $currentPage->nameItIn($name, $language);
170
    }
171
172
    /**
173
     * @When I add it
174
     * @When I try to add it
175
     */
176
    public function iAddIt()
177
    {
178
        /** @var CreatePageInterface $currentPage */
179
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
180
            $this->createSimpleProductPage,
181
            $this->createConfigurableProductPage,
182
        ]);
183
184
        Assert::isInstanceOf($currentPage, CreatePageInterface::class);
185
186
        $currentPage->create();
187
    }
188
189
    /**
190
     * @When I disable its inventory tracking
191
     */
192
    public function iDisableItsTracking()
193
    {
194
        $this->updateSimpleProductPage->disableTracking();
195
    }
196
197
    /**
198
     * @When I enable its inventory tracking
199
     */
200
    public function iEnableItsTracking()
201
    {
202
        $this->updateSimpleProductPage->enableTracking();
203
    }
204
205
    /**
206
     * @When /^I set its price to ("(?:€|£|\$)[^"]+")$/
207
     */
208
    public function iSetItsPriceTo($price)
209
    {
210
        $this->createSimpleProductPage->specifyPrice($price);
211
    }
212
213
    /**
214
     * @When I set its slug to :slug
215
     * @When I remove its slug
216
     */
217
    public function iSetItsSlugTo($slug = null)
218
    {
219
        $this->createSimpleProductPage->specifySlug($slug);
220
    }
221
222
    /**
223
     * @When I enable slug modification
224
     */
225
    public function iEnableSlugModification()
226
    {
227
        $this->createSimpleProductPage->enableSlugModification();
228
    }
229
230
    /**
231
     * @Then the product :productName should appear in the shop
232
     * @Then the product :productName should be in the shop
233
     * @Then this product should still be named :productName
234
     */
235
    public function theProductShouldAppearInTheShop($productName)
236
    {
237
        $this->iWantToBrowseProducts();
238
239
        Assert::true(
240
            $this->indexPage->isSingleResourceOnPage(['name' => $productName]),
241
            sprintf('The product with name %s has not been found.', $productName)
242
        );
243
    }
244
245
    /**
246
     * @Given I am browsing products
247
     * @When I want to browse products
248
     */
249
    public function iWantToBrowseProducts()
250
    {
251
        $this->indexPage->open();
252
    }
253
254
    /**
255
     * @When I filter them by :taxonName taxon
256
     */
257
    public function iFilterThemByTaxon($taxonName)
258
    {
259
        $this->indexPage->filterByTaxon($taxonName);
260
    }
261
262
    /**
263
     * @Then I should( still) see a product with :field :value
264
     */
265
    public function iShouldSeeProductWith($field, $value)
266
    {
267
        Assert::true(
268
            $this->indexPage->isSingleResourceOnPage([$field => $value]),
269
            sprintf('The product with %s "%s" has not been found.', $field, $value)
270
        );
271
    }
272
273
    /**
274
     * @Then I should not see any product with :field :value
275
     */
276
    public function iShouldNotSeeAnyProductWith($field, $value)
277
    {
278
        Assert::false(
279
            $this->indexPage->isSingleResourceOnPage([$field => $value]),
280
            sprintf('The product with %s "%s" has been found.', $field, $value)
281
        );
282
    }
283
284
    /**
285
     * @Then the first product on the list should have :field :value
286
     */
287
    public function theFirstProductOnTheListShouldHave($field, $value)
288
    {
289
        $actualValue = $this->indexPage->getColumnFields($field)[0];
290
291
        Assert::same(
292
            $actualValue,
293
            $value,
294
            sprintf('Expected first product\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
295
        );
296
    }
297
298
    /**
299
     * @When I switch the way products are sorted by :field
300
     * @When I start sorting products by :field
301
     * @Given the products are already sorted by :field
302
     */
303
    public function iSortProductsBy($field)
304
    {
305
        $this->indexPage->sortBy($field);
306
    }
307
308
    /**
309
     * @Then I should see :numberOfProducts products in the list
310
     */
311
    public function iShouldSeeProductsInTheList($numberOfProducts)
312
    {
313
        $foundRows = $this->indexPage->countItems();
314
315
        Assert::same(
316
            (int) $numberOfProducts,
317
            $foundRows,
318
            '%s rows with products should appear on page, %s rows has been found'
319
        );
320
    }
321
322
    /**
323
     * @When I delete the :product product
324
     * @When I try to delete the :product product
325
     */
326
    public function iDeleteProduct(ProductInterface $product)
327
    {
328
        $this->sharedStorage->set('product', $product);
329
330
        $this->iWantToBrowseProducts();
331
        $this->indexPage->deleteResourceOnPage(['name' => $product->getName()]);
332
    }
333
334
    /**
335
     * @Then /^(this product) should not exist in the product catalog$/
336
     */
337
    public function productShouldNotExist(ProductInterface $product)
338
    {
339
        $this->iWantToBrowseProducts();
340
341
        Assert::false(
342
            $this->indexPage->isSingleResourceOnPage(['code' => $product->getCode()]),
343
            sprintf('Product with code %s exists but should not.', $product->getCode())
344
        );
345
    }
346
347
    /**
348
     * @Then I should be notified that this product is in use and cannot be deleted
349
     */
350
    public function iShouldBeNotifiedOfFailure()
351
    {
352
        $this->notificationChecker->checkNotification(
353
            "Cannot delete, the product is in use.",
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal Cannot delete, the product is in use. 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...
354
            NotificationType::failure()
355
        );
356
    }
357
358
    /**
359
     * @Then /^(this product) should still exist in the product catalog$/
360
     */
361
    public function productShouldExistInTheProductCatalog(ProductInterface $product)
362
    {
363
        $this->theProductShouldAppearInTheShop($product->getName());
364
    }
365
366
    /**
367
     * @When I want to modify the :product product
368
     * @When /^I want to modify (this product)$/
369
     */
370
    public function iWantToModifyAProduct(ProductInterface $product)
371
    {
372
        $this->sharedStorage->set('product', $product);
373
374
        if ($product->isSimple()) {
375
            $this->updateSimpleProductPage->open(['id' => $product->getId()]);
376
            return;
377
        }
378
379
        $this->updateConfigurableProductPage->open(['id' => $product->getId()]);
380
    }
381
382
    /**
383
     * @Then the code field should be disabled
384
     */
385
    public function theCodeFieldShouldBeDisabled()
386
    {
387
        /** @var UpdatePageInterface $currentPage */
388
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
389
            $this->updateSimpleProductPage,
390
            $this->updateConfigurableProductPage,
391
        ], $this->sharedStorage->get('product'));
392
393
        Assert::true(
394
            $currentPage->isCodeDisabled(),
395
            'Code should be immutable, but it does not.'
396
        );
397
    }
398
399
    /**
400
     * @Then the slug field should not be editable
401
     */
402
    public function theSlugFieldShouldNotBeEditable()
403
    {
404
        Assert::true(
405
            $this->updateSimpleProductPage->isSlugReadOnly(),
406
            'Slug should be immutable, but it does not.'
407
        );
408
    }
409
410
    /**
411
     * @Then /^this product price should be "(?:€|£|\$)([^"]+)"$/
412
     */
413
    public function thisProductPriceShouldBeEqualTo($price)
414
    {
415
        $this->assertElementValue('price', $price);
416
    }
417
418
    /**
419
     * @Then this product name should be :name
420
     */
421
    public function thisProductElementShouldBe($name)
422
    {
423
        $this->assertElementValue('name', $name);
424
    }
425
426
    /**
427
     * @Then /^I should be notified that (code|name|slug) is required$/
428
     */
429
    public function iShouldBeNotifiedThatIsRequired($element)
430
    {
431
        $this->assertValidationMessage($element, sprintf('Please enter product %s.', $element));
432
    }
433
434
    /**
435
     * @Then I should be notified that price is required
436
     */
437
    public function iShouldBeNotifiedThatPriceIsRequired()
438
    {
439
        $this->assertValidationMessage('price', 'Please enter the price.');
440
    }
441
442
    /**
443
     * @When I save my changes
444
     * @When I try to save my changes
445
     */
446
    public function iSaveMyChanges()
447
    {
448
        /** @var UpdatePageInterface $currentPage */
449
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
450
            $this->updateSimpleProductPage,
451
            $this->updateConfigurableProductPage,
452
        ], $this->sharedStorage->get('product'));
453
454
        Assert::isInstanceOf($currentPage, UpdatePageInterface::class);
455
456
        $currentPage->saveChanges();
457
    }
458
459
    /**
460
     * @When /^I change its price to "(?:€|£|\$)([^"]+)"$/
461
     */
462
    public function iChangeItsPriceTo($price)
463
    {
464
        $this->updateSimpleProductPage->specifyPrice($price);
465
    }
466
467
    /**
468
     * @Given I add the :optionName option to it
469
     */
470
    public function iAddTheOptionToIt($optionName)
471
    {
472
        $this->createConfigurableProductPage->selectOption($optionName);
473
    }
474
475
    /**
476
     * @When I set its :attribute attribute to :value
477
     */
478
    public function iSetItsAttributeTo($attribute, $value)
479
    {
480
        $this->createSimpleProductPage->addAttribute($attribute, $value);
481
    }
482
483
    /**
484
     * @When I remove its :attribute attribute
485
     */
486
    public function iRemoveItsAttribute($attribute)
487
    {
488
        $this->createSimpleProductPage->removeAttribute($attribute);
489
    }
490
491
    /**
492
     * @Then /^attribute "([^"]+)" of (product "[^"]+") should be "([^"]+)"$/
493
     */
494
    public function itsAttributeShouldBe($attribute, ProductInterface $product, $value)
495
    {
496
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
497
498
        Assert::same(
499
            $value,
500
            $this->updateSimpleProductPage->getAttributeValue($attribute),
501
            sprintf('ProductAttribute "%s" should have value "%s" but it does not.', $attribute, $value)
502
        );
503
    }
504
505
    /**
506
     * @Then /^(product "[^"]+") should not have a "([^"]+)" attribute$/
507
     */
508
    public function productShouldNotHaveAttribute(ProductInterface $product, $attribute)
509
    {
510
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
511
512
        Assert::false(
513
            $this->updateSimpleProductPage->hasAttribute($attribute),
514
            sprintf('Product "%s" should not have attribute "%s" but it does.', $product->getName(), $attribute)
515
        );
516
    }
517
518
    /**
519
     * @Given product with :element :value should not be added
520
     */
521
    public function productWithNameShouldNotBeAdded($element, $value)
522
    {
523
        $this->iWantToBrowseProducts();
524
525
        Assert::false(
526
            $this->indexPage->isSingleResourceOnPage([$element => $value]),
527
            sprintf('Product with %s %s was created, but it should not.', $element, $value)
528
        );
529
    }
530
531
    /**
532
     * @When I remove its name from :language translation
533
     */
534
    public function iRemoveItsNameFromTranslation($language)
535
    {
536
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
537
            $this->updateSimpleProductPage,
538
            $this->updateConfigurableProductPage,
539
        ], $this->sharedStorage->get('product'));
540
541
        $currentPage->nameItIn('', $language);
542
    }
543
544
    /**
545
     * @Then /^this product should have (?:a|an) "([^"]+)" option$/
546
     */
547
    public function thisProductShouldHaveOption($productOption)
548
    {
549
        $this->updateConfigurableProductPage->isProductOptionChosen($productOption);
550
    }
551
552
    /**
553
     * @Then the option field should be disabled
554
     */
555
    public function theOptionFieldShouldBeDisabled()
556
    {
557
        Assert::true(
558
            $this->updateConfigurableProductPage->isProductOptionsDisabled(),
559
            'Options field should be immutable, but it does not.'
560
        );
561
    }
562
563
    /**
564
     * @When /^I choose main (taxon "([^"]+)")$/
565
     */
566
    public function iChooseMainTaxon(TaxonInterface $taxon)
567
    {
568
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
569
            $this->updateSimpleProductPage,
570
            $this->updateConfigurableProductPage,
571
        ], $this->sharedStorage->get('product'));
572
573
        $currentPage->selectMainTaxon($taxon);
574
    }
575
576
    /**
577
     * @Then /^the slug of the ("[^"]+" product) should(?:| still) be "([^"]+)"$/
578
     */
579
    public function productSlugShouldBe(ProductInterface $product, $slug)
580
    {
581
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
582
583
        Assert::true(
584
            $this->updateSimpleProductPage->hasResourceValues(['slug' => $slug]),
585
            sprintf('Product\'s slug should be %s.', $slug)
586
        );
587
    }
588
589
    /**
590
     * @Then /^(this product) main taxon should be "([^"]+)"$/
591
     */
592
    public function thisProductMainTaxonShouldBe(ProductInterface $product, $taxonName)
593
    {
594
        /** @var UpdatePageInterface $currentPage */
595
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
596
            $this->updateSimpleProductPage,
597
            $this->updateConfigurableProductPage,
598
        ], $this->sharedStorage->get('product'));
599
600
        $currentPage->open(['id' => $product->getId()]);
601
602
        Assert::true(
603
            $this->updateConfigurableProductPage->isMainTaxonChosen($taxonName),
604
            sprintf('The main taxon %s should be chosen, but it does not.', $taxonName)
605
        );
606
    }
607
608
    /**
609
     * @Then /^inventory of (this product) should not be tracked$/
610
     */
611
    public function thisProductShouldNotBeTracked(ProductInterface $product)
612
    {
613
        $this->iWantToModifyAProduct($product);
614
615
        Assert::false(
616
            $this->updateSimpleProductPage->isTracked(),
617
            '"%s" should not be tracked, but it is.'
618
        );
619
    }
620
621
    /**
622
     * @Then /^inventory of (this product) should be tracked$/
623
     */
624
    public function thisProductShouldBeTracked(ProductInterface $product)
625
    {
626
        $this->iWantToModifyAProduct($product);
627
628
        Assert::true(
629
            $this->updateSimpleProductPage->isTracked(),
630
            '"%s" should be tracked, but it is not.'
631
        );
632
    }
633
634
    /**
635
     * @When I attach the :path image with a code :code
636
     */
637
    public function iAttachImageWithACode($path, $code)
638
    {
639
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
640
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
641
            $this->createSimpleProductPage,
642
            $this->createConfigurableProductPage,
643
            $this->updateSimpleProductPage,
644
            $this->updateConfigurableProductPage,
645
        ], $this->sharedStorage->has('product') ? $this->sharedStorage->get('product') : null);
646
647
        $currentPage->attachImage($path, $code);
648
    }
649
650
    /**
651
     * @When I attach the :path image without a code
652
     */
653
    public function iAttachImageWithoutACode($path)
654
    {
655
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
656
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
657
            $this->updateSimpleProductPage,
658
            $this->updateConfigurableProductPage,
659
        ], $this->sharedStorage->get('product'));
660
661
        $currentPage->attachImage($path);
662
    }
663
664
    /**
665
     * @Then /^(this product) should have(?:| also) an image with a code "([^"]*)"$/
666
     * @Then /^the (product "[^"]+") should have(?:| also) an image with a code "([^"]*)"$/
667
     */
668
    public function thisProductShouldHaveAnImageWithCode(ProductInterface $product, $code)
669
    {
670
        $this->sharedStorage->set('product', $product);
671
672
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
673
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
674
            $this->updateSimpleProductPage,
675
            $this->updateConfigurableProductPage,
676
        ], $product);
677
678
        Assert::true(
679
            $currentPage->isImageWithCodeDisplayed($code),
680
            sprintf('Image with a code %s should have been displayed.', $code)
681
        );
682
    }
683
684
    /**
685
     * @Then /^(this product) should not have(?:| also) an image with a code "([^"]*)"$/
686
     */
687
    public function thisProductShouldNotHaveAnImageWithCode(ProductInterface $product, $code)
688
    {
689
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
690
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
691
            $this->updateSimpleProductPage,
692
            $this->updateConfigurableProductPage,
693
        ], $product);
694
695
        Assert::false(
696
            $currentPage->isImageWithCodeDisplayed($code),
697
            sprintf('Image with a code %s should not have been displayed.', $code)
698
        );
699
    }
700
701
    /**
702
     * @When I change the image with the :code code to :path
703
     */
704
    public function iChangeItsImageToPathForTheCode($path, $code)
705
    {
706
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
707
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
708
            $this->updateSimpleProductPage,
709
            $this->updateConfigurableProductPage,
710
        ], $this->sharedStorage->get('product'));
711
712
        $currentPage->changeImageWithCode($code, $path);
713
    }
714
715
    /**
716
     * @When /^I remove(?:| also) an image with a code "([^"]*)"$/
717
     */
718
    public function iRemoveAnImageWithACode($code)
719
    {
720
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
721
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
722
            $this->updateSimpleProductPage,
723
            $this->updateConfigurableProductPage,
724
        ], $this->sharedStorage->get('product'));
725
726
        $currentPage->removeImageWithCode($code);
727
    }
728
729
    /**
730
     * @When I remove the first image
731
     */
732
    public function iRemoveTheFirstImage()
733
    {
734
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
735
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
736
            $this->updateSimpleProductPage,
737
            $this->updateConfigurableProductPage,
738
        ], $this->sharedStorage->get('product'));
739
740
        $currentPage->removeFirstImage();
741
    }
742
743
    /**
744
     * @Then /^(this product) should not have any images$/
745
     */
746
    public function thisProductShouldNotHaveImages(ProductInterface $product)
747
    {
748
        $this->iWantToModifyAProduct($product);
749
750
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
751
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
752
            $this->updateSimpleProductPage,
753
            $this->updateConfigurableProductPage,
754
        ], $this->sharedStorage->get('product'));
755
756
        Assert::same(
757
            0,
758
            $currentPage->countImages(),
759
            'This product has %2$s, but it should not have.'
760
        );
761
    }
762
763
    /**
764
     * @Then the image code field should be disabled
765
     */
766
    public function theImageCodeFieldShouldBeDisabled()
767
    {
768
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
769
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
770
            $this->updateSimpleProductPage,
771
            $this->updateConfigurableProductPage,
772
        ], $this->sharedStorage->get('product'));
773
774
        Assert::true(
775
            $currentPage->isImageCodeDisabled(),
776
            'Image code field should be disabled but it is not.'
777
        );
778
    }
779
780
    /**
781
     * @Then I should be notified that the image with this code already exists
782
     */
783
    public function iShouldBeNotifiedThatTheImageWithThisCodeAlreadyExists()
784
    {
785
        Assert::same($this->updateSimpleProductPage->getValidationMessageForImage('code'), 'Image code must be unique within this product.');
0 ignored issues
show
Unused Code introduced by
The call to UpdateSimpleProductPageI...dationMessageForImage() has too many arguments starting with 'code'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
786
    }
787
788
    /**
789
     * @Then I should be notified that an image code is required
790
     */
791
    public function iShouldBeNotifiedThatAnImageCodeIsRequired()
792
    {
793
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
794
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
795
            $this->updateSimpleProductPage,
796
            $this->updateConfigurableProductPage,
797
        ], $this->sharedStorage->get('product'));
798
799
        Assert::same(
800
            $currentPage->getValidationMessageForImage(),
801
            'Please enter an image code.'
802
        );
803
    }
804
805
    /**
806
     * @Then there should still be only one image in the :product product
807
     */
808
    public function thereShouldStillBeOnlyOneImageInThisTaxon(ProductInterface $product)
809
    {
810
        $this->iWantToModifyAProduct($product);
811
812
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
813
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
814
            $this->updateSimpleProductPage,
815
            $this->updateConfigurableProductPage,
816
        ], $product);
817
818
        Assert::same(
819
            1,
820
            $currentPage->countImages(),
821
            'This product has %2$s images, but it should have only one.'
822
        );
823
    }
824
825
    /**
826
     * @Then /^there should be no reviews of (this product)$/
827
     */
828
    public function thereAreNoProductReviews(ProductInterface $product)
829
    {
830
        $this->productReviewIndexPage->open();
831
832
        Assert::false(
833
            $this->productReviewIndexPage->isSingleResourceOnPage(['reviewSubject' => $product->getName()]),
834
            sprintf('There should be no reviews of %s.', $product->getName())
835
        );
836
    }
837
838
    /**
839
     * @param string $element
840
     * @param string $value
841
     */
842
    private function assertElementValue($element, $value)
843
    {
844
        /** @var UpdatePageInterface $currentPage */
845
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
846
            $this->updateSimpleProductPage,
847
            $this->updateConfigurableProductPage,
848
        ], $this->sharedStorage->get('product'));
849
850
        Assert::isInstanceOf($currentPage, UpdatePageInterface::class);
851
852
        Assert::true(
853
            $currentPage->hasResourceValues(
854
                [$element => $value]
855
            ),
856
            sprintf('Product should have %s with %s value.', $element, $value)
857
        );
858
    }
859
860
    /**
861
     * @param string $element
862
     * @param string $message
863
     */
864
    private function assertValidationMessage($element, $message)
865
    {
866
        $product = $this->sharedStorage->has('product') ? $this->sharedStorage->get('product') : null;
867
868
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
869
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([
870
            $this->createSimpleProductPage,
871
            $this->createConfigurableProductPage,
872
            $this->updateSimpleProductPage,
873
            $this->updateConfigurableProductPage,
874
        ], $product);
875
876
        Assert::same($currentPage->getValidationMessage($element), $message);
877
    }
878
}
879