Completed
Push — master ( 366a32...09b547 )
by Paweł
87:56 queued 75:08
created

iSpecifyThatThisActionShouldBeAppliedToItemsFromCategory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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