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