Completed
Push — 7.5 ( 872380...ff94d7 )
by Łukasz
21:16
created

testCreateGlobalUrlAliasPropertyValues()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 18
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 18
loc 18
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the URLAliasServiceTest class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Publish\API\Repository\Tests;
10
11
use Doctrine\DBAL\Connection;
12
use eZ\Publish\API\Repository\Exceptions\InvalidArgumentException;
13
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
14
use eZ\Publish\API\Repository\Tests\Common\SlugConverter as TestSlugConverter;
15
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
16
use eZ\Publish\API\Repository\Values\Content\Location;
17
use eZ\Publish\API\Repository\Values\Content\URLAlias;
18
use Exception;
19
use PDO;
20
use RuntimeException;
21
22
/**
23
 * Test case for operations in the URLAliasService using in memory storage.
24
 *
25
 * @see \eZ\Publish\API\Repository\URLAliasService
26
 * @group url-alias
27
 */
28
class URLAliasServiceTest extends BaseTest
29
{
30
    /**
31
     * Tests that the required <b>LocationService::loadLocation()</b>
32
     * at least returns an object, because this method is utilized in several
33
     * tests.
34
     */
35
    protected function setUp()
36
    {
37
        parent::setUp();
38
39
        try {
40
            // Load the LocationService
41
            $locationService = $this->getRepository()->getLocationService();
42
43
            $membersUserGroupLocationId = 12;
44
45
            // Load a location instance
46
            $location = $locationService->loadLocation(
47
                $membersUserGroupLocationId
48
            );
49
50
            if (false === is_object($location)) {
51
                $this->markTestSkipped(
52
                    'This test cannot be executed, because the utilized ' .
53
                    'LocationService::loadLocation() does not ' .
54
                    'return an object.'
55
                );
56
            }
57
        } catch (Exception $e) {
58
            $this->markTestSkipped(
59
                'This test cannot be executed, because the utilized ' .
60
                'LocationService::loadLocation() failed with ' .
61
                PHP_EOL . PHP_EOL .
62
                $e->getTraceAsString()
63
            );
64
        }
65
    }
66
67
    /**
68
     * Test for the createUrlAlias() method.
69
     *
70
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias()
71
     */
72
    public function testCreateUrlAlias()
73
    {
74
        $repository = $this->getRepository();
75
76
        $locationId = $this->generateId('location', 5);
77
78
        /* BEGIN: Use Case */
79
        // $locationId is the ID of an existing location
80
81
        $locationService = $repository->getLocationService();
82
        $urlAliasService = $repository->getURLAliasService();
83
84
        $location = $locationService->loadLocation($locationId);
85
86
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US');
87
        /* END: Use Case */
88
89
        $this->assertInstanceOf(
90
            URLAlias::class,
91
            $createdUrlAlias
92
        );
93
94
        return [$createdUrlAlias, $location->id];
95
    }
96
97
    /**
98
     * Test for the createUrlAlias() method.
99
     *
100
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias()
101
     */
102
    public function testCreateSameAliasForDiffrentLanguage()
103
    {
104
        $repository = $this->getRepository();
105
        $locationId = $this->generateId('location', 5);
106
        $locationService = $repository->getLocationService();
107
        $urlAliasService = $repository->getURLAliasService();
108
        $location = $locationService->loadLocation($locationId);
109
110
        $alias = $urlAliasService->createUrlAlias($location, '/alias', 'eng-US');
0 ignored issues
show
Unused Code introduced by
$alias is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
111
        $updatedAlias = $urlAliasService->createUrlAlias($location, '/alias', 'eng-GB');
112
113
        $this->assertPropertiesCorrect(
114
            [
115
                'languageCodes' => ['eng-US', 'eng-GB'],
116
            ],
117
            $updatedAlias
118
        );
119
    }
120
121
    /**
122
     * @param array $testData
123
     *
124
     * @depends testCreateUrlAlias
125
     */
126 View Code Duplication
    public function testCreateUrlAliasPropertyValues(array $testData)
127
    {
128
        list($createdUrlAlias, $locationId) = $testData;
129
130
        $this->assertNotNull($createdUrlAlias->id);
131
132
        $this->assertPropertiesCorrect(
133
            [
134
                'type' => URLAlias::LOCATION,
135
                'destination' => $locationId,
136
                'path' => '/Home/My-New-Site',
137
                'languageCodes' => ['eng-US'],
138
                'alwaysAvailable' => false,
139
                'isHistory' => false,
140
                'isCustom' => true,
141
                'forward' => false,
142
            ],
143
            $createdUrlAlias
144
        );
145
    }
146
147
    /**
148
     * Test for the createUrlAlias() method.
149
     *
150
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias($location, $path, $languageCode, $forwarding)
151
     * @depends testCreateUrlAliasPropertyValues
152
     */
153 View Code Duplication
    public function testCreateUrlAliasWithForwarding()
154
    {
155
        $repository = $this->getRepository();
156
157
        $locationId = $this->generateId('location', 5);
158
159
        /* BEGIN: Use Case */
160
        // $locationId is the ID of an existing location
161
162
        $locationService = $repository->getLocationService();
163
        $urlAliasService = $repository->getURLAliasService();
164
165
        $location = $locationService->loadLocation($locationId);
166
167
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US', true);
168
        /* END: Use Case */
169
170
        $this->assertInstanceOf(
171
            URLAlias::class,
172
            $createdUrlAlias
173
        );
174
175
        return [$createdUrlAlias, $location->id];
176
    }
177
178
    /**
179
     * @param array $testData
180
     *
181
     * @depends testCreateUrlAliasWithForwarding
182
     */
183 View Code Duplication
    public function testCreateUrlAliasPropertyValuesWithForwarding(array $testData)
184
    {
185
        list($createdUrlAlias, $locationId) = $testData;
186
187
        $this->assertNotNull($createdUrlAlias->id);
188
189
        $this->assertPropertiesCorrect(
190
            [
191
                'type' => URLAlias::LOCATION,
192
                'destination' => $locationId,
193
                'path' => '/Home/My-New-Site',
194
                'languageCodes' => ['eng-US'],
195
                'alwaysAvailable' => false,
196
                'isHistory' => false,
197
                'isCustom' => true,
198
                'forward' => true,
199
            ],
200
            $createdUrlAlias
201
        );
202
    }
203
204
    /**
205
     * Test for the createUrlAlias() method.
206
     *
207
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias($location, $path, $languageCode, $forwarding, $alwaysAvailable)
208
     */
209 View Code Duplication
    public function testCreateUrlAliasWithAlwaysAvailable()
210
    {
211
        $repository = $this->getRepository();
212
213
        $locationId = $this->generateId('location', 5);
214
215
        /* BEGIN: Use Case */
216
        // $locationId is the ID of an existing location
217
218
        $locationService = $repository->getLocationService();
219
        $urlAliasService = $repository->getURLAliasService();
220
221
        $location = $locationService->loadLocation($locationId);
222
223
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US', false, true);
224
        /* END: Use Case */
225
226
        $this->assertInstanceOf(
227
            URLAlias::class,
228
            $createdUrlAlias
229
        );
230
231
        return [$createdUrlAlias, $location->id];
232
    }
233
234
    /**
235
     * @param array $testData
236
     *
237
     * @depends testCreateUrlAliasWithAlwaysAvailable
238
     */
239 View Code Duplication
    public function testCreateUrlAliasPropertyValuesWithAlwaysAvailable(array $testData)
240
    {
241
        list($createdUrlAlias, $locationId) = $testData;
242
243
        $this->assertNotNull($createdUrlAlias->id);
244
245
        $this->assertPropertiesCorrect(
246
            [
247
                'type' => URLAlias::LOCATION,
248
                'destination' => $locationId,
249
                'path' => '/Home/My-New-Site',
250
                'languageCodes' => ['eng-US'],
251
                'alwaysAvailable' => true,
252
                'isHistory' => false,
253
                'isCustom' => true,
254
                'forward' => false,
255
            ],
256
            $createdUrlAlias
257
        );
258
    }
259
260
    /**
261
     * Test for the createUrlAlias() method.
262
     *
263
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias()
264
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
265
     */
266
    public function testCreateUrlAliasThrowsInvalidArgumentException()
267
    {
268
        $repository = $this->getRepository();
269
270
        $locationId = $this->generateId('location', 5);
271
272
        /* BEGIN: Use Case */
273
        // $locationId is the ID of an existing location
274
275
        $locationService = $repository->getLocationService();
276
        $urlAliasService = $repository->getURLAliasService();
277
278
        $location = $locationService->loadLocation($locationId);
279
280
        // Throws InvalidArgumentException, since this path already exists for the
281
        // language
282
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Design/Plain-site', 'eng-US');
0 ignored issues
show
Unused Code introduced by
$createdUrlAlias is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
283
        /* END: Use Case */
284
    }
285
286
    /**
287
     * Test for the createGlobalUrlAlias() method.
288
     *
289
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias()
290
     */
291 View Code Duplication
    public function testCreateGlobalUrlAlias()
292
    {
293
        $repository = $this->getRepository();
294
295
        /* BEGIN: Use Case */
296
        $urlAliasService = $repository->getURLAliasService();
297
298
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
299
            'module:content/search?SearchText=eZ',
300
            '/Home/My-New-Site',
301
            'eng-US'
302
        );
303
        /* END: Use Case */
304
305
        $this->assertInstanceOf(
306
            URLAlias::class,
307
            $createdUrlAlias
308
        );
309
310
        return $createdUrlAlias;
311
    }
312
313
    /**
314
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
315
     *
316
     * @depends testCreateGlobalUrlAlias
317
     */
318 View Code Duplication
    public function testCreateGlobalUrlAliasPropertyValues(URLAlias $createdUrlAlias)
319
    {
320
        $this->assertNotNull($createdUrlAlias->id);
321
322
        $this->assertPropertiesCorrect(
323
            [
324
                'type' => URLAlias::RESOURCE,
325
                'destination' => 'content/search?SearchText=eZ',
326
                'path' => '/Home/My-New-Site',
327
                'languageCodes' => ['eng-US'],
328
                'alwaysAvailable' => false,
329
                'isHistory' => false,
330
                'isCustom' => true,
331
                'forward' => false,
332
            ],
333
            $createdUrlAlias
334
        );
335
    }
336
337
    /**
338
     * Test for the createGlobalUrlAlias() method.
339
     *
340
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forward)
341
     */
342 View Code Duplication
    public function testCreateGlobalUrlAliasWithForward()
343
    {
344
        $repository = $this->getRepository();
345
346
        /* BEGIN: Use Case */
347
        $urlAliasService = $repository->getURLAliasService();
348
349
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
350
            'module:content/search?SearchText=eZ',
351
            '/Home/My-New-Site',
352
            'eng-US',
353
            true
354
        );
355
        /* END: Use Case */
356
357
        $this->assertInstanceOf(
358
            URLAlias::class,
359
            $createdUrlAlias
360
        );
361
362
        return $createdUrlAlias;
363
    }
364
365
    /**
366
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
367
     *
368
     * @depends testCreateGlobalUrlAliasWithForward
369
     */
370 View Code Duplication
    public function testCreateGlobalUrlAliasWithForwardPropertyValues(URLAlias $createdUrlAlias)
371
    {
372
        $this->assertNotNull($createdUrlAlias->id);
373
374
        $this->assertPropertiesCorrect(
375
            [
376
                'type' => URLAlias::RESOURCE,
377
                'destination' => 'content/search?SearchText=eZ',
378
                'path' => '/Home/My-New-Site',
379
                'languageCodes' => ['eng-US'],
380
                'alwaysAvailable' => false,
381
                'isHistory' => false,
382
                'isCustom' => true,
383
                'forward' => true,
384
            ],
385
            $createdUrlAlias
386
        );
387
    }
388
389
    /**
390
     * Test for the createGlobalUrlAlias() method.
391
     *
392
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
393
     */
394 View Code Duplication
    public function testCreateGlobalUrlAliasWithAlwaysAvailable()
395
    {
396
        $repository = $this->getRepository();
397
398
        /* BEGIN: Use Case */
399
        $urlAliasService = $repository->getURLAliasService();
400
401
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
402
            'module:content/search?SearchText=eZ',
403
            '/Home/My-New-Site',
404
            'eng-US',
405
            false,
406
            true
407
        );
408
        /* END: Use Case */
409
410
        $this->assertInstanceOf(
411
            URLAlias::class,
412
            $createdUrlAlias
413
        );
414
415
        return $createdUrlAlias;
416
    }
417
418
    /**
419
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
420
     *
421
     * @depends testCreateGlobalUrlAliasWithAlwaysAvailable
422
     */
423 View Code Duplication
    public function testCreateGlobalUrlAliasWithAlwaysAvailablePropertyValues(URLAlias $createdUrlAlias)
424
    {
425
        $this->assertNotNull($createdUrlAlias->id);
426
427
        $this->assertPropertiesCorrect(
428
            [
429
                'type' => URLAlias::RESOURCE,
430
                'destination' => 'content/search?SearchText=eZ',
431
                'path' => '/Home/My-New-Site',
432
                'languageCodes' => ['eng-US'],
433
                'alwaysAvailable' => true,
434
                'isHistory' => false,
435
                'isCustom' => true,
436
                'forward' => false,
437
            ],
438
            $createdUrlAlias
439
        );
440
    }
441
442
    /**
443
     * Test for the createUrlAlias() method.
444
     *
445
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
446
     */
447 View Code Duplication
    public function testCreateGlobalUrlAliasForLocation()
448
    {
449
        $repository = $this->getRepository();
450
451
        $locationId = $this->generateId('location', 5);
452
        $locationService = $repository->getLocationService();
453
        $location = $locationService->loadLocation($locationId);
454
455
        /* BEGIN: Use Case */
456
        // $locationId is the ID of an existing location
457
458
        $urlAliasService = $repository->getURLAliasService();
459
460
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
461
            'module:content/view/full/' . $locationId,
462
            '/Home/My-New-Site-global',
463
            'eng-US',
464
            false,
465
            true
466
        );
467
        /* END: Use Case */
468
469
        $this->assertInstanceOf(
470
            URLAlias::class,
471
            $createdUrlAlias
472
        );
473
474
        return [$createdUrlAlias, $location->id];
475
    }
476
477
    /**
478
     * Test for the createUrlAlias() method.
479
     *
480
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
481
     */
482 View Code Duplication
    public function testCreateGlobalUrlAliasForLocationVariation()
483
    {
484
        $repository = $this->getRepository();
485
486
        $locationId = $this->generateId('location', 5);
487
        $locationService = $repository->getLocationService();
488
        $location = $locationService->loadLocation($locationId);
489
490
        /* BEGIN: Use Case */
491
        // $locationId is the ID of an existing location
492
493
        $urlAliasService = $repository->getURLAliasService();
494
495
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
496
            'eznode:' . $locationId,
497
            '/Home/My-New-Site-global',
498
            'eng-US',
499
            false,
500
            true
501
        );
502
        /* END: Use Case */
503
504
        $this->assertInstanceOf(
505
            URLAlias::class,
506
            $createdUrlAlias
507
        );
508
509
        return [$createdUrlAlias, $location->id];
510
    }
511
512
    /**
513
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
514
     *
515
     * @depends testCreateGlobalUrlAliasForLocation
516
     */
517 View Code Duplication
    public function testCreateGlobalUrlAliasForLocationPropertyValues($testData)
518
    {
519
        list($createdUrlAlias, $locationId) = $testData;
520
521
        $this->assertNotNull($createdUrlAlias->id);
522
523
        $this->assertPropertiesCorrect(
524
            [
525
                'type' => URLAlias::LOCATION,
526
                'destination' => $locationId,
527
                'path' => '/Home/My-New-Site-global',
528
                'languageCodes' => ['eng-US'],
529
                'alwaysAvailable' => true,
530
                'isHistory' => false,
531
                'isCustom' => true,
532
                'forward' => false,
533
            ],
534
            $createdUrlAlias
535
        );
536
    }
537
538
    /**
539
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
540
     *
541
     * @depends testCreateGlobalUrlAliasForLocationVariation
542
     */
543
    public function testCreateGlobalUrlAliasForLocationVariationPropertyValues($testData)
544
    {
545
        $this->testCreateGlobalUrlAliasForLocationPropertyValues($testData);
546
    }
547
548
    /**
549
     * Test for the createGlobalUrlAlias() method.
550
     *
551
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias()
552
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
553
     */
554
    public function testCreateGlobalUrlAliasThrowsInvalidArgumentException()
555
    {
556
        $repository = $this->getRepository();
557
558
        /* BEGIN: Use Case */
559
        $urlAliasService = $repository->getURLAliasService();
560
561
        // Throws InvalidArgumentException, since this path already exists for the
562
        // language
563
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
0 ignored issues
show
Unused Code introduced by
$createdUrlAlias is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
564
            'module:content/search?SearchText=eZ',
565
            '/Design/Plain-site',
566
            'eng-US'
567
        );
568
        /* END: Use Case */
569
    }
570
571
    /**
572
     * Test for the listLocationAliases() method.
573
     *
574
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases()
575
     */
576
    public function testListLocationAliases()
577
    {
578
        $repository = $this->getRepository();
579
580
        $locationId = $this->generateId('location', 12);
581
582
        /* BEGIN: Use Case */
583
        // $locationId contains the ID of an existing Location
584
        $urlAliasService = $repository->getURLAliasService();
585
        $locationService = $repository->getLocationService();
586
587
        $location = $locationService->loadLocation($locationId);
588
589
        // Create a custom URL alias for $location
590
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'eng-US');
591
592
        // $loadedAliases will contain an array of custom URLAlias objects
593
        $loadedAliases = $urlAliasService->listLocationAliases($location);
594
        /* END: Use Case */
595
596
        $this->assertIsArray($loadedAliases);
597
598
        // Only 1 non-history alias
599
        $this->assertCount(1, $loadedAliases);
600
601
        return [$loadedAliases, $location];
602
    }
603
604
    /**
605
     * @param array $testData
606
     *
607
     * @depends testListLocationAliases
608
     */
609
    public function testListLocationAliasesLoadsCorrectly(array $testData)
610
    {
611
        list($loadedAliases, $location) = $testData;
612
613
        foreach ($loadedAliases as $loadedAlias) {
614
            $this->assertInstanceOf(
615
                URLAlias::class,
616
                $loadedAlias
617
            );
618
            $this->assertEquals(
619
                $location->id,
620
                $loadedAlias->destination
621
            );
622
        }
623
    }
624
625
    /**
626
     * Test for the listLocationAliases() method.
627
     *
628
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases($location, $custom, $languageCode)
629
     */
630 View Code Duplication
    public function testListLocationAliasesWithCustomFilter()
631
    {
632
        $repository = $this->getRepository();
633
634
        $locationId = $this->generateId('location', 12);
635
636
        /* BEGIN: Use Case */
637
        // $locationId contains the ID of an existing Location
638
        $urlAliasService = $repository->getURLAliasService();
639
        $locationService = $repository->getLocationService();
640
641
        $location = $locationService->loadLocation($locationId);
642
643
        // Create a second URL alias for $location, this is a "custom" one
644
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'ger-DE');
645
646
        // $loadedAliases will contain 1 aliases in eng-US only
647
        $loadedAliases = $urlAliasService->listLocationAliases($location, false, 'eng-US');
648
        /* END: Use Case */
649
650
        $this->assertIsArray($loadedAliases);
651
        $this->assertCount(1, $loadedAliases);
652
    }
653
654
    /**
655
     * Test for the listLocationAliases() method.
656
     *
657
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases($location, $custom)
658
     */
659 View Code Duplication
    public function testListLocationAliasesWithLanguageCodeFilter()
660
    {
661
        $repository = $this->getRepository();
662
663
        $locationId = $this->generateId('location', 12);
664
665
        /* BEGIN: Use Case */
666
        // $locationId contains the ID of an existing Location
667
        $urlAliasService = $repository->getURLAliasService();
668
        $locationService = $repository->getLocationService();
669
670
        $location = $locationService->loadLocation($locationId);
671
        // Create a custom URL alias for $location
672
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'eng-US');
673
674
        // $loadedAliases will contain only 1 of 3 aliases (custom in eng-US)
675
        $loadedAliases = $urlAliasService->listLocationAliases($location, true, 'eng-US');
676
        /* END: Use Case */
677
678
        $this->assertIsArray($loadedAliases);
679
        $this->assertCount(1, $loadedAliases);
680
    }
681
682
    /**
683
     * Test for the listGlobalAliases() method.
684
     *
685
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases()
686
     */
687 View Code Duplication
    public function testListGlobalAliases()
688
    {
689
        $repository = $this->getRepository();
690
691
        /* BEGIN: Use Case */
692
        $urlAliasService = $repository->getURLAliasService();
693
694
        // Create some global aliases
695
        $this->createGlobalAliases();
696
697
        // $loadedAliases will contain all 3 global aliases
698
        $loadedAliases = $urlAliasService->listGlobalAliases();
699
        /* END: Use Case */
700
701
        $this->assertIsArray($loadedAliases);
702
        $this->assertCount(3, $loadedAliases);
703
    }
704
705
    /**
706
     * Creates 3 global aliases.
707
     */
708
    private function createGlobalAliases()
709
    {
710
        $repository = $this->getRepository();
711
        $urlAliasService = $repository->getURLAliasService();
712
713
        /* BEGIN: Inline */
714
        $urlAliasService->createGlobalUrlAlias(
715
            'module:content/search?SearchText=eZ',
716
            '/My/Special-Support',
717
            'eng-US'
718
        );
719
        $urlAliasService->createGlobalUrlAlias(
720
            'module:content/search?SearchText=eZ',
721
            '/My/London-Office',
722
            'eng-GB'
723
        );
724
        $urlAliasService->createGlobalUrlAlias(
725
            'module:content/search?SearchText=Sindelfingen',
726
            '/My/Fancy-Site',
727
            'eng-US'
728
        );
729
        /* END: Inline */
730
    }
731
732
    /**
733
     * Test for the listGlobalAliases() method.
734
     *
735
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode)
736
     */
737 View Code Duplication
    public function testListGlobalAliasesWithLanguageFilter()
738
    {
739
        $repository = $this->getRepository();
740
741
        /* BEGIN: Use Case */
742
        $urlAliasService = $repository->getURLAliasService();
743
744
        // Create some global aliases
745
        $this->createGlobalAliases();
746
747
        // $loadedAliases will contain only 2 of 3 global aliases
748
        $loadedAliases = $urlAliasService->listGlobalAliases('eng-US');
749
        /* END: Use Case */
750
751
        $this->assertIsArray($loadedAliases);
752
        $this->assertCount(2, $loadedAliases);
753
    }
754
755
    /**
756
     * Test for the listGlobalAliases() method.
757
     *
758
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode, $offset)
759
     */
760 View Code Duplication
    public function testListGlobalAliasesWithOffset()
761
    {
762
        $repository = $this->getRepository();
763
764
        /* BEGIN: Use Case */
765
        $urlAliasService = $repository->getURLAliasService();
766
767
        // Create some global aliases
768
        $this->createGlobalAliases();
769
770
        // $loadedAliases will contain only 2 of 3 global aliases
771
        $loadedAliases = $urlAliasService->listGlobalAliases(null, 1);
772
        /* END: Use Case */
773
774
        $this->assertIsArray($loadedAliases);
775
        $this->assertCount(2, $loadedAliases);
776
    }
777
778
    /**
779
     * Test for the listGlobalAliases() method.
780
     *
781
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode, $offset, $limit)
782
     */
783 View Code Duplication
    public function testListGlobalAliasesWithLimit()
784
    {
785
        $repository = $this->getRepository();
786
787
        /* BEGIN: Use Case */
788
        $urlAliasService = $repository->getURLAliasService();
789
790
        // Create some global aliases
791
        $this->createGlobalAliases();
792
793
        // $loadedAliases will contain only 1 of 3 global aliases
794
        $loadedAliases = $urlAliasService->listGlobalAliases(null, 0, 1);
795
        /* END: Use Case */
796
797
        $this->assertIsArray($loadedAliases);
798
        $this->assertCount(1, $loadedAliases);
799
    }
800
801
    /**
802
     * Test for the removeAliases() method.
803
     *
804
     * @see \eZ\Publish\API\Repository\URLAliasService::removeAliases()
805
     */
806 View Code Duplication
    public function testRemoveAliases()
807
    {
808
        $repository = $this->getRepository();
809
810
        $locationService = $repository->getLocationService();
811
        $someLocation = $locationService->loadLocation(
812
            $this->generateId('location', 12)
813
        );
814
815
        /* BEGIN: Use Case */
816
        // $someLocation contains a location with automatically generated
817
        // aliases assigned
818
        $urlAliasService = $repository->getURLAliasService();
819
820
        $initialAliases = $urlAliasService->listLocationAliases($someLocation);
821
822
        // Creates a custom alias for $someLocation
823
        $urlAliasService->createUrlAlias(
824
            $someLocation,
825
            '/my/fancy/url/alias/sindelfingen',
826
            'eng-US'
827
        );
828
829
        $customAliases = $urlAliasService->listLocationAliases($someLocation);
830
831
        // The custom alias just created will be removed
832
        // the automatic aliases stay in tact
833
        $urlAliasService->removeAliases($customAliases);
834
        /* END: Use Case */
835
836
        $this->assertEquals(
837
            $initialAliases,
838
            $urlAliasService->listLocationAliases($someLocation)
839
        );
840
    }
841
842
    /**
843
     * Test for the removeAliases() method.
844
     *
845
     * @see \eZ\Publish\API\Repository\URLAliasService::removeAliases()
846
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
847
     */
848
    public function testRemoveAliasesThrowsInvalidArgumentExceptionIfAutogeneratedAliasesAreToBeRemoved()
849
    {
850
        $repository = $this->getRepository();
851
852
        $locationService = $repository->getLocationService();
853
        $someLocation = $locationService->loadLocation(
854
            $this->generateId('location', 12)
855
        );
856
857
        /* BEGIN: Use Case */
858
        // $someLocation contains a location with automatically generated
859
        // aliases assigned
860
        $urlAliasService = $repository->getURLAliasService();
861
862
        $autogeneratedAliases = $urlAliasService->listLocationAliases($someLocation, false);
863
864
        // Throws an InvalidArgumentException, since autogeneratedAliases
865
        // cannot be removed with this method
866
        $urlAliasService->removeAliases($autogeneratedAliases);
867
        /* END: Use Case */
868
    }
869
870
    /**
871
     * Test for the lookUp() method.
872
     *
873
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp()
874
     */
875
    public function testLookUp()
876
    {
877
        $repository = $this->getRepository();
878
879
        /* BEGIN: Use Case */
880
        $urlAliasService = $repository->getURLAliasService();
881
882
        $loadedAlias = $urlAliasService->lookup('/Setup2');
883
        /* END: Use Case */
884
885
        $this->assertInstanceOf(
886
            URLAlias::class,
887
            $loadedAlias
888
        );
889
890
        return $loadedAlias;
891
    }
892
893
    /**
894
     * Test for the lookUp() method.
895
     *
896
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp($url, $languageCode)
897
     */
898
    public function testLookUpWithLanguageFilter()
899
    {
900
        $repository = $this->getRepository();
901
902
        /* BEGIN: Use Case */
903
        $urlAliasService = $repository->getURLAliasService();
904
905
        // Create aliases in multiple languages
906
        $this->createGlobalAliases();
907
908
        $loadedAlias = $urlAliasService->lookup('/My/Special-Support', 'eng-US');
909
        /* END: Use Case */
910
911
        $this->assertInstanceOf(
912
            URLAlias::class,
913
            $loadedAlias
914
        );
915
        $this->assertEquals(
916
            'content/search?SearchText=eZ',
917
            $loadedAlias->destination
918
        );
919
    }
920
921
    /**
922
     * Test for the lookUp() method.
923
     *
924
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp()
925
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
926
     */
927
    public function testLookUpThrowsNotFoundException()
928
    {
929
        $repository = $this->getRepository();
930
931
        /* BEGIN: Use Case */
932
        $urlAliasService = $repository->getURLAliasService();
933
934
        // Throws NotFoundException
935
        $urlAliasService->lookup('/non-existent-url');
936
        /* END: Use Case */
937
    }
938
939
    /**
940
     * Test for the lookUp() method.
941
     *
942
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp($url, $languageCode)
943
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
944
     */
945
    public function testLookUpThrowsNotFoundExceptionWithLanguageFilter()
946
    {
947
        $repository = $this->getRepository();
948
949
        /* BEGIN: Use Case */
950
        $urlAliasService = $repository->getURLAliasService();
951
952
        // Throws NotFoundException
953
        $urlAliasService->lookup('/Contact-Us', 'ger-DE');
954
        /* END: Use Case */
955
    }
956
957
    /**
958
     * Test for the lookUp() method.
959
     *
960
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp($url, $languageCode)
961
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
962
     */
963
    public function testLookUpThrowsInvalidArgumentException()
964
    {
965
        $repository = $this->getRepository();
966
967
        /* BEGIN: Use Case */
968
        $urlAliasService = $repository->getURLAliasService();
969
970
        // Throws InvalidArgumentException
971
        $loadedAlias = $urlAliasService->lookup(str_repeat('/1', 99), 'ger-DE');
0 ignored issues
show
Unused Code introduced by
$loadedAlias is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
972
        /* END: Use Case */
973
    }
974
975
    /**
976
     * Test for the lookUp() method after renaming parent which is a part of the lookup path.
977
     *
978
     * @see https://jira.ez.no/browse/EZP-28046
979
     * @covers \eZ\Publish\API\Repository\URLAliasService::lookUp
980
     * @covers \eZ\Publish\API\Repository\URLAliasService::listLocationAliases
981
     */
982
    public function testLookupOnRenamedParent()
983
    {
984
        $urlAliasService = $this->getRepository()->getURLAliasService();
985
        $locationService = $this->getRepository()->getLocationService();
986
        $contentTypeService = $this->getRepository()->getContentTypeService();
987
        $contentService = $this->getRepository()->getContentService();
988
989
        // 1. Create new container object (e.g. Folder "My Folder").
990
        $folderContentType = $contentTypeService->loadContentTypeByIdentifier('folder');
991
        $folderCreateStruct = $contentService->newContentCreateStruct($folderContentType, 'eng-GB');
992
        $folderCreateStruct->setField('name', 'My-Folder');
993
994
        $folderDraft = $contentService->createContent($folderCreateStruct, [
995
            $locationService->newLocationCreateStruct(2),
996
        ]);
997
998
        $folder = $contentService->publishVersion($folderDraft->versionInfo);
999
1000
        // 2. Create new object inside this container (e.g. article "My Article").
1001
        $folderLocation = $locationService->loadLocation($folder->contentInfo->mainLocationId);
1002
1003
        $articleContentType = $contentTypeService->loadContentTypeByIdentifier('article');
1004
        $articleCreateStruct = $contentService->newContentCreateStruct($articleContentType, 'eng-GB');
1005
        $articleCreateStruct->setField('title', 'My Article');
1006
        $articleCreateStruct->setField(
1007
            'intro',
1008
            <<< DOCBOOK
1009
<?xml version="1.0" encoding="UTF-8"?>
1010
<section xmlns="http://docbook.org/ns/docbook" version="5.0-variant ezpublish-1.0">
1011
    <para>Cache invalidation in eZ</para>
1012
</section>
1013
DOCBOOK
1014
        );
1015
        $article = $contentService->publishVersion(
1016
            $contentService->createContent($articleCreateStruct, [
1017
                $locationService->newLocationCreateStruct($folderLocation->id),
1018
            ])->versionInfo
1019
        );
1020
        $articleLocation = $locationService->loadLocation($article->contentInfo->mainLocationId);
1021
1022
        // 3. Navigate to both of them
1023
        $urlAliasService->lookup('/My-Folder');
1024
        $urlAliasService->listLocationAliases($folderLocation, false);
1025
        $urlAliasService->lookup('/My-Folder/My-Article');
1026
        $urlAliasService->listLocationAliases($articleLocation, false);
1027
1028
        // 4. Rename "My Folder" to "My Folder Modified".
1029
        $folderDraft = $contentService->createContentDraft($folder->contentInfo);
1030
        $folderUpdateStruct = $contentService->newContentUpdateStruct();
1031
        $folderUpdateStruct->setField('name', 'My Folder Modified');
1032
1033
        $contentService->publishVersion(
1034
            $contentService->updateContent($folderDraft->versionInfo, $folderUpdateStruct)->versionInfo
1035
        );
1036
1037
        // 5. Navigate to "Article"
1038
        $urlAliasService->lookup('/My-Folder/My-Article');
1039
        $aliases = $urlAliasService->listLocationAliases($articleLocation, false);
1040
1041
        $this->assertEquals('/My-Folder-Modified/My-Article', $aliases[0]->path);
1042
    }
1043
1044
    /**
1045
     * Test lookup on multilingual nested Locations returns proper UrlAlias Value.
1046
     *
1047
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1048
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1049
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1050
     */
1051
    public function testLookupOnMultilingualNestedLocations()
1052
    {
1053
        $urlAliasService = $this->getRepository()->getURLAliasService();
1054
        $locationService = $this->getRepository()->getLocationService();
1055
1056
        $topFolderNames = [
1057
            'eng-GB' => 'My folder Name',
1058
            'ger-DE' => 'Ger folder Name',
1059
            'eng-US' => 'My folder Name',
1060
        ];
1061
        $nestedFolderNames = [
1062
            'eng-GB' => 'nested Folder name',
1063
            'ger-DE' => 'Ger Nested folder Name',
1064
            'eng-US' => 'nested Folder name',
1065
        ];
1066
        $topFolderLocation = $locationService->loadLocation(
1067
            $this->createFolder($topFolderNames, 2)->contentInfo->mainLocationId
1068
        );
1069
        $nestedFolderLocation = $locationService->loadLocation(
1070
            $this->createFolder(
1071
                $nestedFolderNames,
1072
                $topFolderLocation->id
1073
            )->contentInfo->mainLocationId
1074
        );
1075
        $urlAlias = $urlAliasService->lookup('/My-Folder-Name/Nested-Folder-Name');
1076
        self::assertPropertiesCorrect(
1077
            [
1078
                'destination' => $nestedFolderLocation->id,
1079
                'path' => '/My-folder-Name/nested-Folder-name',
1080
                'languageCodes' => ['eng-US', 'eng-GB'],
1081
                'isHistory' => false,
1082
                'isCustom' => false,
1083
                'forward' => false,
1084
            ],
1085
            $urlAlias
1086
        );
1087
        $urlAlias = $urlAliasService->lookup('/Ger-Folder-Name/Ger-Nested-Folder-Name');
1088
        self::assertPropertiesCorrect(
1089
            [
1090
                'destination' => $nestedFolderLocation->id,
1091
                'path' => '/Ger-folder-Name/Ger-Nested-folder-Name',
1092
                'languageCodes' => ['ger-DE'],
1093
                'isHistory' => false,
1094
                'isCustom' => false,
1095
                'forward' => false,
1096
            ],
1097
            $urlAlias
1098
        );
1099
1100
        return [$topFolderLocation, $nestedFolderLocation];
1101
    }
1102
1103
    /**
1104
     * Test refreshSystemUrlAliasesForLocation historizes and changes current URL alias after
1105
     * changing SlugConverter configuration.
1106
     *
1107
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1108
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1109
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1110
     * @throws \ErrorException
1111
     */
1112
    public function testRefreshSystemUrlAliasesForLocationWithChangedSlugConverterConfiguration()
1113
    {
1114
        list($topFolderLocation, $nestedFolderLocation) = $this->testLookupOnMultilingualNestedLocations();
1115
1116
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1117
1118
        $this->changeSlugConverterConfiguration('transformation', 'urlalias_compat');
1119
        $this->changeSlugConverterConfiguration('wordSeparatorName', 'underscore');
1120
1121
        try {
1122
            $urlAliasService->refreshSystemUrlAliasesForLocation($topFolderLocation);
1123
            $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1124
1125
            $urlAlias = $urlAliasService->lookup('/My-Folder-Name/Nested-Folder-Name');
1126
            $this->assertUrlAliasPropertiesCorrect(
1127
                $nestedFolderLocation,
1128
                '/My-folder-Name/nested-Folder-name',
1129
                ['eng-US', 'eng-GB'],
1130
                true,
1131
                $urlAlias
1132
            );
1133
1134
            $urlAlias = $urlAliasService->lookup('/my_folder_name/nested_folder_name');
1135
            $this->assertUrlAliasPropertiesCorrect(
1136
                $nestedFolderLocation,
1137
                '/my_folder_name/nested_folder_name',
1138
                ['eng-US', 'eng-GB'],
1139
                false,
1140
                $urlAlias
1141
            );
1142
1143
            $urlAlias = $urlAliasService->lookup('/Ger-Folder-Name/Ger-Nested-Folder-Name');
1144
            $this->assertUrlAliasPropertiesCorrect(
1145
                $nestedFolderLocation,
1146
                '/Ger-folder-Name/Ger-Nested-folder-Name',
1147
                ['ger-DE'],
1148
                true,
1149
                $urlAlias
1150
            );
1151
1152
            $urlAlias = $urlAliasService->lookup('/ger_folder_name/ger_nested_folder_name');
1153
            $this->assertUrlAliasPropertiesCorrect(
1154
                $nestedFolderLocation,
1155
                '/ger_folder_name/ger_nested_folder_name',
1156
                ['ger-DE'],
1157
                false,
1158
                $urlAlias
1159
            );
1160
        } finally {
1161
            // restore configuration
1162
            $this->changeSlugConverterConfiguration('transformation', 'urlalias');
1163
            $this->changeSlugConverterConfiguration('wordSeparatorName', 'dash');
1164
        }
1165
    }
1166
1167
    /**
1168
     * Test that URL aliases are refreshed after changing URL alias schema Field name of a Content Type.
1169
     *
1170
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1171
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1172
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1173
     */
1174
    public function testRefreshSystemUrlAliasesForContentsWithUpdatedContentTypes()
1175
    {
1176
        list($topFolderLocation, $nestedFolderLocation) = $this->testLookupOnMultilingualNestedLocations();
1177
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $topFolderLocation */
1178
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $nestedFolderLocation */
1179
1180
        // Default URL Alias schema is <short_name|name> which messes up this test, so:
1181
        $this->changeContentTypeUrlAliasSchema('folder', '<name>');
1182
1183
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1184
1185
        $this->updateContentField(
1186
            $topFolderLocation->getContentInfo(),
1187
            'short_name',
1188
            ['eng-GB' => 'EN Short Name', 'ger-DE' => 'DE Short Name']
1189
        );
1190
        $this->updateContentField(
1191
            $nestedFolderLocation->getContentInfo(),
1192
            'short_name',
1193
            ['eng-GB' => 'EN Nested Short Name', 'ger-DE' => 'DE Nested Short Name']
1194
        );
1195
1196
        $this->changeContentTypeUrlAliasSchema('folder', '<short_name>');
1197
1198
        // sanity test, done after updating CT, because it does not update existing entries by design
1199
        $this->assertUrlIsCurrent('/My-folder-Name', $topFolderLocation->id);
1200
        $this->assertUrlIsCurrent('/Ger-folder-Name', $topFolderLocation->id);
1201
        $this->assertUrlIsCurrent('/My-folder-Name/nested-Folder-name', $nestedFolderLocation->id);
1202
        $this->assertUrlIsCurrent('/Ger-folder-Name/Ger-Nested-folder-Name', $nestedFolderLocation->id);
1203
1204
        // Call API being tested
1205
        $urlAliasService->refreshSystemUrlAliasesForLocation($topFolderLocation);
1206
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1207
1208
        // check archived aliases
1209
        $this->assertUrlIsHistory('/My-folder-Name', $topFolderLocation->id);
1210
        $this->assertUrlIsHistory('/Ger-folder-Name', $topFolderLocation->id);
1211
        $this->assertUrlIsHistory('/My-folder-Name/nested-Folder-name', $nestedFolderLocation->id);
1212
        $this->assertUrlIsHistory('/Ger-folder-Name/Ger-Nested-folder-Name', $nestedFolderLocation->id);
1213
1214
        // check new current aliases
1215
        $this->assertUrlIsCurrent('/EN-Short-Name', $topFolderLocation->id);
1216
        $this->assertUrlIsCurrent('/DE-Short-Name', $topFolderLocation->id);
1217
        $this->assertUrlIsCurrent('/EN-Short-Name/EN-Nested-Short-Name', $nestedFolderLocation->id);
1218
        $this->assertUrlIsCurrent('/DE-Short-Name/DE-Nested-Short-Name', $nestedFolderLocation->id);
1219
    }
1220
1221
    /**
1222
     * Test that created non-latin aliases are non-empty and unique.
1223
     *
1224
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1225
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1226
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1227
     */
1228
    public function testCreateNonLatinNonEmptyUniqueAliases()
1229
    {
1230
        $repository = $this->getRepository();
1231
        $urlAliasService = $repository->getURLAliasService();
1232
        $locationService = $repository->getLocationService();
1233
1234
        $folderNames = [
1235
            'eng-GB' => 'ひらがな',
1236
        ];
1237
1238
        $folderLocation1 = $locationService->loadLocation(
1239
            $this->createFolder($folderNames, 2)->contentInfo->mainLocationId
1240
        );
1241
        $urlAlias1 = $urlAliasService->lookup('/1');
1242
        self::assertPropertiesCorrect(
1243
            [
1244
                'destination' => $folderLocation1->id,
1245
                'path' => '/1',
1246
                'languageCodes' => ['eng-GB'],
1247
                'isHistory' => false,
1248
                'isCustom' => false,
1249
                'forward' => false,
1250
            ],
1251
            $urlAlias1
1252
        );
1253
1254
        $folderLocation2 = $locationService->loadLocation(
1255
            $this->createFolder($folderNames, 2)->contentInfo->mainLocationId
1256
        );
1257
        $urlAlias2 = $urlAliasService->lookup('/2');
1258
        self::assertPropertiesCorrect(
1259
            [
1260
                'destination' => $folderLocation2->id,
1261
                'path' => '/2',
1262
                'languageCodes' => ['eng-GB'],
1263
                'isHistory' => false,
1264
                'isCustom' => false,
1265
                'forward' => false,
1266
            ],
1267
            $urlAlias2
1268
        );
1269
    }
1270
1271
    /**
1272
     * Test restoring missing current URL which has existing history.
1273
     *
1274
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1275
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1276
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1277
     * @throws \Exception
1278
     */
1279
    public function testRefreshSystemUrlAliasesForMissingUrlWithHistory()
1280
    {
1281
        $repository = $this->getRepository();
1282
        $urlAliasService = $repository->getURLAliasService();
1283
        $locationService = $repository->getLocationService();
1284
1285
        $folderNames = ['eng-GB' => 'My folder Name'];
1286
        $folder = $this->createFolder($folderNames, 2);
1287
        $folderLocation = $locationService->loadLocation($folder->contentInfo->mainLocationId);
1288
        $nestedFolder = $this->createFolder(['eng-GB' => 'Nested folder'], $folderLocation->id);
1289
        $nestedFolderLocation = $locationService->loadLocation($nestedFolder->contentInfo->mainLocationId);
1290
1291
        $folder = $this->updateContentField(
1292
            $folder->contentInfo,
1293
            'name',
1294
            ['eng-GB' => 'Updated Name']
1295
        );
1296
        // create more historical entries
1297
        $this->updateContentField(
1298
            $folder->contentInfo,
1299
            'name',
1300
            ['eng-GB' => 'Updated Again Name']
1301
        );
1302
        // create historical entry for nested folder
1303
        $this->updateContentField(
1304
            $nestedFolder->contentInfo,
1305
            'name',
1306
            ['eng-GB' => 'Updated Nested folder']
1307
        );
1308
1309
        // perform sanity check
1310
        $this->assertUrlIsHistory('/My-folder-Name', $folderLocation->id);
1311
        $this->assertUrlIsHistory('/Updated-Name', $folderLocation->id);
1312
        $this->assertUrlIsHistory('/My-folder-Name/Nested-folder', $nestedFolderLocation->id);
1313
        $this->assertUrlIsHistory('/Updated-Name/Nested-folder', $nestedFolderLocation->id);
1314
        $this->assertUrlIsHistory('/Updated-Again-Name/Nested-folder', $nestedFolderLocation->id);
1315
1316
        $this->assertUrlIsCurrent('/Updated-Again-Name', $folderLocation->id);
1317
        $this->assertUrlIsCurrent('/Updated-Again-Name/Updated-Nested-folder', $nestedFolderLocation->id);
1318
1319
        self::assertNotEmpty($urlAliasService->listLocationAliases($folderLocation, false));
1320
1321
        // corrupt database by removing original entry, keeping its history
1322
        $this->performRawDatabaseOperation(
1323
            function (Connection $connection) use ($folderLocation) {
1324
                $queryBuilder = $connection->createQueryBuilder();
1325
                $expr = $queryBuilder->expr();
1326
                $queryBuilder
1327
                    ->delete('ezurlalias_ml')
1328
                    ->where(
1329
                        $expr->andX(
1330
                            $expr->eq(
1331
                                'action',
1332
                                $queryBuilder->createPositionalParameter(
1333
                                    "eznode:{$folderLocation->id}"
1334
                                )
1335
                            ),
1336
                            $expr->eq(
1337
                                'is_original',
1338
                                $queryBuilder->createPositionalParameter(1)
1339
                            )
1340
                        )
1341
                    );
1342
1343
                return $queryBuilder->execute();
1344
            }
1345
        );
1346
1347
        // perform sanity check
1348
        self::assertEmpty($urlAliasService->listLocationAliases($folderLocation, false));
1349
1350
        // Begin the actual test
1351
        $urlAliasService->refreshSystemUrlAliasesForLocation($folderLocation);
1352
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1353
1354
        // make sure there is no corrupted data that could affect the test
1355
        $urlAliasService->deleteCorruptedUrlAliases();
1356
1357
        // test if history was restored
1358
        $this->assertUrlIsHistory('/My-folder-Name', $folderLocation->id);
1359
        $this->assertUrlIsHistory('/Updated-Name', $folderLocation->id);
1360
        $this->assertUrlIsHistory('/My-folder-Name/Nested-folder', $nestedFolderLocation->id);
1361
        $this->assertUrlIsHistory('/Updated-Name/Nested-folder', $nestedFolderLocation->id);
1362
        $this->assertUrlIsHistory('/Updated-Again-Name/Nested-folder', $nestedFolderLocation->id);
1363
1364
        $this->assertUrlIsCurrent('/Updated-Again-Name', $folderLocation->id);
1365
        $this->assertUrlIsCurrent('/Updated-Again-Name/Updated-Nested-folder', $nestedFolderLocation->id);
1366
    }
1367
1368
    /**
1369
     * Test edge case when updated and archived entry gets moved to another subtree.
1370
     *
1371
     * @see https://jira.ez.no/browse/EZP-30004
1372
     *
1373
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1374
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1375
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1376
     * @throws \Exception
1377
     */
1378
    public function testRefreshSystemUrlAliasesForMovedLocation()
1379
    {
1380
        $repository = $this->getRepository();
1381
        $urlAliasService = $repository->getURLAliasService();
1382
        $locationService = $repository->getLocationService();
1383
1384
        $folderNames = ['eng-GB' => 'folder'];
1385
        $folder = $this->createFolder($folderNames, 2);
1386
        $nestedFolder = $this->createFolder($folderNames, $folder->contentInfo->mainLocationId);
1387
1388
        $nestedFolder = $this->updateContentField(
1389
            $nestedFolder->contentInfo,
1390
            'name',
1391
            ['eng-GB' => 'folder2']
1392
        );
1393
1394
        $nestedFolderLocation = $locationService->loadLocation(
1395
            $nestedFolder->contentInfo->mainLocationId
1396
        );
1397
        $rootLocation = $locationService->loadLocation(2);
1398
1399
        $locationService->moveSubtree($nestedFolderLocation, $rootLocation);
1400
        // reload nested Location to get proper parent information
1401
        $nestedFolderLocation = $locationService->loadLocation($nestedFolderLocation->id);
1402
1403
        // corrupt database by breaking link to the original URL alias
1404
        $this->performRawDatabaseOperation(
1405
            function (Connection $connection) use ($nestedFolderLocation) {
1406
                $queryBuilder = $connection->createQueryBuilder();
1407
                $expr = $queryBuilder->expr();
1408
                $queryBuilder
1409
                    ->update('ezurlalias_ml')
1410
                    ->set('link', $queryBuilder->createPositionalParameter(666, \PDO::PARAM_INT))
1411
                    ->where(
1412
                        $expr->eq(
1413
                            'action',
1414
                            $queryBuilder->createPositionalParameter(
1415
                                "eznode:{$nestedFolderLocation->id}"
1416
                            )
1417
                        )
1418
                    )
1419
                    ->andWhere(
1420
                        $expr->eq(
1421
                            'is_original',
1422
                            $queryBuilder->createPositionalParameter(0, \PDO::PARAM_INT)
1423
                        )
1424
                    )
1425
                    ->andWhere(
1426
                        $expr->eq('text', $queryBuilder->createPositionalParameter('folder'))
1427
                    )
1428
                ;
1429
1430
                return $queryBuilder->execute();
1431
            }
1432
        );
1433
1434
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1435
    }
1436
1437
    /**
1438
     * Lookup given URL and check if it is archived and points to the given Location Id.
1439
     *
1440
     * @param string $lookupUrl
1441
     * @param int $expectedDestination Expected Location ID
1442
     */
1443
    protected function assertUrlIsHistory($lookupUrl, $expectedDestination)
1444
    {
1445
        $this->assertLookupHistory(true, $expectedDestination, $lookupUrl);
1446
    }
1447
1448
    /**
1449
     * Lookup given URL and check if it is current (not archived) and points to the given Location Id.
1450
     *
1451
     * @param string $lookupUrl
1452
     * @param int $expectedDestination Expected Location ID
1453
     */
1454
    protected function assertUrlIsCurrent($lookupUrl, $expectedDestination)
1455
    {
1456
        $this->assertLookupHistory(false, $expectedDestination, $lookupUrl);
1457
    }
1458
1459
    /**
1460
     * Lookup and URLAlias VO history and destination properties.
1461
     *
1462
     * @see assertUrlIsHistory
1463
     * @see assertUrlIsCurrent
1464
     *
1465
     * @param bool $expectedIsHistory
1466
     * @param int $expectedDestination Expected Location ID
1467
     * @param string $lookupUrl
1468
     */
1469
    protected function assertLookupHistory($expectedIsHistory, $expectedDestination, $lookupUrl)
1470
    {
1471
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1472
1473
        try {
1474
            $urlAlias = $urlAliasService->lookup($lookupUrl);
1475
            self::assertPropertiesCorrect(
1476
                [
1477
                    'destination' => $expectedDestination,
1478
                    'path' => $lookupUrl,
1479
                    'isHistory' => $expectedIsHistory,
1480
                ],
1481
                $urlAlias
1482
            );
1483
        } catch (InvalidArgumentException $e) {
1484
            self::fail("Failed to lookup {$lookupUrl}: $e");
1485
        } catch (NotFoundException $e) {
1486
            self::fail("Failed to lookup {$lookupUrl}: $e");
1487
        }
1488
    }
1489
1490
    /**
1491
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
1492
     * @param $fieldDefinitionIdentifier
1493
     * @param array $fieldValues
1494
     *
1495
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1496
     *
1497
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1498
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1499
     */
1500
    protected function updateContentField(ContentInfo $contentInfo, $fieldDefinitionIdentifier, array $fieldValues)
1501
    {
1502
        $contentService = $this->getRepository(false)->getContentService();
1503
1504
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1505
        foreach ($fieldValues as $languageCode => $fieldValue) {
1506
            $contentUpdateStruct->setField($fieldDefinitionIdentifier, $fieldValue, $languageCode);
1507
        }
1508
        $contentDraft = $contentService->updateContent(
1509
            $contentService->createContentDraft($contentInfo)->versionInfo,
1510
            $contentUpdateStruct
1511
        );
1512
1513
        return $contentService->publishVersion($contentDraft->versionInfo);
1514
    }
1515
1516
    /**
1517
     * Test deleting corrupted URL aliases.
1518
     *
1519
     * Note: this test will not be needed once we introduce Improved Storage with Foreign keys support.
1520
     *
1521
     * Note: test depends on already broken URL aliases: eznode:59, eznode:59, eznode:60.
1522
     *
1523
     * @throws \ErrorException
1524
     */
1525
    public function testDeleteCorruptedUrlAliases()
1526
    {
1527
        $repository = $this->getRepository();
1528
        $urlAliasService = $repository->getURLAliasService();
1529
        $connection = $this->getRawDatabaseConnection();
1530
1531
        $query = $connection->createQueryBuilder()->select('*')->from('ezurlalias_ml');
1532
        $originalRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1533
1534
        $expectedCount = count($originalRows);
1535
        $expectedCount += $this->insertBrokenUrlAliasTableFixtures($connection);
1536
1537
        // sanity check
1538
        $updatedRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1539
        self::assertCount($expectedCount, $updatedRows, 'Found unexpected number of new rows');
1540
1541
        // BEGIN API use case
1542
        $urlAliasService->deleteCorruptedUrlAliases();
1543
        // END API use case
1544
1545
        $updatedRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1546
        self::assertCount(
1547
            // API should also remove already broken pre-existing URL aliases to Locations 50 and 2x 59
1548
            count($originalRows) - 3,
1549
            $updatedRows,
1550
            'Number of rows after cleanup is not the same as the original number of rows'
1551
        );
1552
    }
1553
1554
    /**
1555
     * Mutate 'ezpublish.persistence.slug_converter' Service configuration.
1556
     *
1557
     * @param string $key
1558
     * @param string $value
1559
     *
1560
     * @throws \ErrorException
1561
     * @throws \Exception
1562
     */
1563
    protected function changeSlugConverterConfiguration($key, $value)
1564
    {
1565
        $testSlugConverter = $this
1566
            ->getSetupFactory()
1567
            ->getServiceContainer()
1568
            ->getInnerContainer()
1569
            ->get('ezpublish.persistence.slug_converter');
1570
1571
        if (!$testSlugConverter instanceof TestSlugConverter) {
1572
            throw new RuntimeException(
1573
                sprintf(
1574
                    '%s: expected instance of %s, got %s',
1575
                    __METHOD__,
1576
                    TestSlugConverter::class,
1577
                    get_class($testSlugConverter)
1578
                )
1579
            );
1580
        }
1581
1582
        $testSlugConverter->setConfigurationValue($key, $value);
1583
    }
1584
1585
    /**
1586
     * Update Content Type URL alias schema pattern.
1587
     *
1588
     * @param string $contentTypeIdentifier
1589
     * @param string $newUrlAliasSchema
1590
     *
1591
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1592
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1593
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1594
     */
1595
    protected function changeContentTypeUrlAliasSchema($contentTypeIdentifier, $newUrlAliasSchema)
1596
    {
1597
        $contentTypeService = $this->getRepository(false)->getContentTypeService();
1598
1599
        $contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1600
1601
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1602
        $contentTypeUpdateStruct = $contentTypeService->newContentTypeUpdateStruct();
1603
        $contentTypeUpdateStruct->urlAliasSchema = $newUrlAliasSchema;
1604
1605
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $contentTypeUpdateStruct);
1606
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1607
    }
1608
1609
    private function assertUrlAliasPropertiesCorrect(
1610
        Location $expectedDestinationLocation,
1611
        $expectedPath,
1612
        array $expectedLanguageCodes,
0 ignored issues
show
Unused Code introduced by
The parameter $expectedLanguageCodes 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...
1613
        $expectedIsHistory,
1614
        URLAlias $actualUrlAliasValue
1615
    ) {
1616
        self::assertPropertiesCorrect(
1617
            [
1618
                'destination' => $expectedDestinationLocation->id,
1619
                'path' => $expectedPath,
1620
                // @todo uncomment after fixing EZP-27124
1621
                //'languageCodes' => $expectedLanguageCodes,
1622
                'isHistory' => $expectedIsHistory,
1623
                'isCustom' => false,
1624
                'forward' => false,
1625
            ],
1626
            $actualUrlAliasValue
1627
        );
1628
    }
1629
1630
    /**
1631
     * Insert intentionally broken rows into ezurlalias_ml table to test cleanup API.
1632
     *
1633
     * @see \eZ\Publish\API\Repository\URLAliasService::deleteCorruptedUrlAliases
1634
     * @see testDeleteCorruptedUrlAliases
1635
     *
1636
     * @param \Doctrine\DBAL\Connection $connection
1637
     *
1638
     * @return int Number of new rows
1639
     */
1640
    private function insertBrokenUrlAliasTableFixtures(Connection $connection)
1641
    {
1642
        $rows = [
1643
            // link to non-existent location
1644
            [
1645
                'action' => 'eznode:9999',
1646
                'action_type' => 'eznode',
1647
                'alias_redirects' => 0,
1648
                'id' => 9997,
1649
                'is_alias' => 0,
1650
                'is_original' => 1,
1651
                'lang_mask' => 3,
1652
                'link' => 9997,
1653
                'parent' => 0,
1654
                'text' => 'my-location',
1655
                'text_md5' => '19d12b1b9994619cd8e90f00a6f5834e',
1656
            ],
1657
            // link to non-existent target URL alias (`link` column)
1658
            [
1659
                'action' => 'nop:',
1660
                'action_type' => 'nop',
1661
                'alias_redirects' => 0,
1662
                'id' => 9998,
1663
                'is_alias' => 1,
1664
                'is_original' => 1,
1665
                'lang_mask' => 2,
1666
                'link' => 9995,
1667
                'parent' => 0,
1668
                'text' => 'my-alias1',
1669
                'text_md5' => 'a29dd95ccf4c1bc7ebbd61086863b632',
1670
            ],
1671
            // link to non-existent parent URL alias
1672
            [
1673
                'action' => 'nop:',
1674
                'action_type' => 'nop',
1675
                'alias_redirects' => 0,
1676
                'id' => 9999,
1677
                'is_alias' => 0,
1678
                'is_original' => 1,
1679
                'lang_mask' => 3,
1680
                'link' => 9999,
1681
                'parent' => 9995,
1682
                'text' => 'my-alias2',
1683
                'text_md5' => 'e5dea18481e4f86857865d9fc94e4ce9',
1684
            ],
1685
        ];
1686
1687
        $query = $connection->createQueryBuilder()->insert('ezurlalias_ml');
1688
1689
        foreach ($rows as $row) {
1690
            foreach ($row as $columnName => $value) {
1691
                $row[$columnName] = $query->createNamedParameter($value);
1692
            }
1693
            $query->values($row);
1694
            $query->execute();
1695
        }
1696
1697
        return count($rows);
1698
    }
1699
}
1700