Completed
Push — master ( bcb54c...8151ca )
by Kamil
05:51 queued 19s
created

ManagingShippingMethodsContext   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 505
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 7

Importance

Changes 0
Metric Value
wmc 53
lcom 3
cbo 7
dl 0
loc 505
rs 6.96
c 0
b 0
f 0

52 Methods

Rating   Name   Duplication   Size   Complexity  
A theShipmentMethodShouldAppearInTheRegistry() 0 6 1
A thisShippingMethodShouldStillBeInTheRegistry() 0 4 1
A theShippingMethodShouldBeAvailableInChannel() 0 8 1
A iShouldBeNotifiedThatShippingMethodWithThisCodeAlreadyExists() 0 4 1
A thereShouldStillBeOnlyOneShippingMethodWith() 0 6 1
A iWantToModifyAShippingMethod() 0 4 1
A theCodeFieldShouldBeDisabled() 0 4 1
A thisShippingMethodNameShouldBe() 0 9 1
A iSaveMyChanges() 0 4 1
A iShouldBeNotifiedThatIsRequired() 0 4 1
A iShouldBeNotifiedThatCodeShouldContain() 0 7 1
A iArchiveTheShippingMethod() 0 5 1
A iRestoreTheShippingMethod() 0 5 1
A iShouldBeViewingNonArchivalShippingMethods() 0 4 1
A __construct() 0 13 1
A iWantToCreateANewShippingMethod() 0 4 1
A iSpecifyItsCodeAs() 0 4 1
A iSpecifyItsPositionAs() 0 4 1
A iNameItIn() 0 4 1
A iDescribeItAsIn() 0 4 1
A iDefineItForTheZone() 0 4 1
A iSpecifyItsAmountForChannel() 0 4 1
A iMakeItAvailableInChannel() 0 4 1
A iAddIt() 0 4 1
A iChooseCalculator() 0 4 1
A iCheckTheShippingMethod() 0 4 1
A iDeleteThem() 0 4 1
A thereShouldBeNoShippingMethodsOnTheList() 0 4 1
A theOnlyShippingMethodOnTheListShouldBe() 0 5 1
A shippingMethodWithElementValueShouldNotBeAdded() 0 6 1
A iDoNotNameIt() 0 4 1
A iDoNotSpecifyItsZone() 0 4 1
A iRemoveItsZone() 0 4 1
A iShouldBeNotifiedThatElementHasToBeSelected() 0 4 1
A iRemoveItsNameFromTranslation() 0 4 1
A iWantToBrowseShippingMethods() 0 4 1
A iAmBrowsingArchivalShippingMethods() 0 6 1
A iFilterArchivalShippingMethods() 0 5 1
A theFirstShippingMethodOnTheListShouldHave() 0 6 1
A theLastShippingMethodOnTheListShouldHave() 0 6 1
A iSortShippingMethodsBy() 0 4 1
A iEnableIt() 0 4 1
A iDisableIt() 0 4 1
A thisShippingMethodShouldBeDisabled() 0 4 1
A thisShippingMethodShouldBeEnabled() 0 4 1
A iDeleteShippingMethod() 0 5 1
A thisShippingMethodShouldNoLongerExistInTheRegistry() 0 4 1
A iShouldBeNotifiedThatItIsInUse() 0 4 1
A iShouldBeNotifiedThatAmountForChannelShouldNotBeBlank() 0 10 1
A iShouldBeNotifiedThatShippingChargeForChannelCannotBeLowerThan0() 0 10 1
A assertFieldValidationMessage() 0 7 1
A assertShippingMethodState() 0 9 2

How to fix   Complexity   

Complex Class

Complex classes like ManagingShippingMethodsContext often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ManagingShippingMethodsContext, and based on these observations, apply Extract Interface, too.

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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Context\Ui\Admin;
15
16
use Behat\Behat\Context\Context;
17
use Sylius\Behat\NotificationType;
18
use Sylius\Behat\Page\Admin\ShippingMethod\CreatePageInterface;
19
use Sylius\Behat\Page\Admin\ShippingMethod\IndexPageInterface;
20
use Sylius\Behat\Page\Admin\ShippingMethod\UpdatePageInterface;
21
use Sylius\Behat\Service\NotificationCheckerInterface;
22
use Sylius\Behat\Service\Resolver\CurrentPageResolverInterface;
23
use Sylius\Component\Channel\Model\ChannelInterface;
24
use Sylius\Component\Core\Model\ShippingMethodInterface;
25
use Webmozart\Assert\Assert;
26
27
final class ManagingShippingMethodsContext implements Context
28
{
29
    /** @var IndexPageInterface */
30
    private $indexPage;
31
32
    /** @var CreatePageInterface */
33
    private $createPage;
34
35
    /** @var UpdatePageInterface */
36
    private $updatePage;
37
38
    /** @var CurrentPageResolverInterface */
39
    private $currentPageResolver;
40
41
    /** @var NotificationCheckerInterface */
42
    private $notificationChecker;
43
44
    public function __construct(
45
        IndexPageInterface $indexPage,
46
        CreatePageInterface $createPage,
47
        UpdatePageInterface $updatePage,
48
        CurrentPageResolverInterface $currentPageResolver,
49
        NotificationCheckerInterface $notificationChecker
50
    ) {
51
        $this->indexPage = $indexPage;
52
        $this->createPage = $createPage;
53
        $this->updatePage = $updatePage;
54
        $this->currentPageResolver = $currentPageResolver;
55
        $this->notificationChecker = $notificationChecker;
56
    }
57
58
    /**
59
     * @When I want to create a new shipping method
60
     */
61
    public function iWantToCreateANewShippingMethod()
62
    {
63
        $this->createPage->open();
64
    }
65
66
    /**
67
     * @When I specify its code as :code
68
     * @When I do not specify its code
69
     */
70
    public function iSpecifyItsCodeAs($code = null)
71
    {
72
        $this->createPage->specifyCode($code ?? '');
73
    }
74
75
    /**
76
     * @When I specify its position as :position
77
     */
78
    public function iSpecifyItsPositionAs(int $position = null)
79
    {
80
        $this->createPage->specifyPosition($position);
81
    }
82
83
    /**
84
     * @When I name it :name in :language
85
     * @When I rename it to :name in :language
86
     */
87
    public function iNameItIn($name, $language)
88
    {
89
        $this->createPage->nameIt($name, $language);
90
    }
91
92
    /**
93
     * @When I describe it as :description in :language
94
     */
95
    public function iDescribeItAsIn($description, $language)
96
    {
97
        $this->createPage->describeIt($description, $language);
98
    }
99
100
    /**
101
     * @When I define it for the :zoneName zone
102
     */
103
    public function iDefineItForTheZone($zoneName)
104
    {
105
        $this->createPage->chooseZone($zoneName);
106
    }
107
108
    /**
109
     * @When I specify its amount as :amount for :channel channel
110
     */
111
    public function iSpecifyItsAmountForChannel($amount, ChannelInterface $channel)
112
    {
113
        $this->createPage->specifyAmountForChannel($channel->getCode(), $amount);
114
    }
115
116
    /**
117
     * @When I make it available in channel :channelName
118
     */
119
    public function iMakeItAvailableInChannel($channelName)
120
    {
121
        $this->createPage->checkChannel($channelName);
122
    }
123
124
    /**
125
     * @When I add it
126
     * @When I try to add it
127
     */
128
    public function iAddIt()
129
    {
130
        $this->createPage->create();
131
    }
132
133
    /**
134
     * @When I choose :calculatorName calculator
135
     * @When I do not specify amount for :calculatorName calculator
136
     */
137
    public function iChooseCalculator($calculatorName)
138
    {
139
        $this->createPage->chooseCalculator($calculatorName);
140
    }
141
142
    /**
143
     * @When I check (also) the :shippingMethodName shipping method
144
     */
145
    public function iCheckTheShippingMethod(string $shippingMethodName): void
146
    {
147
        $this->indexPage->checkResourceOnPage(['name' => $shippingMethodName]);
148
    }
149
150
    /**
151
     * @When I delete them
152
     */
153
    public function iDeleteThem(): void
154
    {
155
        $this->indexPage->bulkDelete();
156
    }
157
158
    /**
159
     * @Then I should see the shipping method :shipmentMethodName in the list
160
     * @Then the shipping method :shipmentMethodName should appear in the registry
161
     * @Then the shipping method :shipmentMethodName should be in the registry
162
     */
163
    public function theShipmentMethodShouldAppearInTheRegistry(string $shipmentMethodName): void
164
    {
165
        $this->iWantToBrowseShippingMethods();
166
167
        Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $shipmentMethodName]));
168
    }
169
170
    /**
171
     * @Given /^(this shipping method) should still be in the registry$/
172
     */
173
    public function thisShippingMethodShouldStillBeInTheRegistry(ShippingMethodInterface $shippingMethod)
174
    {
175
        $this->theShipmentMethodShouldAppearInTheRegistry($shippingMethod->getName());
176
    }
177
178
    /**
179
     * @Then the shipping method :shippingMethod should be available in channel :channelName
180
     */
181
    public function theShippingMethodShouldBeAvailableInChannel(
182
        ShippingMethodInterface $shippingMethod,
183
        $channelName
184
    ) {
185
        $this->iWantToModifyAShippingMethod($shippingMethod);
186
187
        Assert::true($this->updatePage->isAvailableInChannel($channelName));
188
    }
189
190
    /**
191
     * @Then I should be notified that shipping method with this code already exists
192
     */
193
    public function iShouldBeNotifiedThatShippingMethodWithThisCodeAlreadyExists()
194
    {
195
        Assert::same($this->createPage->getValidationMessage('code'), 'The shipping method with given code already exists.');
196
    }
197
198
    /**
199
     * @Then there should still be only one shipping method with :element :code
200
     */
201
    public function thereShouldStillBeOnlyOneShippingMethodWith($element, $code)
202
    {
203
        $this->iWantToBrowseShippingMethods();
204
205
        Assert::true($this->indexPage->isSingleResourceOnPage([$element => $code]));
206
    }
207
208
    /**
209
     * @Given I want to modify a shipping method :shippingMethod
210
     * @Given /^I want to modify (this shipping method)$/
211
     */
212
    public function iWantToModifyAShippingMethod(ShippingMethodInterface $shippingMethod)
213
    {
214
        $this->updatePage->open(['id' => $shippingMethod->getId()]);
215
    }
216
217
    /**
218
     * @Then the code field should be disabled
219
     */
220
    public function theCodeFieldShouldBeDisabled()
221
    {
222
        Assert::true($this->updatePage->isCodeDisabled());
223
    }
224
225
    /**
226
     * @Then /^(this shipping method) name should be "([^"]+)"$/
227
     * @Then /^(this shipping method) should still be named "([^"]+)"$/
228
     */
229
    public function thisShippingMethodNameShouldBe(ShippingMethodInterface $shippingMethod, $shippingMethodName)
230
    {
231
        $this->iWantToBrowseShippingMethods();
232
233
        Assert::true($this->indexPage->isSingleResourceOnPage([
234
            'code' => $shippingMethod->getCode(),
235
            'name' => $shippingMethodName,
236
        ]));
237
    }
238
239
    /**
240
     * @When I save my changes
241
     * @When I try to save my changes
242
     */
243
    public function iSaveMyChanges()
244
    {
245
        $this->updatePage->saveChanges();
246
    }
247
248
    /**
249
     * @Then I should be notified that :element is required
250
     */
251
    public function iShouldBeNotifiedThatIsRequired($element)
252
    {
253
        $this->assertFieldValidationMessage($element, sprintf('Please enter shipping method %s.', $element));
254
    }
255
256
    /**
257
     * @Then I should be notified that code needs to contain only specific symbols
258
     */
259
    public function iShouldBeNotifiedThatCodeShouldContain()
260
    {
261
        $this->assertFieldValidationMessage(
262
            'code',
263
            'Shipping method code can only be comprised of letters, numbers, dashes and underscores.'
264
        );
265
    }
266
267
    /**
268
     * @When I archive the :name shipping method
269
     */
270
    public function iArchiveTheShippingMethod($name)
271
    {
272
        $actions = $this->indexPage->getActionsForResource(['name' => $name]);
273
        $actions->pressButton('Archive');
274
    }
275
276
    /**
277
     * @When I restore the :name shipping method
278
     */
279
    public function iRestoreTheShippingMethod($name)
280
    {
281
        $actions = $this->indexPage->getActionsForResource(['name' => $name]);
282
        $actions->pressButton('Restore');
283
    }
284
285
    /**
286
     * @Then I should be viewing non archival shipping methods
287
     */
288
    public function iShouldBeViewingNonArchivalShippingMethods()
289
    {
290
        Assert::false($this->indexPage->isArchivalFilterEnabled());
291
    }
292
293
    /**
294
     * @Then I should see a single shipping method in the list
295
     * @Then I should see :numberOfShippingMethods shipping methods in the list
296
     * @Then I should see :numberOfShippingMethods shipping methods on the list
297
     */
298
    public function thereShouldBeNoShippingMethodsOnTheList(int $numberOfShippingMethods = 1): void
299
    {
300
        Assert::same($this->indexPage->countItems(), $numberOfShippingMethods);
301
    }
302
303
    /**
304
     * @Then the only shipping method on the list should be :name
305
     */
306
    public function theOnlyShippingMethodOnTheListShouldBe($name)
307
    {
308
        Assert::same((int) $this->indexPage->countItems(), 1);
309
        Assert::true($this->indexPage->isSingleResourceOnPage(['name' => $name]));
310
    }
311
312
    /**
313
     * @Then shipping method with :element :name should not be added
314
     */
315
    public function shippingMethodWithElementValueShouldNotBeAdded($element, $name)
316
    {
317
        $this->iWantToBrowseShippingMethods();
318
319
        Assert::false($this->indexPage->isSingleResourceOnPage([$element => $name]));
320
    }
321
322
    /**
323
     * @When I do not name it
324
     */
325
    public function iDoNotNameIt()
326
    {
327
        // Intentionally left blank to fulfill context expectation
328
    }
329
330
    /**
331
     * @When I do not specify its zone
332
     */
333
    public function iDoNotSpecifyItsZone()
334
    {
335
        // Intentionally left blank to fulfill context expectation
336
    }
337
338
    /**
339
     * @When I remove its zone
340
     */
341
    public function iRemoveItsZone()
342
    {
343
        $this->updatePage->removeZone();
344
    }
345
346
    /**
347
     * @Then I should be notified that :element has to be selected
348
     */
349
    public function iShouldBeNotifiedThatElementHasToBeSelected($element)
350
    {
351
        $this->assertFieldValidationMessage($element, sprintf('Please select shipping method %s.', $element));
352
    }
353
354
    /**
355
     * @When I remove its name from :language translation
356
     */
357
    public function iRemoveItsNameFromTranslation($language)
358
    {
359
        $this->createPage->nameIt('', $language);
360
    }
361
362
    /**
363
     * @Given I am browsing shipping methods
364
     * @When I browse shipping methods
365
     * @When I want to browse shipping methods
366
     */
367
    public function iWantToBrowseShippingMethods()
368
    {
369
        $this->indexPage->open();
370
    }
371
372
    /**
373
     * @Given I am browsing archival shipping methods
374
     */
375
    public function iAmBrowsingArchivalShippingMethods()
376
    {
377
        $this->indexPage->open();
378
        $this->indexPage->chooseArchival('Yes');
379
        $this->indexPage->filter();
380
    }
381
382
    /**
383
     * @Given I filter archival shipping methods
384
     */
385
    public function iFilterArchivalShippingMethods()
386
    {
387
        $this->indexPage->chooseArchival('Yes');
388
        $this->indexPage->filter();
389
    }
390
391
    /**
392
     * @Then the first shipping method on the list should have :field :value
393
     */
394
    public function theFirstShippingMethodOnTheListShouldHave($field, $value)
395
    {
396
        $fields = $this->indexPage->getColumnFields($field);
397
398
        Assert::same(reset($fields), $value);
399
    }
400
401
    /**
402
     * @Then the last shipping method on the list should have :field :value
403
     */
404
    public function theLastShippingMethodOnTheListShouldHave($field, $value)
405
    {
406
        $fields = $this->indexPage->getColumnFields($field);
407
408
        Assert::same(end($fields), $value);
409
    }
410
411
    /**
412
     * @When I switch the way shipping methods are sorted by :field
413
     * @When I start sorting shipping methods by :field
414
     * @Given the shipping methods are already sorted by :field
415
     */
416
    public function iSortShippingMethodsBy($field)
417
    {
418
        $this->indexPage->sortBy($field);
419
    }
420
421
    /**
422
     * @When I enable it
423
     */
424
    public function iEnableIt()
425
    {
426
        $this->updatePage->enable();
427
    }
428
429
    /**
430
     * @When I disable it
431
     */
432
    public function iDisableIt()
433
    {
434
        $this->updatePage->disable();
435
    }
436
437
    /**
438
     * @Then /^(this shipping method) should be disabled$/
439
     */
440
    public function thisShippingMethodShouldBeDisabled(ShippingMethodInterface $shippingMethod)
441
    {
442
        $this->assertShippingMethodState($shippingMethod, false);
443
    }
444
445
    /**
446
     * @Then /^(this shipping method) should be enabled$/
447
     */
448
    public function thisShippingMethodShouldBeEnabled(ShippingMethodInterface $shippingMethod)
449
    {
450
        $this->assertShippingMethodState($shippingMethod, true);
451
    }
452
453
    /**
454
     * @When I delete shipping method :shippingMethod
455
     * @When I try to delete shipping method :shippingMethod
456
     */
457
    public function iDeleteShippingMethod(ShippingMethodInterface $shippingMethod)
458
    {
459
        $this->indexPage->open();
460
        $this->indexPage->deleteResourceOnPage(['name' => $shippingMethod->getName()]);
461
    }
462
463
    /**
464
     * @Then /^(this shipping method) should no longer exist in the registry$/
465
     */
466
    public function thisShippingMethodShouldNoLongerExistInTheRegistry(ShippingMethodInterface $shippingMethod)
467
    {
468
        Assert::false($this->indexPage->isSingleResourceOnPage(['code' => $shippingMethod->getCode()]));
469
    }
470
471
    /**
472
     * @Then I should be notified that it is in use
473
     */
474
    public function iShouldBeNotifiedThatItIsInUse()
475
    {
476
        $this->notificationChecker->checkNotification('Cannot delete, the shipping method is in use.', NotificationType::failure());
477
    }
478
479
    /**
480
     * @Then I should be notified that amount for :channel channel should not be blank
481
     */
482
    public function iShouldBeNotifiedThatAmountForChannelShouldNotBeBlank(ChannelInterface $channel)
483
    {
484
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
485
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
486
487
        Assert::same(
488
            $currentPage->getValidationMessageForAmount($channel->getCode()),
489
            'This value should not be blank.'
490
        );
491
    }
492
493
    /**
494
     * @Then I should be notified that shipping charge for :channel channel cannot be lower than 0
495
     */
496
    public function iShouldBeNotifiedThatShippingChargeForChannelCannotBeLowerThan0(ChannelInterface $channel): void
497
    {
498
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
499
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
500
501
        Assert::same(
502
            $currentPage->getValidationMessageForAmount($channel->getCode()),
503
            'Shipping charge cannot be lower than 0.'
504
        );
505
    }
506
507
    /**
508
     * @param string $element
509
     * @param string $expectedMessage
510
     */
511
    private function assertFieldValidationMessage($element, $expectedMessage)
512
    {
513
        /** @var CreatePageInterface|UpdatePageInterface $currentPage */
514
        $currentPage = $this->currentPageResolver->getCurrentPageWithForm([$this->createPage, $this->updatePage]);
515
516
        Assert::same($currentPage->getValidationMessage($element), $expectedMessage);
517
    }
518
519
    /**
520
     * @param bool $state
521
     */
522
    private function assertShippingMethodState(ShippingMethodInterface $shippingMethod, $state)
523
    {
524
        $this->iWantToBrowseShippingMethods();
525
526
        Assert::true($this->indexPage->isSingleResourceOnPage([
527
            'name' => $shippingMethod->getName(),
528
            'enabled' => $state ? 'Enabled' : 'Disabled',
529
        ]));
530
    }
531
}
532