[TASK] Make frontend/Tests/Unit/Typolink/ tests notice free
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / Typolink / AbstractTypolinkBuilderTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Frontend\Tests\Unit\Typolink;
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
18 use Psr\Log\LoggerInterface;
19 use TYPO3\CMS\Core\Log\LogManager;
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\Typolink\AbstractTypolinkBuilder;
24 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
25
26 /**
27 * Test case
28 */
29 class AbstractTypolinkBuilderTest extends UnitTestCase
30 {
31 /**
32 * @var bool Reset singletons created by subject
33 */
34 protected $resetSingletonInstances = true;
35
36 /**
37 * @var \PHPUnit_Framework_MockObject_MockObject|TypoScriptFrontendController|\TYPO3\TestingFramework\Core\AccessibleObjectInterface
38 */
39 protected $frontendControllerMock;
40
41 /**
42 * Set up
43 */
44 protected function setUp()
45 {
46 GeneralUtility::flushInternalRuntimeCaches();
47
48 $this->createMockedLoggerAndLogManager();
49
50 $this->frontendControllerMock = $this->getAccessibleMock(
51 TypoScriptFrontendController::class,
52 ['dummy'],
53 [],
54 '',
55 false
56 );
57 $GLOBALS['TSFE'] = $this->frontendControllerMock;
58 }
59
60 //////////////////////
61 // Utility functions
62 //////////////////////
63
64 /**
65 * Avoid logging to the file system (file writer is currently the only configured writer)
66 */
67 protected function createMockedLoggerAndLogManager()
68 {
69 $logManagerMock = $this->getMockBuilder(LogManager::class)->getMock();
70 $loggerMock = $this->getMockBuilder(LoggerInterface::class)->getMock();
71 $logManagerMock->expects($this->any())
72 ->method('getLogger')
73 ->willReturn($loggerMock);
74 GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
75 }
76
77 /**
78 * @return array The test data for forceAbsoluteUrlReturnsAbsoluteUrl
79 */
80 public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider()
81 {
82 return [
83 'Missing forceAbsoluteUrl leaves URL untouched' => [
84 'foo',
85 'foo',
86 []
87 ],
88 'Absolute URL stays unchanged' => [
89 'http://example.org/',
90 'http://example.org/',
91 [
92 'forceAbsoluteUrl' => '1'
93 ]
94 ],
95 'Absolute URL stays unchanged 2' => [
96 'http://example.org/resource.html',
97 'http://example.org/resource.html',
98 [
99 'forceAbsoluteUrl' => '1'
100 ]
101 ],
102 'Scheme and host w/o ending slash stays unchanged' => [
103 'http://example.org',
104 'http://example.org',
105 [
106 'forceAbsoluteUrl' => '1'
107 ]
108 ],
109 'Scheme can be forced' => [
110 'typo3://example.org',
111 'http://example.org',
112 [
113 'forceAbsoluteUrl' => '1',
114 'forceAbsoluteUrl.' => [
115 'scheme' => 'typo3'
116 ]
117 ]
118 ],
119 'Relative path old-style' => [
120 'http://localhost/fileadmin/dummy.txt',
121 '/fileadmin/dummy.txt',
122 [
123 'forceAbsoluteUrl' => '1',
124 ]
125 ],
126 'Relative path' => [
127 'http://localhost/fileadmin/dummy.txt',
128 'fileadmin/dummy.txt',
129 [
130 'forceAbsoluteUrl' => '1',
131 ]
132 ],
133 'Scheme can be forced with pseudo-relative path' => [
134 'typo3://localhost/fileadmin/dummy.txt',
135 '/fileadmin/dummy.txt',
136 [
137 'forceAbsoluteUrl' => '1',
138 'forceAbsoluteUrl.' => [
139 'scheme' => 'typo3'
140 ]
141 ]
142 ],
143 'Hostname only is not treated as valid absolute URL' => [
144 'http://localhost/example.org',
145 'example.org',
146 [
147 'forceAbsoluteUrl' => '1'
148 ]
149 ],
150 'Scheme and host is added to local file path' => [
151 'typo3://localhost/fileadmin/my.pdf',
152 'fileadmin/my.pdf',
153 [
154 'forceAbsoluteUrl' => '1',
155 'forceAbsoluteUrl.' => [
156 'scheme' => 'typo3'
157 ]
158 ]
159 ]
160 ];
161 }
162
163 /**
164 * @param string $expected The expected URL
165 * @param string $url The URL to parse and manipulate
166 * @param array $configuration The configuration array
167 * @test
168 * @dataProvider forceAbsoluteUrlReturnsCorrectAbsoluteUrlDataProvider
169 */
170 public function forceAbsoluteUrlReturnsCorrectAbsoluteUrl($expected, $url, array $configuration)
171 {
172 $contentObjectRendererProphecy = $this->prophesize(ContentObjectRenderer::class);
173 $subject = $this->getAccessibleMock(
174 AbstractTypolinkBuilder::class,
175 ['build'],
176 [$contentObjectRendererProphecy->reveal()],
177 '',
178 false
179 );
180 // Force hostname
181 $_SERVER['HTTP_HOST'] = 'localhost';
182 $_SERVER['SCRIPT_NAME'] = '/typo3/index.php';
183 $GLOBALS['TSFE']->absRefPrefix = '';
184
185 $this->assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration));
186 }
187
188 /**
189 * @test
190 */
191 public function forceAbsoluteUrlReturnsCorrectAbsoluteUrlWithSubfolder()
192 {
193 $contentObjectRendererProphecy = $this->prophesize(ContentObjectRenderer::class);
194 $subject = $this->getAccessibleMock(
195 AbstractTypolinkBuilder::class,
196 ['build'],
197 [$contentObjectRendererProphecy->reveal()],
198 '',
199 false
200 );
201 // Force hostname
202 $_SERVER['HTTP_HOST'] = 'localhost';
203 $_SERVER['SCRIPT_NAME'] = '/subfolder/typo3/index.php';
204
205 $expected = 'http://localhost/subfolder/fileadmin/my.pdf';
206 $url = 'fileadmin/my.pdf';
207 $configuration = [
208 'forceAbsoluteUrl' => '1'
209 ];
210
211 $this->assertEquals($expected, $subject->_call('forceAbsoluteUrl', $url, $configuration));
212 }
213
214 /**
215 * Data provider for resolveTargetAttribute
216 *
217 * @return array [[$expected, $conf, $name, $respectFrameSetOption, $fallbackTarget],]
218 */
219 public function resolveTargetAttributeDataProvider(): array
220 {
221 $targetName = $this->getUniqueId('name_');
222 $target = $this->getUniqueId('target_');
223 $fallback = $this->getUniqueId('fallback_');
224 return [
225 'Take target from $conf, if $conf[$targetName] is set.' =>
226 [
227 $target,
228 [$targetName => $target], // $targetName is set
229 $targetName,
230 true,
231 $fallback,
232 'other doctype'
233 ],
234 'Else from fallback, if not $respectFrameSetOption ...' =>
235 [
236 $fallback,
237 [],
238 $targetName,
239 false, // $respectFrameSetOption false
240 $fallback,
241 'other doctype'
242 ],
243 ' ... or no doctype ... ' =>
244 [
245 $fallback,
246 [],
247 $targetName,
248 true,
249 $fallback,
250 null // no $doctype
251 ],
252 ' ... or doctype xhtml_trans... ' =>
253 [
254 $fallback,
255 [],
256 $targetName,
257 true,
258 $fallback,
259 'xhtml_trans'
260 ],
261 ' ... or doctype xhtml_basic... ' =>
262 [
263 $fallback,
264 [],
265 $targetName,
266 true,
267 $fallback,
268 'xhtml_basic'
269 ],
270 ' ... or doctype html5... ' =>
271 [
272 $fallback,
273 [],
274 $targetName,
275 true,
276 $fallback,
277 'html5'
278 ],
279 ' If all hopes fail, an empty string is returned. ' =>
280 [
281 '',
282 [],
283 $targetName,
284 true,
285 $fallback,
286 'other doctype'
287 ],
288 'It finally applies stdWrap' =>
289 [
290 'wrap_target',
291 [$targetName . '.' =>
292 [ 'ifEmpty' => 'wrap_target' ]
293 ],
294 $targetName,
295 true,
296 $fallback,
297 'other doctype'
298 ],
299 ];
300 }
301
302 /**
303 * @test
304 * @dataProvider resolveTargetAttributeDataProvider
305 * @param string $expected
306 * @param array $conf
307 * @param string $name
308 * @param bool $respectFrameSetOption
309 * @param string $fallbackTarget
310 * @param string|null $doctype
311 */
312 public function canResolveTheTargetAttribute(
313 string $expected,
314 array $conf,
315 string $name,
316 bool $respectFrameSetOption,
317 string $fallbackTarget,
318 $doctype
319 ) {
320 $this->frontendControllerMock->config =
321 ['config' => [ 'doctype' => $doctype]];
322 $renderer = GeneralUtility::makeInstance(ContentObjectRenderer::class);
323 $subject = $this->getMockBuilder(AbstractTypolinkBuilder::class)
324 ->setConstructorArgs([$renderer])
325 ->setMethods(['build'])
326 ->getMock();
327 $actual = $this->callInaccessibleMethod(
328 $subject,
329 'resolveTargetAttribute',
330 $conf,
331 $name,
332 $respectFrameSetOption,
333 $fallbackTarget
334 );
335 $this->assertEquals($expected, $actual);
336 }
337 }