Completed
Push — master ( 81c6e7...6c71bd )
by Piotr
02:30
created

CRUDContext   F

Complexity

Total Complexity 85

Size/Duplication

Total Lines 624
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 12

Importance

Changes 0
Metric Value
wmc 85
lcom 2
cbo 12
dl 0
loc 624
c 0
b 0
f 0
rs 3.9233

How to fix   Complexity   

Complex Class

Complex classes like CRUDContext 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 CRUDContext, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * (c) FSi sp. z o.o. <[email protected]>
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace FSi\Bundle\AdminBundle\Behat\Context;
11
12
use Behat\Gherkin\Node\PyStringNode;
13
use Behat\Gherkin\Node\TableNode;
14
use Behat\Mink\Element\NodeElement;
15
use Behat\Symfony2Extension\Context\KernelAwareContext;
16
use Faker\Factory;
17
use FSi\Bundle\AdminBundle\Admin\CRUD\ListElement;
18
use FSi\Bundle\AdminBundle\Behat\Context\Page\NewsList;
19
use PhpSpec\Exception\Example\PendingException;
20
use SensioLabs\Behat\PageObjectExtension\Context\PageObjectContext;
21
use Symfony\Component\HttpKernel\KernelInterface;
22
23
class CRUDContext extends PageObjectContext implements KernelAwareContext
24
{
25
    /**
26
     * @var KernelInterface
27
     */
28
    protected $kernel;
29
30
    /**
31
     * @var \FSi\Component\DataGrid\DataGrid[]
32
     */
33
    protected $datagrids;
34
35
    /**
36
     * @var \FSi\Component\DataSource\DataSource[]
37
     */
38
    protected $datasources;
39
40
    /**
41
     * @var string
42
     */
43
    protected $newsTitle;
44
45
    /**
46
     * @var string
47
     */
48
    protected $subscriberEmail;
49
50
    /**
51
     * @var string
52
     */
53
    protected $invalidEmail = 'not_a_valid_email#email.';
54
55
    /**
56
     * @param KernelInterface $kernel
57
     */
58
    public function setKernel(KernelInterface $kernel)
59
    {
60
        $this->datagrids = array();
61
        $this->datasources = array();
62
        $this->kernel = $kernel;
63
    }
64
65
    /**
66
     * @Then /^I should see list with following columns$/
67
     */
68
    public function iShouldSeeListWithFollowingColumns(TableNode $table)
69
    {
70
        $list = $this->getElement('Elements List');
71
72
        foreach ($table->getHash() as $columnRow) {
73
            expect($list->hasColumn($columnRow['Column name']))->toBe(true);
74
75
            if (array_key_exists('Sortable', $columnRow)) {
76
                expect($list->isColumnSortable($columnRow['Column name']))
77
                    ->toBe(($columnRow['Sortable'] === 'true') ? true : false);
78
            }
79
        }
80
    }
81
82
    /**
83
     * @Given /^("[^"]*" element) datasource max results is set (\d+)$/
84
     */
85
    public function elementDatasourceMaxResultsIsSet(ListElement $adminElement, $maxResults)
86
    {
87
        $datasource = $this->getDataSource($adminElement);
88
89
        expect($datasource->getMaxResults())->toBe($maxResults);
90
    }
91
92
    /**
93
     * @Then /^I should see pagination with following buttons$/
94
     */
95
    public function iShouldSeePaginationWithFollowingButtons(TableNode $table)
96
    {
97
        $pagination = $this->getElement('Pagination');
98
99
        foreach ($table->getHash() as $buttonRow) {
100
            expect($pagination->hasLink($buttonRow['Button']))->toBe(true);
101
102
            if ($buttonRow['Active'] === 'true') {
103
                expect($pagination->isDisabled($buttonRow['Button']))->toBe(false);
104
            } else {
105
                expect($pagination->isDisabled($buttonRow['Button']))->toBe(true);
106
            }
107
108
            if ($buttonRow['Current'] === 'true') {
109
                expect($pagination->isCurrentPage($buttonRow['Button']))->toBe(true);
110
            } else {
111
                expect($pagination->isCurrentPage($buttonRow['Button']))->toBe(false);
112
            }
113
        }
114
    }
115
116
    /**
117
     * @Then /^both sorting buttons in column header "([^"]*)" should be active$/
118
     */
119
    public function bothSortingButtonsInColumnHeaderShouldBeActive($column)
120
    {
121
        expect($this->getElement('Elements List')->isColumnAscSortActive($column))->toBe(true);
122
    }
123
124
    /**
125
     * @When /^I press "([^"]*)" button in "([^"]*)" column header$/
126
     */
127
    public function iPressButtonInColumnHeader($sort, $column)
128
    {
129
        $this->getElement('Elements List')->pressSortButton($column, $sort);
130
    }
131
132
    /**
133
     * @Then /^"([^"]*)" button in "([^"]*)" column header should be disabled$/
134
     */
135
    public function buttonInColumnHeaderShouldBeDisabled($sort, $column)
136
    {
137
        $list = $this->getElement('Elements List');
138
139
        switch (strtolower($sort)) {
140
            case 'sort asc':
141
                expect($list->isColumnAscSortActive($column))->toBe(false);
142
                break;
143
            case 'sort desc':
144
                expect($list->isColumnDescSortActive($column))->toBe(false);
145
                break;
146
            default :
147
                throw new \Exception(sprintf("Unknown sorting type %s", $sort));
148
                break;
149
        }
150
    }
151
152
    /**
153
     * @Given /^"([^"]*)" button in "([^"]*)" column header should be active$/
154
     */
155
    public function buttonInColumnHeaderShouldBeActive($sort, $column)
156
    {
157
        $list = $this->getElement('Elements List');
158
159
        switch (strtolower($sort)) {
160
            case 'sort asc':
161
                expect($list->isColumnAscSortActive($column))->toBe(true);
162
                break;
163
            case 'sort desc':
164
                expect($list->isColumnDescSortActive($column))->toBe(true);
165
                break;
166
            default :
167
                throw new \Exception(sprintf("Unknown sorting type %s", $sort));
168
                break;
169
        }
170
    }
171
172
    /**
173
     * @Then /^I should not see pagination$/
174
     */
175
    public function iShouldNotSeePagination()
176
    {
177
        expect($this->getElement('Pagination'))->toThrow('\LogicException');
178
    }
179
180
    /**
181
     * @When /^I press "([^"]*)" button at pagination$/
182
     */
183
    public function iPressButtonAtPagination($button)
184
    {
185
        $this->getElement('Pagination')->clickLink($button);
186
    }
187
188
    /**
189
     * @Then /^there should be (\d+) elements at list$/
190
     */
191
    public function thereShouldBeElementsAtList($elemetsCount)
192
    {
193
        expect($this->getElement('Elements List')->getElementsCount())->toBe($elemetsCount);
194
    }
195
196
    /**
197
     * @When /^I change elements per page to (\d+)$/
198
     */
199
    public function iChangeElementsPerPageTo($elemetsCount)
200
    {
201
        $this->getElement('Elements List Results')->setElementsPerPage($elemetsCount);
202
    }
203
204
    /**
205
     * @Then /^I should not see any filters$/
206
     */
207
    public function iShouldNotSeeAnyFilters()
208
    {
209
        expect($this->getPage('Custom News List')->find('css', 'form.filters') === null)->toBe(true);
210
    }
211
212
    /**
213
     * @Then /^I should see simple text filter "([^"]*)"$/
214
     */
215
    public function iShouldSeeSimpleTextFilter($filterName)
216
    {
217
        expect($this->getElement('Filters')->hasField($filterName))->toBe(true);
218
    }
219
220
    /**
221
     * @Given /^I should see between filter "([^"]*)" with "([^"]*)" and "([^"]*)" simple text fields$/
222
     */
223
    public function iShouldSeeBetweenFilterWithAndSimpleTextFields($filterName, $fromName, $toName)
224
    {
225
        expect($this->getElement('Filters')->hasBetweenFilter($filterName, $fromName, $toName))->toBe(true);
226
    }
227
228
    /**
229
     * @Given /^I should see choice filter "([^"]*)"$/
230
     */
231
    public function iShouldSeeChoiceFilter($filterName)
232
    {
233
        expect($this->getElement('Filters')->hasChoiceFilter($filterName))->toBe(true);
234
    }
235
236
    /**
237
     * @Given /^I fill simple text filter "([^"]*)" with value "([^"]*)"$/
238
     */
239
    public function iFillSimpleTextFilterWithValue($filterName, $filterValue)
240
    {
241
        $this->getElement('Filters')->fillField($filterName, $filterValue);
242
    }
243
244
    /**
245
     * @When /^I select "([^"]*)" in choice filter "([^"]*)"$/
246
     */
247
    public function iSelectInChoiceFilter($filterValue, $filterName)
248
    {
249
        $this->getElement('Filters')->findField($filterName)->selectOption($filterValue);
250
    }
251
252
    /**
253
     * @Given /^I press "Search" button$/
254
     */
255
    public function iPressSearchButton()
256
    {
257
        $this->getElement('Filters')->pressButton('Search');
258
    }
259
260
    /**
261
     * @Given /^I press "New element" link$/
262
     */
263
    public function iPressNewElementLink()
264
    {
265
        $this->getElement('New Element Link')->click();
266
    }
267
268
    /**
269
     * @Then /^I should see filtered list$/
270
     */
271
    public function iShouldSeeFilteredList()
272
    {
273
        $this->getElement('Elements List')->getHtml();
274
    }
275
276
    /**
277
     * @Given /^simple text filter "([^"]*)" should be filled with value "([^"]*)"$/
278
     */
279
    public function simpleTextFilterShouldBeFilledWithValue($filterName, $filterValue)
280
    {
281
        expect($this->getElement('Filters')->findField($filterName)->getValue())->toBe($filterValue);
282
    }
283
284
    /**
285
     * @Given /^choice filter "([^"]*)" should have value "([^"]*)" selected$/
286
     */
287
    public function choiceFilterShouldHaveValueSelected($filterName, $choice)
288
    {
289
        $field = $this->getElement('Filters')->findField($filterName);
290
        expect($field->find('css', sprintf('option:contains("%s")', $choice))
291
            ->getAttribute('selected'))->toBe('selected');
292
    }
293
294
    /**
295
     * @Given /^I should see form with following fields$/
296
     */
297
    public function iShouldSeeFormWithFollowingFields(TableNode $table)
298
    {
299
        $form = $this->getElement('Form');
300
        foreach($table->getHash() as $fieldRow) {
301
            expect($form->hasField($fieldRow['Field name']))->toBe(true);
302
        }
303
    }
304
305
    /**
306
     * @When /^I fill all form field properly$/
307
     */
308
    public function iFillAllFormFieldProperly()
309
    {
310
        $generator = Factory::create();
311
        $form = $this->getElement('Form');
312
        if ($form->hasField('Title')) {
313
            $form->fillField('Title', $generator->text());
314
        }
315
        if ($form->hasField('Created at')) {
316
            $this->getElement('Form')->fillField('Created at', $generator->date());
317
        }
318
        if ($form->hasField('Visible')) {
319
            if ($generator->boolean()) {
320
                $this->getElement('Form')->checkField('Visible');
321
            } else {
322
                $this->getElement('Form')->uncheckField('Visible');
323
            }
324
        }
325
        if ($form->hasField('Active')) {
326
            $this->getElement('Form')->fillField('Active', $generator->boolean());
327
        }
328
        if ($form->hasField('Email')) {
329
            $this->getElement('Form')->fillField('Email', $generator->email());
330
        }
331
        if ($form->hasField('Creator email')) {
332
            $this->getElement('Form')->fillField('Creator email', $generator->email());
333
        }
334
    }
335
336
    /**
337
     * @Given /^I press form "([^"]*)" button$/
338
     */
339
    public function iPressFormButton($button)
340
    {
341
        $this->getElement('Form')->pressButton($button);
342
    }
343
344
    /**
345
     * @Given /^I should be redirected to "([^"]*)" page$/
346
     */
347
    public function iShouldBeRedirectedToPage($pageName)
348
    {
349
        expect($this->getPage($pageName)->isOpen())->toBe(true);
350
    }
351
352
    /**
353
     * @Given /^I press "([^"]*)" link in "([^"]*)" column of first element at list$/
354
     */
355
    public function iPressLinkInColumnOfFirstElementAtList($link, $columnName)
356
    {
357
        $this->getElement('Elements list')->pressLinkInRowInColumn($link, 1, $columnName);
358
    }
359
360
    /**
361
     * @When /^I change form "([^"]*)" field value$/
362
     */
363
    public function iChangeFormTitleFieldValue($field)
364
    {
365
        $generator = Factory::create();
366
        switch ($field) {
367
            case 'Title':
368
                $this->newsTitle = $generator->text();
369
                expect($this->newsTitle)->toNotBe($this->getElement('Form')->findField($field)->getValue());
370
                $this->getElement('Form')->fillField($field, $this->newsTitle);
371
                break;
372
            case 'Email':
373
                $this->subscriberEmail = $generator->email();
374
                expect($this->subscriberEmail)->toNotBe($this->getElement('Form')->findField($field)->getValue());
375
                $this->getElement('Form')->fillField($field, $this->subscriberEmail);
376
                break;
377
        }
378
    }
379
380
    /**
381
     * @When /^I fill the "([^"]*)" field with invalid data$/
382
     */
383
    public function iFillFormValueWithInvalidData($field)
384
    {
385
        switch ($field) {
386
            case 'Email':
387
                expect($this->invalidEmail)->toNotBe($this->getElement('Form')->findField($field)->getValue());
388
                $this->getElement('Form')->fillField($field, $this->invalidEmail);
389
                break;
390
        }
391
    }
392
393
    /**
394
     * @Then /^news with id (\d+) should have changed title$/
395
     */
396
    public function newsWithIdShouldHaveChangedTitle($id)
397
    {
398
        expect($this->kernel->getContainer()->get('doctrine')->getManager()->getRepository('FSi\FixturesBundle\Entity\News')->findOneById($id)->getTitle())->toBe($this->newsTitle);
399
    }
400
401
    /**
402
     * @Then /^subscriber with id (\d+) should have changed email$/
403
     */
404
    public function subscriberWithIdShouldHaveChangedEmail($id)
405
    {
406
        expect($this->kernel->getContainer()->get('doctrine')->getManager()->getRepository('FSi\FixturesBundle\Entity\Subscriber')->findOneById($id)->getEmail())->toBe($this->subscriberEmail);
407
    }
408
409
    /**
410
     * @Then /^subscriber with id (\d+) should not have his email changed to invalid one$/
411
     */
412
    public function subscriberWithIdShouldNotHaveChangedEmailToInvalid($id)
413
    {
414
        $manager = $this->kernel->getContainer()
415
            ->get('doctrine')
416
            ->getManager()
417
        ;
418
        $subsciber = $manager
419
            ->getRepository('FSi\FixturesBundle\Entity\Subscriber')
420
            ->findOneById($id)
421
        ;
422
        $manager->refresh($subsciber);
423
        expect($subsciber->getEmail())->notToBe($this->invalidEmail);
424
    }
425
426
    /**
427
     * @Then /^I should see customized "([^"]*)" view$/
428
     */
429
    public function iShouldSeeCustomizedView($crudElement)
430
    {
431
        switch($crudElement) {
432
            case 'subscribers list':
433
                $this->getPage('Custom subscribers list')->isOpen();
434
                break;
435
            case 'list':
436
                $this->getPage('Custom news list')->isOpen();
437
                break;
438
            case 'edit':
439
                $this->getPage('Custom news edit')->isOpen();
440
                break;
441
        }
442
    }
443
444
    /**
445
     * @Then /^I should see actions dropdown with following options$/
446
     */
447
    public function iShouldSeeActionsDropdownWithFollowingOptions(TableNode $actions)
448
    {
449
        expect($this->getPage('News list')->hasBatchActionsDropdown())->toBe(true);
450
451
        foreach ($actions->getHash() as $actionRow) {
452
            expect($this->getPage('News list')->hasBatchAction($actionRow['Option']))->toBe(true);
453
        }
454
    }
455
456
    /**
457
     * @Given /^I should see confirmation button "([^"]*)"$/
458
     */
459
    public function iShouldSeeConfirmationButton($button)
460
    {
461
        $this->getPage('News list')->hasButton($button);
462
    }
463
464
    /**
465
     * @When /^I press checkbox in first column in first row$/
466
     */
467
    public function iPressCheckboxInFirstColumnInFirstRow()
468
    {
469
        $this->getPage('News list')->pressBatchCheckboxInRow(1);
470
    }
471
472
    /**
473
     * @Given /^I choose action "([^"]*)" from actions$/
474
     */
475
    public function iChooseActionFromActions($action)
476
    {
477
        $this->getPage('News list')->selectBatchAction($action);
478
    }
479
480
    /**
481
     * @Given /^I press confirmation button "Ok"$/
482
     */
483
    public function iPressConfirmationButton()
484
    {
485
        $this->getPage('News list')->pressBatchActionConfirmationButton();
486
    }
487
488
    /**
489
     * @Then /^I should be redirected to confirmation page with message$/
490
     */
491
    public function iShouldBeRedirectedToConfirmationPageWithMessage(PyStringNode $message)
492
    {
493
        $this->getPage('News delete confirmation')->isOpen();
494
        expect($this->getPage('News delete confirmation')->getConfirmationMessage())->toBe((string) $message);
495
    }
496
497
    /**
498
     * @When /^I press "Yes"$/
499
     */
500
    public function iPress()
501
    {
502
        $this->getPage('News delete confirmation')->pressButton('Yes');
503
    }
504
505
    /**
506
     * @When /^I press checkbox in first column header$/
507
     */
508
    public function iPressCheckboxInFirstColumnHeader()
509
    {
510
        $this->getPage('News list')->selectAllElements();
511
    }
512
513
    /**
514
     * @Given /^"([^"]*)" column is editable$/
515
     */
516
    public function columnIsEditable($columnHeader)
517
    {
518
        expect($this->getPage('News list')->isColumnEditable($columnHeader))->toBe(true);
519
    }
520
521
    /**
522
     * @Given /^I clicked "([^"]*)" in "([^"]*)" column in first row$/
523
     * @When /^I click "([^"]*)" in "([^"]*)" column in first row$/
524
     */
525
    public function iClickInColumnInFirstRow($link, $columnHeader)
526
    {
527
        $this->getPage('News list')->getCell($columnHeader, 1)->clickLink($link);
528
    }
529
530
    /**
531
     * @Given /^I clicked edit in "([^"]*)" column in first row$/
532
     * @When /^I click edit in "([^"]*)" column in first row$/
533
     */
534
    public function iClickEditInColumnInFirstRow($columnHeader)
535
    {
536
        $cell = $this->getPage('News list')->getCell($columnHeader, 1);
537
        $this->getPage('News list')->getSession()->getDriver()->click($cell->getXPath());
538
        $cell->find('css', 'a')->click();
539
    }
540
541
    /**
542
     * @Then /^popover with "([^"]*)" field in form should appear$/
543
     */
544
    public function popoverWithFieldInFormShouldAppear($newsTitle)
545
    {
546
        $popover = $this->getPage('News list')->getPopover();
547
        expect($popover->isVisible())->toBe(true);
548
        expect($popover->findField('Title')->getValue())->toBe($newsTitle);
549
    }
550
551
    /**
552
     * @Then /^popover with empty date field in form should appear$/
553
     */
554
    public function popoverWithEmptyDateFieldInFormShouldAppear()
555
    {
556
        $popover = $this->getPage('News list')->getPopover();
557
        expect($popover->isVisible())->toBe(true);
558
        expect($popover->findField('Date')->getValue())->toBe('');
559
    }
560
561
    /**
562
     * @When /^I click X at popover$/
563
     */
564
    public function iClickXAtPopover()
565
    {
566
        /** @var NewsList $page */
567
        $page = $this->getPage('News list');
568
        $session = $page->getSession();
569
        /** @var NodeElement $popover */
570
        $session->wait(1000, 'jQuery(".popover").length > 0');
571
        $popover = $page->getPopover();
572
        $popover->find('css', '.editable-close')->click();
573
        $session->wait(1000, 'jQuery(".popover").length === 0');
574
    }
575
576
    /**
577
     * @Then /^popover should not be visible anymore$/
578
     */
579
    public function popoverShouldNotBeVisibleAnymore()
580
    {
581
        expect($this->getPage('News list')->getPopover())->toBe(null);
582
    }
583
584
    /**
585
     * @When /^I fill "([^"]*)" field at popover with "([^"]*)" value$/
586
     */
587
    public function iFillFieldAtPopoverWithValue($field, $value)
588
    {
589
        $this->getPage('News list')->getPopover()->fillField($field, $value);
590
    }
591
592
    /**
593
     * @Given /^I press "([^"]*)" at popover$/
594
     */
595
    public function iPressAtPopover($button)
596
    {
597
        $this->getPage('News list')->getPopover()->pressButton($button);
598
    }
599
600
    /**
601
     * @Then /^"([^"]*)" news title should be changed to "([^"]*)"$/
602
     */
603
    public function newsTitleShouldBeChangedTo($arg1, $arg2)
604
    {
605
        throw new PendingException();
606
    }
607
608
    /**
609
     * @param \FSi\Bundle\AdminBundle\Admin\CRUD\ListElement $adminElement
610
     * @return \FSi\Component\DataGrid\DataGrid
611
     */
612
    protected function getDataGrid(ListElement $adminElement)
613
    {
614
        if (!array_key_exists($adminElement->getId(), $this->datagrids)) {
615
            $this->datagrids[$adminElement->getId()] = $adminElement->createDataGrid();
616
        }
617
618
        return $this->datagrids[$adminElement->getId()];
619
    }
620
621
    /**
622
     * @param \FSi\Bundle\AdminBundle\Admin\CRUD\ListElement $adminElement
623
     * @return \FSi\Component\DataSource\DataSource
624
     */
625
    protected function getDataSource(ListElement $adminElement)
626
    {
627
        if (!array_key_exists($adminElement->getId(), $this->datasources)) {
628
            $this->datasources[$adminElement->getId()] = $adminElement->createDataSource();
629
        }
630
631
        return $this->datasources[$adminElement->getId()];
632
    }
633
634
    /**
635
     * @param $optionValue
636
     * @return mixed
637
     */
638
    protected function prepareColumnOptionValue($optionValue)
639
    {
640
        if ($optionValue === 'true' || $optionValue === 'false') {
641
            $optionValue = ($optionValue === 'true') ? true : false;
642
        }
643
644
        return $optionValue;
645
    }
646
}
647