Completed
Push — symfony3 ( 405d0c...88ded0 )
by Kamil
32:03 queued 12:32
created

thereShouldBePromotion()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sylius\Behat\Context\Ui\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 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
     * @Given 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
     * @Then the :promotionName promotion should appear in the registry
122
     * @Then the :promotionName promotion should exist in the registry
123
     * @Then this promotion should still be named :promotionName
124
     * @Then promotion :promotionName should still exist in the registry
125
     */
126
    public function thePromotionShouldAppearInTheRegistry($promotionName)
127
    {
128
        $this->indexPage->open();
129
130
        Assert::true(
131
            $this->indexPage->isSingleResourceOnPage(['name' => $promotionName]),
132
            sprintf('Promotion with name %s has not been found.', $promotionName)
133
        );
134
    }
135
136
    /**
137
     * @When I add it
138
     * @When I try to add it
139
     */
140
    public function iAddIt()
141
    {
142
        $this->createPage->create();
143
    }
144
145
    /**
146
     * @When I add the "Has at least one from taxons" rule configured with :firstTaxon
147
     * @When I add the "Has at least one from taxons" rule configured with :firstTaxon and :secondTaxon
148
     */
149
    public function iAddTheHasTaxonRuleConfiguredWith(...$taxons)
150
    {
151
        $this->createPage->addRule('Has at least one from taxons');
152
153
        foreach ($taxons as $taxon) {
154
            $this->createPage->selectRuleOption('Taxons', $taxon, true);
155
        }
156
    }
157
158
    /**
159
     * @When I add the "Total price of items from taxon" rule configured with :count :taxonName
160
     */
161
    public function iAddTheRuleConfiguredWith($count, $taxonName)
162
    {
163
        $this->createPage->addRule('Total price of items from taxon');
164
        $this->createPage->selectRuleOption('Taxon', $taxonName);
165
        $this->createPage->fillRuleOption('Amount', $count);
166
    }
167
168
    /**
169
     * @When /^I add the "([^"]+)" action configured with amount of "(?:€|£|\$)([^"]+)"$/
170
     */
171
    public function iAddTheActionConfiguredWithAmount($actionType, $amount)
172
    {
173
        $this->createPage->addAction($actionType);
174
        $this->createPage->fillActionOption('Amount', $amount);
175
    }
176
177
    /**
178
     * @When /^I specify that this action should be applied to items with price greater then "(?:€|£|\$)([^"]+)"$/
179
     */
180
    public function iAddAMinPriceFilterRange($minimum)
181
    {
182
        $this->createPage->fillActionOption('Min', $minimum);
183
    }
184
185
    /**
186
     * @When /^I specify that this action should be applied to items with price lesser then "(?:€|£|\$)([^"]+)"$/
187
     */
188
    public function iAddAMaxPriceFilterRange($maximum)
189
    {
190
        $this->createPage->fillActionOption('Max', $maximum);
191
    }
192
193
    /**
194
     * @When /^I specify that this action should be applied to items with price between "(?:€|£|\$)([^"]+)" and "(?:€|£|\$)([^"]+)"$/
195
     */
196
    public function iAddAMinMaxPriceFilterRange($minimum, $maximum)
197
    {
198
        $this->iAddAMinPriceFilterRange($minimum);
199
        $this->iAddAMaxPriceFilterRange($maximum);
200
    }
201
202
    /**
203
     * @When I specify that this action should be applied to items from :taxonName category
204
     */
205
    public function iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory($taxonName)
206
    {
207
        $this->createPage->selectFilterOption('Taxon', $taxonName);
208
209
    }
210
211
    /**
212
     * @Given I add the :actionType action configured with a percentage value of :percentage%
213
     * @Given I add the :actionType action configured without a percentage value
214
     */
215
    public function iAddTheActionConfiguredWithAPercentageValue($actionType, $percentage = null)
216
    {
217
        $this->createPage->addAction($actionType);
218
        $this->createPage->fillActionOption('Percentage', $percentage);
219
    }
220
221
    /**
222
     * @Then /^there should be (\d+) promotion(?:|s)$/
223
     */
224
    public function thereShouldBePromotion($number)
225
    {
226
        Assert::same(
227
            (int) $number,
228
            $this->indexPage->countItems(),
229
            'I should see %s promotions but i see only %2$s'
230
        );
231
    }
232
233
    /**
234
     * @Then /^(this promotion) should be coupon based$/
235
     */
236
    public function thisPromotionShouldBeCouponBased(PromotionInterface $promotion)
237
    {
238
        Assert::true(
239
            $this->indexPage->isCouponBasedFor($promotion),
240
            sprintf('Promotion with name "%s" should be coupon based', $promotion->getName())
241
        );
242
    }
243
244
    /**
245
     * @Then /^I should be able to manage coupons for (this promotion)$/
246
     */
247
    public function iShouldBeAbleToManageCouponsForThisPromotion(PromotionInterface $promotion)
248
    {
249
        Assert::true(
250
            $this->indexPage->isAbleToManageCouponsFor($promotion),
251
            sprintf('I should be able to manage coupons for given promotion with name %s but apparently i am not.', $promotion->getName())
252
        );
253
    }
254
255
    /**
256
     * @Then I should be notified that :element is required
257
     */
258
    public function iShouldBeNotifiedThatIsRequired($element)
259
    {
260
        $this->assertFieldValidationMessage($element, sprintf('Please enter promotion %s.', $element));
261
    }
262
263
    /**
264
     * @Then I should be notified that a :element value should be a numeric value
265
     */
266
    public function iShouldBeNotifiedThatAMinimalValueShouldBeNumeric($element)
267
    {
268
        $this->assertFieldValidationMessage($element, 'This value is not valid.');
269
    }
270
271
    /**
272
     * @Then I should be notified that promotion with this code already exists
273
     */
274
    public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()
275
    {
276
        Assert::same($this->createPage->getValidationMessage('code'), 'The promotion with given code already exists.');
277
    }
278
279
    /**
280
     * @Then promotion with :element :name should not be added
281
     */
282
    public function promotionWithElementValueShouldNotBeAdded($element, $name)
283
    {
284
        $this->indexPage->open();
285
286
        Assert::false(
287
            $this->indexPage->isSingleResourceOnPage([$element => $name]),
288
            sprintf('Promotion with %s "%s" has been created, but it should not.', $element, $name)
289
        );
290
    }
291
292
    /**
293
     * @Then there should still be only one promotion with :element :value
294
     */
295
    public function thereShouldStillBeOnlyOnePromotionWith($element, $value)
296
    {
297
        $this->indexPage->open();
298
299
        Assert::true(
300
            $this->indexPage->isSingleResourceOnPage([$element => $value]),
301
            sprintf('Promotion with %s "%s" cannot be found.', $element, $value)
302
        );
303
    }
304
305
    /**
306
     * @When I set its usage limit to :usageLimit
307
     */
308
    public function iSetItsUsageLimitTo($usageLimit)
309
    {
310
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
311
312
        $currentPage->fillUsageLimit($usageLimit);
313
    }
314
315
    /**
316
     * @Then the :promotion promotion should be available to be used only :usageLimit times
317
     */
318
    public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit)
319
    {
320
        $this->iWantToModifyAPromotion($promotion);
321
322
        Assert::true(
323
            $this->updatePage->hasResourceValues(['usage_limit' => $usageLimit]),
324
            sprintf('Promotion %s does not have usage limit set to %s.', $promotion->getName(), $usageLimit)
325
        );
326
    }
327
328
    /**
329
     * @When I make it exclusive
330
     */
331
    public function iMakeItExclusive()
332
    {
333
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
334
335
        $currentPage->makeExclusive();
336
    }
337
338
    /**
339
     * @Then the :promotion promotion should be exclusive
340
     */
341
    public function thePromotionShouldBeExclusive(PromotionInterface $promotion)
342
    {
343
        $this->assertIfFieldIsTrue($promotion, 'exclusive');
344
    }
345
346
    /**
347
     * @When I make it coupon based
348
     */
349
    public function iMakeItCouponBased()
350
    {
351
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
352
353
        $currentPage->checkCouponBased();
354
    }
355
356
    /**
357
     * @Then the :promotion promotion should be coupon based
358
     */
359
    public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
360
    {
361
        $this->assertIfFieldIsTrue($promotion, 'coupon_based');
362
    }
363
364
    /**
365
     * @When I make it applicable for the :channelName channel
366
     */
367
    public function iMakeItApplicableForTheChannel($channelName)
368
    {
369
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
370
371
        $currentPage->checkChannel($channelName);
372
    }
373
374
    /**
375
     * @Then the :promotion promotion should be applicable for the :channelName channel
376
     */
377
    public function thePromotionShouldBeApplicableForTheChannel(PromotionInterface $promotion, $channelName)
378
    {
379
        $this->iWantToModifyAPromotion($promotion);
380
381
        Assert::true(
382
            $this->updatePage->checkChannelsState($channelName),
383
            sprintf('Promotion %s is not %s, but it should be.', $promotion->getName(), $channelName)
384
        );
385
    }
386
387
    /**
388
     * @Given I want to modify a :promotion promotion
389
     * @Given /^I want to modify (this promotion)$/
390
     */
391
    public function iWantToModifyAPromotion(PromotionInterface $promotion)
392
    {
393
        $this->updatePage->open(['id' => $promotion->getId()]);
394
    }
395
396
    /**
397
     * @Then the code field should be disabled
398
     */
399
    public function theCodeFieldShouldBeDisabled()
400
    {
401
        Assert::true(
402
            $this->updatePage->isCodeDisabled(),
403
            'Code should be immutable, but it does not.'
404
        );
405
    }
406
407
    /**
408
     * @When I save my changes
409
     * @When I try to save my changes
410
     */
411
    public function iSaveMyChanges()
412
    {
413
        $this->updatePage->saveChanges();
414
    }
415
416
    /**
417
     * @When /^I delete a ("([^"]+)" promotion)$/
418
     * @When /^I try to delete a ("([^"]+)" promotion)$/
419
     */
420
    public function iDeletePromotion(PromotionInterface $promotion)
421
    {
422
        $this->sharedStorage->set('promotion', $promotion);
423
424
        $this->indexPage->open();
425
        $this->indexPage->deleteResourceOnPage(['name' => $promotion->getName()]);
426
    }
427
428
    /**
429
     * @Then /^(this promotion) should no longer exist in the promotion registry$/
430
     */
431
    public function promotionShouldNotExistInTheRegistry(PromotionInterface $promotion)
432
    {
433
        $this->indexPage->open();
434
435
        Assert::false(
436
            $this->indexPage->isSingleResourceOnPage(['code' => $promotion->getCode()]),
437
            sprintf('Promotion with code %s exists but should not.', $promotion->getCode())
438
        );
439
    }
440
441
    /**
442
     * @Then I should be notified that it is in use and cannot be deleted
443
     */
444
    public function iShouldBeNotifiedOfFailure()
445
    {
446
        $this->notificationChecker->checkNotification(
447
            'Cannot delete, the promotion is in use.',
448
            NotificationType::failure()
449
        );
450
    }
451
452
    /**
453
     * @When I make it available from :startsDate to :endsDate
454
     */
455
    public function iMakeItAvailableFromTo(\DateTime $startsDate, \DateTime $endsDate)
456
    {
457
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
458
459
        $currentPage->setStartsAt($startsDate);
460
        $currentPage->setEndsAt($endsDate);
461
    }
462
463
    /**
464
     * @Then the :promotion promotion should be available from :startsDate to :endsDate
465
     */
466
    public function thePromotionShouldBeAvailableFromTo(PromotionInterface $promotion, \DateTime $startsDate, \DateTime $endsDate)
467
    {
468
        $this->iWantToModifyAPromotion($promotion);
469
470
        Assert::true(
471
            $this->updatePage->hasStartsAt($startsDate),
472
            sprintf('Promotion %s should starts at %s, but it isn\'t.', $promotion->getName(), date('D, d M Y H:i:s', $startsDate->getTimestamp()))
473
        );
474
475
        Assert::true(
476
            $this->updatePage->hasEndsAt($endsDate),
477
            sprintf('Promotion %s should ends at %s, but it isn\'t.', $promotion->getName(), date('D, d M Y H:i:s', $endsDate->getTimestamp()))
478
        );
479
    }
480
481
    /**
482
     * @Then I should be notified that promotion cannot end before it start
483
     */
484
    public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStart()
485
    {
486
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
487
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
488
489
        Assert::same($currentPage->getValidationMessage('ends_at'), 'End date cannot be set prior start date.');
490
    }
491
492
    /**
493
     * @Then I should be notified that this value should not be blank
494
     */
495
    public function iShouldBeNotifiedThatThisValueShouldNotBeBlank()
496
    {
497
        Assert::same(
498
            $this->createPage->getValidationMessageForAction(),
499
            'This value should not be blank.'
500
        );
501
    }
502
503
    /**
504
     * @Then I should be notified that the maximum value of a percentage discount is 100%
505
     */
506
    public function iShouldBeNotifiedThatTheMaximumValueOfAPercentageDiscountIs100()
507
    {
508
        Assert::same(
509
            $this->createPage->getValidationMessageForAction(),
510
            'The maximum value of a percentage discount is 100%.'
511
        );
512
    }
513
514
    /**
515
     * @Then I should be notified that a percentage discount value must be at least 0%
516
     */
517
    public function iShouldBeNotifiedThatAPercentageDiscountValueMustBeAtLeast0()
518
    {
519
        Assert::same(
520
            $this->createPage->getValidationMessageForAction(),
521
            'The value of a percentage discount must be at least 0%.'
522
        );
523
    }
524
525
    /**
526
     * @Then the promotion :promotion should be used :usage time(s)
527
     */
528
    public function thePromotionShouldBeUsedTime(PromotionInterface $promotion, $usage)
529
    {
530
        Assert::same(
531
            (int) $usage,
532
            $this->indexPage->getUsageNumber($promotion),
533
            'Promotion should be used %s times, but is %2$s.'
534
        );
535
    }
536
537
    /**
538
     * @When I add the "Contains product" rule configured with the :productName product
539
     */
540
    public function iAddTheRuleConfiguredWithTheProduct($productName)
541
    {
542
        $this->createPage->addRule('Contains product');
543
        $this->createPage->selectRuleOption('Product', $productName);
544
    }
545
546
    /**
547
     * @When I specify that this action should be applied to the :productName product
548
     */
549
    public function iSpecifyThatThisActionShouldBeAppliedToTheProduct($productName)
550
    {
551
        $this->createPage->selectFilterOption('Products', $productName);
552
    }
553
554
    /**
555
     * @Then I should see :count promotions on the list
556
     */
557
    public function iShouldSeePromotionsOnTheList($count)
558
    {
559
        $actualCount = $this->indexPage->countItems();
560
561
        Assert::same(
562
            (int) $count,
563
            $actualCount,
564
            'There should be %s promotion, but there\'s %2$s.'
565
        );
566
    }
567
568
    /**
569
     * @Then the first promotion on the list should have :field :value
570
     */
571
    public function theFirstPromotionOnTheListShouldHave($field, $value)
572
    {
573
        $fields = $this->indexPage->getColumnFields($field);
574
        $actualValue = reset($fields);
575
576
        Assert::same(
577
            $actualValue,
578
            $value,
579
            sprintf('Expected first promotion\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
580
        );
581
    }
582
583
    /**
584
     * @Then the last promotion on the list should have :field :value
585
     */
586
    public function theLastPromotionOnTheListShouldHave($field, $value)
587
    {
588
        $fields = $this->indexPage->getColumnFields($field);
589
        $actualValue = end($fields);
590
591
        Assert::same(
592
            $actualValue,
593
            $value,
594
            sprintf('Expected last promotion\'s %s to be "%s", but it is "%s".', $field, $value, $actualValue)
595
        );
596
    }
597
598
    /**
599
     * @param string $element
600
     * @param string $expectedMessage
601
     */
602
    private function assertFieldValidationMessage($element, $expectedMessage)
603
    {
604
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
605
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
606
607
        Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
608
    }
609
610
    /**
611
     * @param PromotionInterface $promotion
612
     * @param string $field
613
     */
614
    private function assertIfFieldIsTrue(PromotionInterface $promotion, $field)
615
    {
616
        $this->iWantToModifyAPromotion($promotion);
617
618
        Assert::true(
619
            $this->updatePage->hasResourceValues([$field => 1]),
620
            sprintf('Promotion %s is not %s, but it should be.', $promotion->getName(), str_replace('_', ' ', $field))
621
        );
622
    }
623
}
624