Completed
Push — 7.5 ( ff94d7...b4b434 )
by
unknown
18:08
created

testCreateSameAliasForDiffrentLanguage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
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
     * @covers \eZ\Publish\API\Repository\URLAliasService::createUrlAlias
101
     *
102
     * @throws \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
103
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
104
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
105
     */
106
    public function testCreateSameAliasForDifferentLanguage()
107
    {
108
        $repository = $this->getRepository();
109
        $locationId = $this->generateId('location', 5);
110
        $locationService = $repository->getLocationService();
111
        $urlAliasService = $repository->getURLAliasService();
112
        $location = $locationService->loadLocation($locationId);
113
114
        $urlAliasService->createUrlAlias($location, '/alias', 'eng-US');
115
        $updatedAlias = $urlAliasService->createUrlAlias($location, '/alias', 'eng-GB');
116
117
        $this->assertPropertiesCorrect(
118
            [
119
                'languageCodes' => ['eng-US', 'eng-GB'],
120
            ],
121
            $updatedAlias
122
        );
123
    }
124
125
    /**
126
     * @param array $testData
127
     *
128
     * @depends testCreateUrlAlias
129
     */
130 View Code Duplication
    public function testCreateUrlAliasPropertyValues(array $testData)
131
    {
132
        list($createdUrlAlias, $locationId) = $testData;
133
134
        $this->assertNotNull($createdUrlAlias->id);
135
136
        $this->assertPropertiesCorrect(
137
            [
138
                'type' => URLAlias::LOCATION,
139
                'destination' => $locationId,
140
                'path' => '/Home/My-New-Site',
141
                'languageCodes' => ['eng-US'],
142
                'alwaysAvailable' => false,
143
                'isHistory' => false,
144
                'isCustom' => true,
145
                'forward' => false,
146
            ],
147
            $createdUrlAlias
148
        );
149
    }
150
151
    /**
152
     * Test for the createUrlAlias() method.
153
     *
154
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias($location, $path, $languageCode, $forwarding)
155
     * @depends testCreateUrlAliasPropertyValues
156
     */
157 View Code Duplication
    public function testCreateUrlAliasWithForwarding()
158
    {
159
        $repository = $this->getRepository();
160
161
        $locationId = $this->generateId('location', 5);
162
163
        /* BEGIN: Use Case */
164
        // $locationId is the ID of an existing location
165
166
        $locationService = $repository->getLocationService();
167
        $urlAliasService = $repository->getURLAliasService();
168
169
        $location = $locationService->loadLocation($locationId);
170
171
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US', true);
172
        /* END: Use Case */
173
174
        $this->assertInstanceOf(
175
            URLAlias::class,
176
            $createdUrlAlias
177
        );
178
179
        return [$createdUrlAlias, $location->id];
180
    }
181
182
    /**
183
     * @param array $testData
184
     *
185
     * @depends testCreateUrlAliasWithForwarding
186
     */
187 View Code Duplication
    public function testCreateUrlAliasPropertyValuesWithForwarding(array $testData)
188
    {
189
        list($createdUrlAlias, $locationId) = $testData;
190
191
        $this->assertNotNull($createdUrlAlias->id);
192
193
        $this->assertPropertiesCorrect(
194
            [
195
                'type' => URLAlias::LOCATION,
196
                'destination' => $locationId,
197
                'path' => '/Home/My-New-Site',
198
                'languageCodes' => ['eng-US'],
199
                'alwaysAvailable' => false,
200
                'isHistory' => false,
201
                'isCustom' => true,
202
                'forward' => true,
203
            ],
204
            $createdUrlAlias
205
        );
206
    }
207
208
    /**
209
     * Test for the createUrlAlias() method.
210
     *
211
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias($location, $path, $languageCode, $forwarding, $alwaysAvailable)
212
     */
213 View Code Duplication
    public function testCreateUrlAliasWithAlwaysAvailable()
214
    {
215
        $repository = $this->getRepository();
216
217
        $locationId = $this->generateId('location', 5);
218
219
        /* BEGIN: Use Case */
220
        // $locationId is the ID of an existing location
221
222
        $locationService = $repository->getLocationService();
223
        $urlAliasService = $repository->getURLAliasService();
224
225
        $location = $locationService->loadLocation($locationId);
226
227
        $createdUrlAlias = $urlAliasService->createUrlAlias($location, '/Home/My-New-Site', 'eng-US', false, true);
228
        /* END: Use Case */
229
230
        $this->assertInstanceOf(
231
            URLAlias::class,
232
            $createdUrlAlias
233
        );
234
235
        return [$createdUrlAlias, $location->id];
236
    }
237
238
    /**
239
     * @param array $testData
240
     *
241
     * @depends testCreateUrlAliasWithAlwaysAvailable
242
     */
243 View Code Duplication
    public function testCreateUrlAliasPropertyValuesWithAlwaysAvailable(array $testData)
244
    {
245
        list($createdUrlAlias, $locationId) = $testData;
246
247
        $this->assertNotNull($createdUrlAlias->id);
248
249
        $this->assertPropertiesCorrect(
250
            [
251
                'type' => URLAlias::LOCATION,
252
                'destination' => $locationId,
253
                'path' => '/Home/My-New-Site',
254
                'languageCodes' => ['eng-US'],
255
                'alwaysAvailable' => true,
256
                'isHistory' => false,
257
                'isCustom' => true,
258
                'forward' => false,
259
            ],
260
            $createdUrlAlias
261
        );
262
    }
263
264
    /**
265
     * Test for the createUrlAlias() method.
266
     *
267
     * @see \eZ\Publish\API\Repository\URLAliasService::createUrlAlias()
268
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
269
     */
270
    public function testCreateUrlAliasThrowsInvalidArgumentException()
271
    {
272
        $repository = $this->getRepository();
273
274
        $locationId = $this->generateId('location', 5);
275
276
        /* BEGIN: Use Case */
277
        // $locationId is the ID of an existing location
278
279
        $locationService = $repository->getLocationService();
280
        $urlAliasService = $repository->getURLAliasService();
281
282
        $location = $locationService->loadLocation($locationId);
283
284
        // Throws InvalidArgumentException, since this path already exists for the
285
        // language
286
        $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...
287
        /* END: Use Case */
288
    }
289
290
    /**
291
     * Test for the createGlobalUrlAlias() method.
292
     *
293
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias()
294
     */
295 View Code Duplication
    public function testCreateGlobalUrlAlias()
296
    {
297
        $repository = $this->getRepository();
298
299
        /* BEGIN: Use Case */
300
        $urlAliasService = $repository->getURLAliasService();
301
302
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
303
            'module:content/search?SearchText=eZ',
304
            '/Home/My-New-Site',
305
            'eng-US'
306
        );
307
        /* END: Use Case */
308
309
        $this->assertInstanceOf(
310
            URLAlias::class,
311
            $createdUrlAlias
312
        );
313
314
        return $createdUrlAlias;
315
    }
316
317
    /**
318
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
319
     *
320
     * @depends testCreateGlobalUrlAlias
321
     */
322 View Code Duplication
    public function testCreateGlobalUrlAliasPropertyValues(URLAlias $createdUrlAlias)
323
    {
324
        $this->assertNotNull($createdUrlAlias->id);
325
326
        $this->assertPropertiesCorrect(
327
            [
328
                'type' => URLAlias::RESOURCE,
329
                'destination' => 'content/search?SearchText=eZ',
330
                'path' => '/Home/My-New-Site',
331
                'languageCodes' => ['eng-US'],
332
                'alwaysAvailable' => false,
333
                'isHistory' => false,
334
                'isCustom' => true,
335
                'forward' => false,
336
            ],
337
            $createdUrlAlias
338
        );
339
    }
340
341
    /**
342
     * Test for the createGlobalUrlAlias() method.
343
     *
344
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forward)
345
     */
346 View Code Duplication
    public function testCreateGlobalUrlAliasWithForward()
347
    {
348
        $repository = $this->getRepository();
349
350
        /* BEGIN: Use Case */
351
        $urlAliasService = $repository->getURLAliasService();
352
353
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
354
            'module:content/search?SearchText=eZ',
355
            '/Home/My-New-Site',
356
            'eng-US',
357
            true
358
        );
359
        /* END: Use Case */
360
361
        $this->assertInstanceOf(
362
            URLAlias::class,
363
            $createdUrlAlias
364
        );
365
366
        return $createdUrlAlias;
367
    }
368
369
    /**
370
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
371
     *
372
     * @depends testCreateGlobalUrlAliasWithForward
373
     */
374 View Code Duplication
    public function testCreateGlobalUrlAliasWithForwardPropertyValues(URLAlias $createdUrlAlias)
375
    {
376
        $this->assertNotNull($createdUrlAlias->id);
377
378
        $this->assertPropertiesCorrect(
379
            [
380
                'type' => URLAlias::RESOURCE,
381
                'destination' => 'content/search?SearchText=eZ',
382
                'path' => '/Home/My-New-Site',
383
                'languageCodes' => ['eng-US'],
384
                'alwaysAvailable' => false,
385
                'isHistory' => false,
386
                'isCustom' => true,
387
                'forward' => true,
388
            ],
389
            $createdUrlAlias
390
        );
391
    }
392
393
    /**
394
     * Test for the createGlobalUrlAlias() method.
395
     *
396
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
397
     */
398 View Code Duplication
    public function testCreateGlobalUrlAliasWithAlwaysAvailable()
399
    {
400
        $repository = $this->getRepository();
401
402
        /* BEGIN: Use Case */
403
        $urlAliasService = $repository->getURLAliasService();
404
405
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
406
            'module:content/search?SearchText=eZ',
407
            '/Home/My-New-Site',
408
            'eng-US',
409
            false,
410
            true
411
        );
412
        /* END: Use Case */
413
414
        $this->assertInstanceOf(
415
            URLAlias::class,
416
            $createdUrlAlias
417
        );
418
419
        return $createdUrlAlias;
420
    }
421
422
    /**
423
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
424
     *
425
     * @depends testCreateGlobalUrlAliasWithAlwaysAvailable
426
     */
427 View Code Duplication
    public function testCreateGlobalUrlAliasWithAlwaysAvailablePropertyValues(URLAlias $createdUrlAlias)
428
    {
429
        $this->assertNotNull($createdUrlAlias->id);
430
431
        $this->assertPropertiesCorrect(
432
            [
433
                'type' => URLAlias::RESOURCE,
434
                'destination' => 'content/search?SearchText=eZ',
435
                'path' => '/Home/My-New-Site',
436
                'languageCodes' => ['eng-US'],
437
                'alwaysAvailable' => true,
438
                'isHistory' => false,
439
                'isCustom' => true,
440
                'forward' => false,
441
            ],
442
            $createdUrlAlias
443
        );
444
    }
445
446
    /**
447
     * Test for the createUrlAlias() method.
448
     *
449
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
450
     */
451 View Code Duplication
    public function testCreateGlobalUrlAliasForLocation()
452
    {
453
        $repository = $this->getRepository();
454
455
        $locationId = $this->generateId('location', 5);
456
        $locationService = $repository->getLocationService();
457
        $location = $locationService->loadLocation($locationId);
458
459
        /* BEGIN: Use Case */
460
        // $locationId is the ID of an existing location
461
462
        $urlAliasService = $repository->getURLAliasService();
463
464
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
465
            'module:content/view/full/' . $locationId,
466
            '/Home/My-New-Site-global',
467
            'eng-US',
468
            false,
469
            true
470
        );
471
        /* END: Use Case */
472
473
        $this->assertInstanceOf(
474
            URLAlias::class,
475
            $createdUrlAlias
476
        );
477
478
        return [$createdUrlAlias, $location->id];
479
    }
480
481
    /**
482
     * Test for the createUrlAlias() method.
483
     *
484
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias($resource, $path, $languageCode, $forwarding, $alwaysAvailable)
485
     */
486 View Code Duplication
    public function testCreateGlobalUrlAliasForLocationVariation()
487
    {
488
        $repository = $this->getRepository();
489
490
        $locationId = $this->generateId('location', 5);
491
        $locationService = $repository->getLocationService();
492
        $location = $locationService->loadLocation($locationId);
493
494
        /* BEGIN: Use Case */
495
        // $locationId is the ID of an existing location
496
497
        $urlAliasService = $repository->getURLAliasService();
498
499
        $createdUrlAlias = $urlAliasService->createGlobalUrlAlias(
500
            'eznode:' . $locationId,
501
            '/Home/My-New-Site-global',
502
            'eng-US',
503
            false,
504
            true
505
        );
506
        /* END: Use Case */
507
508
        $this->assertInstanceOf(
509
            URLAlias::class,
510
            $createdUrlAlias
511
        );
512
513
        return [$createdUrlAlias, $location->id];
514
    }
515
516
    /**
517
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
518
     *
519
     * @depends testCreateGlobalUrlAliasForLocation
520
     */
521 View Code Duplication
    public function testCreateGlobalUrlAliasForLocationPropertyValues($testData)
522
    {
523
        list($createdUrlAlias, $locationId) = $testData;
524
525
        $this->assertNotNull($createdUrlAlias->id);
526
527
        $this->assertPropertiesCorrect(
528
            [
529
                'type' => URLAlias::LOCATION,
530
                'destination' => $locationId,
531
                'path' => '/Home/My-New-Site-global',
532
                'languageCodes' => ['eng-US'],
533
                'alwaysAvailable' => true,
534
                'isHistory' => false,
535
                'isCustom' => true,
536
                'forward' => false,
537
            ],
538
            $createdUrlAlias
539
        );
540
    }
541
542
    /**
543
     * @param \eZ\Publish\API\Repository\Values\Content\URLAlias
544
     *
545
     * @depends testCreateGlobalUrlAliasForLocationVariation
546
     */
547
    public function testCreateGlobalUrlAliasForLocationVariationPropertyValues($testData)
548
    {
549
        $this->testCreateGlobalUrlAliasForLocationPropertyValues($testData);
550
    }
551
552
    /**
553
     * Test for the createGlobalUrlAlias() method.
554
     *
555
     * @see \eZ\Publish\API\Repository\URLAliasService::createGlobalUrlAlias()
556
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
557
     */
558
    public function testCreateGlobalUrlAliasThrowsInvalidArgumentException()
559
    {
560
        $repository = $this->getRepository();
561
562
        /* BEGIN: Use Case */
563
        $urlAliasService = $repository->getURLAliasService();
564
565
        // Throws InvalidArgumentException, since this path already exists for the
566
        // language
567
        $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...
568
            'module:content/search?SearchText=eZ',
569
            '/Design/Plain-site',
570
            'eng-US'
571
        );
572
        /* END: Use Case */
573
    }
574
575
    /**
576
     * Test for the listLocationAliases() method.
577
     *
578
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases()
579
     */
580
    public function testListLocationAliases()
581
    {
582
        $repository = $this->getRepository();
583
584
        $locationId = $this->generateId('location', 12);
585
586
        /* BEGIN: Use Case */
587
        // $locationId contains the ID of an existing Location
588
        $urlAliasService = $repository->getURLAliasService();
589
        $locationService = $repository->getLocationService();
590
591
        $location = $locationService->loadLocation($locationId);
592
593
        // Create a custom URL alias for $location
594
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'eng-US');
595
596
        // $loadedAliases will contain an array of custom URLAlias objects
597
        $loadedAliases = $urlAliasService->listLocationAliases($location);
598
        /* END: Use Case */
599
600
        $this->assertIsArray($loadedAliases);
601
602
        // Only 1 non-history alias
603
        $this->assertCount(1, $loadedAliases);
604
605
        return [$loadedAliases, $location];
606
    }
607
608
    /**
609
     * @param array $testData
610
     *
611
     * @depends testListLocationAliases
612
     */
613
    public function testListLocationAliasesLoadsCorrectly(array $testData)
614
    {
615
        list($loadedAliases, $location) = $testData;
616
617
        foreach ($loadedAliases as $loadedAlias) {
618
            $this->assertInstanceOf(
619
                URLAlias::class,
620
                $loadedAlias
621
            );
622
            $this->assertEquals(
623
                $location->id,
624
                $loadedAlias->destination
625
            );
626
        }
627
    }
628
629
    /**
630
     * Test for the listLocationAliases() method.
631
     *
632
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases($location, $custom, $languageCode)
633
     */
634 View Code Duplication
    public function testListLocationAliasesWithCustomFilter()
635
    {
636
        $repository = $this->getRepository();
637
638
        $locationId = $this->generateId('location', 12);
639
640
        /* BEGIN: Use Case */
641
        // $locationId contains the ID of an existing Location
642
        $urlAliasService = $repository->getURLAliasService();
643
        $locationService = $repository->getLocationService();
644
645
        $location = $locationService->loadLocation($locationId);
646
647
        // Create a second URL alias for $location, this is a "custom" one
648
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'ger-DE');
649
650
        // $loadedAliases will contain 1 aliases in eng-US only
651
        $loadedAliases = $urlAliasService->listLocationAliases($location, false, 'eng-US');
652
        /* END: Use Case */
653
654
        $this->assertIsArray($loadedAliases);
655
        $this->assertCount(1, $loadedAliases);
656
    }
657
658
    /**
659
     * Test for the listLocationAliases() method.
660
     *
661
     * @see \eZ\Publish\API\Repository\URLAliasService::listLocationAliases($location, $custom)
662
     */
663 View Code Duplication
    public function testListLocationAliasesWithLanguageCodeFilter()
664
    {
665
        $repository = $this->getRepository();
666
667
        $locationId = $this->generateId('location', 12);
668
669
        /* BEGIN: Use Case */
670
        // $locationId contains the ID of an existing Location
671
        $urlAliasService = $repository->getURLAliasService();
672
        $locationService = $repository->getLocationService();
673
674
        $location = $locationService->loadLocation($locationId);
675
        // Create a custom URL alias for $location
676
        $urlAliasService->createUrlAlias($location, '/My/Great-new-Site', 'eng-US');
677
678
        // $loadedAliases will contain only 1 of 3 aliases (custom in eng-US)
679
        $loadedAliases = $urlAliasService->listLocationAliases($location, true, 'eng-US');
680
        /* END: Use Case */
681
682
        $this->assertIsArray($loadedAliases);
683
        $this->assertCount(1, $loadedAliases);
684
    }
685
686
    /**
687
     * Test for the listGlobalAliases() method.
688
     *
689
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases()
690
     */
691 View Code Duplication
    public function testListGlobalAliases()
692
    {
693
        $repository = $this->getRepository();
694
695
        /* BEGIN: Use Case */
696
        $urlAliasService = $repository->getURLAliasService();
697
698
        // Create some global aliases
699
        $this->createGlobalAliases();
700
701
        // $loadedAliases will contain all 3 global aliases
702
        $loadedAliases = $urlAliasService->listGlobalAliases();
703
        /* END: Use Case */
704
705
        $this->assertIsArray($loadedAliases);
706
        $this->assertCount(3, $loadedAliases);
707
    }
708
709
    /**
710
     * Creates 3 global aliases.
711
     */
712
    private function createGlobalAliases()
713
    {
714
        $repository = $this->getRepository();
715
        $urlAliasService = $repository->getURLAliasService();
716
717
        /* BEGIN: Inline */
718
        $urlAliasService->createGlobalUrlAlias(
719
            'module:content/search?SearchText=eZ',
720
            '/My/Special-Support',
721
            'eng-US'
722
        );
723
        $urlAliasService->createGlobalUrlAlias(
724
            'module:content/search?SearchText=eZ',
725
            '/My/London-Office',
726
            'eng-GB'
727
        );
728
        $urlAliasService->createGlobalUrlAlias(
729
            'module:content/search?SearchText=Sindelfingen',
730
            '/My/Fancy-Site',
731
            'eng-US'
732
        );
733
        /* END: Inline */
734
    }
735
736
    /**
737
     * Test for the listGlobalAliases() method.
738
     *
739
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode)
740
     */
741 View Code Duplication
    public function testListGlobalAliasesWithLanguageFilter()
742
    {
743
        $repository = $this->getRepository();
744
745
        /* BEGIN: Use Case */
746
        $urlAliasService = $repository->getURLAliasService();
747
748
        // Create some global aliases
749
        $this->createGlobalAliases();
750
751
        // $loadedAliases will contain only 2 of 3 global aliases
752
        $loadedAliases = $urlAliasService->listGlobalAliases('eng-US');
753
        /* END: Use Case */
754
755
        $this->assertIsArray($loadedAliases);
756
        $this->assertCount(2, $loadedAliases);
757
    }
758
759
    /**
760
     * Test for the listGlobalAliases() method.
761
     *
762
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode, $offset)
763
     */
764 View Code Duplication
    public function testListGlobalAliasesWithOffset()
765
    {
766
        $repository = $this->getRepository();
767
768
        /* BEGIN: Use Case */
769
        $urlAliasService = $repository->getURLAliasService();
770
771
        // Create some global aliases
772
        $this->createGlobalAliases();
773
774
        // $loadedAliases will contain only 2 of 3 global aliases
775
        $loadedAliases = $urlAliasService->listGlobalAliases(null, 1);
776
        /* END: Use Case */
777
778
        $this->assertIsArray($loadedAliases);
779
        $this->assertCount(2, $loadedAliases);
780
    }
781
782
    /**
783
     * Test for the listGlobalAliases() method.
784
     *
785
     * @see \eZ\Publish\API\Repository\URLAliasService::listGlobalAliases($languageCode, $offset, $limit)
786
     */
787 View Code Duplication
    public function testListGlobalAliasesWithLimit()
788
    {
789
        $repository = $this->getRepository();
790
791
        /* BEGIN: Use Case */
792
        $urlAliasService = $repository->getURLAliasService();
793
794
        // Create some global aliases
795
        $this->createGlobalAliases();
796
797
        // $loadedAliases will contain only 1 of 3 global aliases
798
        $loadedAliases = $urlAliasService->listGlobalAliases(null, 0, 1);
799
        /* END: Use Case */
800
801
        $this->assertIsArray($loadedAliases);
802
        $this->assertCount(1, $loadedAliases);
803
    }
804
805
    /**
806
     * Test for the removeAliases() method.
807
     *
808
     * @see \eZ\Publish\API\Repository\URLAliasService::removeAliases()
809
     */
810 View Code Duplication
    public function testRemoveAliases()
811
    {
812
        $repository = $this->getRepository();
813
814
        $locationService = $repository->getLocationService();
815
        $someLocation = $locationService->loadLocation(
816
            $this->generateId('location', 12)
817
        );
818
819
        /* BEGIN: Use Case */
820
        // $someLocation contains a location with automatically generated
821
        // aliases assigned
822
        $urlAliasService = $repository->getURLAliasService();
823
824
        $initialAliases = $urlAliasService->listLocationAliases($someLocation);
825
826
        // Creates a custom alias for $someLocation
827
        $urlAliasService->createUrlAlias(
828
            $someLocation,
829
            '/my/fancy/url/alias/sindelfingen',
830
            'eng-US'
831
        );
832
833
        $customAliases = $urlAliasService->listLocationAliases($someLocation);
834
835
        // The custom alias just created will be removed
836
        // the automatic aliases stay in tact
837
        $urlAliasService->removeAliases($customAliases);
838
        /* END: Use Case */
839
840
        $this->assertEquals(
841
            $initialAliases,
842
            $urlAliasService->listLocationAliases($someLocation)
843
        );
844
    }
845
846
    /**
847
     * Test for the removeAliases() method.
848
     *
849
     * @see \eZ\Publish\API\Repository\URLAliasService::removeAliases()
850
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
851
     */
852
    public function testRemoveAliasesThrowsInvalidArgumentExceptionIfAutogeneratedAliasesAreToBeRemoved()
853
    {
854
        $repository = $this->getRepository();
855
856
        $locationService = $repository->getLocationService();
857
        $someLocation = $locationService->loadLocation(
858
            $this->generateId('location', 12)
859
        );
860
861
        /* BEGIN: Use Case */
862
        // $someLocation contains a location with automatically generated
863
        // aliases assigned
864
        $urlAliasService = $repository->getURLAliasService();
865
866
        $autogeneratedAliases = $urlAliasService->listLocationAliases($someLocation, false);
867
868
        // Throws an InvalidArgumentException, since autogeneratedAliases
869
        // cannot be removed with this method
870
        $urlAliasService->removeAliases($autogeneratedAliases);
871
        /* END: Use Case */
872
    }
873
874
    /**
875
     * Test for the lookUp() method.
876
     *
877
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp()
878
     */
879
    public function testLookUp()
880
    {
881
        $repository = $this->getRepository();
882
883
        /* BEGIN: Use Case */
884
        $urlAliasService = $repository->getURLAliasService();
885
886
        $loadedAlias = $urlAliasService->lookup('/Setup2');
887
        /* END: Use Case */
888
889
        $this->assertInstanceOf(
890
            URLAlias::class,
891
            $loadedAlias
892
        );
893
894
        return $loadedAlias;
895
    }
896
897
    /**
898
     * Test for the lookUp() method.
899
     *
900
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp($url, $languageCode)
901
     */
902
    public function testLookUpWithLanguageFilter()
903
    {
904
        $repository = $this->getRepository();
905
906
        /* BEGIN: Use Case */
907
        $urlAliasService = $repository->getURLAliasService();
908
909
        // Create aliases in multiple languages
910
        $this->createGlobalAliases();
911
912
        $loadedAlias = $urlAliasService->lookup('/My/Special-Support', 'eng-US');
913
        /* END: Use Case */
914
915
        $this->assertInstanceOf(
916
            URLAlias::class,
917
            $loadedAlias
918
        );
919
        $this->assertEquals(
920
            'content/search?SearchText=eZ',
921
            $loadedAlias->destination
922
        );
923
    }
924
925
    /**
926
     * Test for the lookUp() method.
927
     *
928
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp()
929
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
930
     */
931
    public function testLookUpThrowsNotFoundException()
932
    {
933
        $repository = $this->getRepository();
934
935
        /* BEGIN: Use Case */
936
        $urlAliasService = $repository->getURLAliasService();
937
938
        // Throws NotFoundException
939
        $urlAliasService->lookup('/non-existent-url');
940
        /* END: Use Case */
941
    }
942
943
    /**
944
     * Test for the lookUp() method.
945
     *
946
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp($url, $languageCode)
947
     * @expectedException \eZ\Publish\API\Repository\Exceptions\NotFoundException
948
     */
949
    public function testLookUpThrowsNotFoundExceptionWithLanguageFilter()
950
    {
951
        $repository = $this->getRepository();
952
953
        /* BEGIN: Use Case */
954
        $urlAliasService = $repository->getURLAliasService();
955
956
        // Throws NotFoundException
957
        $urlAliasService->lookup('/Contact-Us', 'ger-DE');
958
        /* END: Use Case */
959
    }
960
961
    /**
962
     * Test for the lookUp() method.
963
     *
964
     * @see \eZ\Publish\API\Repository\URLAliasService::lookUp($url, $languageCode)
965
     * @expectedException \eZ\Publish\API\Repository\Exceptions\InvalidArgumentException
966
     */
967
    public function testLookUpThrowsInvalidArgumentException()
968
    {
969
        $repository = $this->getRepository();
970
971
        /* BEGIN: Use Case */
972
        $urlAliasService = $repository->getURLAliasService();
973
974
        // Throws InvalidArgumentException
975
        $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...
976
        /* END: Use Case */
977
    }
978
979
    /**
980
     * Test for the lookUp() method after renaming parent which is a part of the lookup path.
981
     *
982
     * @see https://jira.ez.no/browse/EZP-28046
983
     * @covers \eZ\Publish\API\Repository\URLAliasService::lookUp
984
     * @covers \eZ\Publish\API\Repository\URLAliasService::listLocationAliases
985
     */
986
    public function testLookupOnRenamedParent()
987
    {
988
        $urlAliasService = $this->getRepository()->getURLAliasService();
989
        $locationService = $this->getRepository()->getLocationService();
990
        $contentTypeService = $this->getRepository()->getContentTypeService();
991
        $contentService = $this->getRepository()->getContentService();
992
993
        // 1. Create new container object (e.g. Folder "My Folder").
994
        $folderContentType = $contentTypeService->loadContentTypeByIdentifier('folder');
995
        $folderCreateStruct = $contentService->newContentCreateStruct($folderContentType, 'eng-GB');
996
        $folderCreateStruct->setField('name', 'My-Folder');
997
998
        $folderDraft = $contentService->createContent($folderCreateStruct, [
999
            $locationService->newLocationCreateStruct(2),
1000
        ]);
1001
1002
        $folder = $contentService->publishVersion($folderDraft->versionInfo);
1003
1004
        // 2. Create new object inside this container (e.g. article "My Article").
1005
        $folderLocation = $locationService->loadLocation($folder->contentInfo->mainLocationId);
1006
1007
        $articleContentType = $contentTypeService->loadContentTypeByIdentifier('article');
1008
        $articleCreateStruct = $contentService->newContentCreateStruct($articleContentType, 'eng-GB');
1009
        $articleCreateStruct->setField('title', 'My Article');
1010
        $articleCreateStruct->setField(
1011
            'intro',
1012
            <<< DOCBOOK
1013
<?xml version="1.0" encoding="UTF-8"?>
1014
<section xmlns="http://docbook.org/ns/docbook" version="5.0-variant ezpublish-1.0">
1015
    <para>Cache invalidation in eZ</para>
1016
</section>
1017
DOCBOOK
1018
        );
1019
        $article = $contentService->publishVersion(
1020
            $contentService->createContent($articleCreateStruct, [
1021
                $locationService->newLocationCreateStruct($folderLocation->id),
1022
            ])->versionInfo
1023
        );
1024
        $articleLocation = $locationService->loadLocation($article->contentInfo->mainLocationId);
1025
1026
        // 3. Navigate to both of them
1027
        $urlAliasService->lookup('/My-Folder');
1028
        $urlAliasService->listLocationAliases($folderLocation, false);
1029
        $urlAliasService->lookup('/My-Folder/My-Article');
1030
        $urlAliasService->listLocationAliases($articleLocation, false);
1031
1032
        // 4. Rename "My Folder" to "My Folder Modified".
1033
        $folderDraft = $contentService->createContentDraft($folder->contentInfo);
1034
        $folderUpdateStruct = $contentService->newContentUpdateStruct();
1035
        $folderUpdateStruct->setField('name', 'My Folder Modified');
1036
1037
        $contentService->publishVersion(
1038
            $contentService->updateContent($folderDraft->versionInfo, $folderUpdateStruct)->versionInfo
1039
        );
1040
1041
        // 5. Navigate to "Article"
1042
        $urlAliasService->lookup('/My-Folder/My-Article');
1043
        $aliases = $urlAliasService->listLocationAliases($articleLocation, false);
1044
1045
        $this->assertEquals('/My-Folder-Modified/My-Article', $aliases[0]->path);
1046
    }
1047
1048
    /**
1049
     * Test lookup on multilingual nested Locations returns proper UrlAlias Value.
1050
     *
1051
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1052
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1053
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1054
     */
1055
    public function testLookupOnMultilingualNestedLocations()
1056
    {
1057
        $urlAliasService = $this->getRepository()->getURLAliasService();
1058
        $locationService = $this->getRepository()->getLocationService();
1059
1060
        $topFolderNames = [
1061
            'eng-GB' => 'My folder Name',
1062
            'ger-DE' => 'Ger folder Name',
1063
            'eng-US' => 'My folder Name',
1064
        ];
1065
        $nestedFolderNames = [
1066
            'eng-GB' => 'nested Folder name',
1067
            'ger-DE' => 'Ger Nested folder Name',
1068
            'eng-US' => 'nested Folder name',
1069
        ];
1070
        $topFolderLocation = $locationService->loadLocation(
1071
            $this->createFolder($topFolderNames, 2)->contentInfo->mainLocationId
1072
        );
1073
        $nestedFolderLocation = $locationService->loadLocation(
1074
            $this->createFolder(
1075
                $nestedFolderNames,
1076
                $topFolderLocation->id
1077
            )->contentInfo->mainLocationId
1078
        );
1079
        $urlAlias = $urlAliasService->lookup('/My-Folder-Name/Nested-Folder-Name');
1080
        self::assertPropertiesCorrect(
1081
            [
1082
                'destination' => $nestedFolderLocation->id,
1083
                'path' => '/My-folder-Name/nested-Folder-name',
1084
                'languageCodes' => ['eng-US', 'eng-GB'],
1085
                'isHistory' => false,
1086
                'isCustom' => false,
1087
                'forward' => false,
1088
            ],
1089
            $urlAlias
1090
        );
1091
        $urlAlias = $urlAliasService->lookup('/Ger-Folder-Name/Ger-Nested-Folder-Name');
1092
        self::assertPropertiesCorrect(
1093
            [
1094
                'destination' => $nestedFolderLocation->id,
1095
                'path' => '/Ger-folder-Name/Ger-Nested-folder-Name',
1096
                'languageCodes' => ['ger-DE'],
1097
                'isHistory' => false,
1098
                'isCustom' => false,
1099
                'forward' => false,
1100
            ],
1101
            $urlAlias
1102
        );
1103
1104
        return [$topFolderLocation, $nestedFolderLocation];
1105
    }
1106
1107
    /**
1108
     * Test refreshSystemUrlAliasesForLocation historizes and changes current URL alias after
1109
     * changing SlugConverter configuration.
1110
     *
1111
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1112
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1113
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1114
     * @throws \ErrorException
1115
     */
1116
    public function testRefreshSystemUrlAliasesForLocationWithChangedSlugConverterConfiguration()
1117
    {
1118
        list($topFolderLocation, $nestedFolderLocation) = $this->testLookupOnMultilingualNestedLocations();
1119
1120
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1121
1122
        $this->changeSlugConverterConfiguration('transformation', 'urlalias_compat');
1123
        $this->changeSlugConverterConfiguration('wordSeparatorName', 'underscore');
1124
1125
        try {
1126
            $urlAliasService->refreshSystemUrlAliasesForLocation($topFolderLocation);
1127
            $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1128
1129
            $urlAlias = $urlAliasService->lookup('/My-Folder-Name/Nested-Folder-Name');
1130
            $this->assertUrlAliasPropertiesCorrect(
1131
                $nestedFolderLocation,
1132
                '/My-folder-Name/nested-Folder-name',
1133
                ['eng-US', 'eng-GB'],
1134
                true,
1135
                $urlAlias
1136
            );
1137
1138
            $urlAlias = $urlAliasService->lookup('/my_folder_name/nested_folder_name');
1139
            $this->assertUrlAliasPropertiesCorrect(
1140
                $nestedFolderLocation,
1141
                '/my_folder_name/nested_folder_name',
1142
                ['eng-US', 'eng-GB'],
1143
                false,
1144
                $urlAlias
1145
            );
1146
1147
            $urlAlias = $urlAliasService->lookup('/Ger-Folder-Name/Ger-Nested-Folder-Name');
1148
            $this->assertUrlAliasPropertiesCorrect(
1149
                $nestedFolderLocation,
1150
                '/Ger-folder-Name/Ger-Nested-folder-Name',
1151
                ['ger-DE'],
1152
                true,
1153
                $urlAlias
1154
            );
1155
1156
            $urlAlias = $urlAliasService->lookup('/ger_folder_name/ger_nested_folder_name');
1157
            $this->assertUrlAliasPropertiesCorrect(
1158
                $nestedFolderLocation,
1159
                '/ger_folder_name/ger_nested_folder_name',
1160
                ['ger-DE'],
1161
                false,
1162
                $urlAlias
1163
            );
1164
        } finally {
1165
            // restore configuration
1166
            $this->changeSlugConverterConfiguration('transformation', 'urlalias');
1167
            $this->changeSlugConverterConfiguration('wordSeparatorName', 'dash');
1168
        }
1169
    }
1170
1171
    /**
1172
     * Test that URL aliases are refreshed after changing URL alias schema Field name of a Content Type.
1173
     *
1174
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1175
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1176
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1177
     */
1178
    public function testRefreshSystemUrlAliasesForContentsWithUpdatedContentTypes()
1179
    {
1180
        list($topFolderLocation, $nestedFolderLocation) = $this->testLookupOnMultilingualNestedLocations();
1181
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $topFolderLocation */
1182
        /** @var \eZ\Publish\API\Repository\Values\Content\Location $nestedFolderLocation */
1183
1184
        // Default URL Alias schema is <short_name|name> which messes up this test, so:
1185
        $this->changeContentTypeUrlAliasSchema('folder', '<name>');
1186
1187
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1188
1189
        $this->updateContentField(
1190
            $topFolderLocation->getContentInfo(),
1191
            'short_name',
1192
            ['eng-GB' => 'EN Short Name', 'ger-DE' => 'DE Short Name']
1193
        );
1194
        $this->updateContentField(
1195
            $nestedFolderLocation->getContentInfo(),
1196
            'short_name',
1197
            ['eng-GB' => 'EN Nested Short Name', 'ger-DE' => 'DE Nested Short Name']
1198
        );
1199
1200
        $this->changeContentTypeUrlAliasSchema('folder', '<short_name>');
1201
1202
        // sanity test, done after updating CT, because it does not update existing entries by design
1203
        $this->assertUrlIsCurrent('/My-folder-Name', $topFolderLocation->id);
1204
        $this->assertUrlIsCurrent('/Ger-folder-Name', $topFolderLocation->id);
1205
        $this->assertUrlIsCurrent('/My-folder-Name/nested-Folder-name', $nestedFolderLocation->id);
1206
        $this->assertUrlIsCurrent('/Ger-folder-Name/Ger-Nested-folder-Name', $nestedFolderLocation->id);
1207
1208
        // Call API being tested
1209
        $urlAliasService->refreshSystemUrlAliasesForLocation($topFolderLocation);
1210
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1211
1212
        // check archived aliases
1213
        $this->assertUrlIsHistory('/My-folder-Name', $topFolderLocation->id);
1214
        $this->assertUrlIsHistory('/Ger-folder-Name', $topFolderLocation->id);
1215
        $this->assertUrlIsHistory('/My-folder-Name/nested-Folder-name', $nestedFolderLocation->id);
1216
        $this->assertUrlIsHistory('/Ger-folder-Name/Ger-Nested-folder-Name', $nestedFolderLocation->id);
1217
1218
        // check new current aliases
1219
        $this->assertUrlIsCurrent('/EN-Short-Name', $topFolderLocation->id);
1220
        $this->assertUrlIsCurrent('/DE-Short-Name', $topFolderLocation->id);
1221
        $this->assertUrlIsCurrent('/EN-Short-Name/EN-Nested-Short-Name', $nestedFolderLocation->id);
1222
        $this->assertUrlIsCurrent('/DE-Short-Name/DE-Nested-Short-Name', $nestedFolderLocation->id);
1223
    }
1224
1225
    /**
1226
     * Test that created non-latin aliases are non-empty and unique.
1227
     *
1228
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1229
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1230
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1231
     */
1232
    public function testCreateNonLatinNonEmptyUniqueAliases()
1233
    {
1234
        $repository = $this->getRepository();
1235
        $urlAliasService = $repository->getURLAliasService();
1236
        $locationService = $repository->getLocationService();
1237
1238
        $folderNames = [
1239
            'eng-GB' => 'ひらがな',
1240
        ];
1241
1242
        $folderLocation1 = $locationService->loadLocation(
1243
            $this->createFolder($folderNames, 2)->contentInfo->mainLocationId
1244
        );
1245
        $urlAlias1 = $urlAliasService->lookup('/1');
1246
        self::assertPropertiesCorrect(
1247
            [
1248
                'destination' => $folderLocation1->id,
1249
                'path' => '/1',
1250
                'languageCodes' => ['eng-GB'],
1251
                'isHistory' => false,
1252
                'isCustom' => false,
1253
                'forward' => false,
1254
            ],
1255
            $urlAlias1
1256
        );
1257
1258
        $folderLocation2 = $locationService->loadLocation(
1259
            $this->createFolder($folderNames, 2)->contentInfo->mainLocationId
1260
        );
1261
        $urlAlias2 = $urlAliasService->lookup('/2');
1262
        self::assertPropertiesCorrect(
1263
            [
1264
                'destination' => $folderLocation2->id,
1265
                'path' => '/2',
1266
                'languageCodes' => ['eng-GB'],
1267
                'isHistory' => false,
1268
                'isCustom' => false,
1269
                'forward' => false,
1270
            ],
1271
            $urlAlias2
1272
        );
1273
    }
1274
1275
    /**
1276
     * Test restoring missing current URL which has existing history.
1277
     *
1278
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1279
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1280
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1281
     * @throws \Exception
1282
     */
1283
    public function testRefreshSystemUrlAliasesForMissingUrlWithHistory()
1284
    {
1285
        $repository = $this->getRepository();
1286
        $urlAliasService = $repository->getURLAliasService();
1287
        $locationService = $repository->getLocationService();
1288
1289
        $folderNames = ['eng-GB' => 'My folder Name'];
1290
        $folder = $this->createFolder($folderNames, 2);
1291
        $folderLocation = $locationService->loadLocation($folder->contentInfo->mainLocationId);
1292
        $nestedFolder = $this->createFolder(['eng-GB' => 'Nested folder'], $folderLocation->id);
1293
        $nestedFolderLocation = $locationService->loadLocation($nestedFolder->contentInfo->mainLocationId);
1294
1295
        $folder = $this->updateContentField(
1296
            $folder->contentInfo,
1297
            'name',
1298
            ['eng-GB' => 'Updated Name']
1299
        );
1300
        // create more historical entries
1301
        $this->updateContentField(
1302
            $folder->contentInfo,
1303
            'name',
1304
            ['eng-GB' => 'Updated Again Name']
1305
        );
1306
        // create historical entry for nested folder
1307
        $this->updateContentField(
1308
            $nestedFolder->contentInfo,
1309
            'name',
1310
            ['eng-GB' => 'Updated Nested folder']
1311
        );
1312
1313
        // perform sanity check
1314
        $this->assertUrlIsHistory('/My-folder-Name', $folderLocation->id);
1315
        $this->assertUrlIsHistory('/Updated-Name', $folderLocation->id);
1316
        $this->assertUrlIsHistory('/My-folder-Name/Nested-folder', $nestedFolderLocation->id);
1317
        $this->assertUrlIsHistory('/Updated-Name/Nested-folder', $nestedFolderLocation->id);
1318
        $this->assertUrlIsHistory('/Updated-Again-Name/Nested-folder', $nestedFolderLocation->id);
1319
1320
        $this->assertUrlIsCurrent('/Updated-Again-Name', $folderLocation->id);
1321
        $this->assertUrlIsCurrent('/Updated-Again-Name/Updated-Nested-folder', $nestedFolderLocation->id);
1322
1323
        self::assertNotEmpty($urlAliasService->listLocationAliases($folderLocation, false));
1324
1325
        // corrupt database by removing original entry, keeping its history
1326
        $this->performRawDatabaseOperation(
1327
            function (Connection $connection) use ($folderLocation) {
1328
                $queryBuilder = $connection->createQueryBuilder();
1329
                $expr = $queryBuilder->expr();
1330
                $queryBuilder
1331
                    ->delete('ezurlalias_ml')
1332
                    ->where(
1333
                        $expr->andX(
1334
                            $expr->eq(
1335
                                'action',
1336
                                $queryBuilder->createPositionalParameter(
1337
                                    "eznode:{$folderLocation->id}"
1338
                                )
1339
                            ),
1340
                            $expr->eq(
1341
                                'is_original',
1342
                                $queryBuilder->createPositionalParameter(1)
1343
                            )
1344
                        )
1345
                    );
1346
1347
                return $queryBuilder->execute();
1348
            }
1349
        );
1350
1351
        // perform sanity check
1352
        self::assertEmpty($urlAliasService->listLocationAliases($folderLocation, false));
1353
1354
        // Begin the actual test
1355
        $urlAliasService->refreshSystemUrlAliasesForLocation($folderLocation);
1356
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1357
1358
        // make sure there is no corrupted data that could affect the test
1359
        $urlAliasService->deleteCorruptedUrlAliases();
1360
1361
        // test if history was restored
1362
        $this->assertUrlIsHistory('/My-folder-Name', $folderLocation->id);
1363
        $this->assertUrlIsHistory('/Updated-Name', $folderLocation->id);
1364
        $this->assertUrlIsHistory('/My-folder-Name/Nested-folder', $nestedFolderLocation->id);
1365
        $this->assertUrlIsHistory('/Updated-Name/Nested-folder', $nestedFolderLocation->id);
1366
        $this->assertUrlIsHistory('/Updated-Again-Name/Nested-folder', $nestedFolderLocation->id);
1367
1368
        $this->assertUrlIsCurrent('/Updated-Again-Name', $folderLocation->id);
1369
        $this->assertUrlIsCurrent('/Updated-Again-Name/Updated-Nested-folder', $nestedFolderLocation->id);
1370
    }
1371
1372
    /**
1373
     * Test edge case when updated and archived entry gets moved to another subtree.
1374
     *
1375
     * @see https://jira.ez.no/browse/EZP-30004
1376
     *
1377
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1378
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1379
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1380
     * @throws \Exception
1381
     */
1382
    public function testRefreshSystemUrlAliasesForMovedLocation()
1383
    {
1384
        $repository = $this->getRepository();
1385
        $urlAliasService = $repository->getURLAliasService();
1386
        $locationService = $repository->getLocationService();
1387
1388
        $folderNames = ['eng-GB' => 'folder'];
1389
        $folder = $this->createFolder($folderNames, 2);
1390
        $nestedFolder = $this->createFolder($folderNames, $folder->contentInfo->mainLocationId);
1391
1392
        $nestedFolder = $this->updateContentField(
1393
            $nestedFolder->contentInfo,
1394
            'name',
1395
            ['eng-GB' => 'folder2']
1396
        );
1397
1398
        $nestedFolderLocation = $locationService->loadLocation(
1399
            $nestedFolder->contentInfo->mainLocationId
1400
        );
1401
        $rootLocation = $locationService->loadLocation(2);
1402
1403
        $locationService->moveSubtree($nestedFolderLocation, $rootLocation);
1404
        // reload nested Location to get proper parent information
1405
        $nestedFolderLocation = $locationService->loadLocation($nestedFolderLocation->id);
1406
1407
        // corrupt database by breaking link to the original URL alias
1408
        $this->performRawDatabaseOperation(
1409
            function (Connection $connection) use ($nestedFolderLocation) {
1410
                $queryBuilder = $connection->createQueryBuilder();
1411
                $expr = $queryBuilder->expr();
1412
                $queryBuilder
1413
                    ->update('ezurlalias_ml')
1414
                    ->set('link', $queryBuilder->createPositionalParameter(666, \PDO::PARAM_INT))
1415
                    ->where(
1416
                        $expr->eq(
1417
                            'action',
1418
                            $queryBuilder->createPositionalParameter(
1419
                                "eznode:{$nestedFolderLocation->id}"
1420
                            )
1421
                        )
1422
                    )
1423
                    ->andWhere(
1424
                        $expr->eq(
1425
                            'is_original',
1426
                            $queryBuilder->createPositionalParameter(0, \PDO::PARAM_INT)
1427
                        )
1428
                    )
1429
                    ->andWhere(
1430
                        $expr->eq('text', $queryBuilder->createPositionalParameter('folder'))
1431
                    )
1432
                ;
1433
1434
                return $queryBuilder->execute();
1435
            }
1436
        );
1437
1438
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1439
    }
1440
1441
    /**
1442
     * Lookup given URL and check if it is archived and points to the given Location Id.
1443
     *
1444
     * @param string $lookupUrl
1445
     * @param int $expectedDestination Expected Location ID
1446
     */
1447
    protected function assertUrlIsHistory($lookupUrl, $expectedDestination)
1448
    {
1449
        $this->assertLookupHistory(true, $expectedDestination, $lookupUrl);
1450
    }
1451
1452
    /**
1453
     * Lookup given URL and check if it is current (not archived) and points to the given Location Id.
1454
     *
1455
     * @param string $lookupUrl
1456
     * @param int $expectedDestination Expected Location ID
1457
     */
1458
    protected function assertUrlIsCurrent($lookupUrl, $expectedDestination)
1459
    {
1460
        $this->assertLookupHistory(false, $expectedDestination, $lookupUrl);
1461
    }
1462
1463
    /**
1464
     * Lookup and URLAlias VO history and destination properties.
1465
     *
1466
     * @see assertUrlIsHistory
1467
     * @see assertUrlIsCurrent
1468
     *
1469
     * @param bool $expectedIsHistory
1470
     * @param int $expectedDestination Expected Location ID
1471
     * @param string $lookupUrl
1472
     */
1473
    protected function assertLookupHistory($expectedIsHistory, $expectedDestination, $lookupUrl)
1474
    {
1475
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1476
1477
        try {
1478
            $urlAlias = $urlAliasService->lookup($lookupUrl);
1479
            self::assertPropertiesCorrect(
1480
                [
1481
                    'destination' => $expectedDestination,
1482
                    'path' => $lookupUrl,
1483
                    'isHistory' => $expectedIsHistory,
1484
                ],
1485
                $urlAlias
1486
            );
1487
        } catch (InvalidArgumentException $e) {
1488
            self::fail("Failed to lookup {$lookupUrl}: $e");
1489
        } catch (NotFoundException $e) {
1490
            self::fail("Failed to lookup {$lookupUrl}: $e");
1491
        }
1492
    }
1493
1494
    /**
1495
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
1496
     * @param $fieldDefinitionIdentifier
1497
     * @param array $fieldValues
1498
     *
1499
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1500
     *
1501
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1502
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1503
     */
1504
    protected function updateContentField(ContentInfo $contentInfo, $fieldDefinitionIdentifier, array $fieldValues)
1505
    {
1506
        $contentService = $this->getRepository(false)->getContentService();
1507
1508
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1509
        foreach ($fieldValues as $languageCode => $fieldValue) {
1510
            $contentUpdateStruct->setField($fieldDefinitionIdentifier, $fieldValue, $languageCode);
1511
        }
1512
        $contentDraft = $contentService->updateContent(
1513
            $contentService->createContentDraft($contentInfo)->versionInfo,
1514
            $contentUpdateStruct
1515
        );
1516
1517
        return $contentService->publishVersion($contentDraft->versionInfo);
1518
    }
1519
1520
    /**
1521
     * Test deleting corrupted URL aliases.
1522
     *
1523
     * Note: this test will not be needed once we introduce Improved Storage with Foreign keys support.
1524
     *
1525
     * Note: test depends on already broken URL aliases: eznode:59, eznode:59, eznode:60.
1526
     *
1527
     * @throws \ErrorException
1528
     */
1529
    public function testDeleteCorruptedUrlAliases()
1530
    {
1531
        $repository = $this->getRepository();
1532
        $urlAliasService = $repository->getURLAliasService();
1533
        $connection = $this->getRawDatabaseConnection();
1534
1535
        $query = $connection->createQueryBuilder()->select('*')->from('ezurlalias_ml');
1536
        $originalRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1537
1538
        $expectedCount = count($originalRows);
1539
        $expectedCount += $this->insertBrokenUrlAliasTableFixtures($connection);
1540
1541
        // sanity check
1542
        $updatedRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1543
        self::assertCount($expectedCount, $updatedRows, 'Found unexpected number of new rows');
1544
1545
        // BEGIN API use case
1546
        $urlAliasService->deleteCorruptedUrlAliases();
1547
        // END API use case
1548
1549
        $updatedRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1550
        self::assertCount(
1551
            // API should also remove already broken pre-existing URL aliases to Locations 50 and 2x 59
1552
            count($originalRows) - 3,
1553
            $updatedRows,
1554
            'Number of rows after cleanup is not the same as the original number of rows'
1555
        );
1556
    }
1557
1558
    /**
1559
     * Mutate 'ezpublish.persistence.slug_converter' Service configuration.
1560
     *
1561
     * @param string $key
1562
     * @param string $value
1563
     *
1564
     * @throws \ErrorException
1565
     * @throws \Exception
1566
     */
1567
    protected function changeSlugConverterConfiguration($key, $value)
1568
    {
1569
        $testSlugConverter = $this
1570
            ->getSetupFactory()
1571
            ->getServiceContainer()
1572
            ->getInnerContainer()
1573
            ->get('ezpublish.persistence.slug_converter');
1574
1575
        if (!$testSlugConverter instanceof TestSlugConverter) {
1576
            throw new RuntimeException(
1577
                sprintf(
1578
                    '%s: expected instance of %s, got %s',
1579
                    __METHOD__,
1580
                    TestSlugConverter::class,
1581
                    get_class($testSlugConverter)
1582
                )
1583
            );
1584
        }
1585
1586
        $testSlugConverter->setConfigurationValue($key, $value);
1587
    }
1588
1589
    /**
1590
     * Update Content Type URL alias schema pattern.
1591
     *
1592
     * @param string $contentTypeIdentifier
1593
     * @param string $newUrlAliasSchema
1594
     *
1595
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1596
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1597
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1598
     */
1599
    protected function changeContentTypeUrlAliasSchema($contentTypeIdentifier, $newUrlAliasSchema)
1600
    {
1601
        $contentTypeService = $this->getRepository(false)->getContentTypeService();
1602
1603
        $contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1604
1605
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1606
        $contentTypeUpdateStruct = $contentTypeService->newContentTypeUpdateStruct();
1607
        $contentTypeUpdateStruct->urlAliasSchema = $newUrlAliasSchema;
1608
1609
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $contentTypeUpdateStruct);
1610
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1611
    }
1612
1613
    private function assertUrlAliasPropertiesCorrect(
1614
        Location $expectedDestinationLocation,
1615
        $expectedPath,
1616
        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...
1617
        $expectedIsHistory,
1618
        URLAlias $actualUrlAliasValue
1619
    ) {
1620
        self::assertPropertiesCorrect(
1621
            [
1622
                'destination' => $expectedDestinationLocation->id,
1623
                'path' => $expectedPath,
1624
                // @todo uncomment after fixing EZP-27124
1625
                //'languageCodes' => $expectedLanguageCodes,
1626
                'isHistory' => $expectedIsHistory,
1627
                'isCustom' => false,
1628
                'forward' => false,
1629
            ],
1630
            $actualUrlAliasValue
1631
        );
1632
    }
1633
1634
    /**
1635
     * Insert intentionally broken rows into ezurlalias_ml table to test cleanup API.
1636
     *
1637
     * @see \eZ\Publish\API\Repository\URLAliasService::deleteCorruptedUrlAliases
1638
     * @see testDeleteCorruptedUrlAliases
1639
     *
1640
     * @param \Doctrine\DBAL\Connection $connection
1641
     *
1642
     * @return int Number of new rows
1643
     */
1644
    private function insertBrokenUrlAliasTableFixtures(Connection $connection)
1645
    {
1646
        $rows = [
1647
            // link to non-existent location
1648
            [
1649
                'action' => 'eznode:9999',
1650
                'action_type' => 'eznode',
1651
                'alias_redirects' => 0,
1652
                'id' => 9997,
1653
                'is_alias' => 0,
1654
                'is_original' => 1,
1655
                'lang_mask' => 3,
1656
                'link' => 9997,
1657
                'parent' => 0,
1658
                'text' => 'my-location',
1659
                'text_md5' => '19d12b1b9994619cd8e90f00a6f5834e',
1660
            ],
1661
            // link to non-existent target URL alias (`link` column)
1662
            [
1663
                'action' => 'nop:',
1664
                'action_type' => 'nop',
1665
                'alias_redirects' => 0,
1666
                'id' => 9998,
1667
                'is_alias' => 1,
1668
                'is_original' => 1,
1669
                'lang_mask' => 2,
1670
                'link' => 9995,
1671
                'parent' => 0,
1672
                'text' => 'my-alias1',
1673
                'text_md5' => 'a29dd95ccf4c1bc7ebbd61086863b632',
1674
            ],
1675
            // link to non-existent parent URL alias
1676
            [
1677
                'action' => 'nop:',
1678
                'action_type' => 'nop',
1679
                'alias_redirects' => 0,
1680
                'id' => 9999,
1681
                'is_alias' => 0,
1682
                'is_original' => 1,
1683
                'lang_mask' => 3,
1684
                'link' => 9999,
1685
                'parent' => 9995,
1686
                'text' => 'my-alias2',
1687
                'text_md5' => 'e5dea18481e4f86857865d9fc94e4ce9',
1688
            ],
1689
        ];
1690
1691
        $query = $connection->createQueryBuilder()->insert('ezurlalias_ml');
1692
1693
        foreach ($rows as $row) {
1694
            foreach ($row as $columnName => $value) {
1695
                $row[$columnName] = $query->createNamedParameter($value);
1696
            }
1697
            $query->values($row);
1698
            $query->execute();
1699
        }
1700
1701
        return count($rows);
1702
    }
1703
}
1704