Completed
Push — assert-overflow ( bc734e )
by Kamil
19:55
created

ManagingProductsContext::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
cc 1
eloc 21
nc 1
nop 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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 Behat\Mink\Exception\ElementNotFoundException;
16
use Sylius\Behat\NotificationType;
17
use Sylius\Behat\Page\Admin\Crud\CreatePageInterface;
18
use Sylius\Behat\Page\Admin\Crud\UpdatePageInterface;
19
use Sylius\Behat\Page\Admin\Product\CreateConfigurableProductPageInterface;
20
use Sylius\Behat\Page\Admin\Product\CreateSimpleProductPageInterface;
21
use Sylius\Behat\Page\Admin\Product\IndexPageInterface;
22
use Sylius\Behat\Page\Admin\Product\IndexPerTaxonPageInterface;
23
use Sylius\Behat\Page\Admin\Product\UpdateConfigurableProductPageInterface;
24
use Sylius\Behat\Page\Admin\Product\UpdateSimpleProductPageInterface;
25
use Sylius\Behat\Page\Admin\ProductReview\IndexPageInterface as ProductReviewIndexPageInterface;
26
use Sylius\Behat\Page\SymfonyPageInterface;
27
use Sylius\Behat\Service\NotificationCheckerInterface;
28
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
29
use Sylius\Behat\Service\SharedStorageInterface;
30
use Sylius\Component\Core\Model\ProductInterface;
31
use Sylius\Component\Product\Model\ProductAssociationTypeInterface;
32
use Sylius\Component\Taxonomy\Model\TaxonInterface;
33
use Webmozart\Assert\Assert;
34
35
/**
36
 * @author Kamil Kokot <[email protected]>
37
 * @author Magdalena Banasiak <[email protected]>
38
 * @author Łukasz Chruściel <[email protected]>
39
 */
40
final class ManagingProductsContext implements Context
41
{
42
    /**
43
     * @var SharedStorageInterface
44
     */
45
    private $sharedStorage;
46
47
    /**x
48
     * @var CreateSimpleProductPageInterface
49
     */
50
    private $createSimpleProductPage;
51
52
    /**
53
     * @var CreateConfigurableProductPageInterface
54
     */
55
    private $createConfigurableProductPage;
56
57
    /**
58
     * @var IndexPageInterface
59
     */
60
    private $indexPage;
61
62
    /**
63
     * @var UpdateSimpleProductPageInterface
64
     */
65
    private $updateSimpleProductPage;
66
67
    /**
68
     * @var UpdateConfigurableProductPageInterface
69
     */
70
    private $updateConfigurableProductPage;
71
72
    /**
73
     * @var ProductReviewIndexPageInterface
74
     */
75
    private $productReviewIndexPage;
76
77
    /**
78
     * @var IndexPerTaxonPageInterface
79
     */
80
    private $indexPerTaxonPage;
81
82
    /**
83
     * @var CurrentPageResolverInterface
84
     */
85
    private $currentPageResolver;
86
87
    /**
88
     * @var NotificationCheckerInterface
89
     */
90
    private $notificationChecker;
91
92
    /**
93
     * @param SharedStorageInterface $sharedStorage
94
     * @param CreateSimpleProductPageInterface $createSimpleProductPage
95
     * @param CreateConfigurableProductPageInterface $createConfigurableProductPage
96
     * @param IndexPageInterface $indexPage
97
     * @param UpdateSimpleProductPageInterface $updateSimpleProductPage
98
     * @param UpdateConfigurableProductPageInterface $updateConfigurableProductPage
99
     * @param ProductReviewIndexPageInterface $productReviewIndexPage
100
     * @param IndexPerTaxonPageInterface $indexPerTaxonPage
101
     * @param CurrentPageResolverInterface $currentPageResolver
102
     * @param NotificationCheckerInterface $notificationChecker
103
     */
104
    public function __construct(
105
        SharedStorageInterface $sharedStorage,
106
        CreateSimpleProductPageInterface $createSimpleProductPage,
107
        CreateConfigurableProductPageInterface $createConfigurableProductPage,
108
        IndexPageInterface $indexPage,
109
        UpdateSimpleProductPageInterface $updateSimpleProductPage,
110
        UpdateConfigurableProductPageInterface $updateConfigurableProductPage,
111
        ProductReviewIndexPageInterface $productReviewIndexPage,
112
        IndexPerTaxonPageInterface $indexPerTaxonPage,
113
        CurrentPageResolverInterface $currentPageResolver,
114
        NotificationCheckerInterface $notificationChecker
115
    ) {
116
        $this->sharedStorage = $sharedStorage;
117
        $this->createSimpleProductPage = $createSimpleProductPage;
118
        $this->createConfigurableProductPage = $createConfigurableProductPage;
119
        $this->indexPage = $indexPage;
120
        $this->updateSimpleProductPage = $updateSimpleProductPage;
121
        $this->updateConfigurableProductPage = $updateConfigurableProductPage;
122
        $this->productReviewIndexPage = $productReviewIndexPage;
123
        $this->indexPerTaxonPage = $indexPerTaxonPage;
124
        $this->currentPageResolver = $currentPageResolver;
125
        $this->notificationChecker = $notificationChecker;
126
    }
127
128
    /**
129
     * @Given I want to create a new simple product
130
     */
131
    public function iWantToCreateANewSimpleProduct()
132
    {
133
        $this->createSimpleProductPage->open();
134
    }
135
136
    /**
137
     * @Given I want to create a new configurable product
138
     */
139
    public function iWantToCreateANewConfigurableProduct()
140
    {
141
        $this->createConfigurableProductPage->open();
142
    }
143
144
    /**
145
     * @When I specify its code as :code
146
     * @When I do not specify its code
147
     */
148
    public function iSpecifyItsCodeAs($code = null)
149
    {
150
        $currentPage = $this->resolveCurrentPage();
151
152
        $currentPage->specifyCode($code);
153
    }
154
155
    /**
156
     * @When I name it :name in :language
157
     * @When I rename it to :name in :language
158
     */
159
    public function iRenameItToIn($name, $language)
160
    {
161
        $currentPage = $this->resolveCurrentPage();
162
163
        $currentPage->nameItIn($name, $language);
164
    }
165
166
    /**
167
     * @When I add it
168
     * @When I try to add it
169
     */
170
    public function iAddIt()
171
    {
172
        /** @var CreatePageInterface $currentPage */
173
        $currentPage = $this->resolveCurrentPage();
174
175
        $currentPage->create();
176
    }
177
178
    /**
179
     * @When I disable its inventory tracking
180
     */
181
    public function iDisableItsTracking()
182
    {
183
        $this->updateSimpleProductPage->disableTracking();
184
    }
185
186
    /**
187
     * @When I enable its inventory tracking
188
     */
189
    public function iEnableItsTracking()
190
    {
191
        $this->updateSimpleProductPage->enableTracking();
192
    }
193
194
    /**
195
     * @When /^I set its(?:| default) price to "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
196
     */
197
    public function iSetItsPriceTo($price, $channelName)
198
    {
199
        $this->createSimpleProductPage->specifyPrice($channelName, $price);
200
    }
201
202
    /**
203
     * @When I make it available in channel :channel
204
     */
205
    public function iMakeItAvailableInChannel($channel)
206
    {
207
        $this->createSimpleProductPage->checkChannel($channel);
208
    }
209
210
    /**
211
     * @When I assign it to channel :channel
212
     */
213
    public function iAssignItToChannel($channel)
214
    {
215
        // Temporary solution until we will make current page resolver work with product pages
216
        $this->updateConfigurableProductPage->checkChannel($channel);
217
    }
218
219
    /**
220
     * @When I choose :calculatorName calculator
221
     */
222
    public function iChooseCalculator($calculatorName)
223
    {
224
        $this->createSimpleProductPage->choosePricingCalculator($calculatorName);
225
    }
226
227
    /**
228
     * @When I set its slug to :slug
229
     * @When I set its slug to :slug in :language
230
     * @When I remove its slug
231
     */
232
    public function iSetItsSlugToIn($slug = null, $language = 'en_US')
233
    {
234
        $this->createSimpleProductPage->specifySlugIn($slug, $language);
235
    }
236
237
    /**
238
     * @When I enable slug modification
239
     * @When I enable slug modification in :localeCode
240
     */
241
    public function iEnableSlugModification($localeCode = 'en_US')
242
    {
243
        $this->updateSimpleProductPage->activateLanguageTab($localeCode);
244
        $this->updateSimpleProductPage->enableSlugModification($localeCode);
245
    }
246
247
    /**
248
     * @Then the product :productName should appear in the store
249
     * @Then the product :productName should be in the shop
250
     * @Then this product should still be named :productName
251
     */
252
    public function theProductShouldAppearInTheShop($productName)
253
    {
254
        $this->iWantToBrowseProducts();
255
256
        Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $productName]));
257
    }
258
259
    /**
260
     * @Given I am browsing products
261
     * @When I want to browse products
262
     */
263
    public function iWantToBrowseProducts()
264
    {
265
        $this->indexPage->open();
266
    }
267
268
    /**
269
     * @When /^I am browsing products from ("([^"]+)" taxon)$/
270
     */
271
    public function iAmBrowsingProductsFromTaxon(TaxonInterface $taxon)
272
    {
273
        $this->indexPerTaxonPage->open(['taxonId' => $taxon->getId()]);
274
    }
275
276
    /**
277
     * @When I filter them by :taxonName taxon
278
     */
279
    public function iFilterThemByTaxon($taxonName)
280
    {
281
        $this->indexPage->filterByTaxon($taxonName);
282
    }
283
284
    /**
285
     * @Then I should( still) see a product with :field :value
286
     */
287
    public function iShouldSeeProductWith($field, $value)
288
    {
289
        Assert::true($this->indexPage->isSingleResourceOnPage([$field => $value]));
290
    }
291
292
    /**
293
     * @Then I should not see any product with :field :value
294
     */
295
    public function iShouldNotSeeAnyProductWith($field, $value)
296
    {
297
        Assert::false($this->indexPage->isSingleResourceOnPage([$field => $value]));
298
    }
299
300
    /**
301
     * @Then the first product on the list should have :field :value
302
     */
303
    public function theFirstProductOnTheListShouldHave($field, $value)
304
    {
305
        $currentPage = $this->resolveCurrentPage();
306
307
        Assert::same($currentPage->getColumnFields($field)[0], $value);
308
    }
309
310
    /**
311
     * @Then the last product on the list should have :field :value
312
     */
313
    public function theLastProductOnTheListShouldHave($field, $value)
314
    {
315
        $values = $this->indexPerTaxonPage->getColumnFields($field);
316
317
        Assert::same(end($values), $value);
318
    }
319
320
    /**
321
     * @When I switch the way products are sorted by :field
322
     * @When I start sorting products by :field
323
     * @Given the products are already sorted by :field
324
     */
325
    public function iSortProductsBy($field)
326
    {
327
        $this->indexPage->sortBy($field);
328
    }
329
330
    /**
331
     * @Then I should see :numberOfProducts products in the list
332
     */
333
    public function iShouldSeeProductsInTheList($numberOfProducts)
334
    {
335
        Assert::same($this->indexPage->countItems(), (int) $numberOfProducts);
336
    }
337
338
    /**
339
     * @When I delete the :product product
340
     * @When I try to delete the :product product
341
     */
342
    public function iDeleteProduct(ProductInterface $product)
343
    {
344
        $this->sharedStorage->set('product', $product);
345
346
        $this->iWantToBrowseProducts();
347
        $this->indexPage->deleteResourceOnPage(['name' => $product->getName()]);
348
    }
349
350
    /**
351
     * @Then /^(this product) should not exist in the product catalog$/
352
     */
353
    public function productShouldNotExist(ProductInterface $product)
354
    {
355
        $this->iWantToBrowseProducts();
356
357
        Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $product->getCode()]));
358
    }
359
360
    /**
361
     * @Then I should be notified that this product is in use and cannot be deleted
362
     */
363
    public function iShouldBeNotifiedOfFailure()
364
    {
365
        $this->notificationChecker->checkNotification(
366
            'Cannot delete, the product is in use.',
367
            NotificationType::failure()
368
        );
369
    }
370
371
    /**
372
     * @Then /^(this product) should still exist in the product catalog$/
373
     */
374
    public function productShouldExistInTheProductCatalog(ProductInterface $product)
375
    {
376
        $this->theProductShouldAppearInTheShop($product->getName());
377
    }
378
379
    /**
380
     * @When I want to modify the :product product
381
     * @When /^I want to modify (this product)$/
382
     */
383
    public function iWantToModifyAProduct(ProductInterface $product)
384
    {
385
        $this->sharedStorage->set('product', $product);
386
387
        if ($product->isSimple()) {
388
            $this->updateSimpleProductPage->open(['id' => $product->getId()]);
389
            return;
390
        }
391
392
        $this->updateConfigurableProductPage->open(['id' => $product->getId()]);
393
    }
394
395
    /**
396
     * @Then the code field should be disabled
397
     */
398
    public function theCodeFieldShouldBeDisabled()
399
    {
400
        $currentPage = $this->resolveCurrentPage();
401
402
        Assert::true($currentPage->isCodeDisabled());
403
    }
404
405
    /**
406
     * @Then the slug field should not be editable
407
     * @Then the slug field in :localeCode (also )should not be editable
408
     */
409
    public function theSlugFieldShouldNotBeEditable($localeCode = 'en_US')
410
    {
411
        Assert::true($this->updateSimpleProductPage->isSlugReadOnlyIn($localeCode));
412
    }
413
414
    /**
415
     * @Then this product name should be :name
416
     */
417
    public function thisProductElementShouldBe($name)
418
    {
419
        $this->assertElementValue('name', $name);
420
    }
421
422
    /**
423
     * @Then /^I should be notified that (code|name|slug) is required$/
424
     */
425
    public function iShouldBeNotifiedThatIsRequired($element)
426
    {
427
        $this->assertValidationMessage($element, sprintf('Please enter product %s.', $element));
428
    }
429
430
    /**
431
     * @When I save my changes
432
     * @When I try to save my changes
433
     */
434
    public function iSaveMyChanges()
435
    {
436
        /** @var UpdatePageInterface $currentPage */
437
        $currentPage = $this->resolveCurrentPage();
438
439
        $currentPage->saveChanges();
440
    }
441
442
    /**
443
     * @When /^I change its price to (?:€|£|\$)([^"]+) for "([^"]+)" channel$/
444
     */
445
    public function iChangeItsPriceTo($price, $channelName)
446
    {
447
        $this->updateSimpleProductPage->specifyPrice($channelName, $price);
448
    }
449
450
    /**
451
     * @Given I add the :optionName option to it
452
     */
453
    public function iAddTheOptionToIt($optionName)
454
    {
455
        $this->createConfigurableProductPage->selectOption($optionName);
456
    }
457
458
    /**
459
     * @When I set its :attribute attribute to :value
460
     * @When I set its :attribute attribute to :value in :language
461
     */
462
    public function iSetItsAttributeTo($attribute, $value, $language = 'en_US')
463
    {
464
        $this->createSimpleProductPage->addAttribute($attribute, $value, $language);
465
    }
466
467
    /**
468
     * @When I remove its :attribute attribute
469
     * @When I remove its :attribute attribute from :language
470
     */
471
    public function iRemoveItsAttribute($attribute, $language = 'en_US')
472
    {
473
        $this->createSimpleProductPage->removeAttribute($attribute, $language);
474
    }
475
476
    /**
477
     * @When I try to add new attributes
478
     */
479
    public function iTryToAddNewAttributes()
480
    {
481
        $this->updateSimpleProductPage->addSelectedAttributes();
482
    }
483
484
    /**
485
     * @Then attribute :attributeName of product :product should be :value
486
     * @Then attribute :attributeName of product :product should be :value in :language
487
     */
488
    public function itsAttributeShouldBe($attributeName, ProductInterface $product, $value, $language = 'en_US')
489
    {
490
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
491
492
        Assert::same($this->updateSimpleProductPage->getAttributeValue($attributeName, $language), $value);
493
    }
494
495
    /**
496
     * @Then /^(product "[^"]+") should not have a "([^"]+)" attribute$/
497
     */
498
    public function productShouldNotHaveAttribute(ProductInterface $product, $attribute)
499
    {
500
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
501
502
        Assert::false($this->updateSimpleProductPage->hasAttribute($attribute));
503
    }
504
505
    /**
506
     * @Then product :product should not have any attributes
507
     * @Then product :product should have :count attribute
508
     */
509
    public function productShouldNotHaveAnyAttributes(ProductInterface $product, $count = 0)
510
    {
511
        Assert::same($this->updateSimpleProductPage->getNumberOfAttributes(), (int) $count);
512
    }
513
514
    /**
515
     * @Given product with :element :value should not be added
516
     */
517
    public function productWithNameShouldNotBeAdded($element, $value)
518
    {
519
        $this->iWantToBrowseProducts();
520
521
        Assert::false($this->indexPage->isSingleResourceOnPage([$element => $value]));
522
    }
523
524
    /**
525
     * @When I remove its name from :language translation
526
     */
527
    public function iRemoveItsNameFromTranslation($language)
528
    {
529
        $currentPage = $this->resolveCurrentPage();
530
531
        $currentPage->nameItIn('', $language);
532
    }
533
534
    /**
535
     * @Then /^this product should have (?:a|an) "([^"]+)" option$/
536
     */
537
    public function thisProductShouldHaveOption($productOption)
538
    {
539
        $this->updateConfigurableProductPage->isProductOptionChosen($productOption);
540
    }
541
542
    /**
543
     * @Then the option field should be disabled
544
     */
545
    public function theOptionFieldShouldBeDisabled()
546
    {
547
        Assert::true($this->updateConfigurableProductPage->isProductOptionsDisabled());
548
    }
549
550
    /**
551
     * @When /^I choose main (taxon "([^"]+)")$/
552
     */
553
    public function iChooseMainTaxon(TaxonInterface $taxon)
554
    {
555
        $currentPage = $this->resolveCurrentPage();
556
557
        $currentPage->selectMainTaxon($taxon);
558
    }
559
560
    /**
561
     * @Then /^the slug of the ("[^"]+" product) should(?:| still) be "([^"]+)"$/
562
     * @Then /^the slug of the ("[^"]+" product) should(?:| still) be "([^"]+)" (in the "[^"]+" locale)$/
563
     */
564
    public function productSlugShouldBe(ProductInterface $product, $slug, $locale = 'en_US')
565
    {
566
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
567
568
        Assert::same($this->updateSimpleProductPage->getSlug($locale), $slug);
569
    }
570
571
    /**
572
     * @Then /^(this product) main taxon should be "([^"]+)"$/
573
     */
574
    public function thisProductMainTaxonShouldBe(ProductInterface $product, $taxonName)
575
    {
576
        $currentPage = $this->resolveCurrentPage();
577
        $currentPage->open(['id' => $product->getId()]);
578
579
        Assert::true($currentPage->isMainTaxonChosen($taxonName));
580
    }
581
582
    /**
583
     * @Then /^inventory of (this product) should not be tracked$/
584
     */
585
    public function thisProductShouldNotBeTracked(ProductInterface $product)
586
    {
587
        $this->iWantToModifyAProduct($product);
588
589
        Assert::false($this->updateSimpleProductPage->isTracked());
590
    }
591
592
    /**
593
     * @Then /^inventory of (this product) should be tracked$/
594
     */
595
    public function thisProductShouldBeTracked(ProductInterface $product)
596
    {
597
        $this->iWantToModifyAProduct($product);
598
599
        Assert::true($this->updateSimpleProductPage->isTracked());
600
    }
601
602
    /**
603
     * @When I attach the :path image with a code :code
604
     */
605
    public function iAttachImageWithACode($path, $code)
606
    {
607
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
608
        $currentPage = $this->resolveCurrentPage();
609
610
        $currentPage->attachImage($path, $code);
611
    }
612
613
    /**
614
     * @When I attach the :path image without a code
615
     */
616
    public function iAttachImageWithoutACode($path)
617
    {
618
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
619
        $currentPage = $this->resolveCurrentPage();
620
621
        $currentPage->attachImage($path);
622
    }
623
624
    /**
625
     * @When I associate as :productAssociationType the :productName product
626
     * @When I associate as :productAssociationType the :firstProductName and :secondProductName products
627
     */
628
    public function iAssociateProductsAsProductAssociation(
629
        ProductAssociationTypeInterface $productAssociationType,
630
        ...$productsNames
631
    ) {
632
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
633
        $currentPage = $this->resolveCurrentPage();
634
635
        $currentPage->associateProducts($productAssociationType, $productsNames);
636
    }
637
638
    /**
639
     * @When I remove an associated product :productName from :productAssociationType
640
     */
641
    public function iRemoveAnAssociatedProductFromProductAssociation(
642
        $productName,
643
        ProductAssociationTypeInterface $productAssociationType
644
    ) {
645
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
646
        $currentPage = $this->resolveCurrentPage();
647
648
        $currentPage->removeAssociatedProduct($productName, $productAssociationType);
649
    }
650
651
    /**
652
     * @Then /^(this product) should have(?:| also) an image with a code "([^"]*)"$/
653
     * @Then /^the (product "[^"]+") should have(?:| also) an image with a code "([^"]*)"$/
654
     */
655
    public function thisProductShouldHaveAnImageWithCode(ProductInterface $product, $code)
656
    {
657
        $this->sharedStorage->set('product', $product);
658
659
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
660
        $currentPage = $this->resolveCurrentPage();
661
662
        Assert::true($currentPage->isImageWithCodeDisplayed($code));
663
    }
664
665
    /**
666
     * @Then /^this product should not have(?:| also) an image with a code "([^"]*)"$/
667
     */
668
    public function thisProductShouldNotHaveAnImageWithCode($code)
669
    {
670
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
671
        $currentPage = $this->resolveCurrentPage();
672
673
        Assert::false($currentPage->isImageWithCodeDisplayed($code));
674
    }
675
676
    /**
677
     * @When I change the image with the :code code to :path
678
     */
679
    public function iChangeItsImageToPathForTheCode($path, $code)
680
    {
681
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
682
        $currentPage = $this->resolveCurrentPage();
683
684
        $currentPage->changeImageWithCode($code, $path);
685
    }
686
687
    /**
688
     * @When /^I remove(?:| also) an image with a code "([^"]*)"$/
689
     */
690
    public function iRemoveAnImageWithACode($code)
691
    {
692
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
693
        $currentPage = $this->resolveCurrentPage();
694
695
        $currentPage->removeImageWithCode($code);
696
    }
697
698
    /**
699
     * @When I remove the first image
700
     */
701
    public function iRemoveTheFirstImage()
702
    {
703
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
704
        $currentPage = $this->resolveCurrentPage();
705
706
        $currentPage->removeFirstImage();
707
    }
708
709
    /**
710
     * @Then /^(this product) should not have any images$/
711
     */
712
    public function thisProductShouldNotHaveImages(ProductInterface $product)
713
    {
714
        $this->iWantToModifyAProduct($product);
715
716
        $currentPage = $this->resolveCurrentPage();
717
718
        Assert::same($currentPage->countImages(), 0);
719
    }
720
721
    /**
722
     * @Then the image code field should be disabled
723
     */
724
    public function theImageCodeFieldShouldBeDisabled()
725
    {
726
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
727
        $currentPage = $this->resolveCurrentPage();
728
729
        Assert::true($currentPage->isImageCodeDisabled());
730
    }
731
732
    /**
733
     * @Then I should be notified that the image with this code already exists
734
     */
735
    public function iShouldBeNotifiedThatTheImageWithThisCodeAlreadyExists()
736
    {
737
        Assert::same($this->updateSimpleProductPage->getValidationMessageForImage(), 'Image code must be unique within this product.');
738
    }
739
740
    /**
741
     * @Then I should be notified that an image code is required
742
     */
743
    public function iShouldBeNotifiedThatAnImageCodeIsRequired()
744
    {
745
        /** @var UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface $currentPage */
746
        $currentPage = $this->resolveCurrentPage();
747
748
        Assert::same($currentPage->getValidationMessageForImage(), 'Please enter an image code.');
749
    }
750
751
    /**
752
     * @Then there should still be only one image in the :product product
753
     */
754
    public function thereShouldStillBeOnlyOneImageInThisTaxon(ProductInterface $product)
755
    {
756
        $this->iWantToModifyAProduct($product);
757
758
        $currentPage = $this->resolveCurrentPage();
759
760
        Assert::same($currentPage->countImages(), 1);
761
    }
762
763
    /**
764
     * @Then /^there should be no reviews of (this product)$/
765
     */
766
    public function thereAreNoProductReviews(ProductInterface $product)
767
    {
768
        $this->productReviewIndexPage->open();
769
770
        Assert::false($this->productReviewIndexPage->isSingleResourceOnPage(['reviewSubject' => $product->getName()]));
771
    }
772
773
    /**
774
     * @Then this product should( also) have an association :productAssociationType with product :productName
775
     * @Then this product should( also) have an association :productAssociationType with products :firstProductName and :secondProductName
776
     */
777
    public function theProductShouldHaveAnAssociationWithProducts(
778
        ProductAssociationTypeInterface $productAssociationType,
779
        ...$productsNames
780
    ) {
781
        foreach ($productsNames as $productName) {
782
            Assert::true(
783
                $this->updateSimpleProductPage->hasAssociatedProduct($productName, $productAssociationType),
784
                sprintf(
785
                    'This product should have an association %s with product %s.',
786
                    $productAssociationType->getName(),
787
                    $productName
788
                )
789
            );
790
        }
791
    }
792
793
    /**
794
     * @Then this product should not have an association :productAssociationType with product :productName
795
     */
796
    public function theProductShouldNotHaveAnAssociationWithProducts(
797
        ProductAssociationTypeInterface $productAssociationType,
798
        $productName
799
    ) {
800
        Assert::false($this->updateSimpleProductPage->hasAssociatedProduct($productName);
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected ';', expecting ',' or ')'
Loading history...
801
    }
802
803
    /**
804
     * @Then I should be notified that simple product code has to be unique
805
     */
806
    public function iShouldBeNotifiedThatSimpleProductCodeHasToBeUnique()
807
    {
808
        $this->assertValidationMessage('code', 'Simple product code must be unique among all products and product variants.');
809
    }
810
811
    /**
812
     * @Then I should not be notified that simple product code has to be unique
813
     */
814
    public function iShouldNotBeNotifiedThatSimpleProductCodeHasToBeUnique()
815
    {
816
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
817
        $currentPage = $this->resolveCurrentPage();
818
819
        try {
820
            $validationMessge = $currentPage->getValidationMessage('code');
821
822
            Assert::notSame($validationMessge, 'Simple product code must be unique among all products and product variants.');
823
        } catch (ElementNotFoundException $e) {
824
            // intentionally left blank, as it could not have any validation at all
825
        }
826
    }
827
828
    /**
829
     * @Then I should be notified that slug has to be unique
830
     */
831
    public function iShouldBeNotifiedThatSlugHasToBeUnique()
832
    {
833
        $this->assertValidationMessage('slug', 'Product slug must be unique.');
834
    }
835
836
    /**
837
     * @Then I should be notified that code has to be unique
838
     */
839
    public function iShouldBeNotifiedThatCodeHasToBeUnique()
840
    {
841
        $this->assertValidationMessage('code', 'Product code must be unique.');
842
    }
843
844
    /**
845
     * @Then I should be notified that price must be defined for every channel
846
     */
847
    public function iShouldBeNotifiedThatPriceMustBeDefinedForEveryChannel()
848
    {
849
        $this->assertValidationMessage('channel_pricings', 'You must define price for every channel.');
850
    }
851
852
    /**
853
     * @Then they should have order like :firstProductName, :secondProductName and :thirdProductName
854
     */
855
    public function theyShouldHaveOrderLikeAnd(...$productNames)
856
    {
857
        Assert::true($this->indexPerTaxonPage->hasProductsInOrder($productNames));
858
    }
859
860
    /**
861
     * @When I save my new configuration
862
     */
863
    public function iSaveMyNewConfiguration()
864
    {
865
        $this->indexPerTaxonPage->savePositions();
866
    }
867
868
    /**
869
     * @When I set the position of :productName to :position
870
     */
871
    public function iSetThePositionOfTo($productName, $position)
872
    {
873
        $this->indexPerTaxonPage->setPositionOfProduct($productName, (int) $position);
874
    }
875
876
    /**
877
     * @Then this product should( still) have slug :value in :language
878
     */
879
    public function thisProductElementShouldHaveSlugIn($slug, $language)
880
    {
881
        Assert::same($this->updateSimpleProductPage->getSlug($language), $slug);
882
    }
883
884
    /**
885
     * @When I set its shipping category as :shippingCategoryName
886
     */
887
    public function iSetItsShippingCategoryAs($shippingCategoryName)
888
    {
889
        $this->createSimpleProductPage->selectShippingCategory($shippingCategoryName);
890
    }
891
892
    /**
893
     * @Then /^(it|this product) should be priced at (?:€|£|\$)([^"]+) for channel "([^"]+)"$/
894
     * @Then /^(product "[^"]+") should be priced at (?:€|£|\$)([^"]+) for channel "([^"]+)"$/
895
     */
896
    public function itShouldBePricedAtForChannel(ProductInterface $product, $price, $channelName)
897
    {
898
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
899
900
        Assert::same($this->updateSimpleProductPage->getPriceForChannel($channelName), $price);
901
    }
902
903
    /**
904
     * @Then /^(this product) should no longer have price for channel "([^"]+)"$/
905
     */
906
    public function thisProductShouldNoLongerHavePriceForChannel(ProductInterface $product, $channelName)
907
    {
908
        $this->updateSimpleProductPage->open(['id' => $product->getId()]);
909
910
        try {
911
            $this->updateSimpleProductPage->getPriceForChannel($channelName);
912
        } catch (ElementNotFoundException $exception) {
913
            return;
914
        }
915
916
        throw new \Exception(
917
            sprintf('Product "%s" should not have price defined for channel "%s".', $product->getName(), $channelName)
918
        );
919
    }
920
921
    /**
922
     * @Then I should be notified that the :imageNumber image should have an unique code
923
     */
924
    public function iShouldBeNotifiedThatTheFirstImageShouldHaveAnUniqueCode($imageNumber)
925
    {
926
        Assert::same(
927
            $this->updateSimpleProductPage->getValidationMessageForImageAtPosition((int) $imageNumber - 1),
928
            'Image code must be unique within this product.'
929
        );
930
    }
931
932
    /**
933
     * @Then I should be notified that I have to define product variants' prices for newly assigned channels first
934
     */
935
    public function iShouldBeNotifiedThatIHaveToDefineProductVariantsPricesForNewlyAssignedChannelsFirst()
936
    {
937
        Assert::same(
938
            $this->updateConfigurableProductPage->getValidationMessage('channels'),
939
            'You have to define product variants\' prices for newly assigned channels first.'
940
        );
941
    }
942
943
    /**
944
     * @param string $element
945
     * @param string $value
946
     */
947
    private function assertElementValue($element, $value)
948
    {
949
        /** @var UpdatePageInterface $currentPage */
950
        $currentPage = $this->resolveCurrentPage();
951
952
        Assert::isInstanceOf($currentPage, UpdatePageInterface::class);
953
954
        Assert::true(
955
            $currentPage->hasResourceValues([$element => $value]),
956
            sprintf('Product should have %s with %s value.', $element, $value)
957
        );
958
    }
959
960
    /**
961
     * @param string $element
962
     * @param string $message
963
     */
964
    private function assertValidationMessage($element, $message)
965
    {
966
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
967
        $currentPage = $this->resolveCurrentPage();
968
969
        Assert::same($currentPage->getValidationMessage($element), $message);
970
    }
971
972
    /**
973
     * @return IndexPageInterface|IndexPerTaxonPageInterface|CreateSimpleProductPageInterface|CreateConfigurableProductPageInterface|UpdateSimpleProductPageInterface|UpdateConfigurableProductPageInterface
974
     */
975
    private function resolveCurrentPage()
976
    {
977
        return $this->currentPageResolver->getCurrentPageWithForm([
978
            $this->indexPage,
979
            $this->indexPerTaxonPage,
980
            $this->createSimpleProductPage,
981
            $this->createConfigurableProductPage,
982
            $this->updateSimpleProductPage,
983
            $this->updateConfigurableProductPage,
984
        ]);
985
    }
986
}
987