Completed
Push — to-be-a-hat-or-not-to-be-kuhwa ( b72886...e84c48 )
by Kamil
19:11
created

CreatePage::getLeaves()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 4
nop 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\Page\Admin\Taxon;
13
14
use Behat\Mink\Driver\Selenium2Driver;
15
use Behat\Mink\Element\NodeElement;
16
use Behat\Mink\Exception\ElementNotFoundException;
17
use Behat\Mink\Exception\UnsupportedDriverActionException;
18
use Sylius\Behat\Behaviour\SpecifiesItsCode;
19
use Sylius\Behat\Page\Admin\Crud\CreatePage as BaseCreatePage;
20
use Sylius\Component\Core\Model\TaxonInterface;
21
use Webmozart\Assert\Assert;
22
23
/**
24
 * @author Arkadiusz Krakowiak <[email protected]>
25
 */
26
class CreatePage extends BaseCreatePage implements CreatePageInterface
27
{
28
    use SpecifiesItsCode;
29
30
    /**
31
     * {@inheritdoc}
32
     */
33
    public function countTaxons()
34
    {
35
        return count($this->getLeaves());
36
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function countTaxonsByName($name)
42
    {
43
        $matchedLeavesCounter = 0;
44
        $leaves = $this->getLeaves();
45
        foreach ($leaves as $leaf) {
0 ignored issues
show
Bug introduced by
The expression $leaves of type array<integer,object<Beh...ment\NodeElement>>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
46
            if (strpos($leaf->getText(), $name) !== false) {
47
                $matchedLeavesCounter++;
48
            }
49
        }
50
51
        return $matchedLeavesCounter;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function chooseParent(TaxonInterface $taxon)
58
    {
59
        $this->getElement('parent')->selectOption($taxon->getName(), false);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function deleteTaxonOnPageByName($name)
66
    {
67
        $leaves = $this->getLeaves();
68
        foreach ($leaves as $leaf) {
0 ignored issues
show
Bug introduced by
The expression $leaves of type array<integer,object<Beh...ment\NodeElement>>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
69
            if ($leaf->getText() === $name) {
70
                $leaf = $leaf->getParent();
71
                $menuButton = $leaf->find('css', '.wrench');
72
                $menuButton->click();
73
                $deleteButton = $leaf->find('css', '.sylius-delete-resource');
74
                $deleteButton->click();
75
76
                $deleteButton->waitFor(5, function () {
77
                    return false;
78
                });
79
80
                return;
81
            }
82
        }
83
84
        throw new ElementNotFoundException($this->getDriver(), 'Delete button');
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function describeItAs($description, $languageCode)
91
    {
92
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_description', $languageCode), $description);
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function hasTaxonWithName($name)
99
    {
100
        return 0 !== $this->countTaxonsByName($name);
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function nameIt($name, $languageCode)
107
    {
108
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_name', $languageCode), $name);
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function specifyPermalink($permalink, $languageCode)
115
    {
116
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_permalink', $languageCode), $permalink);
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122
    public function attachImage($path, $code = null)
123
    {
124
        $filesPath = $this->getParameter('files_path');
125
126
        $this->getDocument()->find('css', '[data-form-collection="add"]')->click();
127
128
        $imageForm = $this->getLastImageElement();
129
        $imageForm->fillField('Code', $code);
130
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath.$path);
131
    }
132
133
    /**
134
     * {@inheritDoc}
135
     */
136
    public function moveUp(TaxonInterface $taxon)
137
    {
138
        $this->moveLeaf($taxon, self::MOVE_DIRECTION_UP);
139
    }
140
141
    /**
142
     * {@inheritDoc}
143
     */
144
    public function moveDown(TaxonInterface $taxon)
145
    {
146
        $this->moveLeaf($taxon, self::MOVE_DIRECTION_DOWN);
147
    }
148
149
    /**
150
     * {@inheritDoc}
151
     */
152
    public function getFirstLeafName(TaxonInterface $parentTaxon = null)
153
    {
154
        return $this->getLeaves($parentTaxon)[0]->getText();
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160
    public function insertBefore(TaxonInterface $draggableTaxon, TaxonInterface $targetTaxon)
161
    {
162
        $seleniumDriver = $this->getSeleniumDriver();
163
        $draggableTaxonLocator = sprintf('.item[data-id="%s"]', $draggableTaxon->getId());
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $draggableTaxonLocator exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
164
        $targetTaxonLocator = sprintf('.item[data-id="%s"]', $targetTaxon->getId());
165
166
        $script = <<<JS
167
(function ($) {
168
    $('$draggableTaxonLocator').simulate('drag-n-drop',{
169
        dragTarget: $('$targetTaxonLocator'),
170
        interpolation: {stepWidth: 10, stepDelay: 30} 
171
    });    
172
})(jQuery);
173
JS;
174
175
        $seleniumDriver->executeScript($script);
176
        $this->getDocument()->waitFor(5, function () {
177
            return false;
178
        });
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184
    public function getLeaves(TaxonInterface $parentTaxon = null)
185
    {
186
        $tree = $this->getElement('tree');
187
        Assert::notNull($tree);
188
        /** @var NodeElement[] $leaves */
189
        $leaves = $tree->findAll('css', '.item > .content > .header');
190
191
        if (null === $parentTaxon) {
192
            return $leaves;
193
        }
194
195
        foreach ($leaves as $leaf) {
196
            if ($leaf->getText() === $parentTaxon->getName()) {
197
                return $leaf->findAll('css', '.item > .content > .header');
198
            }
199
        }
200
    }
201
202
    /**
203
     * {@inheritdoc}
204
     */
205
    protected function getDefinedElements()
206
    {
207
        return array_merge(parent::getDefinedElements(), [
208
            'code' => '#sylius_taxon_code',
209
            'description' => '#sylius_taxon_translations_en_US_description',
210
            'images' => '#sylius_taxon_images',
211
            'name' => '#sylius_taxon_translations_en_US_name',
212
            'parent' => '#sylius_taxon_parent',
213
            'permalink' => '#sylius_taxon_translations_en_US_permalink',
214
            'tree' => '.ui.list',
215
        ]);
216
    }
217
218
    /**
219
     * @param TaxonInterface $taxon
220
     * @param string $direction
221
     *
222
     * @throws ElementNotFoundException
223
     */
224
    private function moveLeaf(TaxonInterface $taxon, $direction)
225
    {
226
        Assert::oneOf($direction, [self::MOVE_DIRECTION_UP, self::MOVE_DIRECTION_DOWN]);
227
228
        $leaves = $this->getLeaves();
229
        foreach ($leaves as $leaf) {
0 ignored issues
show
Bug introduced by
The expression $leaves of type array<integer,object<Beh...ment\NodeElement>>|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
230
            if ($leaf->getText() === $taxon->getName()) {
231
                $leaf = $leaf->getParent();
232
                $menuButton = $leaf->find('css', '.wrench');
233
                $menuButton->click();
234
                $moveButton = $leaf->find('css', sprintf('.%s', $direction));
235
                $moveButton->click();
236
                $moveButton->waitFor(5, function () use ($taxon) {
237
                    return $this->getFirstLeafName() === $taxon->getName();
238
                });
239
240
                return;
241
            }
242
        }
243
244
        throw new ElementNotFoundException(
245
            $this->getDriver(),
246
            sprintf('Move %s button for %s taxon', $direction, $taxon->getName())
247
        );
248
    }
249
250
    /**
251
     * @return NodeElement
252
     */
253
    private function getLastImageElement()
254
    {
255
        $images = $this->getElement('images');
256
        $items = $images->findAll('css', 'div[data-form-collection="item"]');
257
258
        Assert::notEmpty($items);
259
260
        return end($items);
261
    }
262
263
    /**
264
     * @return Selenium2Driver
265
     *
266
     * @throws UnsupportedDriverActionException
267
     */
268
    private function getSeleniumDriver()
269
    {
270
        /** @var Selenium2Driver $driver */
271
        $driver = $this->getDriver();
272
        if (!$driver instanceof Selenium2Driver) {
273
            throw new UnsupportedDriverActionException('This action is not supported by %s', $driver);
274
        }
275
276
        return $driver;
277
    }
278
}
279