Completed
Push — master ( ae9952...b2a7f6 )
by
unknown
137:19 queued 113:13
created

testCreateUrlAliasPropertyValuesWithAlwaysAvailable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 20

Duplication

Lines 20
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 20
loc 20
rs 9.6
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 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(
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(
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(
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(
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(
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(
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(
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 restoring missing current URL which has existing history.
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
     * @throws \Exception
1225
     */
1226
    public function testRefreshSystemUrlAliasesForMissingUrlWithHistory()
1227
    {
1228
        $repository = $this->getRepository();
1229
        $urlAliasService = $repository->getURLAliasService();
1230
        $locationService = $repository->getLocationService();
1231
1232
        $folderNames = ['eng-GB' => 'My folder Name'];
1233
        $folder = $this->createFolder($folderNames, 2);
1234
        $folderLocation = $locationService->loadLocation($folder->contentInfo->mainLocationId);
1235
        $nestedFolder = $this->createFolder(['eng-GB' => 'Nested folder'], $folderLocation->id);
1236
        $nestedFolderLocation = $locationService->loadLocation($nestedFolder->contentInfo->mainLocationId);
1237
1238
        $folder = $this->updateContentField(
1239
            $folder->contentInfo,
1240
            'name',
1241
            ['eng-GB' => 'Updated Name']
1242
        );
1243
        // create more historical entries
1244
        $this->updateContentField(
1245
            $folder->contentInfo,
1246
            'name',
1247
            ['eng-GB' => 'Updated Again Name']
1248
        );
1249
        // create historical entry for nested folder
1250
        $this->updateContentField(
1251
            $nestedFolder->contentInfo,
1252
            'name',
1253
            ['eng-GB' => 'Updated Nested folder']
1254
        );
1255
1256
        // perform sanity check
1257
        $this->assertUrlIsHistory('/My-folder-Name', $folderLocation->id);
1258
        $this->assertUrlIsHistory('/Updated-Name', $folderLocation->id);
1259
        $this->assertUrlIsHistory('/My-folder-Name/Nested-folder', $nestedFolderLocation->id);
1260
        $this->assertUrlIsHistory('/Updated-Name/Nested-folder', $nestedFolderLocation->id);
1261
        $this->assertUrlIsHistory('/Updated-Again-Name/Nested-folder', $nestedFolderLocation->id);
1262
1263
        $this->assertUrlIsCurrent('/Updated-Again-Name', $folderLocation->id);
1264
        $this->assertUrlIsCurrent('/Updated-Again-Name/Updated-Nested-folder', $nestedFolderLocation->id);
1265
1266
        self::assertNotEmpty($urlAliasService->listLocationAliases($folderLocation, false));
1267
1268
        // corrupt database by removing original entry, keeping its history
1269
        $this->performRawDatabaseOperation(
1270
            function (Connection $connection) use ($folderLocation) {
1271
                $queryBuilder = $connection->createQueryBuilder();
1272
                $expr = $queryBuilder->expr();
1273
                $queryBuilder
1274
                    ->delete('ezurlalias_ml')
1275
                    ->where(
1276
                        $expr->andX(
1277
                            $expr->eq(
1278
                                'action',
1279
                                $queryBuilder->createPositionalParameter(
1280
                                    "eznode:{$folderLocation->id}"
1281
                                )
1282
                            ),
1283
                            $expr->eq(
1284
                                'is_original',
1285
                                $queryBuilder->createPositionalParameter(1)
1286
                            )
1287
                        )
1288
                    );
1289
1290
                return $queryBuilder->execute();
1291
            }
1292
        );
1293
1294
        // perform sanity check
1295
        self::assertEmpty($urlAliasService->listLocationAliases($folderLocation, false));
1296
1297
        // Begin the actual test
1298
        $urlAliasService->refreshSystemUrlAliasesForLocation($folderLocation);
1299
        $urlAliasService->refreshSystemUrlAliasesForLocation($nestedFolderLocation);
1300
1301
        // make sure there is no corrupted data that could affect the test
1302
        $urlAliasService->deleteCorruptedUrlAliases();
1303
1304
        // test if history was restored
1305
        $this->assertUrlIsHistory('/My-folder-Name', $folderLocation->id);
1306
        $this->assertUrlIsHistory('/Updated-Name', $folderLocation->id);
1307
        $this->assertUrlIsHistory('/My-folder-Name/Nested-folder', $nestedFolderLocation->id);
1308
        $this->assertUrlIsHistory('/Updated-Name/Nested-folder', $nestedFolderLocation->id);
1309
        $this->assertUrlIsHistory('/Updated-Again-Name/Nested-folder', $nestedFolderLocation->id);
1310
1311
        $this->assertUrlIsCurrent('/Updated-Again-Name', $folderLocation->id);
1312
        $this->assertUrlIsCurrent('/Updated-Again-Name/Updated-Nested-folder', $nestedFolderLocation->id);
1313
    }
1314
1315
    /**
1316
     * Lookup given URL and check if it is archived and points to the given Location Id.
1317
     *
1318
     * @param string $lookupUrl
1319
     * @param int $expectedDestination Expected Location ID
1320
     */
1321
    protected function assertUrlIsHistory($lookupUrl, $expectedDestination)
1322
    {
1323
        $this->assertLookupHistory(true, $expectedDestination, $lookupUrl);
1324
    }
1325
1326
    /**
1327
     * Lookup given URL and check if it is current (not archived) and points to the given Location Id.
1328
     *
1329
     * @param string $lookupUrl
1330
     * @param int $expectedDestination Expected Location ID
1331
     */
1332
    protected function assertUrlIsCurrent($lookupUrl, $expectedDestination)
1333
    {
1334
        $this->assertLookupHistory(false, $expectedDestination, $lookupUrl);
1335
    }
1336
1337
    /**
1338
     * Lookup and URLAlias VO history and destination properties.
1339
     *
1340
     * @see assertUrlIsHistory
1341
     * @see assertUrlIsCurrent
1342
     *
1343
     * @param bool $expectedIsHistory
1344
     * @param int $expectedDestination Expected Location ID
1345
     * @param string $lookupUrl
1346
     */
1347
    protected function assertLookupHistory($expectedIsHistory, $expectedDestination, $lookupUrl)
1348
    {
1349
        $urlAliasService = $this->getRepository(false)->getURLAliasService();
1350
1351
        try {
1352
            $urlAlias = $urlAliasService->lookup($lookupUrl);
1353
            self::assertPropertiesCorrect(
1354
                [
1355
                    'destination' => $expectedDestination,
1356
                    'path' => $lookupUrl,
1357
                    'isHistory' => $expectedIsHistory,
1358
                ],
1359
                $urlAlias
1360
            );
1361
        } catch (InvalidArgumentException $e) {
1362
            self::fail("Failed to lookup {$lookupUrl}: $e");
1363
        } catch (NotFoundException $e) {
1364
            self::fail("Failed to lookup {$lookupUrl}: $e");
1365
        }
1366
    }
1367
1368
    /**
1369
     * @param \eZ\Publish\API\Repository\Values\Content\ContentInfo $contentInfo
1370
     * @param $fieldDefinitionIdentifier
1371
     * @param array $fieldValues
1372
     *
1373
     * @return \eZ\Publish\API\Repository\Values\Content\Content
1374
     *
1375
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1376
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1377
     */
1378
    protected function updateContentField(ContentInfo $contentInfo, $fieldDefinitionIdentifier, array $fieldValues)
1379
    {
1380
        $contentService = $this->getRepository(false)->getContentService();
1381
1382
        $contentUpdateStruct = $contentService->newContentUpdateStruct();
1383
        foreach ($fieldValues as $languageCode => $fieldValue) {
1384
            $contentUpdateStruct->setField($fieldDefinitionIdentifier, $fieldValue, $languageCode);
1385
        }
1386
        $contentDraft = $contentService->updateContent(
1387
            $contentService->createContentDraft($contentInfo)->versionInfo,
1388
            $contentUpdateStruct
1389
        );
1390
1391
        return $contentService->publishVersion($contentDraft->versionInfo);
1392
    }
1393
1394
    /**
1395
     * Test deleting corrupted URL aliases.
1396
     *
1397
     * Note: this test will not be needed once we introduce Improved Storage with Foreign keys support.
1398
     *
1399
     * Note: test depends on already broken URL aliases: eznode:59, eznode:59, eznode:60.
1400
     *
1401
     * @throws \ErrorException
1402
     */
1403
    public function testDeleteCorruptedUrlAliases()
1404
    {
1405
        $repository = $this->getRepository();
1406
        $urlAliasService = $repository->getURLAliasService();
1407
        $connection = $this->getRawDatabaseConnection();
1408
1409
        $query = $connection->createQueryBuilder()->select('*')->from('ezurlalias_ml');
1410
        $originalRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1411
1412
        $expectedCount = count($originalRows);
1413
        $expectedCount += $this->insertBrokenUrlAliasTableFixtures($connection);
1414
1415
        // sanity check
1416
        $updatedRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1417
        self::assertCount($expectedCount, $updatedRows, 'Found unexpected number of new rows');
1418
1419
        // BEGIN API use case
1420
        $urlAliasService->deleteCorruptedUrlAliases();
1421
        // END API use case
1422
1423
        $updatedRows = $query->execute()->fetchAll(PDO::FETCH_ASSOC);
1424
        self::assertCount(
1425
            // API should also remove already broken pre-existing URL aliases to Locations 50 and 2x 59
1426
            count($originalRows) - 3,
1427
            $updatedRows,
1428
            'Number of rows after cleanup is not the same as the original number of rows'
1429
        );
1430
    }
1431
1432
    /**
1433
     * Mutate 'ezpublish.persistence.slug_converter' Service configuration.
1434
     *
1435
     * @param string $key
1436
     * @param string $value
1437
     *
1438
     * @throws \ErrorException
1439
     * @throws \Exception
1440
     */
1441
    protected function changeSlugConverterConfiguration($key, $value)
1442
    {
1443
        $testSlugConverter = $this
1444
            ->getSetupFactory()
1445
            ->getServiceContainer()
1446
            ->getInnerContainer()
1447
            ->get('ezpublish.persistence.slug_converter');
1448
1449
        if (!$testSlugConverter instanceof TestSlugConverter) {
1450
            throw new RuntimeException(
1451
                sprintf(
1452
                    '%s: expected instance of %s, got %s',
1453
                    __METHOD__,
1454
                    TestSlugConverter::class,
1455
                    get_class($testSlugConverter)
1456
                )
1457
            );
1458
        }
1459
1460
        $testSlugConverter->setConfigurationValue($key, $value);
1461
    }
1462
1463
    /**
1464
     * Update Content Type URL alias schema pattern.
1465
     *
1466
     * @param string $contentTypeIdentifier
1467
     * @param string $newUrlAliasSchema
1468
     *
1469
     * @throws \eZ\Publish\API\Repository\Exceptions\ForbiddenException
1470
     * @throws \eZ\Publish\API\Repository\Exceptions\NotFoundException
1471
     * @throws \eZ\Publish\API\Repository\Exceptions\UnauthorizedException
1472
     */
1473
    protected function changeContentTypeUrlAliasSchema($contentTypeIdentifier, $newUrlAliasSchema)
1474
    {
1475
        $contentTypeService = $this->getRepository(false)->getContentTypeService();
1476
1477
        $contentType = $contentTypeService->loadContentTypeByIdentifier($contentTypeIdentifier);
1478
1479
        $contentTypeDraft = $contentTypeService->createContentTypeDraft($contentType);
1480
        $contentTypeUpdateStruct = $contentTypeService->newContentTypeUpdateStruct();
1481
        $contentTypeUpdateStruct->urlAliasSchema = $newUrlAliasSchema;
1482
1483
        $contentTypeService->updateContentTypeDraft($contentTypeDraft, $contentTypeUpdateStruct);
1484
        $contentTypeService->publishContentTypeDraft($contentTypeDraft);
1485
    }
1486
1487
    private function assertUrlAliasPropertiesCorrect(
1488
        Location $expectedDestinationLocation,
1489
        $expectedPath,
1490
        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...
1491
        $expectedIsHistory,
1492
        URLAlias $actualUrlAliasValue
1493
    ) {
1494
        self::assertPropertiesCorrect(
1495
            [
1496
                'destination' => $expectedDestinationLocation->id,
1497
                'path' => $expectedPath,
1498
                // @todo uncomment after fixing EZP-27124
1499
                //'languageCodes' => $expectedLanguageCodes,
1500
                'isHistory' => $expectedIsHistory,
1501
                'isCustom' => false,
1502
                'forward' => false,
1503
            ],
1504
            $actualUrlAliasValue
1505
        );
1506
    }
1507
1508
    /**
1509
     * Insert intentionally broken rows into ezurlalias_ml table to test cleanup API.
1510
     *
1511
     * @see \eZ\Publish\API\Repository\URLAliasService::deleteCorruptedUrlAliases
1512
     * @see testDeleteCorruptedUrlAliases
1513
     *
1514
     * @param \Doctrine\DBAL\Connection $connection
1515
     *
1516
     * @return int Number of new rows
1517
     */
1518
    private function insertBrokenUrlAliasTableFixtures(Connection $connection)
1519
    {
1520
        $rows = [
1521
            // link to non-existent location
1522
            [
1523
                'action' => 'eznode:9999',
1524
                'action_type' => 'eznode',
1525
                'alias_redirects' => 0,
1526
                'id' => 9997,
1527
                'is_alias' => 0,
1528
                'is_original' => 1,
1529
                'lang_mask' => 3,
1530
                'link' => 9997,
1531
                'parent' => 0,
1532
                'text' => 'my-location',
1533
                'text_md5' => '19d12b1b9994619cd8e90f00a6f5834e',
1534
            ],
1535
            // link to non-existent target URL alias (`link` column)
1536
            [
1537
                'action' => 'nop:',
1538
                'action_type' => 'nop',
1539
                'alias_redirects' => 0,
1540
                'id' => 9998,
1541
                'is_alias' => 1,
1542
                'is_original' => 1,
1543
                'lang_mask' => 2,
1544
                'link' => 9995,
1545
                'parent' => 0,
1546
                'text' => 'my-alias1',
1547
                'text_md5' => 'a29dd95ccf4c1bc7ebbd61086863b632',
1548
            ],
1549
            // link to non-existent parent URL alias
1550
            [
1551
                'action' => 'nop:',
1552
                'action_type' => 'nop',
1553
                'alias_redirects' => 0,
1554
                'id' => 9999,
1555
                'is_alias' => 0,
1556
                'is_original' => 1,
1557
                'lang_mask' => 3,
1558
                'link' => 9999,
1559
                'parent' => 9995,
1560
                'text' => 'my-alias2',
1561
                'text_md5' => 'e5dea18481e4f86857865d9fc94e4ce9',
1562
            ],
1563
        ];
1564
1565
        $query = $connection->createQueryBuilder()->insert('ezurlalias_ml');
1566
1567
        foreach ($rows as $row) {
1568
            foreach ($row as $columnName => $value) {
1569
                $row[$columnName] = $query->createNamedParameter($value);
1570
            }
1571
            $query->values($row);
1572
            $query->execute();
1573
        }
1574
1575
        return count($rows);
1576
    }
1577
}
1578