Completed
Push — master ( f9a038...cc9983 )
by Kamil
22:34
created

ManagingPromotionsContext::iMakeItExclusive()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
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\CurrentPageResolverInterface;
20
use Sylius\Behat\Service\NotificationCheckerInterface;
21
use Sylius\Component\Core\Model\PromotionInterface;
22
use Sylius\Component\Core\Test\Services\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
     */
95
    public function iWantToBrowsePromotions()
96
    {
97
        $this->indexPage->open();
98
    }
99
100
    /**
101
     * @When I specify its code as :code
102
     * @When I do not specify its code
103
     */
104
    public function iSpecifyItsCodeAs($code = null)
105
    {
106
        $this->createPage->specifyCode($code);
107
    }
108
109
    /**
110
     * @When I name it :name
111
     * @When I do not name it
112
     * @When I remove its name
113
     */
114
    public function iNameIt($name = null)
115
    {
116
        $this->createPage->nameIt($name);
117
    }
118
119
    /**
120
     * @Then the :promotionName promotion should appear in the registry
121
     * @Then the :promotionName promotion should exist in the registry
122
     * @Then this promotion should still be named :promotionName
123
     * @Then promotion :promotionName should still exist in the registry
124
     */
125
    public function thePromotionShouldAppearInTheRegistry($promotionName)
126
    {
127
        $this->indexPage->open();
128
129
        Assert::true(
130
            $this->indexPage->isSingleResourceOnPage(['name' => $promotionName]),
131
            sprintf('Promotion with name %s has not been found.', $promotionName)
132
        );
133
    }
134
135
    /**
136
     * @When I add it
137
     * @When I try to add it
138
     */
139
    public function iAddIt()
140
    {
141
        $this->createPage->create();
142
    }
143
144
    /**
145
     * @Given I add the "Contains taxon" rule configured with :count :taxonName
146
     */
147
    public function iAddTheContainsTaxonRuleConfiguredWith($count, $taxonName)
148
    {
149
        $this->createPage->addRule('Contains taxon');
150
        $this->createPage->selectRuleOption('Taxon', $taxonName);
151
        $this->createPage->fillRuleOption('Count', $count);
152
    }
153
154
    /**
155
     * @Given I add the "Taxon" rule configured with :firstTaxon
156
     * @Given I add the "Taxon" rule configured with :firstTaxon and :secondTaxon
157
     */
158
    public function iAddTheTaxonRuleConfiguredWith($firstTaxon, $secondTaxon = null)
159
    {
160
        $this->createPage->addRule('Taxon');
161
        $this->createPage->selectRuleOption('Taxons', $firstTaxon, true);
162
163
        if (null !== $secondTaxon) {
164
            $this->createPage->selectRuleOption('Taxons', $secondTaxon, true);
165
        }
166
    }
167
168
    /**
169
     * @Given I add the "Total of items from taxon" rule configured with :count :taxonName
170
     */
171
    public function iAddTheRuleConfiguredWith($count, $taxonName)
172
    {
173
        $this->createPage->addRule('Total of items from taxon');
174
        $this->createPage->selectRuleOption('Taxon', $taxonName);
175
        $this->createPage->fillRuleOption('Amount', $count);
176
    }
177
178
    /**
179
     * @Given I add the "Order fixed discount" action configured with €:amount
180
     */
181
    public function stepDefinition($amount)
182
    {
183
        $this->createPage->addAction('Order fixed discount');
184
        $this->createPage->fillActionOption('Amount', $amount);
185
    }
186
187
    /**
188
     * @Then /^there should be (\d+) promotion(?:|s)$/
189
     */
190
    public function thereShouldBePromotion($number)
191
    {
192
        Assert::eq(
193
            $number,
194
            $this->indexPage->countItems(),
195
            'I should see %s promotions but i see only %2$s'
196
        );
197
    }
198
199
    /**
200
     * @Then /^(this promotion) should be coupon based$/
201
     */
202
    public function thisPromotionShouldBeCouponBased(PromotionInterface $promotion)
203
    {
204
        Assert::true(
205
            $this->indexPage->isCouponBasedFor($promotion),
206
            sprintf('Promotion with name "%s" should be coupon based', $promotion->getName())
207
        );
208
    }
209
210
    /**
211
     * @Then /^I should be able to manage coupons for (this promotion)$/
212
     */
213
    public function iShouldBeAbleToManageCouponsForThisPromotion(PromotionInterface $promotion)
214
    {
215
        Assert::true(
216
            $this->indexPage->isAbleToManageCouponsFor($promotion),
217
            sprintf('I should be able to manage coupons for given promotion with name %s but apparently i am not.', $promotion->getName())
218
        );
219
    }
220
221
    /**
222
     * @Then I should be notified that :element is required
223
     */
224
    public function iShouldBeNotifiedThatIsRequired($element)
225
    {
226
        $this->assertFieldValidationMessage($element, sprintf('Please enter promotion %s.', $element));
227
    }
228
229
    /**
230
     * @Then I should be notified that promotion with this code already exists
231
     */
232
    public function iShouldBeNotifiedThatPromotionWithThisCodeAlreadyExists()
233
    {
234
        Assert::true(
235
            $this->createPage->checkValidationMessageFor('code', 'The promotion with given code already exists.'),
236
            'Unique code violation message should appear on page, but it does not.'
237
        );
238
    }
239
240
    /**
241
     * @Then promotion with :element :name should not be added
242
     */
243
    public function promotionWithElementValueShouldNotBeAdded($element, $name)
244
    {
245
        $this->indexPage->open();
246
247
        Assert::false(
248
            $this->indexPage->isSingleResourceOnPage([$element => $name]),
249
            sprintf('Promotion with %s "%s" has been created, but it should not.', $element, $name)
250
        );
251
    }
252
253
    /**
254
     * @Then there should still be only one promotion with :element :value
255
     */
256
    public function thereShouldStillBeOnlyOnePromotionWith($element, $value)
257
    {
258
        $this->indexPage->open();
259
260
        Assert::true(
261
            $this->indexPage->isSingleResourceOnPage([$element => $value]),
262
            sprintf('Promotion with %s "%s" cannot be found.', $element, $value)
263
        );
264
    }
265
266
    /**
267
     * @When I set its usage limit to :usageLimit
268
     */
269
    public function iSetItsUsageLimitTo($usageLimit)
270
    {
271
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
272
273
        $currentPage->fillUsageLimit($usageLimit);
274
    }
275
276
    /**
277
     * @Then the :promotion promotion should be available to be used only :usageLimit times
278
     */
279
    public function thePromotionShouldBeAvailableToUseOnlyTimes(PromotionInterface $promotion, $usageLimit)
280
    {
281
        $this->iWantToModifyAPromotion($promotion);
282
283
        Assert::true(
284
            $this->updatePage->hasResourceValues(['usage_limit' => $usageLimit]),
285
            sprintf('Promotion %s does not have usage limit set to %s.', $promotion->getName(), $usageLimit)
286
        );
287
    }
288
289
    /**
290
     * @When I make it exclusive
291
     */
292
    public function iMakeItExclusive()
293
    {
294
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
295
296
        $currentPage->makeExclusive();
297
    }
298
299
    /**
300
     * @Then the :promotion promotion should be exclusive
301
     */
302
    public function thePromotionShouldBeExclusive(PromotionInterface $promotion)
303
    {
304
        $this->assertIfFieldIsTrue($promotion, 'exclusive');
305
    }
306
307
    /**
308
     * @When I make it coupon based
309
     */
310
    public function iMakeItCouponBased()
311
    {
312
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
313
314
        $currentPage->checkCouponBased();
315
    }
316
317
    /**
318
     * @Then the :promotion promotion should be coupon based
319
     */
320
    public function thePromotionShouldBeCouponBased(PromotionInterface $promotion)
321
    {
322
        $this->assertIfFieldIsTrue($promotion, 'coupon_based');
323
    }
324
325
    /**
326
     * @When I make it applicable for the :channelName channel
327
     */
328
    public function iMakeItApplicableForTheChannel($channelName)
329
    {
330
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
331
332
        $currentPage->checkChannel($channelName);
333
    }
334
335
    /**
336
     * @Then the :promotion promotion should be applicable for the :channelName channel
337
     */
338
    public function thePromotionShouldBeApplicatableForTheChannel(PromotionInterface $promotion, $channelName)
339
    {
340
        $this->iWantToModifyAPromotion($promotion);
341
342
        Assert::true(
343
            $this->updatePage->checkChannelsState($channelName),
344
            sprintf('Promotion %s is not %s, but it should be.', $promotion->getName(), $channelName)
345
        );
346
    }
347
348
    /**
349
     * @Given I want to modify a :promotion promotion
350
     * @Given /^I want to modify (this promotion)$/
351
     */
352
    public function iWantToModifyAPromotion(PromotionInterface $promotion)
353
    {
354
        $this->updatePage->open(['id' => $promotion->getId()]);
355
    }
356
357
    /**
358
     * @Then the code field should be disabled
359
     */
360
    public function theCodeFieldShouldBeDisabled()
361
    {
362
        Assert::true(
363
            $this->updatePage->isCodeDisabled(),
364
            'Code should be immutable, but it does not.'
365
        );
366
    }
367
368
    /**
369
     * @When I save my changes
370
     * @When I try to save my changes
371
     */
372
    public function iSaveMyChanges()
373
    {
374
        $this->updatePage->saveChanges();
375
    }
376
377
    /**
378
     * @When /^I delete a ("([^"]+)" promotion)$/
379
     * @When /^I try to delete a ("([^"]+)" promotion)$/
380
     */
381
    public function iDeletePromotion(PromotionInterface $promotion)
382
    {
383
        $this->sharedStorage->set('promotion', $promotion);
384
385
        $this->indexPage->open();
386
        $this->indexPage->deleteResourceOnPage(['name' => $promotion->getName()]);
387
    }
388
389
    /**
390
     * @Then /^(this promotion) should no longer exist in the promotion registry$/
391
     */
392
    public function promotionShouldNotExistInTheRegistry(PromotionInterface $promotion)
393
    {
394
        $this->indexPage->open();
395
396
        Assert::false(
397
            $this->indexPage->isSingleResourceOnPage(['code' => $promotion->getCode()]),
398
            sprintf('Promotion with code %s exists but should not.', $promotion->getCode())
399
        );
400
    }
401
402
    /**
403
     * @Then I should be notified that it is in use and cannot be deleted
404
     */
405
    public function iShouldBeNotifiedOfFailure()
406
    {
407
        $this->notificationChecker->checkNotification(
408
            "Cannot delete, the promotion is in use.",
409
            NotificationType::failure()
410
        );
411
    }
412
413
    /**
414
     * @When I make it available from :startsDate to :endsDate
415
     */
416
    public function iMakeItAvailableFromTo(\DateTime $startsDate, \DateTime $endsDate)
417
    {
418
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
419
420
        $currentPage->setStartsAt($startsDate);
421
        $currentPage->setEndsAt($endsDate);
422
    }
423
424
    /**
425
     * @Then the :promotion promotion should be available from :startsDate to :endsDate
426
     */
427
    public function thePromotionShouldBeAvailableFromTo(PromotionInterface $promotion, \DateTime $startsDate, \DateTime $endsDate)
428
    {
429
        $this->iWantToModifyAPromotion($promotion);
430
431
        Assert::true(
432
            $this->updatePage->hasStartsAt($startsDate),
433
            sprintf('Promotion %s should starts at %s, but it isn\'t.', $promotion->getName(), date('D, d M Y H:i:s', $startsDate->getTimestamp()))
434
        );
435
436
        Assert::true(
437
            $this->updatePage->hasEndsAt($endsDate),
438
            sprintf('Promotion %s should ends at %s, but it isn\'t.', $promotion->getName(), date('D, d M Y H:i:s', $endsDate->getTimestamp()))
439
        );
440
    }
441
442
    /**
443
     * @Then I should be notified that promotion cannot end before it start
444
     */
445
    public function iShouldBeNotifiedThatPromotionCannotEndBeforeItsEvenStart()
446
    {
447
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
448
449
        Assert::true(
450
            $currentPage->checkValidationMessageFor('ends_at', 'End date cannot be set prior start date.'),
451
            'Start date was set after ends date, but it should not be possible.'
452
        );
453
    }
454
455
    /**
456
     * @param string $element
457
     * @param string $expectedMessage
458
     */
459
    private function assertFieldValidationMessage($element, $expectedMessage)
460
    {
461
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
462
463
        Assert::true(
464
            $currentPage->checkValidationMessageFor($element, $expectedMessage),
465
            sprintf('Promotion %s should be required.', $element)
466
        );
467
    }
468
469
    /**
470
     * @param PromotionInterface $promotion
471
     * @param string $field
472
     */
473
    private function assertIfFieldIsTrue(PromotionInterface $promotion, $field)
474
    {
475
        $this->iWantToModifyAPromotion($promotion);
476
477
        Assert::true(
478
            $this->updatePage->hasResourceValues([$field => 1]),
479
            sprintf('Promotion %s is not %s, but it should be.', $promotion->getName(), str_replace('_', ' ', $field))
480
        );
481
    }
482
}
483