Completed
Pull Request — master (#244)
by Łukasz
11:47
created

AdminContext   B

Complexity

Total Complexity 41

Size/Duplication

Total Lines 296
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 9

Importance

Changes 0
Metric Value
wmc 41
lcom 2
cbo 9
dl 0
loc 296
rs 8.2769
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A setKernel() 0 4 1
A transformListNameToAdminElement() 0 4 1
A castStringToNumber() 0 4 1
A castWordToNumber() 0 8 4
A theFollowingAdminElementsWereRegistered() 0 10 2
A elementHaveFollowingOptionsDefined() 0 7 2
A elementHaveDatasourceWithFields() 0 8 1
A elementHaveDatasourceWithoutFilters() 0 15 3
A thereAreFollowingAdminElementsAvailable() 0 9 2
A iAmOnThePage() 0 4 1
A iAmOnThePageWithId() 0 4 1
A iFollowUrlFromTopBar() 0 4 1
A iShouldSeeTitleAtTopBar() 0 4 1
A menuWithFollowingElementsShouldBeVisibleAtTheTopOfThePage() 0 13 3
A iShouldSeePageHeader() 0 4 1
A translationsAreEnabledInApplication() 0 4 1
A iShouldSeeLanguageDropdownButtonInNavigationBarWithText() 0 4 1
A languageDropdownButtonShouldHaveFollowingLinks() 0 9 2
A iClickLinkFromLanguageDropdownButton() 0 4 1
A iShouldSeeDetailsAboutNewsAtPage() 0 4 1
A transformToNoneditableCollection() 0 4 1
A transformToCollection() 0 4 1
A collectionShouldHaveElements() 0 5 1
A collectionShouldHaveButton() 0 4 1
A allCollectionButtonsDisabled() 0 13 3
A iPressInCollection() 0 6 1
A iFillWithInCollectionAtPosition() 0 5 1
A iRemoveElementInCollection() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like AdminContext 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 AdminContext, 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\TableNode;
13
use Behat\Symfony2Extension\Context\KernelAwareContext;
14
use Behat\Mink\Element\NodeElement;
15
use FSi\Bundle\AdminBundle\Admin\AbstractElement;
16
use FSi\Bundle\AdminBundle\Admin\CRUD\ListElement;
17
use SensioLabs\Behat\PageObjectExtension\Context\PageObjectContext;
18
use Symfony\Component\HttpKernel\KernelInterface;
19
20
class AdminContext extends PageObjectContext implements KernelAwareContext
21
{
22
    /**
23
     * @var KernelInterface
24
     */
25
    protected $kernel;
26
27
    public function setKernel(KernelInterface $kernel)
28
    {
29
        $this->kernel = $kernel;
30
    }
31
32
    /**
33
     * @Transform /^"([^"]*)" element/
34
     */
35
    public function transformListNameToAdminElement($id)
36
    {
37
        return $this->kernel->getContainer()->get('admin.manager')->getElement($id);
38
    }
39
40
    /**
41
     * @Transform /^(\d+)/
42
     */
43
    public function castStringToNumber($number)
44
    {
45
        return (int) $number;
46
    }
47
48
    /**
49
     * @Transform /^first|second|third$/
50
     */
51
    public function castWordToNumber($word)
52
    {
53
        switch ($word) {
54
            case 'first': return 1;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
55
            case 'second': return 2;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
56
            case 'third': return 3;
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
Coding Style introduced by
Terminating statement must be on a line by itself

As per the PSR-2 coding standard, the break (or other terminating) statement must be on a line of its own.

switch ($expr) {
     case "A":
         doSomething();
         break; //wrong
     case "B":
         doSomething();
         break; //right
     case "C:":
         doSomething();
         return true; //right
 }

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
57
        }
58
    }
59
60
    /**
61
     * @Given /^the following admin elements were registered$/
62
     */
63
    public function theFollowingAdminElementsWereRegistered(TableNode $table)
64
    {
65
        /** @var \FSi\Bundle\AdminBundle\Admin\Manager $manager */
66
        $manager = $this->kernel->getContainer()->get('admin.manager');
67
68
        foreach ($table->getHash() as $serviceRow) {
69
            expect($manager->hasElement($serviceRow['Id']))->toBe(true);
70
            expect($manager->getElement($serviceRow['Id']))->toBeAnInstanceOf($serviceRow['Class']);
0 ignored issues
show
Bug introduced by
The method toBeAnInstanceOf() does not exist on Bossa\PhpSpec\Expect\Subject. Did you maybe mean beAnInstanceOf()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
71
        }
72
    }
73
74
    /**
75
     * @Given /^("[^"]*" element) have following options defined$/
76
     */
77
    public function elementHaveFollowingOptionsDefined(AbstractElement $adminElement, TableNode $options)
78
    {
79
        foreach ($options->getHash() as $optionRow) {
80
            expect($adminElement->hasOption($optionRow['Option']))->toBe(true);
81
            expect($adminElement->getOption($optionRow['Option']))->toBe($optionRow['Value']);
82
        }
83
    }
84
85
    /**
86
     * @Given /^("[^"]*" element) has datasource with fields$/
87
     */
88
    public function elementHaveDatasourceWithFields(ListElement $adminElement)
89
    {
90
        $dataSource = $adminElement->createDataSource();
91
92
        expect(count($dataSource->getFields()) > 0)->toBe(true);
93
94
        $this->kernel->getContainer()->get('datasource.factory')->clearDataSource('news');
95
    }
96
97
    /**
98
     * @Given /^("[^"]*" element) has datasource without filters$/
99
     */
100
    public function elementHaveDatasourceWithoutFilters(ListElement $adminElement)
101
    {
102
        $dataSource = $adminElement->createDataSource();
103
104
        $filters = false;
105
        foreach ($dataSource->getFields() as $field) {
106
            if ($field->getOption('form_filter')) {
107
                $filters = true;
108
                break;
109
            }
110
        }
111
        expect($filters)->toBe(false);
112
113
        $this->kernel->getContainer()->get('datasource.factory')->clearDataSource('news');
114
    }
115
116
    /**
117
     * @Given /^there are following admin elements available$/
118
     */
119
    public function thereAreFollowingAdminElementsAvailable(TableNode $table)
120
    {
121
        foreach ($table->getHash() as $elementRow) {
122
            expect($this->kernel->getContainer()->get('admin.manager')->hasElement($elementRow['Id']))
123
                ->toBe(true);
124
            expect($this->kernel->getContainer()->get('admin.manager')->getElement($elementRow['Id'])->getName())
125
                ->toBe($elementRow['Name']);
126
        }
127
    }
128
129
    /**
130
     * @Given /^I am on the "([^"]*)" page$/
131
     */
132
    public function iAmOnThePage($pageName)
133
    {
134
        $this->getPage($pageName)->open();
135
    }
136
137
    /**
138
     * @Given /^I am on the "([^"]*)" page with id (\d+)$/
139
     */
140
    public function iAmOnThePageWithId($pageName, $id)
141
    {
142
        $this->getPage($pageName)->open(array('id' => $id));
143
    }
144
145
    /**
146
     * @When /^I follow "([^"]*)" url from top bar$/
147
     * @Given /^I follow "([^"]*)" menu element$/
148
     */
149
    public function iFollowUrlFromTopBar($menuElement)
150
    {
151
        $this->getPage('Admin Panel')->getMenu()->clickLink($menuElement);
152
    }
153
154
    /**
155
     * @Then /^I should see "([^"]*)" title at top bar$/
156
     */
157
    public function iShouldSeeTitleAtTopBar($navbarBrandText)
158
    {
159
        expect($this->getPage('Admin Panel')->getNavbarBrandText())->toBe($navbarBrandText);
160
    }
161
162
    /**
163
     * @Then /^menu with following elements should be visible at the top of the page$/
164
     */
165
    public function menuWithFollowingElementsShouldBeVisibleAtTheTopOfThePage(TableNode $table)
166
    {
167
        $page = $this->getPage('Admin Panel');
168
169
        expect($page->getMenuElementsCount())->toBe(count($table->getHash()));
170
171
        foreach ($table->getHash() as $elementRow) {
172
            expect($page->hasMenuElement(
173
                $elementRow['Element name'],
174
                empty($elementRow['Element group']) ? null : $elementRow['Element group'])
175
            )->toBe(true);
176
        }
177
    }
178
179
    /**
180
     * @Given /^I should see "([^"]*)" page header "([^"]*)"$/
181
     */
182
    public function iShouldSeePageHeader($pageName, $headerContent)
183
    {
184
        expect($this->getPage($pageName)->getHeader())->toBe($headerContent);
185
    }
186
187
    /**
188
     * @Given /^translations are enabled in application$/
189
     */
190
    public function translationsAreEnabledInApplication()
191
    {
192
        expect($this->kernel->getContainer()->get('translator'))->toBeAnInstanceOf('Symfony\Component\Translation\TranslatorInterface');
0 ignored issues
show
Bug introduced by
The method toBeAnInstanceOf() does not exist on Bossa\PhpSpec\Expect\Subject. Did you maybe mean beAnInstanceOf()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
193
    }
194
195
196
    /**
197
     * @Then /^I should see language dropdown button in navigation bar with text "([^"]*)"$/
198
     * @Then /^I should see language dropdown button with text "([^"]*)"$/
199
     */
200
    public function iShouldSeeLanguageDropdownButtonInNavigationBarWithText($button)
201
    {
202
        expect($this->getPage('Admin panel')->getLanguageDropdown()->hasLink($button))->toBe(true);
203
    }
204
205
    /**
206
     * @Given /^language dropdown button should have following links$/
207
     */
208
    public function languageDropdownButtonShouldHaveFollowingLinks(TableNode $dropdownLinks)
209
    {
210
        $links = $this->getPage('Admin panel')->getLanguageDropdownOptions();
211
212
        foreach ($dropdownLinks->getHash() as $link) {
213
            expect($links)->toContain($link['Link']);
214
        }
215
216
    }
217
218
    /**
219
     * @When /^I click "([^"]*)" link from language dropdown button$/
220
     */
221
    public function iClickLinkFromLanguageDropdownButton($link)
222
    {
223
        $this->getPage('Admin panel')->getLanguageDropdown()->clickLink($link);
224
    }
225
226
    /**
227
     * @Then /^I should see details about news at page$/
228
     */
229
    public function iShouldSeeDetailsAboutNewsAtPage()
230
    {
231
        expect($this->getPage('News List')->hasTable('table-bordered'))->toBe(true);
232
    }
233
234
    /**
235
     * @Transform /"([^"]*)" non-editable collection/
236
     * @Transform /non-editable collection "([^"]*)"/
237
     */
238
    public function transformToNoneditableCollection($collectionNames)
239
    {
240
        return $this->getPage('Page')->getNoneditableCollection($collectionNames);
241
    }
242
243
244
    /**
245
     * @Transform /^"([^"]*)" collection/
246
     * @Transform /collection "([^"]*)"/
247
     */
248
    public function transformToCollection($collectionNames)
249
    {
250
        return $this->getPage('Page')->getCollection($collectionNames);
251
    }
252
    /**
253
     * @Given /^("[^"]*" collection) should have (\d+) elements$/
254
     * @Given /^(non-editable collection "[^"]*") should have (\d+) elements$/
255
     */
256
    public function collectionShouldHaveElements(NodeElement $collection, $elementsCount)
257
    {
258
        $elements = $collection->findAll('xpath', '/*/*[@class = "form-group"]');
259
        expect(count($elements))->toBe($elementsCount);
260
    }
261
262
    /**
263
     * @Given /^(collection "[^"]*") should have "([^"]*)" button$/
264
     */
265
    public function collectionShouldHaveButton(NodeElement $collection, $buttonName)
266
    {
267
        expect($collection->findButton($buttonName))->toNotBeNull();
268
    }
269
270
    /**
271
     * @Then /^all buttons for adding and removing items in (non-editable collection "[^"]*") should be disabled$/
272
     */
273
    public function allCollectionButtonsDisabled(NodeElement $collection)
274
    {
275
        $removeButtons = $collection->findAll('css', '.collection-remove');
276
        expect(count($removeButtons))->notToBe(0);
277
        foreach ($removeButtons as $removeButton) {
278
            expect($removeButton->hasClass('disabled'))->toBe(true);
279
        }
280
        $addButtons = $collection->findAll('css', '.collection-add');
281
        expect(count($addButtons))->notToBe(0);
282
        foreach ($addButtons as $addButton) {
283
            expect($addButton->hasClass('disabled'))->toBe(true);
284
        }
285
    }
286
287
288
    /**
289
     * @When /^I press "([^"]*)" in (collection "[^"]*")$/
290
     */
291
    public function iPressInCollection($buttonName, NodeElement $collection)
0 ignored issues
show
Unused Code introduced by
The parameter $buttonName is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
292
    {
293
        $collection
294
            ->find('xpath', '/*[contains(concat(" ",normalize-space(@class)," ")," collection-add ")]')
295
            ->press();
296
    }
297
298
    /**
299
     * @Given /^I fill "([^"]*)" with "([^"]*)" in (collection "[^"]*") at position (\d+)$/
300
     */
301
    public function iFillWithInCollectionAtPosition($fieldName, $fieldValue, NodeElement $collection, $position)
302
    {
303
        $collectionRow = $collection->find('xpath', sprintf('/*/*[@class = "form-group"][%d]', $position));
304
        $collectionRow->fillField($fieldName, $fieldValue);
305
    }
306
307
    /**
308
     * @Given /^I remove (\w+) element in (collection "[^"]*")$/
309
     */
310
    public function iRemoveElementInCollection($index, NodeElement $collection)
311
    {
312
        $collection->find('xpath', sprintf('/*/*[@class = "form-group"][%d]', $index))
313
             ->find('css', '.collection-remove')->click();
314
    }
315
}
316