Completed
Push — symfony-fqcn-sylius-4 ( 896d93...f41f61 )
by Kamil
18:34
created

CreatePage::moveLeaf()   B

Complexity

Conditions 4
Paths 3

Size

Total Lines 23
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 8.7972
c 0
b 0
f 0
cc 4
eloc 13
nc 3
nop 2
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->getParent()->find('css', '.ui.red.button')->press();
71
72
                return;
73
            }
74
        }
75
76
        throw new ElementNotFoundException($this->getDriver(), 'Delete button');
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function describeItAs($description, $languageCode)
83
    {
84
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_description', $languageCode), $description);
85
    }
86
87
    /**
88
     * {@inheritdoc}
89
     */
90
    public function hasTaxonWithName($name)
91
    {
92
        return 0 !== $this->countTaxonsByName($name);
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function nameIt($name, $languageCode)
99
    {
100
        $this->activateLanguageTab($languageCode);
101
        $this->getElement('name', ['%language%' => $languageCode])->setValue($name);
102
103
        $this->waitForSlugGenerationIfNecessary($languageCode);
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function specifySlug($slug, $languageCode)
110
    {
111
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_slug', $languageCode), $slug);
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public function attachImage($path, $code = null)
118
    {
119
        $filesPath = $this->getParameter('files_path');
120
121
        $this->getDocument()->find('css', '[data-form-collection="add"]')->click();
122
123
        $imageForm = $this->getLastImageElement();
124
        $imageForm->fillField('Code', $code);
125
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath.$path);
126
    }
127
128
    /**
129
     * {@inheritDoc}
130
     */
131
    public function moveUp(TaxonInterface $taxon)
132
    {
133
        $this->moveLeaf($taxon, self::MOVE_DIRECTION_UP);
134
    }
135
136
    /**
137
     * {@inheritDoc}
138
     */
139
    public function moveDown(TaxonInterface $taxon)
140
    {
141
        $this->moveLeaf($taxon, self::MOVE_DIRECTION_DOWN);
142
    }
143
144
    /**
145
     * {@inheritDoc}
146
     */
147
    public function getLeafNameFromPosition($position, TaxonInterface $parentTaxon = null)
148
    {
149
        $firstTaxonElement = $this->getLeaves($parentTaxon)[0];
150
151
        return $firstTaxonElement->getText();
152
    }
153
154
    /**
155
     * {@inheritdoc}
156
     */
157
    public function getLeaves(TaxonInterface $parentTaxon = null)
158
    {
159
        $tree = $this->getElement('tree');
160
        Assert::notNull($tree);
161
        /** @var NodeElement[] $leaves */
162
        $leaves = $tree->findAll('css', '.item > .content > .header > a');
163
164
        if (null === $parentTaxon) {
165
            return $leaves;
166
        }
167
168
        foreach ($leaves as $leaf) {
169
            if ($leaf->getText() === $parentTaxon->getName()) {
170
                return $leaf->findAll('css', '.item > .content > .header');
171
            }
172
        }
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178
    public function activateLanguageTab($locale)
179
    {
180
        if (!$this->getDriver() instanceof Selenium2Driver) {
181
            return;
182
        }
183
184
        $languageTabTitle = $this->getElement('language_tab', ['%locale%' => $locale]);
185
        if (!$languageTabTitle->hasClass('active')) {
186
            $languageTabTitle->click();
187
        }
188
    }
189
190
    /**
191
     * {@inheritdoc}
192
     */
193
    protected function getElement($name, array $parameters = [])
194
    {
195
        if (!isset($parameters['%language%'])) {
196
            $parameters['%language%'] = 'en_US';
197
        }
198
199
        return parent::getElement($name, $parameters);
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
            'language_tab' => '[data-locale="%locale%"] .title',
212
            'name' => '#sylius_taxon_translations_%language%_name',
213
            'parent' => '#sylius_taxon_parent',
214
            'slug' => '#sylius_taxon_translations_%language%_slug',
215
            'tree' => '.ui.list',
216
        ]);
217
    }
218
219
    /**
220
     * @param TaxonInterface $taxon
221
     * @param string $direction
222
     *
223
     * @throws ElementNotFoundException
224
     */
225
    private function moveLeaf(TaxonInterface $taxon, $direction)
226
    {
227
        Assert::oneOf($direction, [self::MOVE_DIRECTION_UP, self::MOVE_DIRECTION_DOWN]);
228
229
        $leaves = $this->getLeaves();
230
        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...
231
            if ($leaf->getText() === $taxon->getName()) {
232
                $moveButton = $leaf->getParent()->find('css', sprintf('.sylius-taxon-move-%s', $direction));
233
                $moveButton->click();
234
235
                $moveButton->waitFor(5, function () use ($moveButton) {
236
                    return $this->isOpen() && !$moveButton->hasClass('loading');
237
                });
238
239
                return;
240
            }
241
        }
242
243
        throw new ElementNotFoundException(
244
            $this->getDriver(),
245
            sprintf('Move %s button for %s taxon', $direction, $taxon->getName())
246
        );
247
    }
248
249
    /**
250
     * @return NodeElement
251
     */
252
    private function getLastImageElement()
253
    {
254
        $images = $this->getElement('images');
255
        $items = $images->findAll('css', 'div[data-form-collection="item"]');
256
257
        Assert::notEmpty($items);
258
259
        return end($items);
260
    }
261
262
    /**
263
     * @param string $languageCode
264
     */
265
    private function waitForSlugGenerationIfNecessary($languageCode)
266
    {
267
        if ($this->getDriver() instanceof Selenium2Driver) {
268
            $this->getDocument()->waitFor(10, function () use ($languageCode) {
269
                return '' !== $this->getElement('slug', ['%language%' => $languageCode])->getValue();
270
            });
271
        }
272
    }
273
}
274