Completed
Push — apply-code-style ( 1a43bf...37cc85 )
by
unknown
45:48
created

UrlAliasRouterTest::resetConfigResolver()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
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\MVC\ConfigResolverInterface;
16
use eZ\Publish\Core\Repository\Values\Content\Location;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\Routing\RequestContext;
19
use eZ\Bundle\EzPublishCoreBundle\Routing\UrlAliasRouter;
20
use eZ\Publish\API\Repository\Values\Content\URLAlias;
21
use eZ\Publish\Core\MVC\Symfony\Routing\Generator\UrlAliasGenerator;
22
use eZ\Publish\Core\MVC\Symfony\Routing\Tests\UrlAliasRouterTest as BaseUrlAliasRouterTest;
23
use eZ\Publish\Core\MVC\Symfony\View\Manager as ViewManager;
24
25
class UrlAliasRouterTest extends BaseUrlAliasRouterTest
26
{
27
    /** @var \PHPUnit\Framework\MockObject\MockObject */
28
    private $configResolver;
29
30
    protected function setUp()
31
    {
32
        $this->configResolver = $this->createMock(ConfigResolverInterface::class);
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->createMock(ConfigResolverInterface::class);
62
        $this->container = $this->createMock(ContainerInterface::class);
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
    }
140
141 View Code Duplication
    public function testMatchRequestLocationCaseRedirectWithRootLocation()
142
    {
143
        $rootLocationId = 123;
144
        $this->resetConfigResolver();
145
        $this->configResolver
146
            ->expects($this->any())
147
            ->method('getParameter')
148
            ->will(
149
                $this->returnValueMap(
150
                    [
151
                        ['url_alias_router', null, null, true],
152
                    ]
153
                )
154
            );
155
        $this->router->setRootLocationId($rootLocationId);
156
157
        $prefix = '/root/prefix';
158
        $this->urlALiasGenerator
159
            ->expects($this->exactly(2))
160
            ->method('getPathPrefixByRootLocationId')
161
            ->with($rootLocationId)
162
            ->will($this->returnValue($prefix));
163
        $this->urlALiasGenerator
164
            ->expects($this->once())
165
            ->method('loadLocation')
166
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
167
168
        $locationId = 789;
169
        $path = '/foo/bar';
170
        $requestedPath = '/Foo/Bar';
171
        $urlAlias = new URLAlias(
172
            [
173
                'destination' => $locationId,
174
                'path' => $prefix . $path,
175
                'type' => URLAlias::LOCATION,
176
                'isHistory' => false,
177
            ]
178
        );
179
        $this->urlAliasService
180
            ->expects($this->once())
181
            ->method('lookup')
182
            ->with($prefix . $requestedPath)
183
            ->will($this->returnValue($urlAlias));
184
185
        $expected = [
186
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
187
            '_controller' => UrlAliasRouter::VIEW_ACTION,
188
            'locationId' => $locationId,
189
            'contentId' => 456,
190
            'viewType' => ViewManager::VIEW_TYPE_FULL,
191
            'layout' => true,
192
            'semanticPathinfo' => $path,
193
            'needsRedirect' => true,
194
        ];
195
        $request = $this->getRequestByPathInfo($requestedPath);
196
        $this->assertEquals($expected, $this->router->matchRequest($request));
197
    }
198
199 View Code Duplication
    public function testMatchRequestLocationCaseRedirectWithRootRootLocation()
200
    {
201
        $rootLocationId = 123;
202
        $this->resetConfigResolver();
203
        $this->configResolver
204
            ->expects($this->any())
205
            ->method('getParameter')
206
            ->will(
207
                $this->returnValueMap(
208
                    [
209
                        ['url_alias_router', null, null, true],
210
                    ]
211
                )
212
            );
213
        $this->router->setRootLocationId($rootLocationId);
214
215
        $prefix = '/';
216
        $this->urlALiasGenerator
217
            ->expects($this->exactly(2))
218
            ->method('getPathPrefixByRootLocationId')
219
            ->with($rootLocationId)
220
            ->will($this->returnValue($prefix));
221
222
        $locationId = 789;
223
        $path = '/foo/bar';
224
        $requestedPath = '/Foo/Bar';
225
        $urlAlias = new URLAlias(
226
            [
227
                'destination' => $locationId,
228
                'path' => $path,
229
                'type' => URLAlias::LOCATION,
230
                'isHistory' => false,
231
            ]
232
        );
233
        $this->urlAliasService
234
            ->expects($this->once())
235
            ->method('lookup')
236
            ->with($requestedPath)
237
            ->will($this->returnValue($urlAlias));
238
        $this->urlALiasGenerator
239
            ->expects($this->once())
240
            ->method('loadLocation')
241
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
242
243
        $expected = [
244
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
245
            '_controller' => UrlAliasRouter::VIEW_ACTION,
246
            'locationId' => $locationId,
247
            'contentId' => 456,
248
            'viewType' => ViewManager::VIEW_TYPE_FULL,
249
            'layout' => true,
250
            'semanticPathinfo' => $path,
251
            'needsRedirect' => true,
252
        ];
253
        $request = $this->getRequestByPathInfo($requestedPath);
254
        $this->assertEquals($expected, $this->router->matchRequest($request));
255
    }
256
257
    public function testMatchRequestResourceCaseRedirectWithRootLocation()
258
    {
259
        $rootLocationId = 123;
260
        $this->resetConfigResolver();
261
        $this->configResolver
262
            ->expects($this->any())
263
            ->method('getParameter')
264
            ->will(
265
                $this->returnValueMap(
266
                    [
267
                        ['url_alias_router', null, null, true],
268
                    ]
269
                )
270
            );
271
        $this->router->setRootLocationId($rootLocationId);
272
273
        $prefix = '/root/prefix';
274
        $this->urlALiasGenerator
275
            ->expects($this->exactly(2))
276
            ->method('getPathPrefixByRootLocationId')
277
            ->with($rootLocationId)
278
            ->will($this->returnValue($prefix));
279
280
        $path = '/foo/bar';
281
        $requestedPath = '/Foo/Bar';
282
        $urlAlias = new URLAlias(
283
            [
284
                'destination' => '/content/search',
285
                'path' => $prefix . $path,
286
                'type' => URLAlias::RESOURCE,
287
                'isHistory' => false,
288
            ]
289
        );
290
        $this->urlAliasService
291
            ->expects($this->once())
292
            ->method('lookup')
293
            ->with($prefix . $requestedPath)
294
            ->will($this->returnValue($urlAlias));
295
296
        $expected = [
297
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
298
            'semanticPathinfo' => $path,
299
            'needsRedirect' => true,
300
        ];
301
        $request = $this->getRequestByPathInfo($requestedPath);
302
        $this->assertEquals($expected, $this->router->matchRequest($request));
303
    }
304
305
    public function testMatchRequestVirtualCaseRedirectWithRootLocation()
306
    {
307
        $rootLocationId = 123;
308
        $this->resetConfigResolver();
309
        $this->configResolver
310
            ->expects($this->any())
311
            ->method('getParameter')
312
            ->will(
313
                $this->returnValueMap(
314
                    [
315
                        ['url_alias_router', null, null, true],
316
                    ]
317
                )
318
            );
319
        $this->router->setRootLocationId($rootLocationId);
320
321
        $prefix = '/root/prefix';
322
        $this->urlALiasGenerator
323
            ->expects($this->exactly(2))
324
            ->method('getPathPrefixByRootLocationId')
325
            ->with($rootLocationId)
326
            ->will($this->returnValue($prefix));
327
328
        $path = '/foo/bar';
329
        $requestedPath = '/Foo/Bar';
330
        $urlAlias = new URLAlias(
331
            [
332
                'path' => $prefix . $path,
333
                'type' => URLAlias::VIRTUAL,
334
            ]
335
        );
336
        $this->urlAliasService
337
            ->expects($this->once())
338
            ->method('lookup')
339
            ->with($prefix . $requestedPath)
340
            ->will($this->returnValue($urlAlias));
341
342
        $expected = [
343
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
344
            'semanticPathinfo' => $path,
345
            'needsRedirect' => true,
346
        ];
347
        $request = $this->getRequestByPathInfo($requestedPath);
348
        $this->assertEquals($expected, $this->router->matchRequest($request));
349
    }
350
351
    public function testMatchRequestWithRootLocationAndExclusion()
352
    {
353
        $this->resetConfigResolver();
354
        $this->configResolver
355
            ->expects($this->any())
356
            ->method('getParameter')
357
            ->will(
358
                $this->returnValueMap(
359
                    [
360
                        ['url_alias_router', null, null, true],
361
                        ['content.tree_root.location_id', null, null, 123],
362
                        ['content.tree_root.excluded_uri_prefixes', null, null, ['/shared/content']],
363
                    ]
364
                )
365
            );
366
        $this->router->setRootLocationId(123);
367
368
        $pathInfo = '/shared/content/foo-bar';
369
        $destinationId = 789;
370
        $this->urlALiasGenerator
371
            ->expects($this->any())
372
            ->method('isUriPrefixExcluded')
373
            ->with($pathInfo)
374
            ->will($this->returnValue(true));
375
376
        $urlAlias = new URLAlias(
377
            [
378
                'path' => $pathInfo,
379
                'type' => UrlAlias::LOCATION,
380
                'destination' => $destinationId,
381
                'isHistory' => false,
382
            ]
383
        );
384
        $request = $this->getRequestByPathInfo($pathInfo);
385
        $this->urlAliasService
386
            ->expects($this->once())
387
            ->method('lookup')
388
            ->with($pathInfo)
389
            ->will($this->returnValue($urlAlias));
390
        $this->urlALiasGenerator
391
            ->expects($this->once())
392
            ->method('loadLocation')
393
            ->will($this->returnValue(new Location(['contentInfo' => new ContentInfo(['id' => 456])])));
394
395
        $expected = [
396
            '_route' => UrlAliasRouter::URL_ALIAS_ROUTE_NAME,
397
            '_controller' => UrlAliasRouter::VIEW_ACTION,
398
            'locationId' => $destinationId,
399
            'contentId' => 456,
400
            'viewType' => ViewManager::VIEW_TYPE_FULL,
401
            'layout' => true,
402
        ];
403
        $this->assertEquals($expected, $this->router->matchRequest($request));
404
    }
405
}
406