[FEATURE] Allow extended custom links in FormEngine and TypoLink
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / Typolink / AbstractTypolinkBuilderTest.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Unit\Typolink;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use Psr\Log\LoggerInterface;
18 use TYPO3\CMS\Core\Log\LogManager;
19 use TYPO3\CMS\Core\TypoScript\TemplateService;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
22 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
23 use TYPO3\CMS\Frontend\Page\PageRepository;
24 use TYPO3\CMS\Frontend\Typolink\AbstractTypolinkBuilder;
25 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
26
27 /**
28 * Test case
29 */
30 class AbstractTypolinkBuilderTest extends UnitTestCase
31 {
32 /**
33 * @var array A backup of registered singleton instances
34 */
35 protected $singletonInstances = [];
36
37 /**
38 * @var \PHPUnit_Framework_MockObject_MockObject|TypoScriptFrontendController|\TYPO3\TestingFramework\Core\AccessibleObjectInterface
39 */
40 protected $frontendControllerMock = null;
41
42 /**
43 * @var \PHPUnit_Framework_MockObject_MockObject|TemplateService
44 */
45 protected $templateServiceMock = null;
46
47 /**
48 * Set up
49 */
50 protected function setUp()
51 {
52 GeneralUtility::flushInternalRuntimeCaches();
53
54 $this->singletonInstances = GeneralUtility::getSingletonInstances();
55 $this->createMockedLoggerAndLogManager();
56
57 $this->templateServiceMock =
58 $this->getMockBuilder(TemplateService::class)
59 ->setMethods(['getFileName', 'linkData'])->getMock();
60 $pageRepositoryMock =
61 $this->getAccessibleMock(PageRepository::class, ['getRawRecord', 'getMountPointInfo']);
62 $this->frontendControllerMock =
63 $this->getAccessibleMock(TypoScriptFrontendController::class,
64 ['dummy'], [], '', false);
65 $this->frontendControllerMock->tmpl = $this->templateServiceMock;
66 $this->frontendControllerMock->config = [];
67 $this->frontendControllerMock->page = [];
68 $this->frontendControllerMock->sys_page = $pageRepositoryMock;
69 $GLOBALS['TSFE'] = $this->frontendControllerMock;
70 }
71
72 protected function tearDown()
73 {
74 GeneralUtility::resetSingletonInstances($this->singletonInstances);
75 parent::tearDown();
76 }
77
78 //////////////////////
79 // Utility functions
80 //////////////////////
81
82 /**
83 * @return TypoScriptFrontendController
84 */
85 protected function getFrontendController()
86 {
87 return $GLOBALS['TSFE'];
88 }
89
90 /**
91 * Avoid logging to the file system (file writer is currently the only configured writer)
92 */
93 protected function createMockedLoggerAndLogManager()
94 {
95 $logManagerMock = $this->getMockBuilder(LogManager::class)->getMock();
96 $loggerMock = $this->getMockBuilder(LoggerInterface::class)->getMock();
97 $logManagerMock->expects($this->any())
98 ->method('getLogger')
99 ->willReturn($loggerMock);
100 GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
101 }
102
103 /**
104 * @return array The test data for forceAbsoluteUrlReturnsAbsoluteUrl
105 */
106 public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider()
107 {
108 return [
109 'Missing forceAbsoluteUrl leaves URL untouched' => [
110 'foo',
111 'foo',
112 []
113 ],
114 'Absolute URL stays unchanged' => [
115 'http://example.org/',
116 'http://example.org/',
117 [
118 'forceAbsoluteUrl' => '1'
119 ]
120 ],
121 'Absolute URL stays unchanged 2' => [
122 'http://example.org/resource.html',
123 'http://example.org/resource.html',
124 [
125 'forceAbsoluteUrl' => '1'
126 ]
127 ],
128 'Scheme and host w/o ending slash stays unchanged' => [
129 'http://example.org',
130 'http://example.org',
131 [
132 'forceAbsoluteUrl' => '1'
133 ]
134 ],
135 'Scheme can be forced' => [
136 'typo3://example.org',
137 'http://example.org',
138 [
139 'forceAbsoluteUrl' => '1',
140 'forceAbsoluteUrl.' => [
141 'scheme' => 'typo3'
142 ]
143 ]
144 ],
145 'Relative path old-style' => [
146 'http://localhost/fileadmin/dummy.txt',
147 '/fileadmin/dummy.txt',
148 [
149 'forceAbsoluteUrl' => '1',
150 ]
151 ],
152 'Relative path' => [
153 'http://localhost/fileadmin/dummy.txt',
154 'fileadmin/dummy.txt',
155 [
156 'forceAbsoluteUrl' => '1',
157 ]
158 ],
159 'Scheme can be forced with pseudo-relative path' => [
160 'typo3://localhost/fileadmin/dummy.txt',
161 '/fileadmin/dummy.txt',
162 [
163 'forceAbsoluteUrl' => '1',
164 'forceAbsoluteUrl.' => [
165 'scheme' => 'typo3'
166 ]
167 ]
168 ],
169 'Hostname only is not treated as valid absolute URL' => [
170 'http://localhost/example.org',
171 'example.org',
172 [
173 'forceAbsoluteUrl' => '1'
174 ]
175 ],
176 'Scheme and host is added to local file path' => [
177 'typo3://localhost/fileadmin/my.pdf',
178 'fileadmin/my.pdf',
179 [
180 'forceAbsoluteUrl' => '1',
181 'forceAbsoluteUrl.' => [
182 'scheme' => 'typo3'
183 ]
184 ]
185 ]
186 ];
187 }
188
189 /**
190 * @param string $expected The expected URL
191 * @param string $url The URL to parse and manipulate
192 * @param array $configuration The configuration array
193 * @test
194 * @dataProvider forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider
195 */
196 public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl($expected, $url, array $configuration)
197 {
198 $contentObjectRendererProphecy = $this->prophesize(ContentObjectRenderer::class);
199 $subject = $this->getAccessibleMock(AbstractTypolinkBuilder::class,
200 ['build'],
201 [$contentObjectRendererProphecy->reveal()],
202 '',
203 false
204 );
205 // Force hostname
206 $_SERVER['HTTP_HOST'] = 'localhost';
207 $_SERVER['SCRIPT_NAME'] = '/typo3/index.php';
208 $GLOBALS['TSFE']->absRefPrefix = '';
209
210 $this->assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration));
211 }
212
213 /**
214 * @test
215 */
216 public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlWithSubfolder()
217 {
218 $contentObjectRendererProphecy = $this->prophesize(ContentObjectRenderer::class);
219 $subject = $this->getAccessibleMock(AbstractTypolinkBuilder::class,
220 ['build'],
221 [$contentObjectRendererProphecy->reveal()],
222 '',
223 false
224 );
225 // Force hostname
226 $_SERVER['HTTP_HOST'] = 'localhost';
227 $_SERVER['SCRIPT_NAME'] = '/subfolder/typo3/index.php';
228
229 $expected = 'http://localhost/subfolder/fileadmin/my.pdf';
230 $url = 'fileadmin/my.pdf';
231 $configuration = [
232 'forceAbsoluteUrl' => '1'
233 ];
234
235 $this->assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration));
236 }
237 }