Completed
Push — EZP-31000 ( e99410...e75b72 )
by
unknown
36:08
created

testDoGenerateWithFragmentParameter()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 66

Duplication

Lines 66
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 3
dl 66
loc 66
rs 8.7418
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A UrlAliasGeneratorTest::testDoGenerateNoUrlAlias() 0 20 1

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * File containing the UrlAliasGeneratorTest 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\Core\MVC\Symfony\Routing\Tests;
10
11
use eZ\Publish\API\Repository\LocationService;
12
use eZ\Publish\API\Repository\URLAliasService;
13
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
14
use eZ\Publish\API\Repository\Values\Content\URLAlias;
15
use eZ\Publish\API\Repository\Values\User\UserReference;
16
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
17
use eZ\Publish\Core\Repository\Permission\PermissionResolver;
18
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
19
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessRouterInterface;
20
use eZ\Publish\Core\MVC\ConfigResolverInterface;
21
use eZ\Publish\Core\Repository\Helper\LimitationService;
22
use eZ\Publish\Core\Repository\Helper\RoleDomainMapper;
23
use eZ\Publish\Core\Repository\Repository;
24
use eZ\Publish\Core\Repository\Values\Content\Location;
25
use eZ\Publish\SPI\Persistence\User\Handler as SPIUserHandler;
26
use PHPUnit\Framework\TestCase;
27
use Psr\Log\LoggerInterface;
28
use Symfony\Component\Routing\RouterInterface;
29
30
class UrlAliasGeneratorTest extends TestCase
31
{
32
    /** @var \PHPUnit\Framework\MockObject\MockObject */
33
    private $repository;
34
35
    /** @var \PHPUnit\Framework\MockObject\MockObject */
36
    private $urlAliasService;
37
38
    /** @var \PHPUnit\Framework\MockObject\MockObject */
39
    private $locationService;
40
41
    /** @var \PHPUnit\Framework\MockObject\MockObject */
42
    private $router;
43
44
    /** @var \PHPUnit\Framework\MockObject\MockObject */
45
    private $logger;
46
47
    /** @var UrlAliasGenerator */
48
    private $urlAliasGenerator;
49
50
    /** @var \PHPUnit\Framework\MockObject\MockObject */
51
    private $siteAccessRouter;
52
53
    /** @var \PHPUnit\Framework\MockObject\MockObject */
54
    private $configResolver;
55
56
    protected function setUp()
57
    {
58
        parent::setUp();
59
        $this->router = $this->createMock(RouterInterface::class);
60
        $this->logger = $this->createMock(LoggerInterface::class);
61
        $this->siteAccessRouter = $this->createMock(SiteAccessRouterInterface::class);
62
        $this->configResolver = $this->createMock(ConfigResolverInterface::class);
63
        $repositoryClass = Repository::class;
64
        $this->repository = $repository = $this
65
            ->getMockBuilder($repositoryClass)
66
            ->disableOriginalConstructor()
67
            ->setMethods(
68
                array_diff(
69
                    get_class_methods($repositoryClass),
70
                    ['sudo']
71
                )
72
            )
73
            ->getMock();
74
        $this->urlAliasService = $this->createMock(URLAliasService::class);
75
        $this->locationService = $this->createMock(LocationService::class);
76
        $this->repository
77
            ->expects($this->any())
78
            ->method('getURLAliasService')
79
            ->will($this->returnValue($this->urlAliasService));
80
        $this->repository
81
            ->expects($this->any())
82
            ->method('getLocationService')
83
            ->will($this->returnValue($this->locationService));
84
        $repository
85
            ->expects($this->any())
86
            ->method('getPermissionResolver')
87
            ->will($this->returnValue($this->getPermissionResolverMock()));
88
89
        $urlAliasCharmap = [
90
            '"' => '%22',
91
            "'" => '%27',
92
            '<' => '%3C',
93
            '>' => '%3E',
94
        ];
95
        $this->urlAliasGenerator = new UrlAliasGenerator(
96
            $this->repository,
97
            $this->router,
98
            $this->configResolver,
99
            $urlAliasCharmap
100
        );
101
        $this->urlAliasGenerator->setLogger($this->logger);
102
        $this->urlAliasGenerator->setSiteAccessRouter($this->siteAccessRouter);
103
    }
104
105
    public function testGetPathPrefixByRootLocationId()
106
    {
107
        $rootLocationId = 123;
108
        $rootLocation = new Location(['id' => $rootLocationId]);
109
        $pathPrefix = '/foo/bar';
110
        $rootUrlAlias = new URLAlias(['path' => $pathPrefix]);
111
        $this->locationService
112
            ->expects($this->once())
113
            ->method('loadLocation')
114
            ->with($rootLocationId)
115
            ->will($this->returnValue($rootLocation));
116
        $this->urlAliasService
117
            ->expects($this->once())
118
            ->method('reverseLookup')
119
            ->with($rootLocation)
120
            ->will($this->returnValue($rootUrlAlias));
121
122
        $this->assertSame($pathPrefix, $this->urlAliasGenerator->getPathPrefixByRootLocationId($rootLocationId));
123
    }
124
125
    /**
126
     * @dataProvider providerTestIsPrefixExcluded
127
     */
128
    public function testIsPrefixExcluded($uri, $expectedIsExcluded)
129
    {
130
        $this->urlAliasGenerator->setExcludedUriPrefixes(
131
            [
132
                '/products',
133
                '/shared/content',
134
                '/something/in-the-way/',
135
            ]
136
        );
137
        $this->assertSame($expectedIsExcluded, $this->urlAliasGenerator->isUriPrefixExcluded($uri));
138
    }
139
140
    public function providerTestIsPrefixExcluded()
141
    {
142
        return [
143
            ['/foo/bar', false],
144
            ['/products/bar', true],
145
            ['/ProDUctS/eZ-Publish', true],
146
            ['/ProductsFoo/eZ-Publish', true],
147
            ['/shared/foo', false],
148
            ['/SHARED/contenT/bar', true],
149
            ['/SomeThing/bidule/chose', false],
150
            ['/SomeThing/in-the-way/truc/', true],
151
            ['/CMS/eZ-Publish', false],
152
            ['/Lyon/Best/city', false],
153
        ];
154
    }
155
156
    public function testLoadLocation()
157
    {
158
        $locationId = 123;
159
        $location = new Location(['id' => $locationId]);
160
        $this->locationService
161
            ->expects($this->once())
162
            ->method('loadLocation')
163
            ->with($locationId)
164
            ->will($this->returnValue($location));
165
        $this->urlAliasGenerator->loadLocation($locationId);
166
    }
167
168
    /**
169
     * @dataProvider providerTestDoGenerate
170
     */
171
    public function testDoGenerate(URLAlias $urlAlias, array $parameters, $expected)
172
    {
173
        $location = new Location(['id' => 123]);
174
        $this->urlAliasService
175
            ->expects($this->once())
176
            ->method('listLocationAliases')
177
            ->with($location, false)
178
            ->will($this->returnValue([$urlAlias]));
179
180
        $this->urlAliasGenerator->setSiteAccess(new SiteAccess('test', 'fake', $this->createMock(SiteAccess\URILexer::class)));
181
182
        $this->assertSame($expected, $this->urlAliasGenerator->doGenerate($location, $parameters));
183
    }
184
185
    public function providerTestDoGenerate()
186
    {
187
        return [
188
            'without_parameters' => [
189
                new URLAlias(['path' => '/foo/bar']),
190
                [],
191
                '/foo/bar',
192
            ],
193
            'one_parameter' => [
194
                new URLAlias(['path' => '/foo/bar']),
195
                ['some' => 'thing'],
196
                '/foo/bar?some=thing',
197
            ],
198
            'two_parameters' => [
199
                new URLAlias(['path' => '/foo/bar']),
200
                ['some' => 'thing', 'truc' => 'muche'],
201
                '/foo/bar?some=thing&truc=muche',
202
            ],
203
            '_fragment in parameters' => [
204
                new URLAlias(['path' => '/foo/bar']),
205
                ['some' => 'thing', 'truc' => 'muche', '_fragment' => 'foo'],
206
                '/foo/bar?some=thing&truc=muche#foo',
207
            ],
208
        ];
209
    }
210
211
    /**
212
     * @dataProvider providerTestDoGenerateWithSiteaccess
213
     *
214
     * @param array $parameters
215
     */
216
    public function testDoGenerateWithSiteAccessParam(URLAlias $urlAlias, array $parameters, string $expected)
217
    {
218
        $siteaccessName = 'foo';
219
        $parameters += ['siteaccess' => $siteaccessName];
220
        $languages = ['esl-ES', 'fre-FR', 'eng-GB'];
221
222
        $saRootLocations = [
223
            'foo' => 2,
224
            'bar' => 100,
225
        ];
226
        $treeRootUrlAlias = [
227
            2 => new URLAlias(['path' => '/']),
228
            100 => new URLAlias(['path' => '/foo/bar']),
229
        ];
230
231
        $this->configResolver
232
            ->expects($this->any())
233
            ->method('getParameter')
234
            ->will(
235
                $this->returnValueMap(
236
                    [
237
                        ['languages', null, 'foo', $languages],
238
                        ['languages', null, 'bar', $languages],
239
                        ['content.tree_root.location_id', null, 'foo', $saRootLocations['foo']],
240
                        ['content.tree_root.location_id', null, 'bar', $saRootLocations['bar']],
241
                    ]
242
                )
243
            );
244
245
        $location = new Location(['id' => 123]);
246
        $this->urlAliasService
247
            ->expects($this->exactly(1))
248
            ->method('listLocationAliases')
249
            ->will(
250
                $this->returnValueMap(
251
                    [
252
                        [$location, false, null, null, $languages, [$urlAlias]],
253
                    ]
254
                )
255
            );
256
257
        $this->locationService
258
            ->expects($this->once())
259
            ->method('loadLocation')
260
            ->will(
261
                $this->returnCallback(
262
                    function ($locationId) {
263
                        return new Location(['id' => $locationId]);
264
                    }
265
                )
266
            );
267
        $this->urlAliasService
268
            ->expects($this->exactly(1))
269
            ->method('reverseLookup')
270
            ->will(
271
                $this->returnCallback(
272
                    function ($location) use ($treeRootUrlAlias) {
273
                        return $treeRootUrlAlias[$location->id];
274
                    }
275
                )
276
            );
277
278
        $this->urlAliasGenerator->setSiteAccess(new SiteAccess('test', 'fake', $this->createMock(SiteAccess\URILexer::class)));
279
280
        $this->assertSame($expected, $this->urlAliasGenerator->doGenerate($location, $parameters));
281
    }
282
283
    public function providerTestDoGenerateWithSiteaccess()
284
    {
285
        return [
286
            [
287
                new URLAlias(['path' => '/foo/bar']),
288
                [],
289
                '/foo/bar',
290
            ],
291
            [
292
                new URLAlias(['path' => '/foo/bar/baz']),
293
                ['siteaccess' => 'bar'],
294
                '/baz',
295
            ],
296
            [
297
                new UrlAlias(['path' => '/special-chars-"<>\'']),
298
                [],
299
                '/special-chars-%22%3C%3E%27',
300
            ],
301
            'fragment' => [
302
                new URLAlias(['path' => '/foo/bar']),
303
                ['_fragment' => 'qux'],
304
                '/foo/bar#qux',
305
            ],
306
            'fragment_and_siteaccess' => [
307
                new URLAlias(['path' => '/foo/bar/baz']),
308
                ['_fragment' => 'qux', 'siteaccess' => 'bar'],
309
                '/baz#qux',
310
            ],
311
            'fragment_and_special_chars' => [
312
                new UrlAlias(['path' => '/special-chars-"<>\'']),
313
                ['_fragment' => 'qux'],
314
                '/special-chars-%22%3C%3E%27#qux',
315
            ],
316
            'fragment_site_siteaccess_and_params' => [
317
                new UrlAlias(['path' => '/foo/bar/baz']),
318
                ['_fragment' => 'qux', 'siteaccess' => 'bar', 'some' => 'foo'],
319
                '/baz?some=foo#qux',
320
            ],
321
        ];
322
    }
323
324
    public function testDoGenerateNoUrlAlias()
325
    {
326
        $location = new Location(['id' => 123, 'contentInfo' => new ContentInfo(['id' => 456])]);
327
        $uri = "/content/location/$location->id";
328
        $this->urlAliasService
329
            ->expects($this->once())
330
            ->method('listLocationAliases')
331
            ->with($location, false)
332
            ->will($this->returnValue([]));
333
        $this->router
334
            ->expects($this->once())
335
            ->method('generate')
336
            ->with(
337
                UrlAliasGenerator::INTERNAL_CONTENT_VIEW_ROUTE,
338
                ['contentId' => $location->contentId, 'locationId' => $location->id]
339
            )
340
            ->will($this->returnValue($uri));
341
342
        $this->assertSame($uri, $this->urlAliasGenerator->doGenerate($location, []));
343
    }
344
345
    /**
346
     * @dataProvider providerTestDoGenerateRootLocation
347
     */
348
    public function testDoGenerateRootLocation(URLAlias $urlAlias, $isOutsideAndNotExcluded, $expected, $pathPrefix)
349
    {
350
        $excludedPrefixes = ['/products', '/shared'];
351
        $rootLocationId = 456;
352
        $this->urlAliasGenerator->setRootLocationId($rootLocationId);
353
        $this->urlAliasGenerator->setExcludedUriPrefixes($excludedPrefixes);
354
        $location = new Location(['id' => 123]);
355
356
        $rootLocation = new Location(['id' => $rootLocationId]);
357
        $rootUrlAlias = new URLAlias(['path' => $pathPrefix]);
358
        $this->locationService
359
            ->expects($this->once())
360
            ->method('loadLocation')
361
            ->with($rootLocationId)
362
            ->will($this->returnValue($rootLocation));
363
        $this->urlAliasService
364
            ->expects($this->once())
365
            ->method('reverseLookup')
366
            ->with($rootLocation)
367
            ->will($this->returnValue($rootUrlAlias));
368
369
        $this->urlAliasService
370
            ->expects($this->once())
371
            ->method('listLocationAliases')
372
            ->with($location, false)
373
            ->will($this->returnValue([$urlAlias]));
374
375
        if ($isOutsideAndNotExcluded) {
376
            $this->logger
377
                ->expects($this->once())
378
                ->method('warning');
379
        }
380
381
        $this->assertSame($expected, $this->urlAliasGenerator->doGenerate($location, []));
382
    }
383
384
    public function providerTestDoGenerateRootLocation()
385
    {
386
        return [
387
            [
388
                new UrlAlias(['path' => '/my/root-folder/foo/bar']),
389
                false,
390
                '/foo/bar',
391
                '/my/root-folder',
392
            ],
393
            [
394
                new UrlAlias(['path' => '/my/root-folder/something']),
395
                false,
396
                '/something',
397
                '/my/root-folder',
398
            ],
399
            [
400
                new UrlAlias(['path' => '/my/root-folder']),
401
                false,
402
                '/',
403
                '/my/root-folder',
404
            ],
405
            [
406
                new UrlAlias(['path' => '/foo/bar']),
407
                false,
408
                '/foo/bar',
409
                '/',
410
            ],
411
            [
412
                new UrlAlias(['path' => '/something']),
413
                false,
414
                '/something',
415
                '/',
416
            ],
417
            [
418
                new UrlAlias(['path' => '/']),
419
                false,
420
                '/',
421
                '/',
422
            ],
423
            [
424
                new UrlAlias(['path' => '/outside/tree/foo/bar']),
425
                true,
426
                '/outside/tree/foo/bar',
427
                '/my/root-folder',
428
            ],
429
            [
430
                new UrlAlias(['path' => '/products/ez-publish']),
431
                false,
432
                '/products/ez-publish',
433
                '/my/root-folder',
434
            ],
435
            [
436
                new UrlAlias(['path' => '/shared/some-content']),
437
                false,
438
                '/shared/some-content',
439
                '/my/root-folder',
440
            ],
441
            [
442
                new UrlAlias(['path' => '/products/ez-publish']),
443
                false,
444
                '/products/ez-publish',
445
                '/prod',
446
            ],
447
        ];
448
    }
449
450 View Code Duplication
    protected function getPermissionResolverMock()
451
    {
452
        return $this
453
            ->getMockBuilder(PermissionResolver::class)
454
            ->setMethods(null)
455
            ->setConstructorArgs(
456
                [
457
                    $this->createMock(RoleDomainMapper::class),
458
                    $this->createMock(LimitationService::class),
459
                    $this->createMock(SPIUserHandler::class),
460
                    $this->createMock(UserReference::class),
461
                ]
462
            )
463
            ->getMock();
464
    }
465
}
466