Completed
Push — missing-product-variant-variab... ( a08960 )
by Kamil
22:45
created

thePromotionShouldBeUsedTime()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
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\CreatePageInterface;
17
use Sylius\Behat\Page\Admin\Promotion\IndexPageInterface;
18
use Sylius\Behat\Page\Admin\Promotion\UpdatePageInterface;
19
use Sylius\Behat\Service\NotificationCheckerInterface;
20
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
21
use Sylius\Behat\Service\SharedStorageInterface;
22
use Sylius\Component\Core\Model\PromotionInterface;
23
use Webmozart\Assert\Assert;
24
25
/**
26
 * @author Mateusz Zalewski <[email protected]>
27
 */
28
final class ManagingPromotionsContext implements Context
29
{
30
    /**
31
     * @var SharedStorageInterface
32
     */
33
    private $sharedStorage;
34
35
    /**
36
     * @var IndexPageInterface
37
     */
38
    private $indexPage;
39
40
    /**
41
     * @var CreatePageInterface
42
     */
43
    private $createPage;
44
45
    /**
46
     * @var UpdatePageInterface
47
     */
48
    private $updatePage;
49
50
    /**
51
     * @var CurrentPageResolverInterface
52
     */
53
    private $currentPageResolver;
54
55
    /**
56
     * @var NotificationCheckerInterface
57
     */
58
    private $notificationChecker;
59
60
    /**
61
     * @param SharedStorageInterface $sharedStorage
62
     * @param IndexPageInterface $indexPage
63
     * @param CreatePageInterface $createPage
64
     * @param UpdatePageInterface $updatePage
65
     * @param CurrentPageResolverInterface $currentPageResolver
66
     * @param NotificationCheckerInterface $notificationChecker
67
     */
68
    public function __construct(
69
        SharedStorageInterface $sharedStorage,
70
        IndexPageInterface $indexPage,
71
        CreatePageInterface $createPage,
72
        UpdatePageInterface $updatePage,
73
        CurrentPageResolverInterface $currentPageResolver,
74
        NotificationCheckerInterface $notificationChecker
75
    ) {
76
        $this->sharedStorage = $sharedStorage;
77
        $this->indexPage = $indexPage;
78
        $this->createPage = $createPage;
79
        $this->updatePage = $updatePage;
80
        $this->currentPageResolver = $currentPageResolver;
81
        $this->notificationChecker = $notificationChecker;
82
    }
83
84
    /**
85
     * @When I want to create a new promotion
86
     */
87
    public function iWantToCreateANewPromotion()
88
    {
89
        $this->createPage->open();
90
    }
91
92
    /**
93
     * @Given I want to browse promotions
94
     * @When I browse promotions
95
     */
96
    public function iWantToBrowsePromotions()
97
    {
98
        $this->indexPage->open();
99
    }
100
101
    /**
102
     * @When I specify its code as :code
103
     * @When I do not specify its code
104
     */
105
    public function iSpecifyItsCodeAs($code = null)
106
    {
107
        $this->createPage->specifyCode($code);
108
    }
109
110
    /**
111
     * @When I name it :name
112
     * @When I do not name it
113
     * @When I remove its name
114
     */
115
    public function iNameIt($name = null)
116
    {
117
        $this->createPage->nameIt($name);
118
    }
119
120
    /**
121
     * @When I remove its priority
122
     */
123
    public function iRemoveItsPriority()
124
    {
125
        $this->updatePage->setPriority(null);
126
    }
127
128
    /**
129
     * @Then the :promotionName promotion should appear in the registry
130
     * @Then the :promotionName promotion should exist in the registry
131
     * @Then this promotion should still be named :promotionName
132
     * @Then promotion :promotionName should still exist in the registry
133
     */
134
    public function thePromotionShouldAppearInTheRegistry($promotionName)
135
    {
136
        $this->indexPage->open();
137
138
        Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $promotionName]));
139
    }
140
141
    /**
142
     * @When I add it
143
     * @When I try to add it
144
     */
145
    public function iAddIt()
146
    {
147
        $this->createPage->create();
148
    }
149
150
    /**
151
     * @When I add the "Has at least one from taxons" rule configured with :firstTaxon
152
     * @When I add the "Has at least one from taxons" rule configured with :firstTaxon and :secondTaxon
153
     */
154
    public function iAddTheHasTaxonRuleConfiguredWith(...$taxons)
155
    {
156
        $this->createPage->addRule('Has at least one from taxons');
157
158
        foreach ($taxons as $taxon) {
159
            $this->createPage->selectAutocompleteRuleOption('Taxons', $taxon, true);
160
        }
161
    }
162
163
    /**
164
     * @When /^I add the "Total price of items from taxon" rule configured with "([^"]+)" taxon and (?:€|£|\$)([^"]+) amount for "([^"]+)" channel$/
165
     */
166
    public function iAddTheRuleConfiguredWith($taxonName, $amount, $channelName)
167
    {
168
        $this->createPage->addRule('Total price of items from taxon');
169
        $this->createPage->selectAutocompleteRuleOption('Taxon', $taxonName);
170
        $this->createPage->fillRuleOptionForChannel($channelName, 'Amount', $amount);
171
    }
172
173
    /**
174
     * @When /^I add the "Item total" rule configured with (?:€|£|\$)([^"]+) amount for "([^"]+)" channel and (?:€|£|\$)([^"]+) amount for "([^"]+)" channel$/
175
     */
176
    public function iAddTheItemTotalRuleConfiguredWithTwoChannel(
177
        $firstAmount,
178
        $firstChannelName,
179
        $secondAmount,
180
        $secondChannelName
181
    ) {
182
        $this->createPage->addRule('Item total');
183
        $this->createPage->fillRuleOptionForChannel($firstChannelName, 'Amount', $firstAmount);
184
        $this->createPage->fillRuleOptionForChannel($secondChannelName, 'Amount', $secondAmount);
185
    }
186
187
    /**
188
     * @When /^I add the "([^"]+)" action configured with amount of "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
189
     */
190
    public function iAddTheActionConfiguredWithAmountForChannel($actionType, $amount, $channelName)
191
    {
192
        $this->createPage->addAction($actionType);
193
        $this->createPage->fillActionOptionForChannel($channelName, 'Amount', $amount);
194
    }
195
196
    /**
197
     * @When /^it is(?:| also) configured with amount of "(?:€|£|\$)([^"]+)" for "([^"]+)" channel$/
198
     */
199
    public function itIsConfiguredWithAmountForChannel($amount, $channelName)
200
    {
201
        $this->createPage->fillActionOptionForChannel($channelName, 'Amount', $amount);
202
    }
203
204
    /**
205
     * @When /^I specify that on "([^"]+)" channel this action should be applied to items with price greater then "(?:€|£|\$)([^"]+)"$/
206
     */
207
    public function iAddAMinPriceFilterRangeForChannel($channelName, $minimum)
208
    {
209
        $this->createPage->fillActionOptionForChannel($channelName, 'Min', $minimum);
210
    }
211
212
    /**
213
     * @When /^I specify that on "([^"]+)" channel this action should be applied to items with price lesser then "(?:€|£|\$)([^"]+)"$/
214
     */
215
    public function iAddAMaxPriceFilterRangeForChannel($channelName, $maximum)
216
    {
217
        $this->createPage->fillActionOptionForChannel($channelName, 'Max', $maximum);
218
    }
219
220
    /**
221
     * @When /^I specify that on "([^"]+)" channel this action should be applied to items with price between "(?:€|£|\$)([^"]+)" and "(?:€|£|\$)([^"]+)"$/
222
     */
223
    public function iAddAMinMaxPriceFilterRangeForChannel($channelName, $minimum, $maximum)
224
    {
225
        $this->iAddAMinPriceFilterRangeForChannel($channelName, $minimum);
226
        $this->iAddAMaxPriceFilterRangeForChannel($channelName, $maximum);
227
    }
228
229
    /**
230
     * @When I specify that this action should be applied to items from :taxonName category
231
     */
232
    public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName)
233
    {
234
        $this->createPage->selectAutoCompleteFilterOption('Taxons', $taxonName);
235
    }
236
237
    /**
238
     * @When /^I add the "([^"]+)" action configured with a percentage value of (?:|-)([^"]+)% for ("[^"]+" channel)$/
239
     */
240
    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...
241
    {
242
        $this->createPage->addAction($actionType);
243
        $this->createPage->fillActionOptionForChannel($channelName, 'Percentage', $percentage);
244
    }
245
246
    /**
247
     * @When /^I add the "([^"]+)" action configured with a percentage value of (?:|-)([^"]+)%$/
248
     * @When I add the :actionType action configured without a percentage value
249
     */
250
    public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percentage = null)
251
    {
252
        $this->createPage->addAction($actionType);
253
        $this->createPage->fillActionOption('Percentage', $percentage);
254
    }
255
256
    /**
257
     * @When I add the "Customer group" rule for :customerGroupName group
258
     */
259
    public function iAddTheCustomerGroupRuleConfiguredForGroup($customerGroupName)
260
    {
261
        $this->createPage->addRule('Customer group');
262
        $this->createPage->selectRuleOption('Customer group', $customerGroupName);
263
    }
264
265
    /**
266
     * @Then /^there should be (\d+) promotion(?:|s)$/
267
     */
268
    public function thereShouldBePromotion($number)
269
    {
270
        Assert::same(
271
            (int) $number,
272
            $this->indexPage->countItems(),
273
            'I should see %s promotions but i see only %2$s'
274
        );
275
    }
276
277
    /**
278
     * @Then /^(this promotion) should be coupon based$/
279
     */
280
    public function thisPromotionShouldBeCouponBased(PromotionInterface $promotion)
281
    {
282
        Assert::true($this->indexPage->isCouponBasedFor($promotion));
283
    }
284
285
    /**
286
     * @Then /^I should be able to manage coupons for (this promotion)$/
287
     */
288
    public function iShouldBeAbleToManageCouponsForThisPromotion(PromotionInterface $promotion)
289
    {
290
        Assert::true($this->indexPage->isAbleToManageCouponsFor($promotion));
291
    }
292
293
    /**
294
     * @Then I should be notified that :element is required
295
     */
296
    public function iShouldBeNotifiedThatIsRequired($element)
297
    {
298
        $this->assertFieldValidationMessage($element, sprintf('Please enter promotion %s.', $element));
299
    }
300
301
    /**
302
     * @Then I should be notified that a :element value should be a numeric value
303
     */
304
    public function iShouldBeNotifiedThatAMinimalValueShouldBeNumeric($element)
305
    {
306
        $this->assertFieldValidationMessage($element, 'This value is not valid.');
307
    }
308
309
    /**
310
     * @Then I should be notified that promotion with this code already exists
311
     */
312
    public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()
313
    {
314
        Assert::same($this->createPage->getValidationMessage('code'), 'The promotion with given code already exists.');
315
    }
316
317
    /**
318
     * @Then promotion with :element :name should not be added
319
     */
320
    public function promotionWithElementValueShouldNotBeAdded($element, $name)
321
    {
322
        $this->indexPage->open();
323
324
        Assert::false($this->indexPage->isSingleResourceOnPage([$element => $name]));
325
    }
326
327
    /**
328
     * @Then there should still be only one promotion with :element :value
329
     */
330
    public function thereShouldStillBeOnlyOnePromotionWith($element, $value)
331
    {
332
        $this->indexPage->open();
333
334
        Assert::true($this->indexPage->isSingleResourceOnPage([$element => $value]));
335
    }
336
337
    /**
338
     * @When I set its usage limit to :usageLimit
339
     */
340
    public function iSetItsUsageLimitTo($usageLimit)
341
    {
342
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
343
344
        $currentPage->fillUsageLimit($usageLimit);
345
    }
346
347
    /**
348
     * @Then the :promotion promotion should be available to be used only :usageLimit times
349
     */
350
    public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit)
351
    {
352
        $this->iWantToModifyAPromotion($promotion);
353
354
        Assert::true($this->updatePage->hasResourceValues(['usage_limit' => $usageLimit]));
355
    }
356
357
    /**
358
     * @When I make it exclusive
359
     */
360
    public function iMakeItExclusive()
361
    {
362
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
363
364
        $currentPage->makeExclusive();
365
    }
366
367
    /**
368
     * @Then the :promotion promotion should be exclusive
369
     */
370
    public function thePromotionShouldBeExclusive(PromotionInterface $promotion)
371
    {
372
        $this->assertIfFieldIsTrue($promotion, 'exclusive');
373
    }
374
375
    /**
376
     * @When I make it coupon based
377
     */
378
    public function iMakeItCouponBased()
379
    {
380
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
381
382
        $currentPage->checkCouponBased();
383
    }
384
385
    /**
386
     * @Then the :promotion promotion should be coupon based
387
     */
388
    public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
389
    {
390
        $this->assertIfFieldIsTrue($promotion, 'coupon_based');
391
    }
392
393
    /**
394
     * @When I make it applicable for the :channelName channel
395
     */
396
    public function iMakeItApplicableForTheChannel($channelName)
397
    {
398
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
399
400
        $currentPage->checkChannel($channelName);
401
    }
402
403
    /**
404
     * @Then the :promotion promotion should be applicable for the :channelName channel
405
     */
406
    public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, $channelName)
407
    {
408
        $this->iWantToModifyAPromotion($promotion);
409
410
        Assert::true($this->updatePage->checkChannelsState($channelName));
411
    }
412
413
    /**
414
     * @Given I want to modify a :promotion promotion
415
     * @Given /^I want to modify (this promotion)$/
416
     * @Then I should be able to modify a :promotion promotion
417
     */
418
    public function iWantToModifyAPromotion(PromotionInterface $promotion)
419
    {
420
        $this->updatePage->open(['id' => $promotion->getId()]);
421
    }
422
423
    /**
424
     * @Then the code field should be disabled
425
     */
426
    public function theCodeFieldShouldBeDisabled()
427
    {
428
        Assert::true($this->updatePage->isCodeDisabled());
429
    }
430
431
    /**
432
     * @When I save my changes
433
     * @When I try to save my changes
434
     */
435
    public function iSaveMyChanges()
436
    {
437
        $this->updatePage->saveChanges();
438
    }
439
440
    /**
441
     * @When /^I delete a ("([^"]+)" promotion)$/
442
     * @When /^I try to delete a ("([^"]+)" promotion)$/
443
     */
444
    public function iDeletePromotion(PromotionInterface $promotion)
445
    {
446
        $this->sharedStorage->set('promotion', $promotion);
447
448
        $this->indexPage->open();
449
        $this->indexPage->deleteResourceOnPage(['name' => $promotion->getName()]);
450
    }
451
452
    /**
453
     * @Then /^(this promotion) should no longer exist in the promotion registry$/
454
     */
455
    public function promotionShouldNotExistInTheRegistry(PromotionInterface $promotion)
456
    {
457
        $this->indexPage->open();
458
459
        Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $promotion->getCode()]));
460
    }
461
462
    /**
463
     * @Then I should be notified that it is in use and cannot be deleted
464
     */
465
    public function iShouldBeNotifiedOfFailure()
466
    {
467
        $this->notificationChecker->checkNotification(
468
            'Cannot delete, the promotion is in use.',
469
            NotificationType::failure()
470
        );
471
    }
472
473
    /**
474
     * @When I make it available from :startsDate to :endsDate
475
     */
476
    public function iMakeItAvailableFromTo(\DateTime $startsDate, \DateTime $endsDate)
477
    {
478
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
479
480
        $currentPage->setStartsAt($startsDate);
481
        $currentPage->setEndsAt($endsDate);
482
    }
483
484
    /**
485
     * @Then the :promotion promotion should be available from :startsDate to :endsDate
486
     */
487
    public function thePromotionShouldBeAvailableFromTo(PromotionInterface $promotion, \DateTime $startsDate, \DateTime $endsDate)
488
    {
489
        $this->iWantToModifyAPromotion($promotion);
490
491
        Assert::true($this->updatePage->hasStartsAt($startsDate));
492
493
        Assert::true($this->updatePage->hasEndsAt($endsDate));
494
    }
495
496
    /**
497
     * @Then I should be notified that promotion cannot end before it start
498
     */
499
    public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStart()
500
    {
501
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
502
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
503
504
        Assert::same($currentPage->getValidationMessage('ends_at'), 'End date cannot be set prior start date.');
505
    }
506
507
    /**
508
     * @Then I should be notified that this value should not be blank
509
     */
510
    public function iShouldBeNotifiedThatThisValueShouldNotBeBlank()
511
    {
512
        Assert::same(
513
            $this->createPage->getValidationMessageForAction(),
514
            'This value should not be blank.'
515
        );
516
    }
517
518
    /**
519
     * @Then I should be notified that the maximum value of a percentage discount is 100%
520
     */
521
    public function iShouldBeNotifiedThatTheMaximumValueOfAPercentageDiscountIs100()
522
    {
523
        Assert::same(
524
            $this->createPage->getValidationMessageForAction(),
525
            'The maximum value of a percentage discount is 100%.'
526
        );
527
    }
528
529
    /**
530
     * @Then I should be notified that a percentage discount value must be at least 0%
531
     */
532
    public function iShouldBeNotifiedThatAPercentageDiscountValueMustBeAtLeast0()
533
    {
534
        Assert::same(
535
            $this->createPage->getValidationMessageForAction(),
536
            'The value of a percentage discount must be at least 0%.'
537
        );
538
    }
539
540
    /**
541
     * @Then the promotion :promotion should be used :usage time(s)
542
     * @Then the promotion :promotion should not be used
543
     */
544
    public function thePromotionShouldBeUsedTime(PromotionInterface $promotion, $usage = 0)
545
    {
546
        Assert::same(
547
            (int) $usage,
548
            $this->indexPage->getUsageNumber($promotion),
549
            'Promotion should be used %s times, but is %2$s.'
550
        );
551
    }
552
553
    /**
554
     * @When I add the "Contains product" rule configured with the :productName product
555
     */
556
    public function iAddTheRuleConfiguredWithTheProduct($productName)
557
    {
558
        $this->createPage->addRule('Contains product');
559
        $this->createPage->selectAutocompleteRuleOption('Product code', $productName);
560
    }
561
562
    /**
563
     * @When I specify that this action should be applied to the :productName product
564
     */
565
    public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName)
566
    {
567
        $this->createPage->selectAutoCompleteFilterOption('Products', $productName);
568
    }
569
570
    /**
571
     * @Then I should see :count promotions on the list
572
     */
573
    public function iShouldSeePromotionsOnTheList($count)
574
    {
575
        $actualCount = $this->indexPage->countItems();
576
577
        Assert::same(
578
            (int) $count,
579
            $actualCount,
580
            'There should be %s promotion, but there\'s %2$s.'
581
        );
582
    }
583
584
    /**
585
     * @Then the first promotion on the list should have :field :value
586
     */
587
    public function theFirstPromotionOnTheListShouldHave($field, $value)
588
    {
589
        $fields = $this->indexPage->getColumnFields($field);
590
        $actualValue = reset($fields);
591
592
        Assert::same(
593
            $actualValue,
594
            $value,
595
            sprintf('Expected first promotion\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
596
        );
597
    }
598
599
    /**
600
     * @Then the last promotion on the list should have :field :value
601
     */
602
    public function theLastPromotionOnTheListShouldHave($field, $value)
603
    {
604
        $fields = $this->indexPage->getColumnFields($field);
605
        $actualValue = end($fields);
606
607
        Assert::same(
608
            $actualValue,
609
            $value,
610
            sprintf('Expected last promotion\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
611
        );
612
    }
613
614
    /**
615
     * @Given the :promotion promotion should have priority :priority
616
     */
617
    public function thePromotionsShouldHavePriority(PromotionInterface $promotion, $priority)
618
    {
619
        $this->iWantToModifyAPromotion($promotion);
620
621
        Assert::same($this->updatePage->getPriority(), $priority);
622
    }
623
624
    /**
625
     * @param string $element
626
     * @param string $expectedMessage
627
     */
628
    private function assertFieldValidationMessage($element, $expectedMessage)
629
    {
630
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
631
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
632
633
        Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
634
    }
635
636
    /**
637
     * @param PromotionInterface $promotion
638
     * @param string $field
639
     */
640
    private function assertIfFieldIsTrue(PromotionInterface $promotion, $field)
641
    {
642
        $this->iWantToModifyAPromotion($promotion);
643
644
        Assert::true($this->updatePage->hasResourceValues([$field => 1]));
645
    }
646
}
647