Completed
Push — 1.0-reliable-behat ( 67387b...793074 )
by Kamil
95:43 queued 52:59
created

UpdatePage::isImageWithTypeDisplayed()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
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
declare(strict_types=1);
13
14
namespace Sylius\Behat\Page\Admin\Taxon;
15
16
use Behat\Mink\Driver\Selenium2Driver;
17
use Behat\Mink\Element\NodeElement;
18
use Behat\Mink\Exception\ElementNotFoundException;
19
use Sylius\Behat\Behaviour\ChecksCodeImmutability;
20
use Sylius\Behat\Page\Admin\Crud\UpdatePage as BaseUpdatePage;
21
use Sylius\Behat\Service\AutocompleteHelper;
22
use Sylius\Behat\Service\SlugGenerationHelper;
23
use Sylius\Component\Core\Model\TaxonInterface;
24
use Webmozart\Assert\Assert;
25
26
class UpdatePage extends BaseUpdatePage implements UpdatePageInterface
27
{
28
    use ChecksCodeImmutability;
29
30
    /** @var array */
31
    private $imageUrls = [];
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public function chooseParent(TaxonInterface $taxon)
37
    {
38
        AutocompleteHelper::chooseValue($this->getSession(), $this->getElement('parent')->getParent(), $taxon->getName());
0 ignored issues
show
Bug introduced by
It seems like $this->getElement('parent')->getParent() can be null; however, chooseValue() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function describeItAs($description, $languageCode)
45
    {
46
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_description', $languageCode), $description);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function nameIt($name, $languageCode)
53
    {
54
        $this->activateLanguageTab($languageCode);
55
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_name', $languageCode), $name);
56
57
        if ($this->getDriver() instanceof Selenium2Driver) {
58
            SlugGenerationHelper::waitForSlugGeneration(
59
                $this->getSession(),
60
                $this->getElement('slug', ['%language%' => $languageCode])
61
            );
62
        }
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function specifySlug($slug, $languageCode)
69
    {
70
        $this->getDocument()->fillField(sprintf('sylius_taxon_translations_%s_slug', $languageCode), $slug);
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function attachImage($path, $type = null)
77
    {
78
        $filesPath = $this->getParameter('files_path');
79
80
        $this->getDocument()->find('css', '[data-form-collection="add"]')->click();
81
82
        $imageForm = $this->getLastImageElement();
83
        if (null !== $type) {
84
            $imageForm->fillField('Type', $type);
85
        }
86
87
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
88
    }
89
90
    /**
91
     * {@inheritdoc}
92
     */
93
    public function isImageWithTypeDisplayed($type)
94
    {
95
        $imageElement = $this->getImageElementByType($type);
96
97
        $imageUrl = $imageElement ? $imageElement->find('css', 'img')->getAttribute('src') : $this->provideImageUrlForType($type);
98
        if (null === $imageElement && null === $imageUrl) {
99
            return false;
100
        }
101
102
        $this->getDriver()->visit($imageUrl);
103
        $pageText = $this->getDocument()->getText();
104
        $this->getDriver()->back();
105
106
        return false === stripos($pageText, '404 Not Found');
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function isSlugReadonly($languageCode = 'en_US')
113
    {
114
        return SlugGenerationHelper::isSlugReadonly(
115
            $this->getSession(),
116
            $this->getElement('slug', ['%language%' => $languageCode])
117
        );
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123
    public function removeImageWithType($type)
124
    {
125
        $imageElement = $this->getImageElementByType($type);
126
        $imageSourceElement = $imageElement->find('css', 'img');
127
        if (null !== $imageSourceElement) {
128
            $this->saveImageUrlForType($type, $imageSourceElement->getAttribute('src'));
129
        }
130
131
        $imageElement->clickLink('Delete');
132
    }
133
134
    public function removeFirstImage()
135
    {
136
        $imageElement = $this->getFirstImageElement();
137
        $imageTypeElement = $imageElement->find('css', 'input[type=text]');
138
        $imageSourceElement = $imageElement->find('css', 'img');
139
140
        if (null !== $imageTypeElement && null !== $imageSourceElement) {
141
            $this->saveImageUrlForType(
142
                $imageTypeElement->getValue(),
143
                $imageSourceElement->getAttribute('src')
144
            );
145
        }
146
147
        $imageElement->clickLink('Delete');
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function enableSlugModification($languageCode = 'en_US')
154
    {
155
        SlugGenerationHelper::enableSlugModification(
156
            $this->getSession(),
157
            $this->getElement('toggle_taxon_slug_modification_button', ['%locale%' => $languageCode])
158
        );
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    public function countImages()
165
    {
166
        $imageElements = $this->getImageElements();
167
168
        return count($imageElements);
169
    }
170
171
    /**
172
     * {@inheritdoc}
173
     */
174
    public function changeImageWithType($type, $path)
175
    {
176
        $filesPath = $this->getParameter('files_path');
177
178
        $imageForm = $this->getImageElementByType($type);
179
        $imageForm->find('css', 'input[type="file"]')->attachFile($filesPath . $path);
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185
    public function modifyFirstImageType($type)
186
    {
187
        $firstImage = $this->getFirstImageElement();
188
189
        $typeField = $firstImage->findField('Type');
190
        $typeField->setValue($type);
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function getParent()
197
    {
198
        return $this->getElement('parent')->getValue();
199
    }
200
201
    /**
202
     * {@inheritdoc}
203
     */
204
    public function getSlug($languageCode = 'en_US')
205
    {
206
        return $this->getElement('slug', ['%language%' => $languageCode])->getValue();
207
    }
208
209
    /**
210
     * {@inheritdoc}
211
     */
212
    public function getValidationMessageForImage()
213
    {
214
        $lastImageElement = $this->getLastImageElement();
215
216
        $foundElement = $lastImageElement->find('css', '.sylius-validation-error');
217
        if (null === $foundElement) {
218
            throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
219
        }
220
221
        return $foundElement->getText();
222
    }
223
224
    /**
225
     * {@inheritdoc}
226
     */
227
    public function getValidationMessageForImageAtPlace($place)
228
    {
229
        $images = $this->getImageElements();
230
231
        $foundElement = $images[$place]->find('css', '.sylius-validation-error');
232
        if (null === $foundElement) {
233
            throw new ElementNotFoundException($this->getSession(), 'Tag', 'css', '.sylius-validation-error');
234
        }
235
236
        return $foundElement->getText();
237
    }
238
239
    /**
240
     * {@inheritdoc}
241
     */
242
    public function activateLanguageTab($locale)
243
    {
244
        if (!$this->getDriver() instanceof Selenium2Driver) {
245
            return;
246
        }
247
248
        $languageTabTitle = $this->getElement('language_tab', ['%locale%' => $locale]);
249
        if (!$languageTabTitle->hasClass('active')) {
250
            $languageTabTitle->click();
251
        }
252
253
        $this->getDocument()->waitFor(10, function () use ($languageTabTitle) {
254
            return $languageTabTitle->hasClass('active');
255
        });
256
    }
257
258
    /**
259
     * {@inheritdoc}
260
     */
261
    protected function getElement($name, array $parameters = [])
262
    {
263
        if (!isset($parameters['%language%'])) {
264
            $parameters['%language%'] = 'en_US';
265
        }
266
267
        return parent::getElement($name, $parameters);
268
    }
269
270
    /**
271
     * @return NodeElement
272
     */
273
    protected function getCodeElement()
274
    {
275
        return $this->getElement('code');
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     */
281
    protected function getDefinedElements()
282
    {
283
        return array_merge(parent::getDefinedElements(), [
284
            'code' => '#sylius_taxon_code',
285
            'description' => '#sylius_taxon_translations_en_US_description',
286
            'images' => '#sylius_taxon_images',
287
            'language_tab' => '[data-locale="%locale%"] .title',
288
            'name' => '#sylius_taxon_translations_en_US_name',
289
            'parent' => '#sylius_taxon_parent',
290
            'slug' => '#sylius_taxon_translations_%language%_slug',
291
            'toggle_taxon_slug_modification_button' => '[data-locale="%locale%"] .toggle-taxon-slug-modification',
292
        ]);
293
    }
294
295
    /**
296
     * @return NodeElement
297
     */
298
    private function getLastImageElement()
299
    {
300
        $imageElements = $this->getImageElements();
301
302
        Assert::notEmpty($imageElements);
303
304
        return end($imageElements);
305
    }
306
307
    /**
308
     * @return NodeElement
309
     */
310
    private function getFirstImageElement()
311
    {
312
        $imageElements = $this->getImageElements();
313
314
        Assert::notEmpty($imageElements);
315
316
        return reset($imageElements);
317
    }
318
319
    /**
320
     * @return NodeElement[]
321
     */
322
    private function getImageElements()
323
    {
324
        $images = $this->getElement('images');
325
326
        return $images->findAll('css', 'div[data-form-collection="item"]');
327
    }
328
329
    /**
330
     * @param string $type
331
     *
332
     * @return NodeElement
333
     */
334
    private function getImageElementByType($type)
335
    {
336
        $images = $this->getElement('images');
337
        $typeInput = $images->find('css', 'input[value="' . $type . '"]');
338
339
        if (null === $typeInput) {
340
            return null;
341
        }
342
343
        return $typeInput->getParent()->getParent()->getParent();
344
    }
345
346
    private function provideImageUrlForType(string $type): ?string
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
347
    {
348
        return $this->imageUrls[$type] ?? null;
349
    }
350
351
    private function saveImageUrlForType(string $type, string $imageUrl): void
352
    {
353
        if (false !== strpos($imageUrl, 'data:image/jpeg')) {
354
            return;
355
        }
356
357
        $this->imageUrls[$type] = $imageUrl;
358
    }
359
}
360