Completed
Push — master ( 308c33...4cc160 )
by Michał
303:29 queued 289:05
created

ManagingPromotionsContext   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 447
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 10

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 38
c 3
b 0
f 0
lcom 3
cbo 10
dl 0
loc 447
rs 8.3999

37 Methods

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