Completed
Push — ezp_30981_content_info_proxy ( a78a98...0757d2 )
by
unknown
15:21
created

RouterTest::testMatchByName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 50
rs 9.0909
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
namespace eZ\Publish\Core\MVC\Symfony\SiteAccess\Tests;
8
9
use eZ\Publish\Core\MVC\Exception\InvalidSiteAccessException;
10
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
11
use eZ\Publish\Core\MVC\Symfony\SiteAccess\Router;
12
use eZ\Publish\Core\MVC\Symfony\SiteAccess\MatcherBuilderInterface;
13
use eZ\Publish\Core\MVC\Symfony\SiteAccess\Matcher;
14
use eZ\Publish\Core\MVC\Symfony\Routing\SimplifiedRequest;
15
use eZ\Publish\Core\MVC\Symfony\SiteAccess\VersatileMatcher;
16
use Psr\Log\LoggerInterface;
17
use Symfony\Component\HttpFoundation\Request;
18
19
class RouterTest extends RouterBaseTest
20
{
21
    protected function tearDown(): void
22
    {
23
        putenv('EZPUBLISH_SITEACCESS');
24
        parent::tearDown();
25
    }
26
27
    public function testConstructDebug()
28
    {
29
        return $this->createRouter(true);
30
    }
31
32
    /**
33
     * @dataProvider matchProvider
34
     */
35
    public function testMatch(SimplifiedRequest $request, $siteAccess)
36
    {
37
        $router = $this->createRouter();
38
        $sa = $router->match($request);
39
        $this->assertInstanceOf(SiteAccess::class, $sa);
40
        $this->assertSame($siteAccess, $sa->name);
41
        // SiteAccess must be serializable as a whole. See https://jira.ez.no/browse/EZP-21613
42
        $this->assertIsString(serialize($sa));
43
        $router->setSiteAccess();
44
    }
45
46 View Code Duplication
    public function testMatchWithDevEnvFail()
47
    {
48
        $router = $this->createRouter(true);
49
        putenv('EZPUBLISH_SITEACCESS=' . self::UNDEFINED_SA_NAME);
50
51
        $this->expectException(InvalidSiteAccessException::class);
52
        $this->expectExceptionMessageRegExp(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\TestCa...xceptionMessageRegExp() has been deprecated with message: Use expectExceptionMessageMatches() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
53
            '/^Invalid SiteAccess \'' . self::UNDEFINED_SA_NAME . '\', matched by .+\\. Valid SiteAccesses are/'
54
        );
55
56
        $router->match(new SimplifiedRequest());
57
    }
58
59 View Code Duplication
    public function testMatchWithProdEnvFail()
60
    {
61
        $router = $this->createRouter();
62
        putenv('EZPUBLISH_SITEACCESS=' . self::UNDEFINED_SA_NAME);
63
64
        $this->expectException(InvalidSiteAccessException::class);
65
        $this->expectExceptionMessageRegExp(
0 ignored issues
show
Deprecated Code introduced by
The method PHPUnit\Framework\TestCa...xceptionMessageRegExp() has been deprecated with message: Use expectExceptionMessageMatches() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
66
            '/^Invalid SiteAccess \'' . self::UNDEFINED_SA_NAME . '\', matched by .+\\.$/'
67
        );
68
69
        $router->match(new SimplifiedRequest());
70
    }
71
72
    public function testMatchWithEnv()
73
    {
74
        $router = $this->createRouter();
75
        putenv('EZPUBLISH_SITEACCESS=' . self::ENV_SA_NAME);
76
        $sa = $router->match(new SimplifiedRequest());
77
        $this->assertInstanceOf(SiteAccess::class, $sa);
78
        $this->assertSame(self::ENV_SA_NAME, $sa->name);
79
        $this->assertSame('env', $sa->matchingType);
80
        $router->setSiteAccess();
81
    }
82
83
    public function testMatchWithRequestHeader(): void
84
    {
85
        $router = $this->createRouter();
86
        $request = Request::create('/foo/bar');
87
        $request->headers->set('X-Siteaccess', self::HEADERBASED_SA_NAME);
88
        $sa = $router->match(
89
            new SimplifiedRequest(
90
                [
91
                    'headers' => $request->headers->all(),
92
                ]
93
            )
94
        );
95
        $this->assertInstanceOf(SiteAccess::class, $sa);
96
        $this->assertSame(self::HEADERBASED_SA_NAME, $sa->name);
97
        $this->assertSame('header', $sa->matchingType);
98
        $router->setSiteAccess();
99
    }
100
101
    public function matchProvider(): array
102
    {
103
        return [
104
            [SimplifiedRequest::fromUrl('http://example.com'), 'default_sa'],
105
            [SimplifiedRequest::fromUrl('https://example.com'), 'default_sa'],
106
            [SimplifiedRequest::fromUrl('http://example.com/'), 'default_sa'],
107
            [SimplifiedRequest::fromUrl('https://example.com/'), 'default_sa'],
108
            [SimplifiedRequest::fromUrl('http://example.com//'), 'default_sa'],
109
            [SimplifiedRequest::fromUrl('https://example.com//'), 'default_sa'],
110
            [SimplifiedRequest::fromUrl('http://example.com:8080/'), 'default_sa'],
111
            [SimplifiedRequest::fromUrl('http://example.com/first_siteaccess/'), 'default_sa'],
112
            [SimplifiedRequest::fromUrl('http://example.com/?first_siteaccess'), 'default_sa'],
113
            [SimplifiedRequest::fromUrl('http://example.com/?first_sa'), 'default_sa'],
114
            [SimplifiedRequest::fromUrl('http://example.com/first_salt'), 'default_sa'],
115
            [SimplifiedRequest::fromUrl('http://example.com/first_sa.foo'), 'default_sa'],
116
            [SimplifiedRequest::fromUrl('http://example.com/test'), 'default_sa'],
117
            [SimplifiedRequest::fromUrl('http://example.com/test/foo/'), 'default_sa'],
118
            [SimplifiedRequest::fromUrl('http://example.com/test/foo/bar/'), 'default_sa'],
119
            [SimplifiedRequest::fromUrl('http://example.com/test/foo/bar/first_sa'), 'default_sa'],
120
            [SimplifiedRequest::fromUrl('http://example.com/default_sa'), 'default_sa'],
121
122
            [SimplifiedRequest::fromUrl('http://example.com/first_sa'), 'first_sa'],
123
            [SimplifiedRequest::fromUrl('http://example.com/first_sa/'), 'first_sa'],
124
            [SimplifiedRequest::fromUrl('http://example.com/first_sa//'), 'first_sa'],
125
            // Double slashes shouldn't be considered as one
126
            [SimplifiedRequest::fromUrl('http://example.com//first_sa//'), 'default_sa'],
127
            [SimplifiedRequest::fromUrl('http://example.com/first_sa///test'), 'first_sa'],
128
            [SimplifiedRequest::fromUrl('http://example.com/first_sa/foo'), 'first_sa'],
129
            [SimplifiedRequest::fromUrl('http://example.com/first_sa/foo/bar'), 'first_sa'],
130
            [SimplifiedRequest::fromUrl('http://example.com:82/first_sa/'), 'first_sa'],
131
            [SimplifiedRequest::fromUrl('http://third_siteaccess/first_sa/'), 'first_sa'],
132
            [SimplifiedRequest::fromUrl('http://first_sa/'), 'first_sa'],
133
            [SimplifiedRequest::fromUrl('https://first_sa/'), 'first_sa'],
134
            [SimplifiedRequest::fromUrl('http://first_sa:81/'), 'first_sa'],
135
            [SimplifiedRequest::fromUrl('http://first_siteaccess/'), 'first_sa'],
136
            [SimplifiedRequest::fromUrl('http://first_siteaccess:82/'), 'first_sa'],
137
            [SimplifiedRequest::fromUrl('http://first_siteaccess:83/'), 'first_sa'],
138
            [SimplifiedRequest::fromUrl('http://first_siteaccess/foo/'), 'first_sa'],
139
            [SimplifiedRequest::fromUrl('http://first_siteaccess:82/foo/'), 'first_sa'],
140
            [SimplifiedRequest::fromUrl('http://first_siteaccess:83/foo/'), 'first_sa'],
141
142
            [SimplifiedRequest::fromUrl('http://example.com/second_sa'), 'second_sa'],
143
            [SimplifiedRequest::fromUrl('http://example.com/second_sa/'), 'second_sa'],
144
            [SimplifiedRequest::fromUrl('http://example.com/second_sa?param1=foo'), 'second_sa'],
145
            [SimplifiedRequest::fromUrl('http://example.com/second_sa/foo/'), 'second_sa'],
146
            [SimplifiedRequest::fromUrl('http://example.com:82/second_sa/'), 'second_sa'],
147
            [SimplifiedRequest::fromUrl('http://example.com:83/second_sa/'), 'second_sa'],
148
            [SimplifiedRequest::fromUrl('http://first_siteaccess:82/second_sa/'), 'second_sa'],
149
            [SimplifiedRequest::fromUrl('http://first_siteaccess:83/second_sa/'), 'second_sa'],
150
151
            [SimplifiedRequest::fromUrl('http://example.com:81/'), 'third_sa'],
152
            [SimplifiedRequest::fromUrl('https://example.com:81/'), 'third_sa'],
153
            [SimplifiedRequest::fromUrl('http://example.com:81/foo'), 'third_sa'],
154
            [SimplifiedRequest::fromUrl('http://example.com:81/foo/bar'), 'third_sa'],
155
156
            [SimplifiedRequest::fromUrl('http://example.com:82/'), 'fourth_sa'],
157
            [SimplifiedRequest::fromUrl('https://example.com:82/'), 'fourth_sa'],
158
            [SimplifiedRequest::fromUrl('https://example.com:82/foo'), 'fourth_sa'],
159
160
            [SimplifiedRequest::fromUrl('http://fr.ezpublish.dev/eng'), 'fr_eng'],
161
            [SimplifiedRequest::fromUrl('http://us.ezpublish.dev/fre'), 'fr_us'],
162
        ];
163
    }
164
165
    public function testMatchByNameInvalidSiteAccess()
166
    {
167
        $this->expectException(\InvalidArgumentException::class);
168
169
        $matcherBuilder = $this->createMock(MatcherBuilderInterface::class);
170
        $logger = $this->createMock(LoggerInterface::class);
171
        $siteAccessProvider = $this->createMock(SiteAccess\SiteAccessProviderInterface::class);
172
        $siteAccessProvider
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
173
            ->method('isDefined')
174
            ->with('bar')
175
            ->willReturn(false);
176
        $router = new Router($matcherBuilder, $logger, 'default_sa', [], $siteAccessProvider);
177
        $router->matchByName('bar');
178
    }
179
180
    public function testMatchByName()
181
    {
182
        $matcherBuilder = $this->createMock(MatcherBuilderInterface::class);
183
        $logger = $this->createMock(LoggerInterface::class);
184
        $matcherClass = 'Map\Host';
185
        $matchedSiteAccess = 'foo';
186
        $matcherConfig = [
187
            'phoenix-rises.fm' => $matchedSiteAccess,
188
        ];
189
        $config = [
190
            'Map\URI' => ['default' => 'default_sa'],
191
            $matcherClass => $matcherConfig,
192
        ];
193
        $siteAccessProvider = $this->createMock(SiteAccess\SiteAccessProviderInterface::class);
194
        $siteAccessProvider
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
195
            ->method('isDefined')
196
            ->willReturnMap([
197
                [$matchedSiteAccess, true],
198
                ['default_sa', true],
199
            ]);
200
        $router = new Router($matcherBuilder, $logger, 'default_sa', $config, $siteAccessProvider);
201
        $matcherInitialSA = $this->createMock(SiteAccess\URILexer::class);
202
        $router->setSiteAccess(new SiteAccess('test', 'test', $matcherInitialSA));
203
        $matcherInitialSA
204
            ->expects($this->once())
205
            ->method('analyseURI');
206
207
        $matcher = $this->createMock(VersatileMatcher::class);
208
        $matcherBuilder
209
            ->expects($this->exactly(2))
210
            ->method('buildMatcher')
211
            ->will(
212
                $this->onConsecutiveCalls(
213
                    $this->createMock(Matcher::class),
214
                    $matcher
215
                )
216
            );
217
218
        $reverseMatchedMatcher = $this->createMock(VersatileMatcher::class);
219
        $matcher
220
            ->expects($this->once())
221
            ->method('reverseMatch')
222
            ->with($matchedSiteAccess)
223
            ->will($this->returnValue($reverseMatchedMatcher));
224
225
        $siteAccess = $router->matchByName($matchedSiteAccess);
226
        $this->assertInstanceOf(SiteAccess::class, $siteAccess);
227
        $this->assertSame($reverseMatchedMatcher, $siteAccess->matcher);
228
        $this->assertSame($matchedSiteAccess, $siteAccess->name);
229
    }
230
231
    public function testMatchByNameNoVersatileMatcher()
232
    {
233
        $matcherBuilder = $this->createMock(MatcherBuilderInterface::class);
234
        $logger = $this->createMock(LoggerInterface::class);
235
        $matcherClass = 'Map\Host';
236
        $defaultSiteAccess = 'default_sa';
237
        $matcherConfig = [
238
            'phoenix-rises.fm' => 'foo',
239
        ];
240
        $config = [$matcherClass => $matcherConfig];
241
        $siteAccessProvider = $this->createMock(SiteAccess\SiteAccessProviderInterface::class);
242
        $siteAccessProvider
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
243
            ->method('isDefined')
244
            ->willReturnMap([
245
                [$defaultSiteAccess, true],
246
                ['foo', true],
247
            ]);
248
        $router = new Router($matcherBuilder, $logger, $defaultSiteAccess, $config, $siteAccessProvider);
249
        $router->setSiteAccess(new SiteAccess('test', 'test'));
250
        $request = $router->getRequest();
251
        $matcherBuilder
252
            ->expects($this->once())
253
            ->method('buildMatcher')
254
            ->with($matcherClass, $matcherConfig, $request)
255
            ->will($this->returnValue($this->createMock(Matcher::class)));
256
257
        $logger
258
            ->expects($this->once())
259
            ->method('notice');
260
        $this->assertEquals(new SiteAccess($defaultSiteAccess, 'default'), $router->matchByName($defaultSiteAccess));
261
    }
262
263
    protected function createRouter($debug = false): Router
264
    {
265
        return new Router(
266
            $this->matcherBuilder,
267
            $this->createMock(LoggerInterface::class),
268
            'default_sa',
269
            [
270
                'Map\\URI' => [
271
                    'first_sa' => 'first_sa',
272
                    'second_sa' => 'second_sa',
273
                ],
274
                'Map\\Host' => [
275
                    'first_sa' => 'first_sa',
276
                    'first_siteaccess' => 'first_sa',
277
                    'third_siteaccess' => 'third_sa',
278
                ],
279
                'Map\\Port' => [
280
                    81 => 'third_sa',
281
                    82 => 'fourth_sa',
282
                    83 => 'first_sa',
283
                    85 => 'first_sa',
284
                ],
285
                'Compound\\LogicalAnd' => [
286
                    [
287
                        'matchers' => [
288
                            'Map\\URI' => ['eng' => true],
289
                            'Map\\Host' => ['fr.ezpublish.dev' => true],
290
                        ],
291
                        'match' => 'fr_eng',
292
                    ],
293
                    [
294
                        'matchers' => [
295
                            'Map\\URI' => ['fre' => true],
296
                            'Map\\Host' => ['us.ezpublish.dev' => true],
297
                        ],
298
                        'match' => 'fr_us',
299
                    ],
300
                ],
301
            ],
302
            $this->siteAccessProvider,
303
            null,
304
            $debug
305
        );
306
    }
307
308
    /**
309
     * @return \eZ\Publish\Core\MVC\Symfony\SiteAccess\Tests\SiteAccessSetting[]
310
     */
311
    public function getSiteAccessProviderSettings(): array
312
    {
313
        return [
314
            new SiteAccessSetting('first_sa', true),
315
            new SiteAccessSetting('second_sa', true),
316
            new SiteAccessSetting('third_sa', true),
317
            new SiteAccessSetting('fourth_sa', true),
318
            new SiteAccessSetting('fr_eng', true),
319
            new SiteAccessSetting('fr_us', true),
320
            new SiteAccessSetting(self::HEADERBASED_SA_NAME, true),
321
            new SiteAccessSetting(self::ENV_SA_NAME, true),
322
            new SiteAccessSetting(self::UNDEFINED_SA_NAME, false),
323
        ];
324
    }
325
}
326