8a1c44592557c378eff192904924b0998a006246
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Mvc / Web / Routing / UriBuilderTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Extbase\Tests\Unit\Mvc\Web\Routing;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17 use TYPO3\CMS\Backend\Routing\Route;
18 use TYPO3\CMS\Backend\Routing\Router;
19 use TYPO3\CMS\Core\Utility\GeneralUtility;
20 use TYPO3\CMS\Extbase\Configuration\ConfigurationManager;
21 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
22 use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
23 use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentValueException;
24 use TYPO3\CMS\Extbase\Mvc\Web\Request;
25 use TYPO3\CMS\Extbase\Mvc\Web\Routing\UriBuilder;
26 use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
27 use TYPO3\CMS\Extbase\Service\EnvironmentService;
28 use TYPO3\CMS\Extbase\Service\ExtensionService;
29 use TYPO3\CMS\Extbase\Tests\Unit\Mvc\Web\Routing\Fixtures\EntityFixture;
30 use TYPO3\CMS\Extbase\Tests\Unit\Mvc\Web\Routing\Fixtures\ValueObjectFixture;
31 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
32 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
33 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
34
35 /**
36 * Test case
37 */
38 class UriBuilderTest extends UnitTestCase
39 {
40 /**
41 * @var bool Reset singletons created by subject
42 */
43 protected $resetSingletonInstances = true;
44
45 /**
46 * @var ConfigurationManagerInterface
47 */
48 protected $mockConfigurationManager;
49
50 /**
51 * @var ContentObjectRenderer|\PHPUnit_Framework_MockObject_MockObject
52 */
53 protected $mockContentObject;
54
55 /**
56 * @var Request|\PHPUnit_Framework_MockObject_MockObject
57 */
58 protected $mockRequest;
59
60 /**
61 * @var ExtensionService|\PHPUnit_Framework_MockObject_MockObject
62 */
63 protected $mockExtensionService;
64
65 /**
66 * @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface
67 */
68 protected $uriBuilder;
69
70 /**
71 * @throws \InvalidArgumentException
72 * @throws \PHPUnit\Framework\Exception
73 */
74 protected function setUp(): void
75 {
76 parent::setUp();
77 $GLOBALS['TSFE'] = $this->createMock(TypoScriptFrontendController::class);
78 $this->mockContentObject = $this->createMock(ContentObjectRenderer::class);
79 $this->mockRequest = $this->createMock(Request::class);
80 $this->mockExtensionService = $this->createMock(ExtensionService::class);
81 $this->mockConfigurationManager = $this->createMock(ConfigurationManagerInterface::class);
82 $this->uriBuilder = $this->getAccessibleMock(UriBuilder::class, ['build']);
83 $this->uriBuilder->setRequest($this->mockRequest);
84 $this->uriBuilder->_set('contentObject', $this->mockContentObject);
85 $this->uriBuilder->_set('configurationManager', $this->mockConfigurationManager);
86 $this->uriBuilder->_set('extensionService', $this->mockExtensionService);
87 $this->uriBuilder->_set('environmentService', $this->createMock(EnvironmentService::class));
88 $router = GeneralUtility::makeInstance(Router::class);
89 $router->addRoute('module_key', new Route('/test/Path', []));
90 $router->addRoute('module_key2', new Route('/test/Path2', []));
91 $router->addRoute('', new Route('', []));
92 }
93
94 /**
95 * @test
96 */
97 public function settersAndGettersWorkAsExpected()
98 {
99 $this->uriBuilder
100 ->reset()
101 ->setArguments(['test' => 'arguments'])
102 ->setSection('testSection')
103 ->setFormat('testFormat')
104 ->setCreateAbsoluteUri(true)
105 ->setAbsoluteUriScheme('https')
106 ->setAddQueryString(true)
107 ->setArgumentsToBeExcludedFromQueryString(['test' => 'addQueryStringExcludeArguments'])
108 ->setAddQueryStringMethod('GET,POST')
109 ->setArgumentPrefix('testArgumentPrefix')
110 ->setLinkAccessRestrictedPages(true)
111 ->setTargetPageUid(123)
112 ->setTargetPageType(321)
113 ->setNoCache(true)
114 ->setUseCacheHash(false);
115 $this->assertEquals(['test' => 'arguments'], $this->uriBuilder->getArguments());
116 $this->assertEquals('testSection', $this->uriBuilder->getSection());
117 $this->assertEquals('testFormat', $this->uriBuilder->getFormat());
118 $this->assertEquals(true, $this->uriBuilder->getCreateAbsoluteUri());
119 $this->assertEquals('https', $this->uriBuilder->getAbsoluteUriScheme());
120 $this->assertEquals(true, $this->uriBuilder->getAddQueryString());
121 $this->assertEquals(['test' => 'addQueryStringExcludeArguments'], $this->uriBuilder->getArgumentsToBeExcludedFromQueryString());
122 $this->assertEquals('GET,POST', $this->uriBuilder->getAddQueryStringMethod());
123 $this->assertEquals('testArgumentPrefix', $this->uriBuilder->getArgumentPrefix());
124 $this->assertEquals(true, $this->uriBuilder->getLinkAccessRestrictedPages());
125 $this->assertEquals(123, $this->uriBuilder->getTargetPageUid());
126 $this->assertEquals(321, $this->uriBuilder->getTargetPageType());
127 $this->assertEquals(true, $this->uriBuilder->getNoCache());
128 $this->assertEquals(false, $this->uriBuilder->getUseCacheHash());
129 }
130
131 /**
132 * @test
133 */
134 public function uriForPrefixesArgumentsWithExtensionAndPluginNameAndSetsControllerArgument()
135 {
136 $this->mockExtensionService->expects($this->once())->method('getPluginNamespace')->will($this->returnValue('tx_someextension_someplugin'));
137 $expectedArguments = ['tx_someextension_someplugin' => ['foo' => 'bar', 'baz' => ['extbase' => 'fluid'], 'controller' => 'SomeController']];
138 $GLOBALS['TSFE'] = null;
139 $this->uriBuilder->uriFor(null, ['foo' => 'bar', 'baz' => ['extbase' => 'fluid']], 'SomeController', 'SomeExtension', 'SomePlugin');
140 $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
141 }
142
143 /**
144 * @test
145 */
146 public function uriForRecursivelyMergesAndOverrulesControllerArgumentsWithArguments()
147 {
148 $this->mockExtensionService->expects($this->once())->method('getPluginNamespace')->will($this->returnValue('tx_someextension_someplugin'));
149 $arguments = ['tx_someextension_someplugin' => ['foo' => 'bar'], 'additionalParam' => 'additionalValue'];
150 $controllerArguments = ['foo' => 'overruled', 'baz' => ['extbase' => 'fluid']];
151 $expectedArguments = ['tx_someextension_someplugin' => ['foo' => 'overruled', 'baz' => ['extbase' => 'fluid'], 'controller' => 'SomeController'], 'additionalParam' => 'additionalValue'];
152 $this->uriBuilder->setArguments($arguments);
153 $this->uriBuilder->uriFor(null, $controllerArguments, 'SomeController', 'SomeExtension', 'SomePlugin');
154 $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
155 }
156
157 /**
158 * @test
159 */
160 public function uriForOnlySetsActionArgumentIfSpecified()
161 {
162 $this->mockExtensionService->expects($this->once())->method('getPluginNamespace')->will($this->returnValue('tx_someextension_someplugin'));
163 $expectedArguments = ['tx_someextension_someplugin' => ['controller' => 'SomeController']];
164 $this->uriBuilder->uriFor(null, [], 'SomeController', 'SomeExtension', 'SomePlugin');
165 $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
166 }
167
168 /**
169 * @test
170 */
171 public function uriForSetsControllerFromRequestIfControllerIsNotSet()
172 {
173 $this->mockExtensionService->expects($this->once())->method('getPluginNamespace')->will($this->returnValue('tx_someextension_someplugin'));
174 $this->mockRequest->expects($this->once())->method('getControllerName')->will($this->returnValue('SomeControllerFromRequest'));
175 $expectedArguments = ['tx_someextension_someplugin' => ['controller' => 'SomeControllerFromRequest']];
176 $this->uriBuilder->uriFor(null, [], null, 'SomeExtension', 'SomePlugin');
177 $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
178 }
179
180 /**
181 * @test
182 */
183 public function uriForSetsExtensionNameFromRequestIfExtensionNameIsNotSet()
184 {
185 $this->mockExtensionService->expects($this->any())->method('getPluginNamespace')->will($this->returnValue('tx_someextensionnamefromrequest_someplugin'));
186 $this->mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('SomeExtensionNameFromRequest'));
187 $expectedArguments = ['tx_someextensionnamefromrequest_someplugin' => ['controller' => 'SomeController']];
188 $this->uriBuilder->uriFor(null, [], 'SomeController', null, 'SomePlugin');
189 $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
190 }
191
192 /**
193 * @test
194 */
195 public function uriForSetsPluginNameFromRequestIfPluginNameIsNotSet()
196 {
197 $this->mockExtensionService->expects($this->once())->method('getPluginNamespace')->will($this->returnValue('tx_someextension_somepluginnamefromrequest'));
198 $this->mockRequest->expects($this->once())->method('getPluginName')->will($this->returnValue('SomePluginNameFromRequest'));
199 $expectedArguments = ['tx_someextension_somepluginnamefromrequest' => ['controller' => 'SomeController']];
200 $this->uriBuilder->uriFor(null, [], 'SomeController', 'SomeExtension');
201 $this->assertEquals($expectedArguments, $this->uriBuilder->getArguments());
202 }
203
204 /**
205 * @test
206 */
207 public function uriForDoesNotDisableCacheHashForNonCacheableActions()
208 {
209 $this->mockExtensionService->expects($this->any())->method('isActionCacheable')->will($this->returnValue(false));
210 $this->uriBuilder->uriFor('someNonCacheableAction', [], 'SomeController', 'SomeExtension');
211 $this->assertTrue($this->uriBuilder->getUseCacheHash());
212 }
213
214 /**
215 * @test
216 */
217 public function buildBackendUriKeepsQueryParametersIfAddQueryStringIsSet()
218 {
219 $_GET['route'] = '/test/Path';
220 $_GET['id'] = 'pageId';
221 $_GET['foo'] = 'bar';
222 $_POST = [];
223 $_POST['foo2'] = 'bar2';
224 $this->uriBuilder->setAddQueryString(true);
225 $this->uriBuilder->setAddQueryStringMethod('GET,POST');
226 $expectedResult = '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken&id=pageId&foo=bar&foo2=bar2';
227 $actualResult = $this->uriBuilder->buildBackendUri();
228 $this->assertEquals($expectedResult, $actualResult);
229 }
230
231 /**
232 * @test
233 */
234 public function buildBackendUriKeepsQueryParametersIfAddQueryStringMethodIsNotSet()
235 {
236 $_GET['route'] = '/test/Path';
237 $_GET['id'] = 'pageId';
238 $_GET['foo'] = 'bar';
239 $_POST = [];
240 $_POST['foo2'] = 'bar2';
241 $this->uriBuilder->setAddQueryString(true);
242 $this->uriBuilder->setAddQueryStringMethod(null);
243 $expectedResult = '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken&id=pageId&foo=bar';
244 $actualResult = $this->uriBuilder->buildBackendUri();
245 $this->assertEquals($expectedResult, $actualResult);
246 }
247
248 /**
249 * return array
250 */
251 public function buildBackendUriRemovesSpecifiedQueryParametersIfArgumentsToBeExcludedFromQueryStringIsSetDataProvider()
252 {
253 return [
254 'Arguments to be excluded in the beginning' => [
255 [
256 'route' => '/test/Path',
257 'id' => 'pageId',
258 'foo' => 'bar'
259 ],
260 [
261 'foo2' => 'bar2'
262 ],
263 [
264 'route',
265 'id'
266 ],
267 '/typo3/index.php?route=%2F&token=dummyToken&foo=bar&foo2=bar2'
268 ],
269 'Arguments to be excluded in the end' => [
270 [
271 'foo' => 'bar',
272 'id' => 'pageId',
273 'route' => '/test/Path'
274 ],
275 [
276 'foo2' => 'bar2'
277 ],
278 [
279 'route',
280 'id'
281 ],
282 '/typo3/index.php?route=%2F&token=dummyToken&foo=bar&foo2=bar2'
283 ],
284 'Arguments in nested array to be excluded' => [
285 [
286 'tx_foo' => [
287 'bar' => 'baz'
288 ],
289 'id' => 'pageId',
290 'route' => '/test/Path'
291 ],
292 [
293 'foo2' => 'bar2'
294 ],
295 [
296 'id',
297 'tx_foo[bar]'
298 ],
299 '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken&foo2=bar2'
300 ],
301 'Arguments in multidimensional array to be excluded' => [
302 [
303 'tx_foo' => [
304 'bar' => [
305 'baz' => 'bay'
306 ]
307 ],
308 'id' => 'pageId',
309 'route' => '/test/Path'
310 ],
311 [
312 'foo2' => 'bar2'
313 ],
314 [
315 'id',
316 'tx_foo[bar][baz]'
317 ],
318 '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken&foo2=bar2'
319 ],
320 ];
321 }
322
323 /**
324 * @test
325 * @dataProvider buildBackendUriRemovesSpecifiedQueryParametersIfArgumentsToBeExcludedFromQueryStringIsSetDataProvider
326 * @param array $parameters
327 * @param array $postArguments
328 * @param array $excluded
329 * @param string $expected
330 */
331 public function buildBackendUriRemovesSpecifiedQueryParametersIfArgumentsToBeExcludedFromQueryStringIsSet(array $parameters, array $postArguments, array $excluded, $expected)
332 {
333 $_GET = array_replace_recursive($_GET, $parameters);
334 $_POST = $postArguments;
335 $this->uriBuilder->setAddQueryString(true);
336 $this->uriBuilder->setAddQueryStringMethod('GET,POST');
337 $this->uriBuilder->setArgumentsToBeExcludedFromQueryString($excluded);
338 $actualResult = $this->uriBuilder->buildBackendUri();
339 $this->assertEquals($expected, $actualResult);
340 }
341
342 /**
343 * @test
344 */
345 public function buildBackendUriKeepsModuleQueryParametersIfAddQueryStringIsNotSet()
346 {
347 $_GET = (['route' => '/test/Path', 'id' => 'pageId', 'foo' => 'bar']);
348 $expectedResult = '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken&id=pageId';
349 $actualResult = $this->uriBuilder->buildBackendUri();
350 $this->assertEquals($expectedResult, $actualResult);
351 }
352
353 /**
354 * @test
355 */
356 public function buildBackendUriMergesAndOverrulesQueryParametersWithArguments()
357 {
358 $_GET = ['route' => '/test/Path', 'id' => 'pageId', 'foo' => 'bar'];
359 $this->uriBuilder->setArguments(['route' => '/test/Path2', 'somePrefix' => ['bar' => 'baz']]);
360 $expectedResult = '/typo3/index.php?route=%2Ftest%2FPath2&token=dummyToken&id=pageId&somePrefix%5Bbar%5D=baz';
361 $actualResult = $this->uriBuilder->buildBackendUri();
362 $this->assertEquals($expectedResult, $actualResult);
363 }
364
365 /**
366 * @test
367 */
368 public function buildBackendUriConvertsDomainObjectsAfterArgumentsHaveBeenMerged()
369 {
370 $_GET['route'] = '/test/Path';
371 $mockDomainObject = $this->getAccessibleMock(AbstractEntity::class, ['dummy']);
372 $mockDomainObject->_set('uid', '123');
373 $this->uriBuilder->setArguments(['somePrefix' => ['someDomainObject' => $mockDomainObject]]);
374 $expectedResult = '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken&somePrefix%5BsomeDomainObject%5D=123';
375 $actualResult = $this->uriBuilder->buildBackendUri();
376 $this->assertEquals($expectedResult, $actualResult);
377 }
378
379 /**
380 * @test
381 */
382 public function buildBackendUriRespectsSection()
383 {
384 $_GET['route'] = '/test/Path';
385 $this->uriBuilder->setSection('someSection');
386 $expectedResult = '/typo3/index.php?route=%2Ftest%2FPath&token=dummyToken#someSection';
387 $actualResult = $this->uriBuilder->buildBackendUri();
388 $this->assertEquals($expectedResult, $actualResult);
389 }
390
391 /**
392 * @test
393 */
394 public function buildBackendUriCreatesAbsoluteUrisIfSpecified()
395 {
396 $_GET['route'] = '/test/Path';
397 $_SERVER['HTTP_HOST'] = 'baseuri';
398 $_SERVER['SCRIPT_NAME'] = '/typo3/index.php';
399 $_SERVER['ORIG_SCRIPT_NAME'] = '/typo3/index.php';
400 $_SERVER['REMOTE_ADDR'] = '127.0.0.1';
401 $this->mockRequest->expects($this->any())->method('getBaseUri')->will($this->returnValue('http://baseuri'));
402 $this->uriBuilder->setCreateAbsoluteUri(true);
403 $expectedResult = 'http://baseuri/' . TYPO3_mainDir . 'index.php?route=%2Ftest%2FPath&token=dummyToken';
404 $actualResult = $this->uriBuilder->buildBackendUri();
405 $this->assertSame($expectedResult, $actualResult);
406 }
407
408 /**
409 * @test
410 */
411 public function buildBackendUriWithQueryStringMethodPostGetMergesParameters()
412 {
413 $_POST = [
414 'key1' => 'POST1',
415 'key2' => 'POST2',
416 'key3' => [
417 'key31' => 'POST31',
418 'key32' => 'POST32',
419 'key33' => [
420 'key331' => 'POST331',
421 'key332' => 'POST332',
422 ]
423 ],
424 ];
425 $_GET = [
426 'key2' => 'GET2',
427 'key3' => [
428 'key32' => 'GET32',
429 'key33' => [
430 'key331' => 'GET331',
431 ]
432 ]
433 ];
434 $this->uriBuilder->setAddQueryString(true);
435 $this->uriBuilder->setAddQueryStringMethod('POST,GET');
436 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('/typo3/index.php?route=%2F&token=dummyToken&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
437 $actualResult = $this->uriBuilder->buildBackendUri();
438 $this->assertEquals($expectedResult, $actualResult);
439 }
440
441 /**
442 * @test
443 */
444 public function buildBackendUriWithQueryStringMethodGetPostMergesParameters()
445 {
446 $_GET = [
447 'key1' => 'GET1',
448 'key2' => 'GET2',
449 'key3' => [
450 'key31' => 'GET31',
451 'key32' => 'GET32',
452 'key33' => [
453 'key331' => 'GET331',
454 'key332' => 'GET332',
455 ]
456 ],
457 ];
458 $_POST = [
459 'key2' => 'POST2',
460 'key3' => [
461 'key32' => 'POST32',
462 'key33' => [
463 'key331' => 'POST331',
464 ]
465 ]
466 ];
467 $this->uriBuilder->setAddQueryString(true);
468 $this->uriBuilder->setAddQueryStringMethod('GET,POST');
469 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('/typo3/index.php?route=%2F&token=dummyToken&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
470 $actualResult = $this->uriBuilder->buildBackendUri();
471 $this->assertEquals($expectedResult, $actualResult);
472 }
473
474 /**
475 * Encodes square brackets in URL.
476 *
477 * @param string $string
478 * @return string
479 */
480 private function rawUrlEncodeSquareBracketsInUrl($string)
481 {
482 return str_replace(['[', ']'], ['%5B', '%5D'], $string);
483 }
484
485 /**
486 * @test
487 */
488 public function buildFrontendUriCreatesTypoLink()
489 {
490 /** @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $uriBuilder */
491 $uriBuilder = $this->getAccessibleMock(UriBuilder::class, ['buildTypolinkConfiguration']);
492 $uriBuilder->_set('contentObject', $this->mockContentObject);
493 $uriBuilder->expects($this->once())->method('buildTypolinkConfiguration')->will($this->returnValue(['someTypoLinkConfiguration']));
494 $this->mockContentObject->expects($this->once())->method('typoLink_URL')->with(['someTypoLinkConfiguration']);
495 $uriBuilder->buildFrontendUri();
496 }
497
498 /**
499 * @test
500 */
501 public function buildFrontendUriCreatesRelativeUrisByDefault()
502 {
503 $this->mockContentObject->expects($this->once())->method('typoLink_URL')->will($this->returnValue('relative/uri'));
504 $expectedResult = 'relative/uri';
505 $actualResult = $this->uriBuilder->buildFrontendUri();
506 $this->assertSame($expectedResult, $actualResult);
507 }
508
509 /**
510 * @test
511 */
512 public function buildFrontendUriDoesNotStripLeadingSlashesFromRelativeUris()
513 {
514 $this->mockContentObject->expects($this->once())->method('typoLink_URL')->will($this->returnValue('/relative/uri'));
515 $expectedResult = '/relative/uri';
516 $actualResult = $this->uriBuilder->buildFrontendUri();
517 $this->assertSame($expectedResult, $actualResult);
518 }
519
520 /**
521 * @test
522 */
523 public function buildFrontendUriCreatesAbsoluteUrisIfSpecified()
524 {
525 /** @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $uriBuilder */
526 $uriBuilder = $this->getAccessibleMock(UriBuilder::class, ['buildTypolinkConfiguration']);
527 $uriBuilder->_set('contentObject', $this->mockContentObject);
528 $uriBuilder->expects($this->once())->method('buildTypolinkConfiguration')->will($this->returnValue(['foo' => 'bar']));
529 $this->mockContentObject->expects($this->once())->method('typoLink_URL')->with(['foo' => 'bar', 'forceAbsoluteUrl' => true])->will($this->returnValue('http://baseuri/relative/uri'));
530 $uriBuilder->setCreateAbsoluteUri(true);
531 $expectedResult = 'http://baseuri/relative/uri';
532 $actualResult = $uriBuilder->buildFrontendUri();
533 $this->assertSame($expectedResult, $actualResult);
534 }
535
536 /**
537 * @test
538 */
539 public function buildFrontendUriSetsAbsoluteUriSchemeIfSpecified()
540 {
541 /** @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $uriBuilder */
542 $uriBuilder = $this->getAccessibleMock(UriBuilder::class, ['buildTypolinkConfiguration']);
543 $uriBuilder->_set('contentObject', $this->mockContentObject);
544 $uriBuilder->expects($this->once())->method('buildTypolinkConfiguration')->will($this->returnValue(['foo' => 'bar']));
545 $this->mockContentObject->expects($this->once())->method('typoLink_URL')->with(['foo' => 'bar', 'forceAbsoluteUrl' => true, 'forceAbsoluteUrl.' => ['scheme' => 'someScheme']])->will($this->returnValue('http://baseuri/relative/uri'));
546 $uriBuilder->setCreateAbsoluteUri(true);
547 $uriBuilder->setAbsoluteUriScheme('someScheme');
548 $expectedResult = 'http://baseuri/relative/uri';
549 $actualResult = $uriBuilder->buildFrontendUri();
550 $this->assertSame($expectedResult, $actualResult);
551 }
552
553 /**
554 * @test
555 */
556 public function buildFrontendUriDoesNotSetAbsoluteUriSchemeIfCreateAbsoluteUriIsFalse()
557 {
558 /** @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\TestingFramework\Core\AccessibleObjectInterface $uriBuilder */
559 $uriBuilder = $this->getAccessibleMock(UriBuilder::class, ['buildTypolinkConfiguration']);
560 $uriBuilder->_set('contentObject', $this->mockContentObject);
561 $uriBuilder->expects($this->once())->method('buildTypolinkConfiguration')->will($this->returnValue(['foo' => 'bar']));
562 $this->mockContentObject->expects($this->once())->method('typoLink_URL')->with(['foo' => 'bar'])->will($this->returnValue('http://baseuri/relative/uri'));
563 $uriBuilder->setCreateAbsoluteUri(false);
564 $uriBuilder->setAbsoluteUriScheme('someScheme');
565 $expectedResult = 'http://baseuri/relative/uri';
566 $actualResult = $uriBuilder->buildFrontendUri();
567 $this->assertSame($expectedResult, $actualResult);
568 }
569
570 /**
571 * @test
572 */
573 public function resetSetsAllOptionsToTheirDefaultValue()
574 {
575 $this->uriBuilder->setArguments(['test' => 'arguments'])->setSection('testSection')->setFormat('someFormat')->setCreateAbsoluteUri(true)->setAddQueryString(true)->setArgumentsToBeExcludedFromQueryString(['test' => 'addQueryStringExcludeArguments'])->setAddQueryStringMethod(null)->setArgumentPrefix('testArgumentPrefix')->setLinkAccessRestrictedPages(true)->setTargetPageUid(123)->setTargetPageType(321)->setNoCache(true)->setUseCacheHash(false);
576 $this->uriBuilder->reset();
577 $this->assertEquals([], $this->uriBuilder->getArguments());
578 $this->assertEquals('', $this->uriBuilder->getSection());
579 $this->assertEquals('', $this->uriBuilder->getFormat());
580 $this->assertEquals(false, $this->uriBuilder->getCreateAbsoluteUri());
581 $this->assertEquals(false, $this->uriBuilder->getAddQueryString());
582 $this->assertEquals([], $this->uriBuilder->getArgumentsToBeExcludedFromQueryString());
583 $this->assertEquals(null, $this->uriBuilder->getAddQueryStringMethod());
584 $this->assertEquals(null, $this->uriBuilder->getArgumentPrefix());
585 $this->assertEquals(false, $this->uriBuilder->getLinkAccessRestrictedPages());
586 $this->assertEquals(null, $this->uriBuilder->getTargetPageUid());
587 $this->assertEquals(0, $this->uriBuilder->getTargetPageType());
588 $this->assertEquals(false, $this->uriBuilder->getNoCache());
589 $this->assertEquals(true, $this->uriBuilder->getUseCacheHash());
590 }
591
592 /**
593 * @test
594 */
595 public function buildTypolinkConfigurationRespectsSpecifiedTargetPageUid()
596 {
597 $GLOBALS['TSFE']->id = 123;
598 $this->uriBuilder->setTargetPageUid(321);
599 $expectedConfiguration = ['parameter' => 321, 'useCacheHash' => 1];
600 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
601 $this->assertEquals($expectedConfiguration, $actualConfiguration);
602 }
603
604 /**
605 * @test
606 */
607 public function buildTypolinkConfigurationUsesCurrentPageUidIfTargetPageUidIsNotSet()
608 {
609 $GLOBALS['TSFE']->id = 123;
610 $expectedConfiguration = ['parameter' => 123, 'useCacheHash' => 1];
611 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
612 $this->assertEquals($expectedConfiguration, $actualConfiguration);
613 }
614
615 /**
616 * @test
617 */
618 public function buildTypolinkConfigurationProperlySetsAdditionalArguments()
619 {
620 $this->uriBuilder->setTargetPageUid(123);
621 $this->uriBuilder->setArguments(['foo' => 'bar', 'baz' => ['extbase' => 'fluid']]);
622 $expectedConfiguration = ['parameter' => 123, 'useCacheHash' => 1, 'additionalParams' => '&foo=bar&baz%5Bextbase%5D=fluid'];
623 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
624 $this->assertEquals($expectedConfiguration, $actualConfiguration);
625 }
626
627 /**
628 * @test
629 */
630 public function buildTypolinkConfigurationProperlySetsAddQueryString()
631 {
632 $this->uriBuilder->setTargetPageUid(123);
633 $this->uriBuilder->setAddQueryString(true);
634 $expectedConfiguration = ['parameter' => 123, 'addQueryString' => 1, 'useCacheHash' => 1];
635 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
636 $this->assertEquals($expectedConfiguration, $actualConfiguration);
637 }
638
639 /**
640 * @test
641 */
642 public function buildTypolinkConfigurationProperlySetsAddQueryStringMethod()
643 {
644 $this->uriBuilder->setTargetPageUid(123);
645 $this->uriBuilder->setAddQueryString(true);
646 $this->uriBuilder->setAddQueryStringMethod('GET,POST');
647 $expectedConfiguration = ['parameter' => 123, 'addQueryString' => 1, 'addQueryString.' => ['method' => 'GET,POST'], 'useCacheHash' => 1];
648 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
649 $this->assertEquals($expectedConfiguration, $actualConfiguration);
650 }
651
652 /**
653 * @test
654 */
655 public function buildTypolinkConfigurationConvertsDomainObjects()
656 {
657 $mockDomainObject1 = $this->getAccessibleMock(AbstractEntity::class, ['dummy']);
658 $mockDomainObject1->_set('uid', '123');
659 $mockDomainObject2 = $this->getAccessibleMock(AbstractEntity::class, ['dummy']);
660 $mockDomainObject2->_set('uid', '321');
661 $this->uriBuilder->setTargetPageUid(123);
662 $this->uriBuilder->setArguments(['someDomainObject' => $mockDomainObject1, 'baz' => ['someOtherDomainObject' => $mockDomainObject2]]);
663 $expectedConfiguration = ['parameter' => 123, 'useCacheHash' => 1, 'additionalParams' => '&someDomainObject=123&baz%5BsomeOtherDomainObject%5D=321'];
664 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
665 $this->assertEquals($expectedConfiguration, $actualConfiguration);
666 }
667
668 /**
669 * @test
670 */
671 public function buildTypolinkConfigurationResolvesPageTypeFromFormat()
672 {
673 $this->uriBuilder->setTargetPageUid(123);
674 $this->uriBuilder->setFormat('txt');
675 $this->mockRequest->expects($this->once())->method('getControllerExtensionName')->will($this->returnValue('SomeExtensionNameFromRequest'));
676
677 $mockConfigurationManager = $this->createMock(ConfigurationManager::class);
678 $mockConfigurationManager->expects($this->any())->method('getConfiguration')
679 ->will($this->returnValue(['formatToPageTypeMapping' => ['txt' => 2]]));
680 $this->uriBuilder->_set('configurationManager', $mockConfigurationManager);
681
682 $this->mockExtensionService->expects($this->any())->method('getTargetPageTypeByFormat')
683 ->with('SomeExtensionNameFromRequest', 'txt')
684 ->will($this->returnValue(2));
685
686 $expectedConfiguration = ['parameter' => '123,2', 'useCacheHash' => 1];
687 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
688 $this->assertEquals($expectedConfiguration, $actualConfiguration);
689 }
690
691 /**
692 * @test
693 */
694 public function buildTypolinkConfigurationResolvesDefaultPageTypeFromFormatIfNoMappingIsConfigured()
695 {
696 $this->uriBuilder->setTargetPageUid(123);
697 $this->uriBuilder->setFormat('txt');
698
699 $mockConfigurationManager = $this->createMock(ConfigurationManager::class);
700 $mockConfigurationManager->expects($this->any())->method('getConfiguration')->will($this->returnValue([]));
701 $this->uriBuilder->_set('configurationManager', $mockConfigurationManager);
702
703 $this->mockExtensionService->expects($this->any())->method('getTargetPageTypeByFormat')
704 ->with(null, 'txt')
705 ->will($this->returnValue(0));
706
707 $expectedConfiguration = ['parameter' => '123,0', 'useCacheHash' => 1];
708 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
709
710 $this->assertEquals($expectedConfiguration, $actualConfiguration);
711 }
712
713 /**
714 * @test
715 */
716 public function buildTypolinkConfigurationResolvesDefaultPageTypeFromFormatIfFormatIsNotMapped()
717 {
718 $this->uriBuilder->setTargetPageUid(123);
719 $this->uriBuilder->setFormat('txt');
720
721 $mockConfigurationManager = $this->createMock(ConfigurationManager::class);
722 $mockConfigurationManager->expects($this->any())->method('getConfiguration')
723 ->will($this->returnValue(['formatToPageTypeMapping' => ['pdf' => 2]]));
724 $this->uriBuilder->_set('configurationManager', $mockConfigurationManager);
725
726 $this->mockExtensionService->expects($this->any())->method('getTargetPageTypeByFormat')
727 ->with(null, 'txt')
728 ->will($this->returnValue(0));
729
730 $expectedConfiguration = ['parameter' => '123,0', 'useCacheHash' => 1];
731 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
732
733 $this->assertEquals($expectedConfiguration, $actualConfiguration);
734 }
735
736 /**
737 * @test
738 */
739 public function buildTypolinkConfigurationDisablesCacheHashIfNoCacheIsSet()
740 {
741 $this->uriBuilder->setTargetPageUid(123);
742 $this->uriBuilder->setNoCache(true);
743 $expectedConfiguration = ['parameter' => 123, 'no_cache' => 1];
744 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
745 $this->assertEquals($expectedConfiguration, $actualConfiguration);
746 }
747
748 /**
749 * @test
750 */
751 public function buildTypolinkConfigurationDoesNotSetUseCacheHashOptionIfUseCacheHashIsDisabled()
752 {
753 $this->uriBuilder->setTargetPageUid(123);
754 $this->uriBuilder->setUseCacheHash(false);
755 $expectedConfiguration = ['parameter' => 123];
756 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
757 $this->assertEquals($expectedConfiguration, $actualConfiguration);
758 }
759
760 /**
761 * @test
762 */
763 public function buildTypolinkConfigurationConsidersSection()
764 {
765 $this->uriBuilder->setTargetPageUid(123);
766 $this->uriBuilder->setSection('SomeSection');
767 $expectedConfiguration = ['parameter' => 123, 'useCacheHash' => 1, 'section' => 'SomeSection'];
768 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
769 $this->assertEquals($expectedConfiguration, $actualConfiguration);
770 }
771
772 /**
773 * @test
774 */
775 public function buildTypolinkConfigurationLinkAccessRestrictedPagesSetting()
776 {
777 $this->uriBuilder->setTargetPageUid(123);
778 $this->uriBuilder->setLinkAccessRestrictedPages(true);
779 $expectedConfiguration = ['parameter' => 123, 'useCacheHash' => 1, 'linkAccessRestrictedPages' => 1];
780 $actualConfiguration = $this->uriBuilder->_call('buildTypolinkConfiguration');
781 $this->assertEquals($expectedConfiguration, $actualConfiguration);
782 }
783
784 /**
785 * @test
786 */
787 public function convertDomainObjectsToIdentityArraysConvertsDomainObjects()
788 {
789 $mockDomainObject1 = $this->getAccessibleMock(AbstractEntity::class, ['dummy']);
790 $mockDomainObject1->_set('uid', '123');
791 $mockDomainObject2 = $this->getAccessibleMock(AbstractEntity::class, ['dummy']);
792 $mockDomainObject2->_set('uid', '321');
793 $expectedResult = ['foo' => ['bar' => 'baz'], 'domainObject1' => '123', 'second' => ['domainObject2' => '321']];
794 $actualResult = $this->uriBuilder->_call('convertDomainObjectsToIdentityArrays', ['foo' => ['bar' => 'baz'], 'domainObject1' => $mockDomainObject1, 'second' => ['domainObject2' => $mockDomainObject2]]);
795 $this->assertEquals($expectedResult, $actualResult);
796 }
797
798 /**
799 * @test
800 */
801 public function convertDomainObjectsToIdentityArraysConvertsObjectStoragesWithDomainObjects()
802 {
803 $objectStorage = new ObjectStorage();
804 $mockChildObject1 = $this->getAccessibleMock(AbstractEntity::class, ['dummy']);
805 $mockChildObject1->_set('uid', '123');
806 $objectStorage->attach($mockChildObject1);
807 $expectedResult = ['foo' => ['bar' => 'baz'], 'objectStorage' => ['123']];
808 $actualResult = $this->uriBuilder->_call('convertDomainObjectsToIdentityArrays', ['foo' => ['bar' => 'baz'], 'objectStorage' => $objectStorage]);
809 $this->assertEquals($expectedResult, $actualResult);
810 }
811
812 /**
813 * @test
814 */
815 public function conversionOfTansientObjectsIsInvoked()
816 {
817 $mockValueObject = new ValueObjectFixture();
818 $mockValueObject->name = 'foo';
819 /** @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|object $mockUriBuilder */
820 $mockUriBuilder = $this->getAccessibleMock(UriBuilder::class, ['convertTransientObjectToArray']);
821 $mockUriBuilder->expects($this->once())->method('convertTransientObjectToArray')->will($this->returnValue(['foo' => 'bar']));
822 $actualResult = $mockUriBuilder->_call('convertDomainObjectsToIdentityArrays', ['object' => $mockValueObject]);
823 $expectedResult = ['object' => ['foo' => 'bar']];
824 $this->assertEquals($expectedResult, $actualResult);
825 }
826
827 /**
828 * @test
829 */
830 public function conversionOfTansientObjectsThrowsExceptionForOtherThanValueObjects()
831 {
832 $this->expectException(InvalidArgumentValueException::class);
833 $this->expectExceptionCode(1260881688);
834 $mockEntity = new EntityFixture();
835 $mockEntity->name = 'foo';
836 /** @var UriBuilder|\PHPUnit_Framework_MockObject_MockObject|object $mockUriBuilder */
837 $mockUriBuilder = $this->getAccessibleMock(UriBuilder::class, ['dummy']);
838 $mockUriBuilder->_call('convertDomainObjectsToIdentityArrays', ['object' => $mockEntity]);
839 }
840
841 /**
842 * @test
843 */
844 public function tansientObjectsAreConvertedToAnArrayOfProperties()
845 {
846 $mockValueObject = new ValueObjectFixture();
847 $mockValueObject->name = 'foo';
848 $uriBuilder = new UriBuilder();
849 $actualResult = $uriBuilder->convertTransientObjectToArray($mockValueObject);
850 $expectedResult = ['name' => 'foo', 'object' => null, 'uid' => null, 'pid' => null];
851 $this->assertEquals($expectedResult, $actualResult);
852 }
853
854 /**
855 * @test
856 */
857 public function tansientObjectsWithObjectStorageAreConvertedToAnArrayOfProperties()
858 {
859 $mockValueObject = new ValueObjectFixture();
860 $objectStorage = new ObjectStorage();
861 $mockValueObject->name = 'foo';
862 $mockValueObject2 = new ValueObjectFixture();
863 $mockValueObject2->name = 'bar';
864 $objectStorage->attach($mockValueObject2);
865 $mockValueObject->object = $objectStorage;
866 $uriBuilder = new UriBuilder();
867 $actualResult = $uriBuilder->convertTransientObjectToArray($mockValueObject);
868 $expectedResult = [
869 'name' => 'foo',
870 'object' => [
871 [
872 'name' => 'bar',
873 'uid' => null,
874 'pid' => null,
875 'object' => null
876 ]
877 ],
878 'uid' => null,
879 'pid' => null
880 ];
881 $this->assertEquals($expectedResult, $actualResult);
882 }
883
884 /**
885 * @test
886 */
887 public function tansientObjectsAreRecursivelyConverted()
888 {
889 $mockInnerValueObject2 = new ValueObjectFixture();
890 $mockInnerValueObject2->name = 'foo';
891 $mockInnerValueObject2->uid = 99;
892 $mockInnerValueObject1 = new ValueObjectFixture();
893 $mockInnerValueObject1->object = $mockInnerValueObject2;
894 $mockValueObject = new ValueObjectFixture();
895 $mockValueObject->object = $mockInnerValueObject1;
896 $uriBuilder = new UriBuilder();
897 $actualResult = $uriBuilder->convertTransientObjectToArray($mockValueObject);
898 $expectedResult = [
899 'name' => null,
900 'object' => [
901 'name' => null,
902 'object' => 99,
903 'uid' => null,
904 'pid' => null
905 ],
906 'uid' => null,
907 'pid' => null
908 ];
909 $this->assertEquals($expectedResult, $actualResult);
910 }
911
912 /**
913 * @test
914 */
915 public function removeDefaultControllerAndActionDoesNotModifyArgumentsifSpecifiedControlerAndActionIsNotEqualToDefaults()
916 {
917 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultControllerNameByPlugin')->with('ExtensionName', 'PluginName')->will($this->returnValue('DefaultController'));
918 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultActionNameByPluginAndController')->with('ExtensionName', 'PluginName', 'SomeController')->will($this->returnValue('defaultAction'));
919 $arguments = ['controller' => 'SomeController', 'action' => 'someAction', 'foo' => 'bar'];
920 $extensionName = 'ExtensionName';
921 $pluginName = 'PluginName';
922 $expectedResult = ['controller' => 'SomeController', 'action' => 'someAction', 'foo' => 'bar'];
923 $actualResult = $this->uriBuilder->_callRef('removeDefaultControllerAndAction', $arguments, $extensionName, $pluginName);
924 $this->assertEquals($expectedResult, $actualResult);
925 }
926
927 /**
928 * @test
929 */
930 public function removeDefaultControllerAndActionRemovesControllerIfItIsEqualToTheDefault()
931 {
932 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultControllerNameByPlugin')->with('ExtensionName', 'PluginName')->will($this->returnValue('DefaultController'));
933 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultActionNameByPluginAndController')->with('ExtensionName', 'PluginName', 'DefaultController')->will($this->returnValue('defaultAction'));
934 $arguments = ['controller' => 'DefaultController', 'action' => 'someAction', 'foo' => 'bar'];
935 $extensionName = 'ExtensionName';
936 $pluginName = 'PluginName';
937 $expectedResult = ['action' => 'someAction', 'foo' => 'bar'];
938 $actualResult = $this->uriBuilder->_callRef('removeDefaultControllerAndAction', $arguments, $extensionName, $pluginName);
939 $this->assertEquals($expectedResult, $actualResult);
940 }
941
942 /**
943 * @test
944 */
945 public function removeDefaultControllerAndActionRemovesActionIfItIsEqualToTheDefault()
946 {
947 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultControllerNameByPlugin')->with('ExtensionName', 'PluginName')->will($this->returnValue('DefaultController'));
948 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultActionNameByPluginAndController')->with('ExtensionName', 'PluginName', 'SomeController')->will($this->returnValue('defaultAction'));
949 $arguments = ['controller' => 'SomeController', 'action' => 'defaultAction', 'foo' => 'bar'];
950 $extensionName = 'ExtensionName';
951 $pluginName = 'PluginName';
952 $expectedResult = ['controller' => 'SomeController', 'foo' => 'bar'];
953 $actualResult = $this->uriBuilder->_callRef('removeDefaultControllerAndAction', $arguments, $extensionName, $pluginName);
954 $this->assertEquals($expectedResult, $actualResult);
955 }
956
957 /**
958 * @test
959 */
960 public function removeDefaultControllerAndActionRemovesControllerAndActionIfBothAreEqualToTheDefault()
961 {
962 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultControllerNameByPlugin')->with('ExtensionName', 'PluginName')->will($this->returnValue('DefaultController'));
963 $this->mockExtensionService->expects($this->atLeastOnce())->method('getDefaultActionNameByPluginAndController')->with('ExtensionName', 'PluginName', 'DefaultController')->will($this->returnValue('defaultAction'));
964 $arguments = ['controller' => 'DefaultController', 'action' => 'defaultAction', 'foo' => 'bar'];
965 $extensionName = 'ExtensionName';
966 $pluginName = 'PluginName';
967 $expectedResult = ['foo' => 'bar'];
968 $actualResult = $this->uriBuilder->_callRef('removeDefaultControllerAndAction', $arguments, $extensionName, $pluginName);
969 $this->assertEquals($expectedResult, $actualResult);
970 }
971
972 /**
973 * @return array
974 */
975 public function convertIteratorToArrayConvertsIteratorsToArrayProvider()
976 {
977 return [
978 'Extbase ObjectStorage' => [new ObjectStorage()],
979 'SplObjectStorage' => [new \SplObjectStorage()],
980 'ArrayIterator' => [new \ArrayIterator()]
981 ];
982 }
983
984 /**
985 * @dataProvider convertIteratorToArrayConvertsIteratorsToArrayProvider
986 * @test
987 */
988 public function convertIteratorToArrayConvertsIteratorsToArray($iterator)
989 {
990 $result = $this->uriBuilder->_call('convertIteratorToArray', $iterator);
991 $this->assertTrue(is_array($result));
992 }
993 }