Completed
Push — ezp30878_cant_add_image_with_p... ( e19ea7...263f1b )
by
unknown
20:16
created

UrlAliasRouterTest   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 388
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
dl 0
loc 388
rs 10
c 0
b 0
f 0
wmc 10
lcom 1
cbo 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 17 1
A getRouter() 0 7 1
A resetConfigResolver() 0 6 1
A testMatchRequestDeactivatedUrlAlias() 0 15 1
B testMatchRequestWithRootLocation() 0 56 1
B testMatchRequestLocationCaseRedirectWithRootLocation() 0 59 1
B testMatchRequestLocationCaseRedirectWithRootRootLocation() 0 58 1
A testMatchRequestResourceCaseRedirectWithRootLocation() 0 47 1
A testMatchRequestVirtualCaseRedirectWithRootLocation() 0 45 1
B testMatchRequestWithRootLocationAndExclusion() 0 55 1
1
<?php
2
3
/**
4
 * File containing the UrlAliasRouterTest 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\Bundle\EzPublishCoreBundle\Tests\Routing;
10
11
use eZ\Publish\API\Repository\LocationService;
12
use eZ\Publish\API\Repository\URLAliasService;
13
use eZ\Publish\API\Repository\ContentService;
14
use eZ\Publish\API\Repository\Values\Content\ContentInfo;
15
use eZ\Publish\Core\Repository\Values\Content\Location;
16
use Symfony\Component\Routing\RequestContext;
17
use eZ\Bundle\EzPublishCoreBundle\Routing\UrlAliasRouter;
18
use eZ\Publish\API\Repository\Values\Content\URLAlias;
19
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
20
use eZ\Publish\Core\MVC\Symfony\Routing\Tests\UrlAliasRouterTest as BaseUrlAliasRouterTest;
21
use eZ\Publish\Core\MVC\Symfony\View\Manager as ViewManager;
22
23
class UrlAliasRouterTest extends BaseUrlAliasRouterTest
24
{
25
    /**
26
     * @var \PHPUnit_Framework_MockObject_MockObject
27
     */
28
    private $configResolver;
29
30
    protected function setUp()
31
    {
32
        $this->configResolver = $this->getMock('eZ\\Publish\\Core\\MVC\\ConfigResolverInterface');
33
        $this->configResolver
34
            ->expects($this->any())
35
            ->method('getParameter')
36
            ->will(
37
                $this->returnValueMap(
38
                    [
39
                        ['url_alias_router', null, null, true],
40
                        ['content.tree_root.location_id', null, null, null],
41
                        ['content.tree_root.excluded_uri_prefixes', null, null, []],
42
                    ]
43
                )
44
            );
45
        parent::setUp();
46
    }
47
48
    protected function getRouter(LocationService $locationService, URLAliasService $urlAliasService, ContentService $contentService, UrlAliasGenerator $urlAliasGenerator, RequestContext $requestContext)
49
    {
50
        $router = new UrlAliasRouter($locationService, $urlAliasService, $contentService, $urlAliasGenerator, $requestContext);
51
        $router->setConfigResolver($this->configResolver);
52
53
        return $router;
54
    }
55
56
    /**
57
     * Resets container and configResolver mocks.
58
     */
59
    protected function resetConfigResolver()
60
    {
61
        $this->configResolver = $this->getMock('eZ\\Publish\\Core\\MVC\\ConfigResolverInterface');
62
        $this->container = $this->getMock('Symfony\\Component\\DependencyInjection\\ContainerInterface');
0 ignored issues
show
Bug introduced by
The property container does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
63
        $this->router->setConfigResolver($this->configResolver);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class eZ\Publish\Core\MVC\Symfony\Routing\UrlAliasRouter as the method setConfigResolver() does only exist in the following sub-classes of eZ\Publish\Core\MVC\Symfony\Routing\UrlAliasRouter: eZ\Bundle\EzPublishCoreB...\Routing\UrlAliasRouter. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
64
    }
65
66
    /**
67
     * @expectedException \Symfony\Component\Routing\Exception\ResourceNotFoundException
68
     */
69
    public function testMatchRequestDeactivatedUrlAlias()
70
    {
71
        $this->resetConfigResolver();
72
        $this->configResolver
73
            ->expects($this->any())
74
            ->method('getParameter')
75
            ->will(
76
                $this->returnValueMap(
77
                    [
78
                        ['url_alias_router', null, null, false],
79
                    ]
80
                )
81
            );
82
        $this->router->matchRequest($this->getRequestByPathInfo('/foo'));
83
    }
84
85
    public function testMatchRequestWithRootLocation()
86
    {
87
        $rootLocationId = 123;
88
        $this->resetConfigResolver();
89
        $this->configResolver
90
            ->expects($this->any())
91
            ->method('getParameter')
92
            ->will(
93
                $this->returnValueMap(
94
                    [
95
                        ['url_alias_router', null, null, true],
96
                    ]
97
                )
98
            );
99
        $this->router->setRootLocationId($rootLocationId);
100
101
        $prefix = '/root/prefix';
102
        $this->urlALiasGenerator
103
            ->expects($this->exactly(2))
104
            ->method('getPathPrefixByRootLocationId')
105
            ->with($rootLocationId)
106
            ->will($this->returnValue($prefix));
107
108
        $locationId = 789;
109
        $path = '/foo/bar';
110
        $urlAlias = new URLAlias(
111
            [
112
                'destination' => $locationId,
113
                'path' => $prefix . $path,
114
                'type' => URLAlias::LOCATION,
115
                'isHistory' => false,
116
            ]
117
        );
118
        $this->urlAliasService
119
            ->expects($this->once())
120
            ->method('lookup')
121
            ->with($prefix . $path)
122
            ->will($this->returnValue($urlAlias));
123
124
        $this->urlALiasGenerator
125
            ->expects($this->once())
126
            ->method('loadLocation')
127
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
128
129
        $expected = [
130
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
131
            '_controller' => UrlAliasRouter::VIEW_ACTION,
132
            'locationId' => $locationId,
133
            'contentId' => 456,
134
            'viewType' => ViewManager::VIEW_TYPE_FULL,
135
            'layout' => true,
136
        ];
137
        $request = $this->getRequestByPathInfo($path);
138
        $this->assertEquals($expected, $this->router->matchRequest($request));
139
        $this->assertSame($locationId, $request->attributes->get('locationId'));
140
    }
141
142
    public function testMatchRequestLocationCaseRedirectWithRootLocation()
143
    {
144
        $rootLocationId = 123;
145
        $this->resetConfigResolver();
146
        $this->configResolver
147
            ->expects($this->any())
148
            ->method('getParameter')
149
            ->will(
150
                $this->returnValueMap(
151
                    [
152
                        ['url_alias_router', null, null, true],
153
                    ]
154
                )
155
            );
156
        $this->router->setRootLocationId($rootLocationId);
157
158
        $prefix = '/root/prefix';
159
        $this->urlALiasGenerator
160
            ->expects($this->exactly(2))
161
            ->method('getPathPrefixByRootLocationId')
162
            ->with($rootLocationId)
163
            ->will($this->returnValue($prefix));
164
        $this->urlALiasGenerator
165
            ->expects($this->once())
166
            ->method('loadLocation')
167
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
168
169
        $locationId = 789;
170
        $path = '/foo/bar';
171
        $requestedPath = '/Foo/Bar';
172
        $urlAlias = new URLAlias(
173
            [
174
                'destination' => $locationId,
175
                'path' => $prefix . $path,
176
                'type' => URLAlias::LOCATION,
177
                'isHistory' => false,
178
            ]
179
        );
180
        $this->urlAliasService
181
            ->expects($this->once())
182
            ->method('lookup')
183
            ->with($prefix . $requestedPath)
184
            ->will($this->returnValue($urlAlias));
185
186
        $expected = [
187
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
188
            '_controller' => UrlAliasRouter::VIEW_ACTION,
189
            'locationId' => $locationId,
190
            'contentId' => 456,
191
            'viewType' => ViewManager::VIEW_TYPE_FULL,
192
            'layout' => true,
193
        ];
194
        $request = $this->getRequestByPathInfo($requestedPath);
195
        $this->assertEquals($expected, $this->router->matchRequest($request));
196
        $this->assertSame($locationId, $request->attributes->get('locationId'));
197
        $this->assertTrue($request->attributes->get('needsRedirect'));
198
        $this->assertSame($path, $request->attributes->get('semanticPathinfo'));
199
        $this->assertSame($locationId, $request->attributes->get('locationId'));
200
    }
201
202
    public function testMatchRequestLocationCaseRedirectWithRootRootLocation()
203
    {
204
        $rootLocationId = 123;
205
        $this->resetConfigResolver();
206
        $this->configResolver
207
            ->expects($this->any())
208
            ->method('getParameter')
209
            ->will(
210
                $this->returnValueMap(
211
                    [
212
                        ['url_alias_router', null, null, true],
213
                    ]
214
                )
215
            );
216
        $this->router->setRootLocationId($rootLocationId);
217
218
        $prefix = '/';
219
        $this->urlALiasGenerator
220
            ->expects($this->exactly(2))
221
            ->method('getPathPrefixByRootLocationId')
222
            ->with($rootLocationId)
223
            ->will($this->returnValue($prefix));
224
225
        $locationId = 789;
226
        $path = '/foo/bar';
227
        $requestedPath = '/Foo/Bar';
228
        $urlAlias = new URLAlias(
229
            [
230
                'destination' => $locationId,
231
                'path' => $path,
232
                'type' => URLAlias::LOCATION,
233
                'isHistory' => false,
234
            ]
235
        );
236
        $this->urlAliasService
237
            ->expects($this->once())
238
            ->method('lookup')
239
            ->with($requestedPath)
240
            ->will($this->returnValue($urlAlias));
241
        $this->urlALiasGenerator
242
            ->expects($this->once())
243
            ->method('loadLocation')
244
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
245
246
        $expected = [
247
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
248
            '_controller' => UrlAliasRouter::VIEW_ACTION,
249
            'locationId' => $locationId,
250
            'contentId' => 456,
251
            'viewType' => ViewManager::VIEW_TYPE_FULL,
252
            'layout' => true,
253
        ];
254
        $request = $this->getRequestByPathInfo($requestedPath);
255
        $this->assertEquals($expected, $this->router->matchRequest($request));
256
        $this->assertSame($locationId, $request->attributes->get('locationId'));
257
        $this->assertTrue($request->attributes->get('needsRedirect'));
258
        $this->assertSame($path, $request->attributes->get('semanticPathinfo'));
259
    }
260
261
    public function testMatchRequestResourceCaseRedirectWithRootLocation()
262
    {
263
        $rootLocationId = 123;
264
        $this->resetConfigResolver();
265
        $this->configResolver
266
            ->expects($this->any())
267
            ->method('getParameter')
268
            ->will(
269
                $this->returnValueMap(
270
                    [
271
                        ['url_alias_router', null, null, true],
272
                    ]
273
                )
274
            );
275
        $this->router->setRootLocationId($rootLocationId);
276
277
        $prefix = '/root/prefix';
278
        $this->urlALiasGenerator
279
            ->expects($this->exactly(2))
280
            ->method('getPathPrefixByRootLocationId')
281
            ->with($rootLocationId)
282
            ->will($this->returnValue($prefix));
283
284
        $path = '/foo/bar';
285
        $requestedPath = '/Foo/Bar';
286
        $urlAlias = new URLAlias(
287
            [
288
                'destination' => '/content/search',
289
                'path' => $prefix . $path,
290
                'type' => URLAlias::RESOURCE,
291
                'isHistory' => false,
292
            ]
293
        );
294
        $this->urlAliasService
295
            ->expects($this->once())
296
            ->method('lookup')
297
            ->with($prefix . $requestedPath)
298
            ->will($this->returnValue($urlAlias));
299
300
        $expected = [
301
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
302
        ];
303
        $request = $this->getRequestByPathInfo($requestedPath);
304
        $this->assertEquals($expected, $this->router->matchRequest($request));
305
        $this->assertTrue($request->attributes->get('needsRedirect'));
306
        $this->assertSame($path, $request->attributes->get('semanticPathinfo'));
307
    }
308
309
    public function testMatchRequestVirtualCaseRedirectWithRootLocation()
310
    {
311
        $rootLocationId = 123;
312
        $this->resetConfigResolver();
313
        $this->configResolver
314
            ->expects($this->any())
315
            ->method('getParameter')
316
            ->will(
317
                $this->returnValueMap(
318
                    [
319
                        ['url_alias_router', null, null, true],
320
                    ]
321
                )
322
            );
323
        $this->router->setRootLocationId($rootLocationId);
324
325
        $prefix = '/root/prefix';
326
        $this->urlALiasGenerator
327
            ->expects($this->exactly(2))
328
            ->method('getPathPrefixByRootLocationId')
329
            ->with($rootLocationId)
330
            ->will($this->returnValue($prefix));
331
332
        $path = '/foo/bar';
333
        $requestedPath = '/Foo/Bar';
334
        $urlAlias = new URLAlias(
335
            [
336
                'path' => $prefix . $path,
337
                'type' => URLAlias::VIRTUAL,
338
            ]
339
        );
340
        $this->urlAliasService
341
            ->expects($this->once())
342
            ->method('lookup')
343
            ->with($prefix . $requestedPath)
344
            ->will($this->returnValue($urlAlias));
345
346
        $expected = [
347
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
348
        ];
349
        $request = $this->getRequestByPathInfo($requestedPath);
350
        $this->assertEquals($expected, $this->router->matchRequest($request));
351
        $this->assertTrue($request->attributes->get('needsRedirect'));
352
        $this->assertSame($path, $request->attributes->get('semanticPathinfo'));
353
    }
354
355
    public function testMatchRequestWithRootLocationAndExclusion()
356
    {
357
        $this->resetConfigResolver();
358
        $this->configResolver
359
            ->expects($this->any())
360
            ->method('getParameter')
361
            ->will(
362
                $this->returnValueMap(
363
                    [
364
                        ['url_alias_router', null, null, true],
365
                        ['content.tree_root.location_id', null, null, 123],
366
                        ['content.tree_root.excluded_uri_prefixes', null, null, ['/shared/content']],
367
                    ]
368
                )
369
            );
370
        $this->router->setRootLocationId(123);
371
372
        $pathInfo = '/shared/content/foo-bar';
373
        $destinationId = 789;
374
        $this->urlALiasGenerator
375
            ->expects($this->any())
376
            ->method('isUriPrefixExcluded')
377
            ->with($pathInfo)
378
            ->will($this->returnValue(true));
379
380
        $urlAlias = new URLAlias(
381
            [
382
                'path' => $pathInfo,
383
                'type' => UrlAlias::LOCATION,
384
                'destination' => $destinationId,
385
                'isHistory' => false,
386
            ]
387
        );
388
        $request = $this->getRequestByPathInfo($pathInfo);
389
        $this->urlAliasService
390
            ->expects($this->once())
391
            ->method('lookup')
392
            ->with($pathInfo)
393
            ->will($this->returnValue($urlAlias));
394
        $this->urlALiasGenerator
395
            ->expects($this->once())
396
            ->method('loadLocation')
397
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
398
399
        $expected = [
400
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
401
            '_controller' => UrlAliasRouter::VIEW_ACTION,
402
            'locationId' => $destinationId,
403
            'contentId' => 456,
404
            'viewType' => ViewManager::VIEW_TYPE_FULL,
405
            'layout' => true,
406
        ];
407
        $this->assertEquals($expected, $this->router->matchRequest($request));
408
        $this->assertSame($destinationId, $request->attributes->get('locationId'));
409
    }
410
}
411