Completed
Push — master ( 28c8cd...7e44c6 )
by André
18:53
created

UrlAliasGeneratorTest::getPermissionResolverMock()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 10
nc 1
nop 0
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
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
    /**
33
     * @var \PHPUnit_Framework_MockObject_MockObject
34
     */
35
    private $repository;
36
37
    /**
38
     * @var \PHPUnit_Framework_MockObject_MockObject
39
     */
40
    private $urlAliasService;
41
42
    /**
43
     * @var \PHPUnit_Framework_MockObject_MockObject
44
     */
45
    private $locationService;
46
47
    /**
48
     * @var \PHPUnit_Framework_MockObject_MockObject
49
     */
50
    private $router;
51
52
    /**
53
     * @var \PHPUnit_Framework_MockObject_MockObject
54
     */
55
    private $logger;
56
57
    /**
58
     * @var UrlAliasGenerator
59
     */
60
    private $urlAliasGenerator;
61
62
    /**
63
     * @var \PHPUnit_Framework_MockObject_MockObject
64
     */
65
    private $siteAccessRouter;
66
67
    /**
68
     * @var \PHPUnit_Framework_MockObject_MockObject
69
     */
70
    private $configResolver;
71
72
    protected function setUp()
73
    {
74
        parent::setUp();
75
        $this->router = $this->createMock(RouterInterface::class);
76
        $this->logger = $this->createMock(LoggerInterface::class);
77
        $this->siteAccessRouter = $this->createMock(SiteAccessRouterInterface::class);
78
        $this->configResolver = $this->createMock(ConfigResolverInterface::class);
79
        $repositoryClass = Repository::class;
80
        $this->repository = $repository = $this
81
            ->getMockBuilder($repositoryClass)
82
            ->disableOriginalConstructor()
83
            ->setMethods(
84
                array_diff(
85
                    get_class_methods($repositoryClass),
86
                    array('sudo')
87
                )
88
            )
89
            ->getMock();
90
        $this->urlAliasService = $this->createMock(URLAliasService::class);
91
        $this->locationService = $this->createMock(LocationService::class);
92
        $this->repository
93
            ->expects($this->any())
94
            ->method('getURLAliasService')
95
            ->will($this->returnValue($this->urlAliasService));
96
        $this->repository
97
            ->expects($this->any())
98
            ->method('getLocationService')
99
            ->will($this->returnValue($this->locationService));
100
        $repository
101
            ->expects($this->any())
102
            ->method('getPermissionResolver')
103
            ->will($this->returnValue($this->getPermissionResolverMock()));
104
105
        $urlAliasCharmap = array(
106
            '"' => '%22',
107
            "'" => '%27',
108
            '<' => '%3C',
109
            '>' => '%3E',
110
        );
111
        $this->urlAliasGenerator = new UrlAliasGenerator(
112
            $this->repository,
113
            $this->router,
114
            $this->configResolver,
115
            $urlAliasCharmap
116
        );
117
        $this->urlAliasGenerator->setLogger($this->logger);
118
        $this->urlAliasGenerator->setSiteAccessRouter($this->siteAccessRouter);
119
    }
120
121
    public function testGetPathPrefixByRootLocationId()
122
    {
123
        $rootLocationId = 123;
124
        $rootLocation = new Location(array('id' => $rootLocationId));
125
        $pathPrefix = '/foo/bar';
126
        $rootUrlAlias = new URLAlias(array('path' => $pathPrefix));
127
        $this->locationService
128
            ->expects($this->once())
129
            ->method('loadLocation')
130
            ->with($rootLocationId)
131
            ->will($this->returnValue($rootLocation));
132
        $this->urlAliasService
133
            ->expects($this->once())
134
            ->method('reverseLookup')
135
            ->with($rootLocation)
136
            ->will($this->returnValue($rootUrlAlias));
137
138
        $this->assertSame($pathPrefix, $this->urlAliasGenerator->getPathPrefixByRootLocationId($rootLocationId));
139
    }
140
141
    /**
142
     * @dataProvider providerTestIsPrefixExcluded
143
     */
144
    public function testIsPrefixExcluded($uri, $expectedIsExcluded)
145
    {
146
        $this->urlAliasGenerator->setExcludedUriPrefixes(
147
            array(
148
                '/products',
149
                '/shared/content',
150
                '/something/in-the-way/',
151
            )
152
        );
153
        $this->assertSame($expectedIsExcluded, $this->urlAliasGenerator->isUriPrefixExcluded($uri));
154
    }
155
156
    public function providerTestIsPrefixExcluded()
157
    {
158
        return array(
159
            array('/foo/bar', false),
160
            array('/products/bar', true),
161
            array('/ProDUctS/eZ-Publish', true),
162
            array('/ProductsFoo/eZ-Publish', true),
163
            array('/shared/foo', false),
164
            array('/SHARED/contenT/bar', true),
165
            array('/SomeThing/bidule/chose', false),
166
            array('/SomeThing/in-the-way/truc/', true),
167
            array('/CMS/eZ-Publish', false),
168
            array('/Lyon/Best/city', false),
169
        );
170
    }
171
172
    public function testLoadLocation()
173
    {
174
        $locationId = 123;
175
        $location = new Location(array('id' => $locationId));
176
        $this->locationService
177
            ->expects($this->once())
178
            ->method('loadLocation')
179
            ->with($locationId)
180
            ->will($this->returnValue($location));
181
        $this->urlAliasGenerator->loadLocation($locationId);
182
    }
183
184
    /**
185
     * @dataProvider providerTestDoGenerate
186
     */
187
    public function testDoGenerate(URLAlias $urlAlias, array $parameters, $expected)
188
    {
189
        $location = new Location(array('id' => 123));
190
        $this->urlAliasService
191
            ->expects($this->once())
192
            ->method('listLocationAliases')
193
            ->with($location, false)
194
            ->will($this->returnValue(array($urlAlias)));
195
196
        $this->urlAliasGenerator->setSiteAccess(new SiteAccess('test', 'fake', $this->createMock(SiteAccess\URILexer::class)));
197
198
        $this->assertSame($expected, $this->urlAliasGenerator->doGenerate($location, $parameters));
199
    }
200
201
    public function providerTestDoGenerate()
202
    {
203
        return array(
204
            array(
205
                new URLAlias(array('path' => '/foo/bar')),
206
                array(),
207
                '/foo/bar',
208
            ),
209
            array(
210
                new URLAlias(array('path' => '/foo/bar')),
211
                array('some' => 'thing'),
212
                '/foo/bar?some=thing',
213
            ),
214
            array(
215
                new URLAlias(array('path' => '/foo/bar')),
216
                array('some' => 'thing', 'truc' => 'muche'),
217
                '/foo/bar?some=thing&truc=muche',
218
            ),
219
        );
220
    }
221
222
    /**
223
     * @dataProvider providerTestDoGenerateWithSiteaccess
224
     */
225
    public function testDoGenerateWithSiteAccessParam(URLAlias $urlAlias, array $parameters, $expected)
226
    {
227
        $siteaccessName = 'foo';
228
        $parameters += array('siteaccess' => $siteaccessName);
229
        $languages = array('esl-ES', 'fre-FR', 'eng-GB');
230
231
        $saRootLocations = array(
232
            'foo' => 2,
233
            'bar' => 100,
234
        );
235
        $treeRootUrlAlias = array(
236
            2 => new URLAlias(array('path' => '/')),
237
            100 => new URLAlias(array('path' => '/foo/bar')),
238
        );
239
240
        $this->configResolver
241
            ->expects($this->any())
242
            ->method('getParameter')
243
            ->will(
244
                $this->returnValueMap(
245
                    array(
246
                        array('languages', null, 'foo', $languages),
247
                        array('languages', null, 'bar', $languages),
248
                        array('content.tree_root.location_id', null, 'foo', $saRootLocations['foo']),
249
                        array('content.tree_root.location_id', null, 'bar', $saRootLocations['bar']),
250
                    )
251
                )
252
            );
253
254
        $location = new Location(array('id' => 123));
255
        $this->urlAliasService
256
            ->expects($this->exactly(1))
257
            ->method('listLocationAliases')
258
            ->will(
259
                $this->returnValueMap(
260
                    array(
261
                        array($location, false, null, null, $languages, array($urlAlias)),
262
                    )
263
                )
264
            );
265
266
        $this->locationService
267
            ->expects($this->once())
268
            ->method('loadLocation')
269
            ->will(
270
                $this->returnCallback(
271
                    function ($locationId) {
272
                        return new Location(array('id' => $locationId));
273
                    }
274
                )
275
            );
276
        $this->urlAliasService
277
            ->expects($this->exactly(1))
278
            ->method('reverseLookup')
279
            ->will(
280
                $this->returnCallback(
281
                    function ($location) use ($treeRootUrlAlias) {
282
                        return $treeRootUrlAlias[$location->id];
283
                    }
284
                )
285
            );
286
287
        $this->urlAliasGenerator->setSiteAccess(new SiteAccess('test', 'fake', $this->createMock(SiteAccess\URILexer::class)));
288
289
        $this->assertSame($expected, $this->urlAliasGenerator->doGenerate($location, $parameters));
290
    }
291
292
    public function providerTestDoGenerateWithSiteaccess()
293
    {
294
        return array(
295
            array(
296
                new URLAlias(array('path' => '/foo/bar')),
297
                array(),
298
                '/foo/bar',
299
            ),
300
            array(
301
                new URLAlias(array('path' => '/foo/bar/baz')),
302
                array('siteaccess' => 'bar'),
303
                '/baz',
304
            ),
305
            array(
306
                new UrlAlias(array('path' => '/special-chars-"<>\'')),
307
                array(),
308
                '/special-chars-%22%3C%3E%27',
309
            ),
310
        );
311
    }
312
313
    public function testDoGenerateNoUrlAlias()
314
    {
315
        $location = new Location(array('id' => 123, 'contentInfo' => new ContentInfo(array('id' => 456))));
316
        $uri = "/content/location/$location->id";
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repository\Values\Content\Location. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
317
        $this->urlAliasService
318
            ->expects($this->once())
319
            ->method('listLocationAliases')
320
            ->with($location, false)
321
            ->will($this->returnValue(array()));
322
        $this->router
323
            ->expects($this->once())
324
            ->method('generate')
325
            ->with(
326
                UrlAliasGenerator::INTERNAL_CONTENT_VIEW_ROUTE,
327
                array('contentId' => $location->contentId, 'locationId' => $location->id)
0 ignored issues
show
Documentation introduced by
The property $id is declared protected in eZ\Publish\API\Repository\Values\Content\Location. Since you implemented __get(), maybe consider adding a @property or @property-read annotation. This makes it easier for IDEs to provide auto-completion.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
328
            )
329
            ->will($this->returnValue($uri));
330
331
        $this->assertSame($uri, $this->urlAliasGenerator->doGenerate($location, array()));
332
    }
333
334
    /**
335
     * @dataProvider providerTestDoGenerateRootLocation
336
     */
337
    public function testDoGenerateRootLocation(URLAlias $urlAlias, $isOutsideAndNotExcluded, $expected, $pathPrefix)
338
    {
339
        $excludedPrefixes = array('/products', '/shared');
340
        $rootLocationId = 456;
341
        $this->urlAliasGenerator->setRootLocationId($rootLocationId);
342
        $this->urlAliasGenerator->setExcludedUriPrefixes($excludedPrefixes);
343
        $location = new Location(array('id' => 123));
344
345
        $rootLocation = new Location(array('id' => $rootLocationId));
346
        $rootUrlAlias = new URLAlias(array('path' => $pathPrefix));
347
        $this->locationService
348
            ->expects($this->once())
349
            ->method('loadLocation')
350
            ->with($rootLocationId)
351
            ->will($this->returnValue($rootLocation));
352
        $this->urlAliasService
353
            ->expects($this->once())
354
            ->method('reverseLookup')
355
            ->with($rootLocation)
356
            ->will($this->returnValue($rootUrlAlias));
357
358
        $this->urlAliasService
359
            ->expects($this->once())
360
            ->method('listLocationAliases')
361
            ->with($location, false)
362
            ->will($this->returnValue(array($urlAlias)));
363
364
        if ($isOutsideAndNotExcluded) {
365
            $this->logger
366
                ->expects($this->once())
367
                ->method('warning');
368
        }
369
370
        $this->assertSame($expected, $this->urlAliasGenerator->doGenerate($location, array()));
371
    }
372
373
    public function providerTestDoGenerateRootLocation()
374
    {
375
        return array(
376
            array(
377
                new UrlAlias(array('path' => '/my/root-folder/foo/bar')),
378
                false,
379
                '/foo/bar',
380
                '/my/root-folder',
381
            ),
382
            array(
383
                new UrlAlias(array('path' => '/my/root-folder/something')),
384
                false,
385
                '/something',
386
                '/my/root-folder',
387
            ),
388
            array(
389
                new UrlAlias(array('path' => '/my/root-folder')),
390
                false,
391
                '/',
392
                '/my/root-folder',
393
            ),
394
            array(
395
                new UrlAlias(array('path' => '/foo/bar')),
396
                false,
397
                '/foo/bar',
398
                '/',
399
            ),
400
            array(
401
                new UrlAlias(array('path' => '/something')),
402
                false,
403
                '/something',
404
                '/',
405
            ),
406
            array(
407
                new UrlAlias(array('path' => '/')),
408
                false,
409
                '/',
410
                '/',
411
            ),
412
            array(
413
                new UrlAlias(array('path' => '/outside/tree/foo/bar')),
414
                true,
415
                '/outside/tree/foo/bar',
416
                '/my/root-folder',
417
            ),
418
            array(
419
                new UrlAlias(array('path' => '/products/ez-publish')),
420
                false,
421
                '/products/ez-publish',
422
                '/my/root-folder',
423
            ),
424
            array(
425
                new UrlAlias(array('path' => '/shared/some-content')),
426
                false,
427
                '/shared/some-content',
428
                '/my/root-folder',
429
            ),
430
        );
431
    }
432
433
    protected function getPermissionResolverMock()
434
    {
435
        return $this
436
            ->getMockBuilder(PermissionResolver::class)
437
            ->setMethods(null)
438
            ->setConstructorArgs(
439
                [
440
                    $this->createMock(RoleDomainMapper::class),
441
                    $this->createMock(LimitationService::class),
442
                    $this->createMock(SPIUserHandler::class),
443
                    $this->createMock(UserReference::class),
444
                ]
445
            )
446
            ->getMock();
447
    }
448
}
449