moveNavigationNode()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
/**
4
 * This file is part of the Spryker Commerce OS.
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types = 1);
9
10
namespace PyzTest\Zed\NavigationGui;
11
12
use Codeception\Actor;
13
use Exception;
14
use Generated\Shared\Transfer\NavigationTreeNodeTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfe...igationTreeNodeTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Generated\Shared\Transfer\NavigationTreeTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\NavigationTreeTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Orm\Zed\Navigation\Persistence\SpyNavigation;
17
use Orm\Zed\Navigation\Persistence\SpyNavigationQuery;
18
19
/**
20
 * Inherited Methods
21
 *
22
 * @method void wantToTest($text)
23
 * @method void wantTo($text)
24
 * @method void execute($callable)
25
 * @method void expectTo($prediction)
26
 * @method void expect($prediction)
27
 * @method void amGoingTo($argumentation)
28
 * @method void am($role)
29
 * @method void lookForwardTo($achieveValue)
30
 * @method void comment($description)
31
 * @method \Codeception\Lib\Friend haveFriend($name, $actorClass = NULL)
32
 *
33
 * @SuppressWarnings(\PyzTest\Zed\NavigationGui\PHPMD)
34
 */
35
class NavigationGuiPresentationTester extends Actor
36
{
37
    use _generated\NavigationGuiPresentationTesterActions;
0 ignored issues
show
Bug introduced by
The type PyzTest\Zed\NavigationGu...esentationTesterActions was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
38
39
    /**
40
     * @var string
41
     */
42
    public const ROOT_NODE_ANCHOR_SELECTOR = '#navigation-node-0_anchor';
43
44
    /**
45
     * @var string
46
     */
47
    public const CHILD_NODE_ANCHOR_SELECTOR = '#navigation-node-%d_anchor';
48
49
    /**
50
     * @var string
51
     */
52
    public const NAVIGATION_NODE_SELECTOR = '.jstree-node';
53
54
    /**
55
     * @var string
56
     */
57
    public const NAVIGATION_TREE_SELECTOR = '#navigation-tree';
58
59
    /**
60
     * @var string
61
     */
62
    public const NAVIGATION_TREE_SAVE_BUTTON_SELECTOR = '#navigation-tree-save-btn';
63
64
    /**
65
     * @var string
66
     */
67
    public const REMOVE_NODE_BUTTON_SELECTOR = '#remove-selected-node-btn';
68
69
    /**
70
     * @var string
71
     */
72
    public const ADD_CHILD_NODE_BUTTON_SELECTOR = '#add-child-node-btn';
73
74
    /**
75
     * @var string
76
     */
77
    public const LOCALIZED_FORM_CONTAINER_SELECTOR = '#localized_attributes_container-%s .collapse-link';
78
79
    /**
80
     * @var string
81
     */
82
    public const NODE_CHILD_SELECTOR = '#navigation-node-%d #navigation-node-%d';
83
84
    /**
85
     * @var string
86
     */
87
    public const NODE_NAME_CHILD_SELECTOR = "//*[@id=\"navigation-node-%d\"]//*[text()[contains(.,'%s')]]";
88
89
    /**
90
     * @var string
91
     */
92
    public const NODE_FORM_IFRAME_NAME = 'navigation-node-form-iframe';
93
94
    /**
95
     * @var string
96
     */
97
    public const SUCCESS_MESSAGE_SELECTOR = '.flash-messages .alert-success';
98
99
    /**
100
     * @var string
101
     */
102
    public const SWEET_ALERT_SELECTOR = '.sweet-alert';
103
104
    /**
105
     * @var string
106
     */
107
    public const SWEET_ALERT_CONFIRM_SELECTOR = '.sweet-alert button.confirm';
108
109
    /**
110
     * @var string
111
     */
112
    public const NODE_FORM_SELECTOR = 'form';
113
114
    /**
115
     * @var string
116
     */
117
    public const NODE_UPDATE_FORM_SELECTOR = '//form[@name="navigation_node"]';
118
119
    /**
120
     * @var string
121
     */
122
    public const FLASH_MESSAGE_TEXT_SELECTOR = '//div[@class="flash-messages"]/div';
123
124
    /**
125
     * @var string
126
     */
127
    public const NAVIGATION_DELETE_FORM_SELECTOR = '//*[@id="navigation-table"]/tbody/tr/td[5]/form[1]';
128
129
    /**
130
     * @var string
131
     */
132
    public const NAVIGATION_ROW_ACTIVE_LINK_SELECTOR = '//*[@id="navigation-table"]/tbody/tr[1]/td[5]/a[2]';
133
134
    /**
135
     * @param string $value
136
     *
137
     * @return void
138
     */
139
    public function setNameField(string $value): void
140
    {
141
        $this->fillField('//*[@id="navigation_name"]', $value);
142
    }
143
144
    /**
145
     * @param string $value
146
     *
147
     * @return void
148
     */
149
    public function setKeyField(string $value): void
150
    {
151
        $this->fillField('//*[@id="navigation_key"]', $value);
152
    }
153
154
    /**
155
     * @param bool $checked
156
     *
157
     * @return void
158
     */
159
    public function checkIsActiveField(bool $checked): void
160
    {
161
        if ($checked) {
162
            $this->checkOption('//*[@id="navigation_is_active"]');
163
        } else {
164
            $this->uncheckOption('//*[@id="navigation_is_active"]');
165
        }
166
    }
167
168
    /**
169
     * @return void
170
     */
171
    public function submitNavigationForm(): void
172
    {
173
        $this->click('//*[@id="navigation-save-btn"]');
174
    }
175
176
    /**
177
     * @return void
178
     */
179
    public function submitDeleteNavigationForm(): void
180
    {
181
        $this->click('//*[@id="delete_navigation_form_submit"]');
182
    }
183
184
    /**
185
     * @param string $pattern
186
     * @param string $value
187
     *
188
     * @return void
189
     */
190
    public function seeMatches(string $pattern, string $value): void
191
    {
192
        $this->assertRegExp($pattern, $value);
193
    }
194
195
    /**
196
     * @return void
197
     */
198
    public function clickEditFirstRowInList(): void
199
    {
200
        $this->click('//*[@id="navigation-table"]/tbody/tr[1]/td[5]/a');
201
    }
202
203
    /**
204
     * @param string $expectedMessagePattern
205
     *
206
     * @return string
207
     */
208
    public function seeSuccessMessage(string $expectedMessagePattern): string
209
    {
210
        $this->waitForElementVisible(static::FLASH_MESSAGE_TEXT_SELECTOR, 90);
211
        $successMessage = $this->grabTextFrom(static::FLASH_MESSAGE_TEXT_SELECTOR);
212
        $this->seeMatches($expectedMessagePattern, $successMessage);
213
214
        preg_match($expectedMessagePattern, $successMessage, $matches);
215
216
        return $matches[1];
217
    }
218
219
    /**
220
     * @return void
221
     */
222
    public function activateFirstNavigationRow(): void
223
    {
224
        $this->click(static::NAVIGATION_ROW_ACTIVE_LINK_SELECTOR);
225
    }
226
227
    /**
228
     * @return void
229
     */
230
    public function deleteFirstNavigationRow(): void
231
    {
232
        $this->submitForm(static::NAVIGATION_DELETE_FORM_SELECTOR, []);
233
    }
234
235
    /**
236
     * @return int
237
     */
238
    public function prepareTestNavigationEntity(): int
239
    {
240
        $navigationEntity = new SpyNavigation();
241
        $navigationEntity
242
            ->setName('Acceptance navigation (2)')
243
            ->setKey('acceptance2')
244
            ->setIsActive(true)
245
            ->save();
246
247
        return $navigationEntity->getIdNavigation();
248
    }
249
250
    /**
251
     * @param string $localeName
252
     *
253
     * @return void
254
     */
255
    public function expandLocalizedForm(string $localeName): void
256
    {
257
        $this->click(sprintf(self::LOCALIZED_FORM_CONTAINER_SELECTOR, $localeName));
258
    }
259
260
    /**
261
     * @return void
262
     */
263
    public function clickRootNode(): void
264
    {
265
        $this->click(self::ROOT_NODE_ANCHOR_SELECTOR);
266
    }
267
268
    /**
269
     * @param int $idNavigationNode
270
     *
271
     * @return void
272
     */
273
    public function clickNode(int $idNavigationNode): void
274
    {
275
        $this->click(sprintf(self::CHILD_NODE_ANCHOR_SELECTOR, $idNavigationNode));
276
    }
277
278
    /**
279
     * @return void
280
     */
281
    public function waitForNavigationTree(): void
282
    {
283
        $this->waitForElement(self::NAVIGATION_TREE_SELECTOR);
284
        $this->wait(5);
285
    }
286
287
    /**
288
     * @param int $count
289
     *
290
     * @return void
291
     */
292
    public function seeNumberOfNavigationNodes(int $count): void
293
    {
294
        $this->seeNumberOfElements(self::NAVIGATION_NODE_SELECTOR, $count);
295
    }
296
297
    /**
298
     * @param int $idParentNavigationNode
299
     * @param int $idChildNavigationNode
300
     *
301
     * @return void
302
     */
303
    public function seeNavigationNodeHierarchy(int $idParentNavigationNode, int $idChildNavigationNode): void
304
    {
305
        $this->waitForElement(sprintf(
306
            self::NODE_CHILD_SELECTOR,
307
            $idParentNavigationNode,
308
            $idChildNavigationNode,
309
        ), 1);
310
    }
311
312
    /**
313
     * @param int $idParentNavigationNode
314
     * @param string $childNavigationNodeName
315
     *
316
     * @return void
317
     */
318
    public function seeNavigationNodeHierarchyByChildNodeName(int $idParentNavigationNode, string $childNavigationNodeName): void
319
    {
320
        $this->seeElement(sprintf(
321
            self::NODE_NAME_CHILD_SELECTOR,
322
            $idParentNavigationNode,
323
            $childNavigationNodeName,
324
        ));
325
    }
326
327
    /**
328
     * @param int $idNavigationNode
329
     * @param int $idTargetNavigationNode
330
     *
331
     * @return void
332
     */
333
    public function moveNavigationNode(int $idNavigationNode, int $idTargetNavigationNode): void
334
    {
335
        $this->dragAndDrop(
336
            sprintf(self::CHILD_NODE_ANCHOR_SELECTOR, $idNavigationNode),
337
            sprintf(self::CHILD_NODE_ANCHOR_SELECTOR, $idTargetNavigationNode),
338
        );
339
    }
340
341
    /**
342
     * @return void
343
     */
344
    public function saveNavigationTreeOrder(): void
345
    {
346
        $this->click(self::NAVIGATION_TREE_SAVE_BUTTON_SELECTOR);
347
    }
348
349
    /**
350
     * @param string $message
351
     *
352
     * @return void
353
     */
354
    public function seeSuccessfulOrderSaveMessage(string $message): void
355
    {
356
        $this->waitForElement(self::SWEET_ALERT_SELECTOR, 5);
357
        $this->wait(1);
358
        $this->see($message);
359
        $this->click(self::SWEET_ALERT_CONFIRM_SELECTOR);
360
    }
361
362
    /**
363
     * @return void
364
     */
365
    public function switchToNodeForm(): void
366
    {
367
        $this->switchToIFrame(self::NODE_FORM_IFRAME_NAME);
368
        $this->waitForElement(self::NODE_FORM_SELECTOR, 5);
369
    }
370
371
    /**
372
     * @return void
373
     */
374
    public function switchToNavigationTree(): void
375
    {
376
        $this->switchToIFrame();
377
        $this->waitForNavigationTree();
378
    }
379
380
    /**
381
     * @return void
382
     */
383
    public function clickRemoveNodeButton(): void
384
    {
385
        $this->click(self::REMOVE_NODE_BUTTON_SELECTOR);
386
    }
387
388
    /**
389
     * @return void
390
     */
391
    public function clickAddChildNodeButton(): void
392
    {
393
        $this->click(self::ADD_CHILD_NODE_BUTTON_SELECTOR);
394
    }
395
396
    /**
397
     * @param string $title
398
     *
399
     * @return void
400
     */
401
    public function submitCreateNodeFormWithoutType(string $title): void
402
    {
403
        $this->submitForm(self::NODE_FORM_SELECTOR, [
404
            'navigation_node[navigation_node_localized_attributes][0][title]' => $title,
405
            'navigation_node[navigation_node_localized_attributes][1][title]' => $title,
406
            'navigation_node[is_active]' => true,
407
        ]);
408
    }
409
410
    /**
411
     * @param string $title
412
     * @param string $externalUrl
413
     *
414
     * @return void
415
     */
416
    public function submitCreateNodeFormWithExternalUrlType(string $title, string $externalUrl): void
417
    {
418
        $this->submitForm(self::NODE_FORM_SELECTOR, [
419
            'navigation_node[node_type]' => 'external_url',
420
            'navigation_node[navigation_node_localized_attributes][0][external_url]' => $externalUrl,
421
            'navigation_node[navigation_node_localized_attributes][1][external_url]' => $externalUrl,
422
            'navigation_node[navigation_node_localized_attributes][0][title]' => $title,
423
            'navigation_node[navigation_node_localized_attributes][1][title]' => $title,
424
            'navigation_node[is_active]' => true,
425
        ]);
426
    }
427
428
    /**
429
     * @param string $categoryUrl_en_US
430
     * @param string $categoryUrl_de_DE
431
     *
432
     * @return void
433
     */
434
    public function submitUpdateNodeToCategoryType(string $categoryUrl_en_US, string $categoryUrl_de_DE): void
435
    {
436
        $this->selectOption('#navigation_node_node_type', 'Category');
437
438
        $this->fillField('//form[@name=\'navigation_node\']//input[@name=\'navigation_node[navigation_node_localized_attributes][0][category_url]\']', $categoryUrl_en_US);
439
        $this->fillField('//form[@name=\'navigation_node\']//input[@name=\'navigation_node[navigation_node_localized_attributes][1][category_url]\']', $categoryUrl_de_DE);
440
441
        $this->click('//*[@id="navigation-node-form-submit"]');
442
    }
443
444
    /**
445
     * @param string $title
446
     * @param string $cmsPageUrl_en_US
447
     * @param string $cmsPageUrl_de_DE
448
     *
449
     * @return void
450
     */
451
    public function submitCreateNodeFormWithCmsPageType(string $title, string $cmsPageUrl_en_US, string $cmsPageUrl_de_DE): void
452
    {
453
        $this->submitForm(self::NODE_FORM_SELECTOR, [
454
            'navigation_node[node_type]' => 'cms_page',
455
            'navigation_node[navigation_node_localized_attributes][0][title]' => $title,
456
            'navigation_node[navigation_node_localized_attributes][0][cms_page_url]' => $cmsPageUrl_en_US,
457
            'navigation_node[navigation_node_localized_attributes][1][title]' => $title,
458
            'navigation_node[navigation_node_localized_attributes][1][cms_page_url]' => $cmsPageUrl_de_DE,
459
            'navigation_node[is_active]' => true,
460
        ]);
461
    }
462
463
    /**
464
     * @param \Generated\Shared\Transfer\NavigationTreeTransfer $navigationTreeTransfer
465
     *
466
     * @return \Generated\Shared\Transfer\NavigationTreeTransfer
467
     */
468
    public function prepareTestNavigationTreeEntities(NavigationTreeTransfer $navigationTreeTransfer): NavigationTreeTransfer
469
    {
470
        $navigationTransfer = $this->getLocator()->navigation()->facade()->createNavigation($navigationTreeTransfer->getNavigation());
471
472
        foreach ($navigationTreeTransfer->getNodes() as $navigationTreeNodeTransfer) {
473
            $this->createNavigationNodesRecursively($navigationTreeNodeTransfer, $navigationTransfer->getIdNavigation());
474
        }
475
476
        return $navigationTreeTransfer;
477
    }
478
479
    /**
480
     * @param \Generated\Shared\Transfer\NavigationTreeNodeTransfer $navigationTreeNodeTransfer
481
     * @param int $idNavigation
482
     * @param int|null $idParentNavigationNode
483
     *
484
     * @return void
485
     */
486
    protected function createNavigationNodesRecursively(
487
        NavigationTreeNodeTransfer $navigationTreeNodeTransfer,
488
        int $idNavigation,
489
        ?int $idParentNavigationNode = null,
490
    ): void {
491
        $navigationNodeTransfer = $navigationTreeNodeTransfer->getNavigationNode();
492
        $navigationNodeTransfer
493
            ->setFkNavigation($idNavigation)
494
            ->setFkParentNavigationNode($idParentNavigationNode);
495
496
        $navigationNodeTransfer = $this->getLocator()->navigation()->facade()->createNavigationNode($navigationNodeTransfer);
497
498
        foreach ($navigationTreeNodeTransfer->getChildren() as $childNavigationTreeNodeTransfer) {
499
            $this->createNavigationNodesRecursively($childNavigationTreeNodeTransfer, $idNavigation, $navigationNodeTransfer->getIdNavigationNode());
500
        }
501
    }
502
503
    /**
504
     * @param string $locale
505
     *
506
     * @return int
507
     */
508
    public function getIdLocale(string $locale): int
509
    {
510
        return $this->getLocator()->locale()->facade()->getLocale($locale)->getIdLocale();
511
    }
512
513
    /**
514
     * @param \Generated\Shared\Transfer\NavigationTreeTransfer $navigationTreeTransfer
515
     *
516
     * @return void
517
     */
518
    public function cleanUpNavigationTree(NavigationTreeTransfer $navigationTreeTransfer): void
519
    {
520
        $navigationEntity = $this->findNavigationByIdNavigation(
521
            $navigationTreeTransfer->getNavigationOrFail()->getIdNavigationOrFail(),
522
        );
523
524
        if (!$navigationEntity) {
525
            return;
526
        }
527
528
        $navigationNodeEntities = $navigationEntity->getSpyNavigationNodes();
529
530
        foreach ($navigationNodeEntities as $navigationNodeEntity) {
531
            $navigationNodeEntity->getSpyNavigationNodeLocalizedAttributess()->delete();
532
        }
533
534
        $navigationNodeEntities->delete();
535
        $navigationEntity->delete();
536
    }
537
538
    /**
539
     * @param int $idNavigation
540
     *
541
     * @return \Orm\Zed\Navigation\Persistence\SpyNavigation|null
542
     */
543
    protected function findNavigationByIdNavigation(int $idNavigation): ?SpyNavigation
544
    {
545
        return (new SpyNavigationQuery())->findOneByIdNavigation($idNavigation);
546
    }
547
548
    /**
549
     * @param array $data
550
     *
551
     * @return void
552
     */
553
    public function submitCreateNodeFormWithCmsPageTypeWithFormData(array $data): void
554
    {
555
        $formData = [
556
            'navigation_node[node_type]' => 'cms_page',
557
            'navigation_node[is_active]' => true,
558
        ];
559
        foreach ($data as $index => $localizedData) {
560
            $titleKey = sprintf('navigation_node[navigation_node_localized_attributes][%s][title]', $index);
561
            $urlKey = sprintf('navigation_node[navigation_node_localized_attributes][%s][cms_page_url]', $index);
562
            $formData[$titleKey] = $localizedData['title'];
563
            $formData[$urlKey] = $localizedData['url'];
564
        }
565
        $this->submitForm(static::NODE_FORM_SELECTOR, $formData);
566
    }
567
568
    /**
569
     * @param string $defaultSlug
570
     * @param array<string> $localizedSlugs
571
     *
572
     * @return array
573
     */
574
    public function generateUrlByAvailableLocaleTransfers(string $defaultSlug, array $localizedSlugs): array
575
    {
576
        $localeTransfers = $this->getLocator()->locale()->facade()->getLocaleCollection();
577
578
        $localeUrls = [];
579
        foreach ($localeTransfers as $localeTransfer) {
580
            $localePrefix = substr($localeTransfer->getLocaleName(), 0, 2);
581
            $localeUrls[] = sprintf('/%s/%s', $localePrefix, $localizedSlugs[$localeTransfer->getLocaleName()] ?? $defaultSlug);
582
        }
583
584
        return $localeUrls;
585
    }
586
587
    /**
588
     * @param callable $callable
589
     * @param int $maxCount
590
     * @param bool $verbose
591
     *
592
     * @return void
593
     */
594
    public function repeatUnstableActions(callable $callable, int $maxCount = 10, bool $verbose = false): void
595
    {
596
        $count = 0;
597
598
        while ($count < $maxCount) {
599
            try {
600
                $callable();
601
602
                break;
603
            } catch (Exception $exception) {
604
                $count++;
605
                if ($verbose) {
606
                    echo "Try: {$count}: ";
607
                }
608
            }
609
        }
610
    }
611
}
612