Completed
Push — master ( 26132b...c9e982 )
by Kamil
31:04 queued 12:47
created

iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()   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 0
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\Promotion\IndexPageInterface;
17
use Sylius\Behat\Page\Admin\Promotion\CreatePageInterface;
18
use Sylius\Behat\Page\Admin\Promotion\UpdatePageInterface;
19
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
20
use Sylius\Behat\Service\NotificationCheckerInterface;
21
use Sylius\Component\Core\Model\PromotionInterface;
22
use Sylius\Behat\Service\SharedStorageInterface;
23
use Sylius\Component\Currency\Provider\CurrencyProviderInterface;
24
use Webmozart\Assert\Assert;
25
26
/**
27
 * @author Mateusz Zalewski <[email protected]>
28
 */
29
final class ManagingPromotionsContext implements Context
30
{
31
    /**
32
     * @var SharedStorageInterface
33
     */
34
    private $sharedStorage;
35
36
    /**
37
     * @var IndexPageInterface
38
     */
39
    private $indexPage;
40
41
    /**
42
     * @var CreatePageInterface
43
     */
44
    private $createPage;
45
46
    /**
47
     * @var UpdatePageInterface
48
     */
49
    private $updatePage;
50
51
    /**
52
     * @var CurrentPageResolverInterface
53
     */
54
    private $currentPageResolver;
55
56
    /**
57
     * @var NotificationCheckerInterface
58
     */
59
    private $notificationChecker;
60
61
    /**
62
     * @var CurrencyProviderInterface
63
     */
64
    private $currencyProvider;
65
66
    /**
67
     * @param SharedStorageInterface $sharedStorage
68
     * @param IndexPageInterface $indexPage
69
     * @param CreatePageInterface $createPage
70
     * @param UpdatePageInterface $updatePage
71
     * @param CurrentPageResolverInterface $currentPageResolver
72
     * @param NotificationCheckerInterface $notificationChecker
73
     * @param CurrencyProviderInterface $currencyProvider
74
     */
75
    public function __construct(
76
        SharedStorageInterface $sharedStorage,
77
        IndexPageInterface $indexPage,
78
        CreatePageInterface $createPage,
79
        UpdatePageInterface $updatePage,
80
        CurrentPageResolverInterface $currentPageResolver,
81
        NotificationCheckerInterface $notificationChecker,
82
        CurrencyProviderInterface $currencyProvider
83
    ) {
84
        $this->sharedStorage = $sharedStorage;
85
        $this->indexPage = $indexPage;
86
        $this->createPage = $createPage;
87
        $this->updatePage = $updatePage;
88
        $this->currentPageResolver = $currentPageResolver;
89
        $this->notificationChecker = $notificationChecker;
90
        $this->currencyProvider = $currencyProvider;
91
    }
92
93
    /**
94
     * @When I want to create a new promotion
95
     */
96
    public function iWantToCreateANewPromotion()
97
    {
98
        $this->createPage->open();
99
    }
100
101
    /**
102
     * @Given I want to browse promotions
103
     * @When I browse promotions
104
     */
105
    public function iWantToBrowsePromotions()
106
    {
107
        $this->indexPage->open();
108
    }
109
110
    /**
111
     * @When I specify its code as :code
112
     * @When I do not specify its code
113
     */
114
    public function iSpecifyItsCodeAs($code = null)
115
    {
116
        $this->createPage->specifyCode($code);
117
    }
118
119
    /**
120
     * @When I name it :name
121
     * @When I do not name it
122
     * @When I remove its name
123
     */
124
    public function iNameIt($name = null)
125
    {
126
        $this->createPage->nameIt($name);
127
    }
128
129
    /**
130
     * @Then the :promotionName promotion should appear in the registry
131
     * @Then the :promotionName promotion should exist in the registry
132
     * @Then this promotion should still be named :promotionName
133
     * @Then promotion :promotionName should still exist in the registry
134
     */
135
    public function thePromotionShouldAppearInTheRegistry($promotionName)
136
    {
137
        $this->indexPage->open();
138
139
        Assert::true(
140
            $this->indexPage->isSingleResourceOnPage(['name' => $promotionName]),
141
            sprintf('Promotion with name %s has not been found.', $promotionName)
142
        );
143
    }
144
145
    /**
146
     * @When I add it
147
     * @When I try to add it
148
     */
149
    public function iAddIt()
150
    {
151
        $this->createPage->create();
152
    }
153
154
    /**
155
     * @When I add the "Has at least one from taxons" rule configured with :firstTaxon
156
     * @When I add the "Has at least one from taxons" rule configured with :firstTaxon and :secondTaxon
157
     */
158
    public function iAddTheHasTaxonRuleConfiguredWith(...$taxons)
159
    {
160
        $this->createPage->addRule('Has at least one from taxons');
161
162
        foreach ($taxons as $taxon) {
163
            $this->createPage->selectRuleOption('Taxons', $taxon, true);
164
        }
165
    }
166
167
    /**
168
     * @When /^I add the "Total price of items from taxon" rule configured with "([^"]+)" taxon and (?:€|£|\$)([^"]+) amount for "([^"]+)" channel$/
169
     */
170
    public function iAddTheRuleConfiguredWith($taxonName, $amount, $channelName)
171
    {
172
        $this->createPage->addRule('Total price of items from taxon');
173
        $this->createPage->selectRuleOption('Taxon', $taxonName);
174
        $this->createPage->fillRuleOptionForChannel($channelName, 'Amount', $amount);
175
    }
176
177
    /**
178
     * @When /^I add the "Item total" rule configured with (?:€|£|\$)([^"]+) amount for "([^"]+)" channel and (?:€|£|\$)([^"]+) amount for "([^"]+)" channel$/
179
     */
180
    public function iAddTheItemTotalRuleConfiguredWithTwoChannel(
181
        $firstAmount,
182
        $firstChannelName,
183
        $secondAmount,
184
        $secondChannelName
185
    ) {
186
        $this->createPage->addRule('Item total');
187
        $this->createPage->fillRuleOptionForChannel($firstChannelName, 'Amount', $firstAmount);
188
        $this->createPage->fillRuleOptionForChannel($secondChannelName, 'Amount', $secondAmount);
189
    }
190
191
    /**
192
     * @When /^I add the "([^"]+)" action configured with amount of "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
193
     */
194
    public function iAddTheActionConfiguredWithAmountForChannel($actionType, $amount, $channelName)
195
    {
196
        $this->createPage->addAction($actionType);
197
        $this->createPage->fillActionOptionForChannel($channelName, 'Amount', $amount);
198
    }
199
200
    /**
201
     * @When I add the :actionType action
202
     */
203
    public function iAddTheAction($actionType)
204
    {
205
        $this->createPage->addAction($actionType);
206
    }
207
208
    /**
209
     * @When /^it is(?:| also) configured with amount of "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
210
     */
211
    public function itIsConfiguredWithAmountForChannel($amount, $channelName)
212
    {
213
        $this->createPage->fillActionOptionForChannel($channelName, 'Amount', $amount);
214
    }
215
216
    /**
217
     * @When /^I specify that on "([^"]+)" channel this action should be applied to items with price greater then "(?:€|£|\$)([^"]+)"$/
218
     */
219
    public function iAddAMinPriceFilterRangeForChannel($channelName, $minimum)
220
    {
221
        $this->createPage->fillActionOptionForChannel($channelName, 'Min', $minimum);
222
    }
223
224
    /**
225
     * @When /^I specify that on "([^"]+)" channel this action should be applied to items with price lesser then "(?:€|£|\$)([^"]+)"$/
226
     */
227
    public function iAddAMaxPriceFilterRangeForChannel($channelName, $maximum)
228
    {
229
        $this->createPage->fillActionOptionForChannel($channelName, 'Max', $maximum);
230
    }
231
232
    /**
233
     * @When /^I specify that on "([^"]+)" channel this action should be applied to items with price between "(?:€|£|\$)([^"]+)" and "(?:€|£|\$)([^"]+)"$/
234
     */
235
    public function iAddAMinMaxPriceFilterRangeForChannel($channelName, $minimum, $maximum)
236
    {
237
        $this->iAddAMinPriceFilterRangeForChannel($channelName, $minimum);
238
        $this->iAddAMaxPriceFilterRangeForChannel($channelName, $maximum);
239
    }
240
241
    /**
242
     * @When I specify that this action should be applied to items from :taxonName category
243
     */
244
    public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName)
245
    {
246
        $this->createPage->selectFilterOption('Taxons filter', $taxonName);
247
    }
248
249
    /**
250
     * @When /^I add the "([^"]+)" action configured with a percentage value of (?:|-)([^"]+)% for ("[^"]+" channel)$/
251
     * @When I add the :actionType action configured without a percentage value for :channelName channel
252
     */
253
    public function iAddTheActionConfiguredWithAPercentageValueForChannel($actionType, $percentage = null, $channelName)
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
254
    {
255
        $this->createPage->addAction($actionType);
256
        $this->createPage->fillActionOptionForChannel($channelName, 'Percentage', $percentage);
257
    }
258
259
    /**
260
     * @When /^I add the "([^"]+)" action configured with a percentage value of (?:|-)([^"]+)%$/
261
     * @When I add the :actionType action configured without a percentage value
262
     */
263
    public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percentage = null)
264
    {
265
        $this->createPage->addAction($actionType);
266
        $this->createPage->fillActionOption('Percentage', $percentage);
267
    }
268
269
    /**
270
     * @Then /^there should be (\d+) promotion(?:|s)$/
271
     */
272
    public function thereShouldBePromotion($number)
273
    {
274
        Assert::same(
275
            (int) $number,
276
            $this->indexPage->countItems(),
277
            'I should see %s promotions but i see only %2$s'
278
        );
279
    }
280
281
    /**
282
     * @Then /^(this promotion) should be coupon based$/
283
     */
284
    public function thisPromotionShouldBeCouponBased(PromotionInterface $promotion)
285
    {
286
        Assert::true(
287
            $this->indexPage->isCouponBasedFor($promotion),
288
            sprintf('Promotion with name "%s" should be coupon based', $promotion->getName())
289
        );
290
    }
291
292
    /**
293
     * @Then /^I should be able to manage coupons for (this promotion)$/
294
     */
295
    public function iShouldBeAbleToManageCouponsForThisPromotion(PromotionInterface $promotion)
296
    {
297
        Assert::true(
298
            $this->indexPage->isAbleToManageCouponsFor($promotion),
299
            sprintf('I should be able to manage coupons for given promotion with name %s but apparently i am not.', $promotion->getName())
300
        );
301
    }
302
303
    /**
304
     * @Then I should be notified that :element is required
305
     */
306
    public function iShouldBeNotifiedThatIsRequired($element)
307
    {
308
        $this->assertFieldValidationMessage($element, sprintf('Please enter promotion %s.', $element));
309
    }
310
311
    /**
312
     * @Then I should be notified that a :element value should be a numeric value
313
     */
314
    public function iShouldBeNotifiedThatAMinimalValueShouldBeNumeric($element)
315
    {
316
        $this->assertFieldValidationMessage($element, 'This value is not valid.');
317
    }
318
319
    /**
320
     * @Then I should be notified that promotion with this code already exists
321
     */
322
    public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()
323
    {
324
        Assert::same($this->createPage->getValidationMessage('code'), 'The promotion with given code already exists.');
325
    }
326
327
    /**
328
     * @Then promotion with :element :name should not be added
329
     */
330
    public function promotionWithElementValueShouldNotBeAdded($element, $name)
331
    {
332
        $this->indexPage->open();
333
334
        Assert::false(
335
            $this->indexPage->isSingleResourceOnPage([$element => $name]),
336
            sprintf('Promotion with %s "%s" has been created, but it should not.', $element, $name)
337
        );
338
    }
339
340
    /**
341
     * @Then there should still be only one promotion with :element :value
342
     */
343
    public function thereShouldStillBeOnlyOnePromotionWith($element, $value)
344
    {
345
        $this->indexPage->open();
346
347
        Assert::true(
348
            $this->indexPage->isSingleResourceOnPage([$element => $value]),
349
            sprintf('Promotion with %s "%s" cannot be found.', $element, $value)
350
        );
351
    }
352
353
    /**
354
     * @When I set its usage limit to :usageLimit
355
     */
356
    public function iSetItsUsageLimitTo($usageLimit)
357
    {
358
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
359
360
        $currentPage->fillUsageLimit($usageLimit);
361
    }
362
363
    /**
364
     * @Then the :promotion promotion should be available to be used only :usageLimit times
365
     */
366
    public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit)
367
    {
368
        $this->iWantToModifyAPromotion($promotion);
369
370
        Assert::true(
371
            $this->updatePage->hasResourceValues(['usage_limit' => $usageLimit]),
372
            sprintf('Promotion %s does not have usage limit set to %s.', $promotion->getName(), $usageLimit)
373
        );
374
    }
375
376
    /**
377
     * @When I make it exclusive
378
     */
379
    public function iMakeItExclusive()
380
    {
381
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
382
383
        $currentPage->makeExclusive();
384
    }
385
386
    /**
387
     * @Then the :promotion promotion should be exclusive
388
     */
389
    public function thePromotionShouldBeExclusive(PromotionInterface $promotion)
390
    {
391
        $this->assertIfFieldIsTrue($promotion, 'exclusive');
392
    }
393
394
    /**
395
     * @When I make it coupon based
396
     */
397
    public function iMakeItCouponBased()
398
    {
399
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
400
401
        $currentPage->checkCouponBased();
402
    }
403
404
    /**
405
     * @Then the :promotion promotion should be coupon based
406
     */
407
    public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
408
    {
409
        $this->assertIfFieldIsTrue($promotion, 'coupon_based');
410
    }
411
412
    /**
413
     * @When I make it applicable for the :channelName channel
414
     */
415
    public function iMakeItApplicableForTheChannel($channelName)
416
    {
417
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
418
419
        $currentPage->checkChannel($channelName);
420
    }
421
422
    /**
423
     * @Then the :promotion promotion should be applicable for the :channelName channel
424
     */
425
    public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, $channelName)
426
    {
427
        $this->iWantToModifyAPromotion($promotion);
428
429
        Assert::true(
430
            $this->updatePage->checkChannelsState($channelName),
431
            sprintf('Promotion %s is not %s, but it should be.', $promotion->getName(), $channelName)
432
        );
433
    }
434
435
    /**
436
     * @Given I want to modify a :promotion promotion
437
     * @Given /^I want to modify (this promotion)$/
438
     */
439
    public function iWantToModifyAPromotion(PromotionInterface $promotion)
440
    {
441
        $this->updatePage->open(['id' => $promotion->getId()]);
442
    }
443
444
    /**
445
     * @Then the code field should be disabled
446
     */
447
    public function theCodeFieldShouldBeDisabled()
448
    {
449
        Assert::true(
450
            $this->updatePage->isCodeDisabled(),
451
            'Code should be immutable, but it does not.'
452
        );
453
    }
454
455
    /**
456
     * @When I save my changes
457
     * @When I try to save my changes
458
     */
459
    public function iSaveMyChanges()
460
    {
461
        $this->updatePage->saveChanges();
462
    }
463
464
    /**
465
     * @When /^I delete a ("([^"]+)" promotion)$/
466
     * @When /^I try to delete a ("([^"]+)" promotion)$/
467
     */
468
    public function iDeletePromotion(PromotionInterface $promotion)
469
    {
470
        $this->sharedStorage->set('promotion', $promotion);
471
472
        $this->indexPage->open();
473
        $this->indexPage->deleteResourceOnPage(['name' => $promotion->getName()]);
474
    }
475
476
    /**
477
     * @Then /^(this promotion) should no longer exist in the promotion registry$/
478
     */
479
    public function promotionShouldNotExistInTheRegistry(PromotionInterface $promotion)
480
    {
481
        $this->indexPage->open();
482
483
        Assert::false(
484
            $this->indexPage->isSingleResourceOnPage(['code' => $promotion->getCode()]),
485
            sprintf('Promotion with code %s exists but should not.', $promotion->getCode())
486
        );
487
    }
488
489
    /**
490
     * @Then I should be notified that it is in use and cannot be deleted
491
     */
492
    public function iShouldBeNotifiedOfFailure()
493
    {
494
        $this->notificationChecker->checkNotification(
495
            'Cannot delete, the promotion is in use.',
496
            NotificationType::failure()
497
        );
498
    }
499
500
    /**
501
     * @When I make it available from :startsDate to :endsDate
502
     */
503
    public function iMakeItAvailableFromTo(\DateTime $startsDate, \DateTime $endsDate)
504
    {
505
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
506
507
        $currentPage->setStartsAt($startsDate);
508
        $currentPage->setEndsAt($endsDate);
509
    }
510
511
    /**
512
     * @Then the :promotion promotion should be available from :startsDate to :endsDate
513
     */
514
    public function thePromotionShouldBeAvailableFromTo(PromotionInterface $promotion, \DateTime $startsDate, \DateTime $endsDate)
515
    {
516
        $this->iWantToModifyAPromotion($promotion);
517
518
        Assert::true(
519
            $this->updatePage->hasStartsAt($startsDate),
520
            sprintf('Promotion %s should starts at %s, but it isn\'t.', $promotion->getName(), date('D, d M Y H:i:s', $startsDate->getTimestamp()))
521
        );
522
523
        Assert::true(
524
            $this->updatePage->hasEndsAt($endsDate),
525
            sprintf('Promotion %s should ends at %s, but it isn\'t.', $promotion->getName(), date('D, d M Y H:i:s', $endsDate->getTimestamp()))
526
        );
527
    }
528
529
    /**
530
     * @Then I should be notified that promotion cannot end before it start
531
     */
532
    public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStart()
533
    {
534
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
535
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
536
537
        Assert::same($currentPage->getValidationMessage('ends_at'), 'End date cannot be set prior start date.');
538
    }
539
540
    /**
541
     * @Then I should be notified that this value should not be blank
542
     */
543
    public function iShouldBeNotifiedThatThisValueShouldNotBeBlank()
544
    {
545
        Assert::same(
546
            $this->createPage->getValidationMessageForAction(),
547
            'This value should not be blank.'
548
        );
549
    }
550
551
    /**
552
     * @Then I should be notified that the maximum value of a percentage discount is 100%
553
     */
554
    public function iShouldBeNotifiedThatTheMaximumValueOfAPercentageDiscountIs100()
555
    {
556
        Assert::same(
557
            $this->createPage->getValidationMessageForAction(),
558
            'The maximum value of a percentage discount is 100%.'
559
        );
560
    }
561
562
    /**
563
     * @Then I should be notified that a percentage discount value must be at least 0%
564
     */
565
    public function iShouldBeNotifiedThatAPercentageDiscountValueMustBeAtLeast0()
566
    {
567
        Assert::same(
568
            $this->createPage->getValidationMessageForAction(),
569
            'The value of a percentage discount must be at least 0%.'
570
        );
571
    }
572
573
    /**
574
     * @Then the promotion :promotion should be used :usage time(s)
575
     */
576
    public function thePromotionShouldBeUsedTime(PromotionInterface $promotion, $usage)
577
    {
578
        Assert::same(
579
            (int) $usage,
580
            $this->indexPage->getUsageNumber($promotion),
581
            'Promotion should be used %s times, but is %2$s.'
582
        );
583
    }
584
585
    /**
586
     * @When I add the "Contains product" rule configured with the :productName product
587
     */
588
    public function iAddTheRuleConfiguredWithTheProduct($productName)
589
    {
590
        $this->createPage->addRule('Contains product');
591
        $this->createPage->selectRuleOption('Product', $productName);
592
    }
593
594
    /**
595
     * @When I specify that this action should be applied to the :productName product
596
     */
597
    public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName)
598
    {
599
        $this->createPage->selectFilterOption('Products filter', $productName);
600
    }
601
602
    /**
603
     * @Then I should see :count promotions on the list
604
     */
605
    public function iShouldSeePromotionsOnTheList($count)
606
    {
607
        $actualCount = $this->indexPage->countItems();
608
609
        Assert::same(
610
            (int) $count,
611
            $actualCount,
612
            'There should be %s promotion, but there\'s %2$s.'
613
        );
614
    }
615
616
    /**
617
     * @Then the first promotion on the list should have :field :value
618
     */
619
    public function theFirstPromotionOnTheListShouldHave($field, $value)
620
    {
621
        $fields = $this->indexPage->getColumnFields($field);
622
        $actualValue = reset($fields);
623
624
        Assert::same(
625
            $actualValue,
626
            $value,
627
            sprintf('Expected first promotion\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
628
        );
629
    }
630
631
    /**
632
     * @Then the last promotion on the list should have :field :value
633
     */
634
    public function theLastPromotionOnTheListShouldHave($field, $value)
635
    {
636
        $fields = $this->indexPage->getColumnFields($field);
637
        $actualValue = end($fields);
638
639
        Assert::same(
640
            $actualValue,
641
            $value,
642
            sprintf('Expected last promotion\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
643
        );
644
    }
645
646
    /**
647
     * @param string $element
648
     * @param string $expectedMessage
649
     */
650
    private function assertFieldValidationMessage($element, $expectedMessage)
651
    {
652
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
653
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
654
655
        Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
656
    }
657
658
    /**
659
     * @param PromotionInterface $promotion
660
     * @param string $field
661
     */
662
    private function assertIfFieldIsTrue(PromotionInterface $promotion, $field)
663
    {
664
        $this->iWantToModifyAPromotion($promotion);
665
666
        Assert::true(
667
            $this->updatePage->hasResourceValues([$field => 1]),
668
            sprintf('Promotion %s is not %s, but it should be.', $promotion->getName(), str_replace('_', ' ', $field))
669
        );
670
    }
671
}
672