Completed
Push — master ( ee6594...6a5050 )
by
unknown
76:11 queued 51:14
created

testRefreshSystemUrlAliasesForMovedLocation()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 58

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 58
rs 8.9163
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 View Code Duplication
    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
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
91
            $createdUrlAlias
92
        );
93
94
        return array($createdUrlAlias, $location->id);
95
    }
96
97
    /**
98
     * @param array $testData
99
     *
100
     * @depends testCreateUrlAlias
101
     */
102 View Code Duplication
    public function testCreateUrlAliasPropertyValues(array $testData)
103
    {
104
        list($createdUrlAlias, $locationId) = $testData;
105
106
        $this->assertNotNull($createdUrlAlias->id);
107
108
        $this->assertPropertiesCorrect(
109
            array(
110
                'type' => URLAlias::LOCATION,
111
                'destination' => $locationId,
112
                'path' => '/Home/My-New-Site',
113
                'languageCodes' => array('eng-US'),
114
                'alwaysAvailable' => false,
115
                'isHistory' => false,
116
                'isCustom' => true,
117
                'forward' => false,
118
            ),
119
            $createdUrlAlias
120
        );
121
    }
122
123
    /**
124
     * Test for the createUrlAlias() method.
125
     *
126
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias($location, $path, $languageCode, $forwarding)
127
     * @depends testCreateUrlAliasPropertyValues
128
     */
129 View Code Duplication
    public function testCreateUrlAliasWithForwarding()
130
    {
131
        $repository = $this->getRepository();
132
133
        $locationId = $this->generateId('location', 5);
134
135
        /* BEGIN: Use Case */
136
        // $locationId is the ID of an existing location
137
138
        $locationService = $repository->getLocationService();
139
        $urlAliasService = $repository->getURLAliasService();
140
141
        $location = $locationService->loadLocation($locationId);
142
143
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US', true);
144
        /* END: Use Case */
145
146
        $this->assertInstanceOf(
147
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
148
            $createdUrlAlias
149
        );
150
151
        return array($createdUrlAlias, $location->id);
152
    }
153
154
    /**
155
     * @param array $testData
156
     *
157
     * @depends testCreateUrlAliasWithForwarding
158
     */
159 View Code Duplication
    public function testCreateUrlAliasPropertyValuesWithForwarding(array $testData)
160
    {
161
        list($createdUrlAlias, $locationId) = $testData;
162
163
        $this->assertNotNull($createdUrlAlias->id);
164
165
        $this->assertPropertiesCorrect(
166
            array(
167
                'type' => URLAlias::LOCATION,
168
                'destination' => $locationId,
169
                'path' => '/Home/My-New-Site',
170
                'languageCodes' => array('eng-US'),
171
                'alwaysAvailable' => false,
172
                'isHistory' => false,
173
                'isCustom' => true,
174
                'forward' => true,
175
            ),
176
            $createdUrlAlias
177
        );
178
    }
179
180
    /**
181
     * Test for the createUrlAlias() method.
182
     *
183
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias($location, $path, $languageCode, $forwarding, $alwaysAvailable)
184
     */
185 View Code Duplication
    public function testCreateUrlAliasWithAlwaysAvailable()
186
    {
187
        $repository = $this->getRepository();
188
189
        $locationId = $this->generateId('location', 5);
190
191
        /* BEGIN: Use Case */
192
        // $locationId is the ID of an existing location
193
194
        $locationService = $repository->getLocationService();
195
        $urlAliasService = $repository->getURLAliasService();
196
197
        $location = $locationService->loadLocation($locationId);
198
199
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US', false, true);
200
        /* END: Use Case */
201
202
        $this->assertInstanceOf(
203
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
204
            $createdUrlAlias
205
        );
206
207
        return array($createdUrlAlias, $location->id);
208
    }
209
210
    /**
211
     * @param array $testData
212
     *
213
     * @depends testCreateUrlAliasWithAlwaysAvailable
214
     */
215 View Code Duplication
    public function testCreateUrlAliasPropertyValuesWithAlwaysAvailable(array $testData)
216
    {
217
        list($createdUrlAlias, $locationId) = $testData;
218
219
        $this->assertNotNull($createdUrlAlias->id);
220
221
        $this->assertPropertiesCorrect(
222
            array(
223
                'type' => URLAlias::LOCATION,
224
                'destination' => $locationId,
225
                'path' => '/Home/My-New-Site',
226
                'languageCodes' => array('eng-US'),
227
                'alwaysAvailable' => true,
228
                'isHistory' => false,
229
                'isCustom' => true,
230
                'forward' => false,
231
            ),
232
            $createdUrlAlias
233
        );
234
    }
235
236
    /**
237
     * Test for the createUrlAlias() method.
238
     *
239
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias()
240
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
241
     */
242
    public function testCreateUrlAliasThrowsInvalidArgumentException()
243
    {
244
        $repository = $this->getRepository();
245
246
        $locationId = $this->generateId('location', 5);
247
248
        /* BEGIN: Use Case */
249
        // $locationId is the ID of an existing location
250
251
        $locationService = $repository->getLocationService();
252
        $urlAliasService = $repository->getURLAliasService();
253
254
        $location = $locationService->loadLocation($locationId);
255
256
        // Throws InvalidArgumentException, since this path already exists for the
257
        // language
258
        $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...
259
        /* END: Use Case */
260
    }
261
262
    /**
263
     * Test for the createGlobalUrlAlias() method.
264
     *
265
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias()
266
     */
267 View Code Duplication
    public function testCreateGlobalUrlAlias()
268
    {
269
        $repository = $this->getRepository();
270
271
        /* BEGIN: Use Case */
272
        $urlAliasService = $repository->getURLAliasService();
273
274
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
275
            'module:content/search?SearchText=eZ',
276
            '/Home/My-New-Site',
277
            'eng-US'
278
        );
279
        /* END: Use Case */
280
281
        $this->assertInstanceOf(
282
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
283
            $createdUrlAlias
284
        );
285
286
        return $createdUrlAlias;
287
    }
288
289
    /**
290
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
291
     *
292
     * @depends testCreateGlobalUrlAlias
293
     */
294 View Code Duplication
    public function testCreateGlobalUrlAliasPropertyValues(URLAlias $createdUrlAlias)
295
    {
296
        $this->assertNotNull($createdUrlAlias->id);
297
298
        $this->assertPropertiesCorrect(
299
            array(
300
                'type' => URLAlias::RESOURCE,
301
                'destination' => 'content/search?SearchText=eZ',
302
                'path' => '/Home/My-New-Site',
303
                'languageCodes' => array('eng-US'),
304
                'alwaysAvailable' => false,
305
                'isHistory' => false,
306
                'isCustom' => true,
307
                'forward' => false,
308
            ),
309
            $createdUrlAlias
310
        );
311
    }
312
313
    /**
314
     * Test for the createGlobalUrlAlias() method.
315
     *
316
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forward)
317
     */
318 View Code Duplication
    public function testCreateGlobalUrlAliasWithForward()
319
    {
320
        $repository = $this->getRepository();
321
322
        /* BEGIN: Use Case */
323
        $urlAliasService = $repository->getURLAliasService();
324
325
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
326
            'module:content/search?SearchText=eZ',
327
            '/Home/My-New-Site',
328
            'eng-US',
329
            true
330
        );
331
        /* END: Use Case */
332
333
        $this->assertInstanceOf(
334
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
335
            $createdUrlAlias
336
        );
337
338
        return $createdUrlAlias;
339
    }
340
341
    /**
342
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
343
     *
344
     * @depends testCreateGlobalUrlAliasWithForward
345
     */
346 View Code Duplication
    public function testCreateGlobalUrlAliasWithForwardPropertyValues(URLAlias $createdUrlAlias)
347
    {
348
        $this->assertNotNull($createdUrlAlias->id);
349
350
        $this->assertPropertiesCorrect(
351
            array(
352
                'type' => URLAlias::RESOURCE,
353
                'destination' => 'content/search?SearchText=eZ',
354
                'path' => '/Home/My-New-Site',
355
                'languageCodes' => array('eng-US'),
356
                'alwaysAvailable' => false,
357
                'isHistory' => false,
358
                'isCustom' => true,
359
                'forward' => true,
360
            ),
361
            $createdUrlAlias
362
        );
363
    }
364
365
    /**
366
     * Test for the createGlobalUrlAlias() method.
367
     *
368
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
369
     */
370 View Code Duplication
    public function testCreateGlobalUrlAliasWithAlwaysAvailable()
371
    {
372
        $repository = $this->getRepository();
373
374
        /* BEGIN: Use Case */
375
        $urlAliasService = $repository->getURLAliasService();
376
377
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
378
            'module:content/search?SearchText=eZ',
379
            '/Home/My-New-Site',
380
            'eng-US',
381
            false,
382
            true
383
        );
384
        /* END: Use Case */
385
386
        $this->assertInstanceOf(
387
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
388
            $createdUrlAlias
389
        );
390
391
        return $createdUrlAlias;
392
    }
393
394
    /**
395
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
396
     *
397
     * @depends testCreateGlobalUrlAliasWithAlwaysAvailable
398
     */
399 View Code Duplication
    public function testCreateGlobalUrlAliasWithAlwaysAvailablePropertyValues(URLAlias $createdUrlAlias)
400
    {
401
        $this->assertNotNull($createdUrlAlias->id);
402
403
        $this->assertPropertiesCorrect(
404
            array(
405
                'type' => URLAlias::RESOURCE,
406
                'destination' => 'content/search?SearchText=eZ',
407
                'path' => '/Home/My-New-Site',
408
                'languageCodes' => array('eng-US'),
409
                'alwaysAvailable' => true,
410
                'isHistory' => false,
411
                'isCustom' => true,
412
                'forward' => false,
413
            ),
414
            $createdUrlAlias
415
        );
416
    }
417
418
    /**
419
     * Test for the createUrlAlias() method.
420
     *
421
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
422
     */
423 View Code Duplication
    public function testCreateGlobalUrlAliasForLocation()
424
    {
425
        $repository = $this->getRepository();
426
427
        $locationId = $this->generateId('location', 5);
428
        $locationService = $repository->getLocationService();
429
        $location = $locationService->loadLocation($locationId);
430
431
        /* BEGIN: Use Case */
432
        // $locationId is the ID of an existing location
433
434
        $urlAliasService = $repository->getURLAliasService();
435
436
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
437
            'module:content/view/full/' . $locationId,
438
            '/Home/My-New-Site-global',
439
            'eng-US',
440
            false,
441
            true
442
        );
443
        /* END: Use Case */
444
445
        $this->assertInstanceOf(
446
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
447
            $createdUrlAlias
448
        );
449
450
        return array($createdUrlAlias, $location->id);
451
    }
452
453
    /**
454
     * Test for the createUrlAlias() method.
455
     *
456
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
457
     */
458 View Code Duplication
    public function testCreateGlobalUrlAliasForLocationVariation()
459
    {
460
        $repository = $this->getRepository();
461
462
        $locationId = $this->generateId('location', 5);
463
        $locationService = $repository->getLocationService();
464
        $location = $locationService->loadLocation($locationId);
465
466
        /* BEGIN: Use Case */
467
        // $locationId is the ID of an existing location
468
469
        $urlAliasService = $repository->getURLAliasService();
470
471
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
472
            'eznode:' . $locationId,
473
            '/Home/My-New-Site-global',
474
            'eng-US',
475
            false,
476
            true
477
        );
478
        /* END: Use Case */
479
480
        $this->assertInstanceOf(
481
            'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
482
            $createdUrlAlias
483
        );
484
485
        return array($createdUrlAlias, $location->id);
486
    }
487
488
    /**
489
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
490
     *
491
     * @depends testCreateGlobalUrlAliasForLocation
492
     */
493 View Code Duplication
    public function testCreateGlobalUrlAliasForLocationPropertyValues($testData)
494
    {
495
        list($createdUrlAlias, $locationId) = $testData;
496
497
        $this->assertNotNull($createdUrlAlias->id);
498
499
        $this->assertPropertiesCorrect(
500
            array(
501
                'type' => URLAlias::LOCATION,
502
                'destination' => $locationId,
503
                'path' => '/Home/My-New-Site-global',
504
                'languageCodes' => array('eng-US'),
505
                'alwaysAvailable' => true,
506
                'isHistory' => false,
507
                'isCustom' => true,
508
                'forward' => false,
509
            ),
510
            $createdUrlAlias
511
        );
512
    }
513
514
    /**
515
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
516
     *
517
     * @depends testCreateGlobalUrlAliasForLocationVariation
518
     */
519
    public function testCreateGlobalUrlAliasForLocationVariationPropertyValues($testData)
520
    {
521
        $this->testCreateGlobalUrlAliasForLocationPropertyValues($testData);
522
    }
523
524
    /**
525
     * Test for the createGlobalUrlAlias() method.
526
     *
527
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias()
528
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
529
     */
530
    public function testCreateGlobalUrlAliasThrowsInvalidArgumentException()
531
    {
532
        $repository = $this->getRepository();
533
534
        /* BEGIN: Use Case */
535
        $urlAliasService = $repository->getURLAliasService();
536
537
        // Throws InvalidArgumentException, since this path already exists for the
538
        // language
539
        $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...
540
            'module:content/search?SearchText=eZ',
541
            '/Design/Plain-site',
542
            'eng-US'
543
        );
544
        /* END: Use Case */
545
    }
546
547
    /**
548
     * Test for the listLocationAliases() method.
549
     *
550
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases()
551
     */
552
    public function testListLocationAliases()
553
    {
554
        $repository = $this->getRepository();
555
556
        $locationId = $this->generateId('location', 12);
557
558
        /* BEGIN: Use Case */
559
        // $locationId contains the ID of an existing Location
560
        $urlAliasService = $repository->getURLAliasService();
561
        $locationService = $repository->getLocationService();
562
563
        $location = $locationService->loadLocation($locationId);
564
565
        // Create a custom URL alias for $location
566
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'eng-US');
567
568
        // $loadedAliases will contain an array of custom URLAlias objects
569
        $loadedAliases = $urlAliasService->listLocationAliases($location);
570
        /* END: Use Case */
571
572
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
573
            'array',
574
            $loadedAliases
575
        );
576
577
        // Only 1 non-history alias
578
        $this->assertEquals(1, count($loadedAliases));
579
580
        return array($loadedAliases, $location);
581
    }
582
583
    /**
584
     * @param array $testData
585
     *
586
     * @depends testListLocationAliases
587
     */
588
    public function testListLocationAliasesLoadsCorrectly(array $testData)
589
    {
590
        list($loadedAliases, $location) = $testData;
591
592
        foreach ($loadedAliases as $loadedAlias) {
593
            $this->assertInstanceOf(
594
                'eZ\\Publish\\API\\Repository\\Values\\Content\\URLAlias',
595
                $loadedAlias
596
            );
597
            $this->assertEquals(
598
                $location->id,
599
                $loadedAlias->destination
600
            );
601
        }
602
    }
603
604
    /**
605
     * Test for the listLocationAliases() method.
606
     *
607
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases($location, $custom, $languageCode)
608
     */
609 View Code Duplication
    public function testListLocationAliasesWithCustomFilter()
610
    {
611
        $repository = $this->getRepository();
612
613
        $locationId = $this->generateId('location', 12);
614
615
        /* BEGIN: Use Case */
616
        // $locationId contains the ID of an existing Location
617
        $urlAliasService = $repository->getURLAliasService();
618
        $locationService = $repository->getLocationService();
619
620
        $location = $locationService->loadLocation($locationId);
621
622
        // Create a second URL alias for $location, this is a "custom" one
623
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'ger-DE');
624
625
        // $loadedAliases will contain 1 aliases in eng-US only
626
        $loadedAliases = $urlAliasService->listLocationAliases($location, false, 'eng-US');
627
        /* END: Use Case */
628
629
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
630
            'array',
631
            $loadedAliases
632
        );
633
        $this->assertEquals(1, count($loadedAliases));
634
    }
635
636
    /**
637
     * Test for the listLocationAliases() method.
638
     *
639
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases($location, $custom)
640
     */
641 View Code Duplication
    public function testListLocationAliasesWithLanguageCodeFilter()
642
    {
643
        $repository = $this->getRepository();
644
645
        $locationId = $this->generateId('location', 12);
646
647
        /* BEGIN: Use Case */
648
        // $locationId contains the ID of an existing Location
649
        $urlAliasService = $repository->getURLAliasService();
650
        $locationService = $repository->getLocationService();
651
652
        $location = $locationService->loadLocation($locationId);
653
        // Create a custom URL alias for $location
654
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'eng-US');
655
656
        // $loadedAliases will contain only 1 of 3 aliases (custom in eng-US)
657
        $loadedAliases = $urlAliasService->listLocationAliases($location, true, 'eng-US');
658
        /* END: Use Case */
659
660
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
661
            'array',
662
            $loadedAliases
663
        );
664
        $this->assertEquals(1, count($loadedAliases));
665
    }
666
667
    /**
668
     * Test for the listGlobalAliases() method.
669
     *
670
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases()
671
     */
672 View Code Duplication
    public function testListGlobalAliases()
673
    {
674
        $repository = $this->getRepository();
675
676
        /* BEGIN: Use Case */
677
        $urlAliasService = $repository->getURLAliasService();
678
679
        // Create some global aliases
680
        $this->createGlobalAliases();
681
682
        // $loadedAliases will contain all 3 global aliases
683
        $loadedAliases = $urlAliasService->listGlobalAliases();
684
        /* END: Use Case */
685
686
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
687
            'array',
688
            $loadedAliases
689
        );
690
        $this->assertEquals(3, count($loadedAliases));
691
    }
692
693
    /**
694
     * Creates 3 global aliases.
695
     */
696
    private function createGlobalAliases()
697
    {
698
        $repository = $this->getRepository();
699
        $urlAliasService = $repository->getURLAliasService();
700
701
        /* BEGIN: Inline */
702
        $urlAliasService->createGlobalUrlAlias(
703
            'module:content/search?SearchText=eZ',
704
            '/My/Special-Support',
705
            'eng-US'
706
        );
707
        $urlAliasService->createGlobalUrlAlias(
708
            'module:content/search?SearchText=eZ',
709
            '/My/London-Office',
710
            'eng-GB'
711
        );
712
        $urlAliasService->createGlobalUrlAlias(
713
            'module:content/search?SearchText=Sindelfingen',
714
            '/My/Fancy-Site',
715
            'eng-US'
716
        );
717
        /* END: Inline */
718
    }
719
720
    /**
721
     * Test for the listGlobalAliases() method.
722
     *
723
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode)
724
     */
725 View Code Duplication
    public function testListGlobalAliasesWithLanguageFilter()
726
    {
727
        $repository = $this->getRepository();
728
729
        /* BEGIN: Use Case */
730
        $urlAliasService = $repository->getURLAliasService();
731
732
        // Create some global aliases
733
        $this->createGlobalAliases();
734
735
        // $loadedAliases will contain only 2 of 3 global aliases
736
        $loadedAliases = $urlAliasService->listGlobalAliases('eng-US');
737
        /* END: Use Case */
738
739
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
740
            'array',
741
            $loadedAliases
742
        );
743
        $this->assertEquals(2, count($loadedAliases));
744
    }
745
746
    /**
747
     * Test for the listGlobalAliases() method.
748
     *
749
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode, $offset)
750
     */
751 View Code Duplication
    public function testListGlobalAliasesWithOffset()
752
    {
753
        $repository = $this->getRepository();
754
755
        /* BEGIN: Use Case */
756
        $urlAliasService = $repository->getURLAliasService();
757
758
        // Create some global aliases
759
        $this->createGlobalAliases();
760
761
        // $loadedAliases will contain only 2 of 3 global aliases
762
        $loadedAliases = $urlAliasService->listGlobalAliases(null, 1);
763
        /* END: Use Case */
764
765
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
766
            'array',
767
            $loadedAliases
768
        );
769
        $this->assertEquals(2, count($loadedAliases));
770
    }
771
772
    /**
773
     * Test for the listGlobalAliases() method.
774
     *
775
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode, $offset, $limit)
776
     */
777 View Code Duplication
    public function testListGlobalAliasesWithLimit()
778
    {
779
        $repository = $this->getRepository();
780
781
        /* BEGIN: Use Case */
782
        $urlAliasService = $repository->getURLAliasService();
783
784
        // Create some global aliases
785
        $this->createGlobalAliases();
786
787
        // $loadedAliases will contain only 1 of 3 global aliases
788
        $loadedAliases = $urlAliasService->listGlobalAliases(null, 0, 1);
789
        /* END: Use Case */
790
791
        $this->assertInternalType(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\Assert::assertInternalType() has been deprecated with message: https://github.com/sebastianbergmann/phpunit/issues/3369

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

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