3bb7353db68fe3a432d74e866d20472308bfd1da
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Utility / GeneralUtilityTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Utility;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 /**
28 * Testcase for class \TYPO3\CMS\Core\Utility\GeneralUtility
29 *
30 * @author Ingo Renner <ingo@typo3.org>
31 * @author Oliver Klee <typo3-coding@oliverklee.de>
32 * @package TYPO3
33 * @subpackage t3lib
34 */
35 class GeneralUtilityTest extends \tx_phpunit_testcase {
36
37 /**
38 * Enable backup of global and system variables
39 *
40 * @var boolean
41 */
42 protected $backupGlobals = TRUE;
43
44 /**
45 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
46 * because resource types cannot be handled during serializing
47 *
48 * @var array
49 */
50 protected $backupGlobalsBlacklist = array('TYPO3_DB');
51
52 /**
53 * @var array A backup of registered singleton instances
54 */
55 protected $singletonInstances = array();
56
57 public function setUp() {
58 $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
59 }
60
61 public function tearDown() {
62 \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
63 }
64
65 ///////////////////////////
66 // Tests concerning _GP
67 ///////////////////////////
68 /**
69 * @test
70 * @dataProvider gpDataProvider
71 */
72 public function canRetrieveValueWithGP($key, $get, $post, $expected) {
73 $_GET = $get;
74 $_POST = $post;
75 $this->assertSame($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::_GP($key));
76 }
77
78 /**
79 * Data provider for canRetrieveValueWithGP.
80 * All test values also check whether slashes are stripped properly.
81 *
82 * @return array
83 */
84 public function gpDataProvider() {
85 return array(
86 'No key parameter' => array(NULL, array(), array(), NULL),
87 'Key not found' => array('cake', array(), array(), NULL),
88 'Value only in GET' => array('cake', array('cake' => 'li\\e'), array(), 'lie'),
89 'Value only in POST' => array('cake', array(), array('cake' => 'l\\ie'), 'lie'),
90 'Value from POST preferred over GET' => array('cake', array('cake' => 'is a'), array('cake' => '\\lie'), 'lie'),
91 'Value can be an array' => array(
92 'cake',
93 array('cake' => array('is a' => 'l\\ie')),
94 array(),
95 array('is a' => 'lie')
96 )
97 );
98 }
99
100 ///////////////////////////
101 // Tests concerning _GPmerged
102 ///////////////////////////
103 /**
104 * @test
105 * @dataProvider gpMergedDataProvider
106 */
107 public function gpMergedWillMergeArraysFromGetAndPost($get, $post, $expected) {
108 $_POST = $post;
109 $_GET = $get;
110 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::_GPmerged('cake'));
111 }
112
113 /**
114 * Data provider for gpMergedWillMergeArraysFromGetAndPost
115 *
116 * @return array
117 */
118 public function gpMergedDataProvider() {
119 $fullDataArray = array('cake' => array('a' => 'is a', 'b' => 'lie'));
120 $postPartData = array('cake' => array('b' => 'lie'));
121 $getPartData = array('cake' => array('a' => 'is a'));
122 $getPartDataModified = array('cake' => array('a' => 'is not a'));
123 return array(
124 'Key doesn\' exist' => array(array('foo'), array('bar'), array()),
125 'No POST data' => array($fullDataArray, array(), $fullDataArray['cake']),
126 'No GET data' => array(array(), $fullDataArray, $fullDataArray['cake']),
127 'POST and GET are merged' => array($getPartData, $postPartData, $fullDataArray['cake']),
128 'POST is preferred over GET' => array($getPartDataModified, $fullDataArray, $fullDataArray['cake'])
129 );
130 }
131
132 ///////////////////////////////
133 // Tests concerning _GET / _POST
134 ///////////////////////////////
135 /**
136 * Data provider for canRetrieveGlobalInputsThroughGet
137 * and canRetrieveGlobalInputsThroughPost
138 *
139 * @return array
140 */
141 public function getAndPostDataProvider() {
142 return array(
143 'Requested input data doesn\'t exist' => array('cake', array(), NULL),
144 'No key will return entire input data' => array(NULL, array('cake' => 'l\\ie'), array('cake' => 'lie')),
145 'Can retrieve specific input' => array('cake', array('cake' => 'li\\e', 'foo'), 'lie'),
146 'Can retrieve nested input data' => array('cake', array('cake' => array('is a' => 'l\\ie')), array('is a' => 'lie'))
147 );
148 }
149
150 /**
151 * @test
152 * @dataProvider getAndPostDataProvider
153 */
154 public function canRetrieveGlobalInputsThroughGet($key, $get, $expected) {
155 $_GET = $get;
156 $this->assertSame($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::_GET($key));
157 }
158
159 /**
160 * @test
161 * @dataProvider getAndPostDataProvider
162 */
163 public function canRetrieveGlobalInputsThroughPost($key, $post, $expected) {
164 $_POST = $post;
165 $this->assertSame($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::_POST($key));
166 }
167
168 ///////////////////////////////
169 // Tests concerning _GETset
170 ///////////////////////////////
171 /**
172 * @test
173 * @dataProvider getSetDataProvider
174 */
175 public function canSetNewGetInputValues($input, $key, $expected, $getPreset = array()) {
176 $_GET = $getPreset;
177 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset($input, $key);
178 $this->assertSame($expected, $_GET);
179 }
180
181 /**
182 * Data provider for canSetNewGetInputValues
183 *
184 * @return array
185 */
186 public function getSetDataProvider() {
187 return array(
188 'No input data used without target key' => array(NULL, NULL, array()),
189 'No input data used with target key' => array(NULL, 'cake', array('cake' => '')),
190 'No target key used with string input data' => array('data', NULL, array()),
191 'No target key used with array input data' => array(array('cake' => 'lie'), NULL, array('cake' => 'lie')),
192 'Target key and string input data' => array('lie', 'cake', array('cake' => 'lie')),
193 'Replace existing GET data' => array('lie', 'cake', array('cake' => 'lie'), array('cake' => 'is a lie')),
194 'Target key pointing to sublevels and string input data' => array('lie', 'cake|is', array('cake' => array('is' => 'lie'))),
195 'Target key pointing to sublevels and array input data' => array(array('a' => 'lie'), 'cake|is', array('cake' => array('is' => array('a' => 'lie'))))
196 );
197 }
198
199 ///////////////////////////////
200 // Tests concerning gif_compress
201 ///////////////////////////////
202 /**
203 * @test
204 */
205 public function gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() {
206 if (TYPO3_OS == 'WIN') {
207 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
208 }
209 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
210 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available without imagemagick setup.');
211 }
212 $testFinder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('Tx_Phpunit_Service_TestFinder');
213 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.gif';
214 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
215 // Copy file to unique filename in typo3temp, set target permissions and run method
216 $testFilename = ((PATH_site . 'typo3temp/') . uniqid('test_')) . '.gif';
217 @copy($fixtureGifFile, $testFilename);
218 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
219 \TYPO3\CMS\Core\Utility\GeneralUtility::gif_compress($testFilename, 'IM');
220 // Get actual permissions and clean up
221 clearstatcache();
222 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
223 \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($testFilename);
224 $this->assertEquals($resultFilePermissions, '0777');
225 }
226
227 /**
228 * @test
229 */
230 public function gifCompressFixesPermissionOfConvertedFileIfUsingGd() {
231 if (TYPO3_OS == 'WIN') {
232 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
233 }
234 $testFinder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('Tx_Phpunit_Service_TestFinder');
235 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.gif';
236 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] = TRUE;
237 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] = FALSE;
238 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
239 // Copy file to unique filename in typo3temp, set target permissions and run method
240 $testFilename = ((PATH_site . 'typo3temp/') . uniqid('test_')) . '.gif';
241 @copy($fixtureGifFile, $testFilename);
242 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
243 \TYPO3\CMS\Core\Utility\GeneralUtility::gif_compress($testFilename, 'GD');
244 // Get actual permissions and clean up
245 clearstatcache();
246 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
247 \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($testFilename);
248 $this->assertEquals($resultFilePermissions, '0777');
249 }
250
251 ///////////////////////////////
252 // Tests concerning png_to_gif_by_imagemagick
253 ///////////////////////////////
254 /**
255 * @test
256 */
257 public function pngToGifByImagemagickFixesPermissionsOfConvertedFile() {
258 if (TYPO3_OS == 'WIN') {
259 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available on Windows.');
260 }
261 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
262 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
263 }
264 $testFinder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('Tx_Phpunit_Service_TestFinder');
265 $fixturePngFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.png';
266 $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] = TRUE;
267 // Copy file to unique filename in typo3temp, set target permissions and run method
268 $testFilename = ((PATH_site . 'typo3temp/') . uniqid('test_')) . '.png';
269 @copy($fixturePngFile, $testFilename);
270 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
271 $newGifFile = \TYPO3\CMS\Core\Utility\GeneralUtility::png_to_gif_by_imagemagick($testFilename);
272 // Get actual permissions and clean up
273 clearstatcache();
274 $resultFilePermissions = substr(decoct(fileperms($newGifFile)), 2);
275 \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($newGifFile);
276 $this->assertEquals($resultFilePermissions, '0777');
277 }
278
279 ///////////////////////////////
280 // Tests concerning read_png_gif
281 ///////////////////////////////
282 /**
283 * @test
284 */
285 public function readPngGifFixesPermissionsOfConvertedFile() {
286 if (TYPO3_OS == 'WIN') {
287 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available on Windows.');
288 }
289 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
290 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
291 }
292 $testFinder = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('Tx_Phpunit_Service_TestFinder');
293 $testGifFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.gif';
294 // Set target permissions and run method
295 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
296 $newPngFile = \TYPO3\CMS\Core\Utility\GeneralUtility::read_png_gif($testGifFile, TRUE);
297 // Get actual permissions and clean up
298 clearstatcache();
299 $resultFilePermissions = substr(decoct(fileperms($newPngFile)), 2);
300 \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($newPngFile);
301 $this->assertEquals($resultFilePermissions, '0777');
302 }
303
304 ///////////////////////////
305 // Tests concerning cmpIPv4
306 ///////////////////////////
307 /**
308 * Data provider for cmpIPv4ReturnsTrueForMatchingAddress
309 *
310 * @return array Data sets
311 */
312 static public function cmpIPv4DataProviderMatching() {
313 return array(
314 'host with full IP address' => array('127.0.0.1', '127.0.0.1'),
315 'host with two wildcards at the end' => array('127.0.0.1', '127.0.*.*'),
316 'host with wildcard at third octet' => array('127.0.0.1', '127.0.*.1'),
317 'host with wildcard at second octet' => array('127.0.0.1', '127.*.0.1'),
318 '/8 subnet' => array('127.0.0.1', '127.1.1.1/8'),
319 '/32 subnet (match only name)' => array('127.0.0.1', '127.0.0.1/32'),
320 '/30 subnet' => array('10.10.3.1', '10.10.3.3/30'),
321 'host with wildcard in list with IPv4/IPv6 addresses' => array('192.168.1.1', '127.0.0.1, 1234:5678::/126, 192.168.*'),
322 'host in list with IPv4/IPv6 addresses' => array('192.168.1.1', '::1, 1234:5678::/126, 192.168.1.1'),
323 );
324 }
325
326 /**
327 * @test
328 * @dataProvider cmpIPv4DataProviderMatching
329 */
330 public function cmpIPv4ReturnsTrueForMatchingAddress($ip, $list) {
331 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIPv4($ip, $list));
332 }
333
334 /**
335 * Data provider for cmpIPv4ReturnsFalseForNotMatchingAddress
336 *
337 * @return array Data sets
338 */
339 static public function cmpIPv4DataProviderNotMatching() {
340 return array(
341 'single host' => array('127.0.0.1', '127.0.0.2'),
342 'single host with wildcard' => array('127.0.0.1', '127.*.1.1'),
343 'single host with /32 subnet mask' => array('127.0.0.1', '127.0.0.2/32'),
344 '/31 subnet' => array('127.0.0.1', '127.0.0.2/31'),
345 'list with IPv4/IPv6 addresses' => array('127.0.0.1', '10.0.2.3, 192.168.1.1, ::1'),
346 'list with only IPv6 addresses' => array('10.20.30.40', '::1, 1234:5678::/127')
347 );
348 }
349
350 /**
351 * @test
352 * @dataProvider cmpIPv4DataProviderNotMatching
353 */
354 public function cmpIPv4ReturnsFalseForNotMatchingAddress($ip, $list) {
355 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIPv4($ip, $list));
356 }
357
358 ///////////////////////////
359 // Tests concerning cmpIPv6
360 ///////////////////////////
361 /**
362 * Data provider for cmpIPv6ReturnsTrueForMatchingAddress
363 *
364 * @return array Data sets
365 */
366 static public function cmpIPv6DataProviderMatching() {
367 return array(
368 'empty address' => array('::', '::'),
369 'empty with netmask in list' => array('::', '::/0'),
370 'empty with netmask 0 and host-bits set in list' => array('::', '::123/0'),
371 'localhost' => array('::1', '::1'),
372 'localhost with leading zero blocks' => array('::1', '0:0::1'),
373 'host with submask /128' => array('::1', '0:0::1/128'),
374 '/16 subnet' => array('1234::1', '1234:5678::/16'),
375 '/126 subnet' => array('1234:5678::3', '1234:5678::/126'),
376 '/126 subnet with host-bits in list set' => array('1234:5678::3', '1234:5678::2/126'),
377 'list with IPv4/IPv6 addresses' => array('1234:5678::3', '::1, 127.0.0.1, 1234:5678::/126, 192.168.1.1')
378 );
379 }
380
381 /**
382 * @test
383 * @dataProvider cmpIPv6DataProviderMatching
384 */
385 public function cmpIPv6ReturnsTrueForMatchingAddress($ip, $list) {
386 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIPv6($ip, $list));
387 }
388
389 /**
390 * Data provider for cmpIPv6ReturnsFalseForNotMatchingAddress
391 *
392 * @return array Data sets
393 */
394 static public function cmpIPv6DataProviderNotMatching() {
395 return array(
396 'empty against localhost' => array('::', '::1'),
397 'empty against localhost with /128 netmask' => array('::', '::1/128'),
398 'localhost against different host' => array('::1', '::2'),
399 'localhost against host with prior bits set' => array('::1', '::1:1'),
400 'host against different /17 subnet' => array('1234::1', '1234:f678::/17'),
401 'host against different /127 subnet' => array('1234:5678::3', '1234:5678::/127'),
402 'host against IPv4 address list' => array('1234:5678::3', '127.0.0.1, 192.168.1.1'),
403 'host against mixed list with IPv6 host in different subnet' => array('1234:5678::3', '::1, 1234:5678::/127')
404 );
405 }
406
407 /**
408 * @test
409 * @dataProvider cmpIPv6DataProviderNotMatching
410 */
411 public function cmpIPv6ReturnsFalseForNotMatchingAddress($ip, $list) {
412 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIPv6($ip, $list));
413 }
414
415 ///////////////////////////////
416 // Tests concerning IPv6Hex2Bin
417 ///////////////////////////////
418 /**
419 * Data provider for IPv6Hex2BinCorrect
420 *
421 * @return array Data sets
422 */
423 static public function IPv6Hex2BinDataProviderCorrect() {
424 return array(
425 'empty 1' => array('::', str_pad('', 16, "\x00")),
426 'empty 2, already normalized' => array('0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")),
427 'already normalized' => array('0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"),
428 'expansion in middle 1' => array('1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"),
429 'expansion in middle 2' => array('beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"),
430 );
431 }
432
433 /**
434 * @test
435 * @dataProvider IPv6Hex2BinDataProviderCorrect
436 */
437 public function IPv6Hex2BinCorrectlyConvertsAddresses($hex, $binary) {
438 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Hex2Bin($hex) === $binary);
439 }
440
441 ///////////////////////////////
442 // Tests concerning IPv6Bin2Hex
443 ///////////////////////////////
444 /**
445 * Data provider for IPv6Bin2HexCorrect
446 *
447 * @return array Data sets
448 */
449 static public function IPv6Bin2HexDataProviderCorrect() {
450 return array(
451 'empty' => array(str_pad('', 16, "\x00"), '::'),
452 'non-empty front' => array("\x01" . str_pad('', 15, "\x00"), '100::'),
453 'non-empty back' => array(str_pad('', 15, "\x00") . "\x01", '::1'),
454 'normalized' => array("\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78", '102:304::506:78'),
455 'expansion in middle 1' => array("\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02", '1::2'),
456 'expansion in middle 2' => array("\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa", 'beef::fefa'),
457 );
458 }
459
460 /**
461 * @test
462 * @dataProvider IPv6Bin2HexDataProviderCorrect
463 */
464 public function IPv6Bin2HexCorrectlyConvertsAddresses($binary, $hex) {
465 if (!class_exists('t3lib_diff')) {
466 $this->markTestSkipped('The current version of phpunit relies on t3lib_diff which is removed in 6.0 and thus this test fails. Move t3lib_diff to phpunit and reenable this test.');
467 }
468 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::IPv6Bin2Hex($binary), $hex);
469 }
470
471 ////////////////////////////////////////////////
472 // Tests concerning normalizeIPv6 / compressIPv6
473 ////////////////////////////////////////////////
474 /**
475 * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat
476 *
477 * @return array Data sets
478 */
479 static public function normalizeCompressIPv6DataProviderCorrect() {
480 return array(
481 'empty' => array('::', '0000:0000:0000:0000:0000:0000:0000:0000'),
482 'localhost' => array('::1', '0000:0000:0000:0000:0000:0000:0000:0001'),
483 'some address on right side' => array('::f0f', '0000:0000:0000:0000:0000:0000:0000:0f0f'),
484 'expansion in middle 1' => array('1::2', '0001:0000:0000:0000:0000:0000:0000:0002'),
485 'expansion in middle 2' => array('1:2::3', '0001:0002:0000:0000:0000:0000:0000:0003'),
486 'expansion in middle 3' => array('1::2:3', '0001:0000:0000:0000:0000:0000:0002:0003'),
487 'expansion in middle 4' => array('1:2::3:4:5', '0001:0002:0000:0000:0000:0003:0004:0005')
488 );
489 }
490
491 /**
492 * @test
493 * @dataProvider normalizeCompressIPv6DataProviderCorrect
494 */
495 public function normalizeIPv6CorrectlyNormalizesAddresses($compressed, $normalized) {
496 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::normalizeIPv6($compressed), $normalized);
497 }
498
499 /**
500 * @test
501 * @dataProvider normalizeCompressIPv6DataProviderCorrect
502 */
503 public function compressIPv6CorrectlyCompressesAdresses($compressed, $normalized) {
504 if (!class_exists('t3lib_diff')) {
505 $this->markTestSkipped('The current version of phpunit relies on t3lib_diff which is removed in 6.0 and thus this test fails. Move t3lib_diff to phpunit and reenable this test.');
506 }
507 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::compressIPv6($normalized), $compressed);
508 }
509
510 ///////////////////////////////
511 // Tests concerning validIP
512 ///////////////////////////////
513 /**
514 * Data provider for checkValidIpReturnsTrueForValidIp
515 *
516 * @return array Data sets
517 */
518 static public function validIpDataProvider() {
519 return array(
520 '0.0.0.0' => array('0.0.0.0'),
521 'private IPv4 class C' => array('192.168.0.1'),
522 'private IPv4 class A' => array('10.0.13.1'),
523 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb')
524 );
525 }
526
527 /**
528 * @test
529 * @dataProvider validIpDataProvider
530 */
531 public function validIpReturnsTrueForValidIp($ip) {
532 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::validIP($ip));
533 }
534
535 /**
536 * Data provider for checkValidIpReturnsFalseForInvalidIp
537 *
538 * @return array Data sets
539 */
540 static public function invalidIpDataProvider() {
541 return array(
542 'null' => array(NULL),
543 'zero' => array(0),
544 'string' => array('test'),
545 'string empty' => array(''),
546 'string NULL' => array('NULL'),
547 'out of bounds IPv4' => array('300.300.300.300'),
548 'dotted decimal notation with only two dots' => array('127.0.1')
549 );
550 }
551
552 /**
553 * @test
554 * @dataProvider invalidIpDataProvider
555 */
556 public function validIpReturnsFalseForInvalidIp($ip) {
557 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::validIP($ip));
558 }
559
560 ///////////////////////////////
561 // Tests concerning cmpFQDN
562 ///////////////////////////////
563 /**
564 * Data provider for cmpFqdnReturnsTrue
565 *
566 * @return array Data sets
567 */
568 static public function cmpFqdnValidDataProvider() {
569 return array(
570 'localhost should usually resolve, IPv4' => array('127.0.0.1', '*'),
571 'localhost should usually resolve, IPv6' => array('::1', '*'),
572 // other testcases with resolving not possible since it would
573 // require a working IPv4/IPv6-connectivity
574 'aaa.bbb.ccc.ddd.eee, full' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee'),
575 'aaa.bbb.ccc.ddd.eee, wildcard first' => array('aaa.bbb.ccc.ddd.eee', '*.ccc.ddd.eee'),
576 'aaa.bbb.ccc.ddd.eee, wildcard last' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.*'),
577 'aaa.bbb.ccc.ddd.eee, wildcard middle' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.eee'),
578 'list-matches, 1' => array('aaa.bbb.ccc.ddd.eee', 'xxx, yyy, zzz, aaa.*.eee'),
579 'list-matches, 2' => array('aaa.bbb.ccc.ddd.eee', '127:0:0:1,,aaa.*.eee,::1')
580 );
581 }
582
583 /**
584 * @test
585 * @dataProvider cmpFqdnValidDataProvider
586 */
587 public function cmpFqdnReturnsTrue($baseHost, $list) {
588 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::cmpFQDN($baseHost, $list));
589 }
590
591 /**
592 * Data provider for cmpFqdnReturnsFalse
593 *
594 * @return array Data sets
595 */
596 static public function cmpFqdnInvalidDataProvider() {
597 return array(
598 'num-parts of hostname to check can only be less or equal than hostname, 1' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee.fff'),
599 'num-parts of hostname to check can only be less or equal than hostname, 2' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.bbb.ccc.ddd.eee')
600 );
601 }
602
603 /**
604 * @test
605 * @dataProvider cmpFqdnInvalidDataProvider
606 */
607 public function cmpFqdnReturnsFalse($baseHost, $list) {
608 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::cmpFQDN($baseHost, $list));
609 }
610
611 ///////////////////////////////
612 // Tests concerning inList
613 ///////////////////////////////
614 /**
615 * @test
616 * @param string $haystack
617 * @dataProvider inListForItemContainedReturnsTrueDataProvider
618 */
619 public function inListForItemContainedReturnsTrue($haystack) {
620 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::inList($haystack, 'findme'));
621 }
622
623 /**
624 * Data provider for inListForItemContainedReturnsTrue.
625 *
626 * @return array
627 */
628 public function inListForItemContainedReturnsTrueDataProvider() {
629 return array(
630 'Element as second element of four items' => array('one,findme,three,four'),
631 'Element at beginning of list' => array('findme,one,two'),
632 'Element at end of list' => array('one,two,findme'),
633 'One item list' => array('findme')
634 );
635 }
636
637 /**
638 * @test
639 * @param string $haystack
640 * @dataProvider inListForItemNotContainedReturnsFalseDataProvider
641 */
642 public function inListForItemNotContainedReturnsFalse($haystack) {
643 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::inList($haystack, 'findme'));
644 }
645
646 /**
647 * Data provider for inListForItemNotContainedReturnsFalse.
648 *
649 * @return array
650 */
651 public function inListForItemNotContainedReturnsFalseDataProvider() {
652 return array(
653 'Four item list' => array('one,two,three,four'),
654 'One item list' => array('one'),
655 'Empty list' => array('')
656 );
657 }
658
659 ///////////////////////////////
660 // Tests concerning rmFromList
661 ///////////////////////////////
662 /**
663 * @test
664 * @param string $initialList
665 * @param string $listWithElementRemoved
666 * @dataProvider rmFromListRemovesElementsFromCommaSeparatedListDataProvider
667 */
668 public function rmFromListRemovesElementsFromCommaSeparatedList($initialList, $listWithElementRemoved) {
669 $this->assertSame($listWithElementRemoved, \TYPO3\CMS\Core\Utility\GeneralUtility::rmFromList('removeme', $initialList));
670 }
671
672 /**
673 * Data provider for rmFromListRemovesElementsFromCommaSeparatedList
674 *
675 * @return array
676 */
677 public function rmFromListRemovesElementsFromCommaSeparatedListDataProvider() {
678 return array(
679 'Element as second element of three' => array('one,removeme,two', 'one,two'),
680 'Element at beginning of list' => array('removeme,one,two', 'one,two'),
681 'Element at end of list' => array('one,two,removeme', 'one,two'),
682 'One item list' => array('removeme', ''),
683 'Element not contained in list' => array('one,two,three', 'one,two,three'),
684 'Empty list' => array('', '')
685 );
686 }
687
688 ///////////////////////////////
689 // Tests concerning expandList
690 ///////////////////////////////
691 /**
692 * @test
693 * @param string $list
694 * @param string $expectation
695 * @dataProvider expandListExpandsIntegerRangesDataProvider
696 */
697 public function expandListExpandsIntegerRanges($list, $expectation) {
698 $this->assertSame($expectation, \TYPO3\CMS\Core\Utility\GeneralUtility::expandList($list));
699 }
700
701 /**
702 * Data provider for expandListExpandsIntegerRangesDataProvider
703 *
704 * @return array
705 */
706 public function expandListExpandsIntegerRangesDataProvider() {
707 return array(
708 'Expand for the same number' => array('1,2-2,7', '1,2,7'),
709 'Small range expand with parameters reversed ignores reversed items' => array('1,5-3,7', '1,7'),
710 'Small range expand' => array('1,3-5,7', '1,3,4,5,7'),
711 'Expand at beginning' => array('3-5,1,7', '3,4,5,1,7'),
712 'Expand at end' => array('1,7,3-5', '1,7,3,4,5'),
713 'Multiple small range expands' => array('1,3-5,7-10,12', '1,3,4,5,7,8,9,10,12'),
714 'One item list' => array('1-5', '1,2,3,4,5'),
715 'Nothing to expand' => array('1,2,3,4', '1,2,3,4'),
716 'Empty list' => array('', '')
717 );
718 }
719
720 /**
721 * @test
722 */
723 public function expandListExpandsForTwoThousandElementsExpandsOnlyToThousandElementsMaximum() {
724 $list = \TYPO3\CMS\Core\Utility\GeneralUtility::expandList('1-2000');
725 $this->assertSame(1000, count(explode(',', $list)));
726 }
727
728 ///////////////////////////////
729 // Tests concerning uniqueList
730 ///////////////////////////////
731 /**
732 * @test
733 * @param string $initialList
734 * @param string $unifiedList
735 * @dataProvider uniqueListUnifiesCommaSeparatedListDataProvider
736 */
737 public function uniqueListUnifiesCommaSeparatedList($initialList, $unifiedList) {
738 $this->assertSame($unifiedList, \TYPO3\CMS\Core\Utility\GeneralUtility::uniqueList($initialList));
739 }
740
741 /**
742 * Data provider for uniqueListUnifiesCommaSeparatedList
743 *
744 * @return array
745 */
746 public function uniqueListUnifiesCommaSeparatedListDataProvider() {
747 return array(
748 'List without duplicates' => array('one,two,three', 'one,two,three'),
749 'List with two consecutive duplicates' => array('one,two,two,three,three', 'one,two,three'),
750 'List with non-consecutive duplicates' => array('one,two,three,two,three', 'one,two,three'),
751 'One item list' => array('one', 'one'),
752 'Empty list' => array('', '')
753 );
754 }
755
756 ///////////////////////////////
757 // Tests concerning isFirstPartOfStr
758 ///////////////////////////////
759 /**
760 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
761 *
762 * @return array
763 */
764 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
765 return array(
766 'match first part of string' => array('hello world', 'hello'),
767 'match whole string' => array('hello', 'hello'),
768 'integer is part of string with same number' => array('24', 24),
769 'string is part of integer with same number' => array(24, '24'),
770 'integer is part of string starting with same number' => array('24 beer please', 24)
771 );
772 }
773
774 /**
775 * @test
776 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
777 */
778 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
779 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($string, $part));
780 }
781
782 /**
783 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
784 *
785 * @return array
786 */
787 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
788 return array(
789 'no string match' => array('hello', 'bye'),
790 'no case sensitive string match' => array('hello world', 'Hello'),
791 'array is not part of string' => array('string', array()),
792 'string is not part of array' => array(array(), 'string'),
793 'NULL is not part of string' => array('string', NULL),
794 'string is not part of array' => array(NULL, 'string'),
795 'NULL is not part of array' => array(array(), NULL),
796 'array is not part of string' => array(NULL, array()),
797 'empty string is not part of empty string' => array('', ''),
798 'NULL is not part of empty string' => array('', NULL),
799 'false is not part of empty string' => array('', FALSE),
800 'empty string is not part of NULL' => array(NULL, ''),
801 'empty string is not part of false' => array(FALSE, ''),
802 'empty string is not part of zero integer' => array(0, ''),
803 'zero integer is not part of NULL' => array(NULL, 0),
804 'zero integer is not part of empty string' => array('', 0)
805 );
806 }
807
808 /**
809 * @test
810 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
811 */
812 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
813 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::isFirstPartOfStr($string, $part));
814 }
815
816 ///////////////////////////////
817 // Tests concerning formatSize
818 ///////////////////////////////
819 /**
820 * @test
821 * @dataProvider formatSizeDataProvider
822 */
823 public function formatSizeTranslatesBytesToHigherOrderRepresentation($size, $label, $expected) {
824 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::formatSize($size, $label));
825 }
826
827 /**
828 * Data provider for formatSizeTranslatesBytesToHigherOrderRepresentation
829 *
830 * @return array
831 */
832 public function formatSizeDataProvider() {
833 return array(
834 'Bytes keep beeing bytes (min)' => array(1, '', '1 '),
835 'Bytes keep beeing bytes (max)' => array(899, '', '899 '),
836 'Kilobytes are detected' => array(1024, '', '1.0 K'),
837 'Megabytes are detected' => array(1048576, '', '1.0 M'),
838 'Gigabytes are detected' => array(1073741824, '', '1.0 G'),
839 'Decimal is omitted for large kilobytes' => array(31080, '', '30 K'),
840 'Decimal is omitted for large megabytes' => array(31458000, '', '30 M'),
841 'Decimal is omitted for large gigabytes' => array(32212254720, '', '30 G'),
842 'Label for bytes can be exchanged' => array(1, ' Foo|||', '1 Foo'),
843 'Label for kilobytes can be exchanged' => array(1024, '| Foo||', '1.0 Foo'),
844 'Label for megabyes can be exchanged' => array(1048576, '|| Foo|', '1.0 Foo'),
845 'Label for gigabytes can be exchanged' => array(1073741824, '||| Foo', '1.0 Foo')
846 );
847 }
848
849 ///////////////////////////////
850 // Tests concerning splitCalc
851 ///////////////////////////////
852 /**
853 * Data provider for splitCalc
854 *
855 * @return array expected values, arithmetic expression
856 */
857 public function splitCalcDataProvider() {
858 return array(
859 'empty string returns empty array' => array(
860 array(),
861 ''
862 ),
863 'number without operator returns array with plus and number' => array(
864 array(array('+', 42)),
865 '42'
866 ),
867 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
868 array(array('+', 42), array('*', 31)),
869 '42 * 31'
870 )
871 );
872 }
873
874 /**
875 * @test
876 * @dataProvider splitCalcDataProvider
877 */
878 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
879 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::splitCalc($expression, '+-*/'));
880 }
881
882 ///////////////////////////////
883 // Tests concerning htmlspecialchars_decode
884 ///////////////////////////////
885 /**
886 * @test
887 */
888 public function htmlspecialcharsDecodeReturnsDecodedString() {
889 $string = '<typo3 version="6.0">&nbsp;</typo3>';
890 $encoded = htmlspecialchars($string);
891 $decoded = \TYPO3\CMS\Core\Utility\GeneralUtility::htmlspecialchars_decode($encoded);
892 $this->assertEquals($string, $decoded);
893 }
894
895 ///////////////////////////////
896 // Tests concerning deHSCentities
897 ///////////////////////////////
898 /**
899 * @test
900 * @dataProvider deHSCentitiesReturnsDecodedStringDataProvider
901 */
902 public function deHSCentitiesReturnsDecodedString($input, $expected) {
903 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::deHSCentities($input));
904 }
905
906 /**
907 * Data provider for deHSCentitiesReturnsDecodedString
908 *
909 * @return array
910 */
911 public function deHSCentitiesReturnsDecodedStringDataProvider() {
912 return array(
913 'Empty string' => array('', ''),
914 'Double encoded &' => array('&amp;amp;', '&amp;'),
915 'Double encoded numeric entity' => array('&amp;#1234;', '&#1234;'),
916 'Double encoded hexadecimal entity' => array('&amp;#x1b;', '&#x1b;'),
917 'Single encoded entities are not touched' => array('&amp; &#1234; &#x1b;', '&amp; &#1234; &#x1b;')
918 );
919 }
920
921 //////////////////////////////////
922 // Tests concerning slashJS
923 //////////////////////////////////
924 /**
925 * @test
926 * @dataProvider slashJsDataProvider
927 */
928 public function slashJsEscapesSingleQuotesAndSlashes($input, $extended, $expected) {
929 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::slashJS($input, $extended));
930 }
931
932 /**
933 * Data provider for slashJsEscapesSingleQuotesAndSlashes
934 *
935 * @return array
936 */
937 public function slashJsDataProvider() {
938 return array(
939 'Empty string is not changed' => array('', FALSE, ''),
940 'Normal string is not changed' => array('The cake is a lie √', FALSE, 'The cake is a lie √'),
941 'String with single quotes' => array('The \'cake\' is a lie', FALSE, 'The \\\'cake\\\' is a lie'),
942 'String with single quotes and backslashes - just escape single quotes' => array('The \\\'cake\\\' is a lie', FALSE, 'The \\\\\'cake\\\\\' is a lie'),
943 'String with single quotes and backslashes - escape both' => array('The \\\'cake\\\' is a lie', TRUE, 'The \\\\\\\'cake\\\\\\\' is a lie')
944 );
945 }
946
947 //////////////////////////////////
948 // Tests concerning rawUrlEncodeJS
949 //////////////////////////////////
950 /**
951 * @test
952 */
953 public function rawUrlEncodeJsPreservesWhitespaces() {
954 $input = 'Encode \'me\', but leave my spaces √';
955 $expected = 'Encode %27me%27%2C but leave my spaces %E2%88%9A';
956 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::rawUrlEncodeJS($input));
957 }
958
959 //////////////////////////////////
960 // Tests concerning rawUrlEncodeJS
961 //////////////////////////////////
962 /**
963 * @test
964 */
965 public function rawUrlEncodeFpPreservesSlashes() {
966 $input = 'Encode \'me\', but leave my / √';
967 $expected = 'Encode%20%27me%27%2C%20but%20leave%20my%20/%20%E2%88%9A';
968 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::rawUrlEncodeFP($input));
969 }
970
971 //////////////////////////////////
972 // Tests concerning strtoupper / strtolower
973 //////////////////////////////////
974 /**
975 * Data provider for strtoupper and strtolower
976 *
977 * @return array
978 */
979 public function strtouppperDataProvider() {
980 return array(
981 'Empty string' => array('', ''),
982 'String containing only latin characters' => array('the cake is a lie.', 'THE CAKE IS A LIE.'),
983 'String with umlauts and accent characters' => array('the càkê is ä lie.', 'THE CàKê IS ä LIE.')
984 );
985 }
986
987 /**
988 * @test
989 * @dataProvider strtouppperDataProvider
990 */
991 public function strtoupperConvertsOnlyLatinCharacters($input, $expected) {
992 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::strtoupper($input));
993 }
994
995 /**
996 * @test
997 * @dataProvider strtouppperDataProvider
998 */
999 public function strtolowerConvertsOnlyLatinCharacters($expected, $input) {
1000 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::strtolower($input));
1001 }
1002
1003 //////////////////////////////////
1004 // Tests concerning validEmail
1005 //////////////////////////////////
1006 /**
1007 * Data provider for valid validEmail's
1008 *
1009 * @return array Valid email addresses
1010 */
1011 public function validEmailValidDataProvider() {
1012 return array(
1013 'short mail address' => array('a@b.c'),
1014 'simple mail address' => array('test@example.com'),
1015 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
1016 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
1017 // 'equal sign in local part' => array('test=mail@example.com'),
1018 'dash in local part' => array('test-mail@example.com'),
1019 'plus in local part' => array('test+mail@example.com'),
1020 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
1021 // 'question mark in local part' => array('test?mail@example.com'),
1022 'slash in local part' => array('foo/bar@example.com'),
1023 'hash in local part' => array('foo#bar@example.com'),
1024 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
1025 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
1026 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
1027 // 'dash as local part' => array('-@foo.com'),
1028 'umlauts in local part' => array('äöüfoo@bar.com'),
1029 'umlauts in domain part' => array('foo@äöüfoo.com')
1030 );
1031 }
1032
1033 /**
1034 * @test
1035 * @dataProvider validEmailValidDataProvider
1036 */
1037 public function validEmailReturnsTrueForValidMailAddress($address) {
1038 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::validEmail($address));
1039 }
1040
1041 /**
1042 * Data provider for invalid validEmail's
1043 *
1044 * @return array Invalid email addresses
1045 */
1046 public function validEmailInvalidDataProvider() {
1047 return array(
1048 '@ sign only' => array('@'),
1049 'duplicate @' => array('test@@example.com'),
1050 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
1051 'opening parenthesis in local part' => array('foo(bar@example.com'),
1052 'closing parenthesis in local part' => array('foo)bar@example.com'),
1053 'opening square bracket in local part' => array('foo[bar@example.com'),
1054 'closing square bracket as local part' => array(']@example.com'),
1055 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
1056 // 'top level domain only' => array('test@com'),
1057 'dash as second level domain' => array('foo@-.com'),
1058 'domain part starting with dash' => array('foo@-foo.com'),
1059 'domain part ending with dash' => array('foo@foo-.com'),
1060 'number as top level domain' => array('foo@bar.123'),
1061 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
1062 // 'dash as top level domain' => array('foo@bar.-'),
1063 'dot at beginning of domain part' => array('test@.com'),
1064 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
1065 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
1066 'trailing whitespace' => array('test@example.com '),
1067 'trailing carriage return' => array('test@example.com' . CR),
1068 'trailing linefeed' => array('test@example.com' . LF),
1069 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
1070 'trailing tab' => array('test@example.com' . TAB)
1071 );
1072 }
1073
1074 /**
1075 * @test
1076 * @dataProvider validEmailInvalidDataProvider
1077 */
1078 public function validEmailReturnsFalseForInvalidMailAddress($address) {
1079 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::validEmail($address));
1080 }
1081
1082 //////////////////////////////////
1083 // Tests concerning inArray
1084 //////////////////////////////////
1085 /**
1086 * @test
1087 * @dataProvider inArrayDataProvider
1088 */
1089 public function inArrayChecksStringExistenceWithinArray($array, $item, $expected) {
1090 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::inArray($array, $item));
1091 }
1092
1093 /**
1094 * Data provider for inArrayChecksStringExistenceWithinArray
1095 *
1096 * @return array
1097 */
1098 public function inArrayDataProvider() {
1099 return array(
1100 'Empty array' => array(array(), 'search', FALSE),
1101 'One item array no match' => array(array('one'), 'two', FALSE),
1102 'One item array match' => array(array('one'), 'one', TRUE),
1103 'Multiple items array no match' => array(array('one', 2, 'three', 4), 'four', FALSE),
1104 'Multiple items array match' => array(array('one', 2, 'three', 4), 'three', TRUE),
1105 'Integer search items can match string values' => array(array('0', '1', '2'), 1, TRUE),
1106 'Search item is not casted to integer for a match' => array(array(4), '4a', FALSE),
1107 'Empty item won\'t match - in contrast to the php-builtin ' => array(array(0, 1, 2), '', FALSE)
1108 );
1109 }
1110
1111 //////////////////////////////////
1112 // Tests concerning intExplode
1113 //////////////////////////////////
1114 /**
1115 * @test
1116 */
1117 public function intExplodeConvertsStringsToInteger() {
1118 $testString = '1,foo,2';
1119 $expectedArray = array(1, 0, 2);
1120 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::intExplode(',', $testString);
1121 $this->assertEquals($expectedArray, $actualArray);
1122 }
1123
1124 //////////////////////////////////
1125 // Tests concerning keepItemsInArray
1126 //////////////////////////////////
1127 /**
1128 * @test
1129 * @dataProvider keepItemsInArrayWorksWithOneArgumentDataProvider
1130 */
1131 public function keepItemsInArrayWorksWithOneArgument($search, $array, $expected) {
1132 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::keepItemsInArray($array, $search));
1133 }
1134
1135 /**
1136 * Data provider for keepItemsInArrayWorksWithOneArgument
1137 *
1138 * @return array
1139 */
1140 public function keepItemsInArrayWorksWithOneArgumentDataProvider() {
1141 $array = array(
1142 'one' => 'one',
1143 'two' => 'two',
1144 'three' => 'three'
1145 );
1146 return array(
1147 'Empty argument will match "all" elements' => array(NULL, $array, $array),
1148 'No match' => array('four', $array, array()),
1149 'One match' => array('two', $array, array('two' => 'two')),
1150 'Multiple matches' => array('two,one', $array, array('one' => 'one', 'two' => 'two')),
1151 'Argument can be an array' => array(array('three'), $array, array('three' => 'three'))
1152 );
1153 }
1154
1155 /**
1156 * Shows the exmaple from the doc comment where
1157 * a function is used to reduce the sub arrays to one item which
1158 * is then used for the matching.
1159 *
1160 * @test
1161 */
1162 public function keepItemsInArrayCanUseCallbackOnSearchArray() {
1163 $array = array(
1164 'aa' => array('first', 'second'),
1165 'bb' => array('third', 'fourth'),
1166 'cc' => array('fifth', 'sixth')
1167 );
1168 $expected = array('bb' => array('third', 'fourth'));
1169 $keepItems = 'third';
1170 $getValueFunc = create_function('$value', 'return $value[0];');
1171 $match = \TYPO3\CMS\Core\Utility\GeneralUtility::keepItemsInArray($array, $keepItems, $getValueFunc);
1172 $this->assertEquals($expected, $match);
1173 }
1174
1175 //////////////////////////////////
1176 // Tests concerning implodeArrayForUrl / explodeUrl2Array
1177 //////////////////////////////////
1178 /**
1179 * Data provider for implodeArrayForUrlBuildsValidParameterString and
1180 * explodeUrl2ArrayTransformsParameterStringToArray
1181 *
1182 * @return array
1183 */
1184 public function implodeArrayForUrlDataProvider() {
1185 $valueArray = array('one' => '√', 'two' => 2);
1186 return array(
1187 'Empty input' => array('foo', array(), ''),
1188 'String parameters' => array('foo', $valueArray, '&foo[one]=%E2%88%9A&foo[two]=2'),
1189 'Nested array parameters' => array('foo', array($valueArray), '&foo[0][one]=%E2%88%9A&foo[0][two]=2'),
1190 'Keep blank parameters' => array('foo', array('one' => '√', ''), '&foo[one]=%E2%88%9A&foo[0]=')
1191 );
1192 }
1193
1194 /**
1195 * @test
1196 * @dataProvider implodeArrayForUrlDataProvider
1197 */
1198 public function implodeArrayForUrlBuildsValidParameterString($name, $input, $expected) {
1199 $this->assertSame($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl($name, $input));
1200 }
1201
1202 /**
1203 * @test
1204 */
1205 public function implodeArrayForUrlCanSkipEmptyParameters() {
1206 $input = array('one' => '√', '');
1207 $expected = '&foo[one]=%E2%88%9A';
1208 $this->assertSame($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl('foo', $input, '', TRUE));
1209 }
1210
1211 /**
1212 * @test
1213 */
1214 public function implodeArrayForUrlCanUrlEncodeKeyNames() {
1215 $input = array('one' => '√', '');
1216 $expected = '&foo%5Bone%5D=%E2%88%9A&foo%5B0%5D=';
1217 $this->assertSame($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::implodeArrayForUrl('foo', $input, '', FALSE, TRUE));
1218 }
1219
1220 /**
1221 * @test
1222 * @dataProvider implodeArrayForUrlDataProvider
1223 */
1224 public function explodeUrl2ArrayTransformsParameterStringToNestedArray($name, $array, $input) {
1225 $expected = $array ? array($name => $array) : array();
1226 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array($input, TRUE));
1227 }
1228
1229 /**
1230 * @test
1231 * @dataProvider explodeUrl2ArrayDataProvider
1232 */
1233 public function explodeUrl2ArrayTransformsParameterStringToFlatArray($input, $expected) {
1234 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::explodeUrl2Array($input, FALSE));
1235 }
1236
1237 /**
1238 * Data provider for explodeUrl2ArrayTransformsParameterStringToFlatArray
1239 *
1240 * @return array
1241 */
1242 public function explodeUrl2ArrayDataProvider() {
1243 return array(
1244 'Empty string' => array('', array()),
1245 'Simple parameter string' => array('&one=%E2%88%9A&two=2', array('one' => '√', 'two' => 2)),
1246 'Nested parameter string' => array('&foo[one]=%E2%88%9A&two=2', array('foo[one]' => '√', 'two' => 2))
1247 );
1248 }
1249
1250 //////////////////////////////////
1251 // Tests concerning compileSelectedGetVarsFromArray
1252 //////////////////////////////////
1253 /**
1254 * @test
1255 */
1256 public function compileSelectedGetVarsFromArrayFiltersIncomingData() {
1257 $filter = 'foo,bar';
1258 $getArray = array('foo' => 1, 'cake' => 'lie');
1259 $expected = array('foo' => 1);
1260 $result = \TYPO3\CMS\Core\Utility\GeneralUtility::compileSelectedGetVarsFromArray($filter, $getArray, FALSE);
1261 $this->assertSame($expected, $result);
1262 }
1263
1264 /**
1265 * @test
1266 */
1267 public function compileSelectedGetVarsFromArrayUsesGetPostDataFallback() {
1268 $_GET['bar'] = '2';
1269 $filter = 'foo,bar';
1270 $getArray = array('foo' => 1, 'cake' => 'lie');
1271 $expected = array('foo' => 1, 'bar' => '2');
1272 $result = \TYPO3\CMS\Core\Utility\GeneralUtility::compileSelectedGetVarsFromArray($filter, $getArray, TRUE);
1273 $this->assertSame($expected, $result);
1274 }
1275
1276 //////////////////////////////////
1277 // Tests concerning remapArrayKeys
1278 //////////////////////////////////
1279 /**
1280 * @test
1281 */
1282 public function remapArrayKeysExchangesKeysWithGivenMapping() {
1283 $array = array(
1284 'one' => 'one',
1285 'two' => 'two',
1286 'three' => 'three'
1287 );
1288 $keyMapping = array(
1289 'one' => '1',
1290 'two' => '2'
1291 );
1292 $expected = array(
1293 '1' => 'one',
1294 '2' => 'two',
1295 'three' => 'three'
1296 );
1297 \TYPO3\CMS\Core\Utility\GeneralUtility::remapArrayKeys($array, $keyMapping);
1298 $this->assertEquals($expected, $array);
1299 }
1300
1301 //////////////////////////////////
1302 // Tests concerning array_merge
1303 //////////////////////////////////
1304 /**
1305 * Test demonstrating array_merge. This is actually
1306 * a native PHP operator, therefore this test is mainly used to
1307 * show how this function can be used.
1308 *
1309 * @test
1310 */
1311 public function arrayMergeKeepsIndexesAfterMerge() {
1312 $array1 = array(10 => 'FOO', '20' => 'BAR');
1313 $array2 = array('5' => 'PLONK');
1314 $expected = array('5' => 'PLONK', 10 => 'FOO', '20' => 'BAR');
1315 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::array_merge($array1, $array2));
1316 }
1317
1318 //////////////////////////////////
1319 // Tests concerning int_from_ver
1320 //////////////////////////////////
1321 /**
1322 * Data Provider for intFromVerConvertsVersionNumbersToIntegersDataProvider
1323 *
1324 * return array
1325 */
1326 public function intFromVerConvertsVersionNumbersToIntegersDataProvider() {
1327 return array(
1328 array('4003003', '4.3.3'),
1329 array('4012003', '4.12.3'),
1330 array('5000000', '5.0.0'),
1331 array('3008001', '3.8.1'),
1332 array('1012', '0.1.12')
1333 );
1334 }
1335
1336 /**
1337 * @test
1338 * @dataProvider intFromVerConvertsVersionNumbersToIntegersDataProvider
1339 */
1340 public function intFromVerConvertsVersionNumbersToIntegers($expected, $version) {
1341 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::int_from_ver($version));
1342 }
1343
1344 //////////////////////////////////
1345 // Tests concerning revExplode
1346 //////////////////////////////////
1347 /**
1348 * @test
1349 */
1350 public function revExplodeExplodesString() {
1351 $testString = 'my:words:here';
1352 $expectedArray = array('my:words', 'here');
1353 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::revExplode(':', $testString, 2);
1354 $this->assertEquals($expectedArray, $actualArray);
1355 }
1356
1357 //////////////////////////////////
1358 // Tests concerning trimExplode
1359 //////////////////////////////////
1360 /**
1361 * @test
1362 */
1363 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
1364 $testString = ' a , b , c ,d ,, e,f,';
1365 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
1366 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString);
1367 $this->assertEquals($expectedArray, $actualArray);
1368 }
1369
1370 /**
1371 * @test
1372 */
1373 public function checkTrimExplodeRemovesNewLines() {
1374 $testString = (' a , b , ' . LF) . ' ,d ,, e,f,';
1375 $expectedArray = array('a', 'b', 'd', 'e', 'f');
1376 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, TRUE);
1377 $this->assertEquals($expectedArray, $actualArray);
1378 }
1379
1380 /**
1381 * @test
1382 */
1383 public function checkTrimExplodeRemovesEmptyElements() {
1384 $testString = 'a , b , c , ,d ,, ,e,f,';
1385 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
1386 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, TRUE);
1387 $this->assertEquals($expectedArray, $actualArray);
1388 }
1389
1390 /**
1391 * @test
1392 */
1393 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
1394 $testString = ' a , b , c , , d,, ,e ';
1395 $expectedArray = array('a', 'b', 'c,,d,,,e');
1396 // Limiting returns the rest of the string as the last element
1397 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, FALSE, 3);
1398 $this->assertEquals($expectedArray, $actualArray);
1399 }
1400
1401 /**
1402 * @test
1403 */
1404 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
1405 $testString = ' a , b , c , , d,, ,e ';
1406 $expectedArray = array('a', 'b', 'c,d,e');
1407 // Limiting returns the rest of the string as the last element
1408 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, TRUE, 3);
1409 $this->assertEquals($expectedArray, $actualArray);
1410 }
1411
1412 /**
1413 * @test
1414 */
1415 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
1416 $testString = ' a , b , c , d, ,e, f , , ';
1417 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
1418 // limiting returns the rest of the string as the last element
1419 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, FALSE, -3);
1420 $this->assertEquals($expectedArray, $actualArray);
1421 }
1422
1423 /**
1424 * @test
1425 */
1426 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
1427 $testString = ' a , b , c , d, ,e, f , , ';
1428 $expectedArray = array('a', 'b', 'c');
1429 // Limiting returns the rest of the string as the last element
1430 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, TRUE, -3);
1431 $this->assertEquals($expectedArray, $actualArray);
1432 }
1433
1434 /**
1435 * @test
1436 */
1437 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
1438 $testString = ' a , b , , c , , , ';
1439 $expectedArray = array('a', 'b', 'c');
1440 // Limiting returns the rest of the string as the last element
1441 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, TRUE, 4);
1442 $this->assertEquals($expectedArray, $actualArray);
1443 }
1444
1445 /**
1446 * @test
1447 */
1448 public function checkTrimExplodeKeepsZeroAsString() {
1449 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
1450 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
1451 $actualArray = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $testString, TRUE);
1452 $this->assertEquals($expectedArray, $actualArray);
1453 }
1454
1455 //////////////////////////////////
1456 // Tests concerning removeArrayEntryByValue
1457 //////////////////////////////////
1458 /**
1459 * @test
1460 */
1461 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
1462 $inputArray = array(
1463 '0' => 'test1',
1464 '1' => 'test2',
1465 '2' => 'test3',
1466 '3' => 'test2'
1467 );
1468 $compareValue = 'test2';
1469 $expectedResult = array(
1470 '0' => 'test1',
1471 '2' => 'test3'
1472 );
1473 $actualResult = \TYPO3\CMS\Core\Utility\GeneralUtility::removeArrayEntryByValue($inputArray, $compareValue);
1474 $this->assertEquals($expectedResult, $actualResult);
1475 }
1476
1477 /**
1478 * @test
1479 */
1480 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
1481 $inputArray = array(
1482 '0' => 'foo',
1483 '1' => array(
1484 '10' => 'bar'
1485 ),
1486 '2' => 'bar'
1487 );
1488 $compareValue = 'bar';
1489 $expectedResult = array(
1490 '0' => 'foo',
1491 '1' => array()
1492 );
1493 $actualResult = \TYPO3\CMS\Core\Utility\GeneralUtility::removeArrayEntryByValue($inputArray, $compareValue);
1494 $this->assertEquals($expectedResult, $actualResult);
1495 }
1496
1497 /**
1498 * @test
1499 */
1500 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
1501 $inputArray = array(
1502 '0' => 'foo',
1503 '1' => '',
1504 '2' => 'bar'
1505 );
1506 $compareValue = '';
1507 $expectedResult = array(
1508 '0' => 'foo',
1509 '2' => 'bar'
1510 );
1511 $actualResult = \TYPO3\CMS\Core\Utility\GeneralUtility::removeArrayEntryByValue($inputArray, $compareValue);
1512 $this->assertEquals($expectedResult, $actualResult);
1513 }
1514
1515 //////////////////////////////////
1516 // Tests concerning getBytesFromSizeMeasurement
1517 //////////////////////////////////
1518 /**
1519 * Data provider for getBytesFromSizeMeasurement
1520 *
1521 * @return array expected value, input string
1522 */
1523 public function getBytesFromSizeMeasurementDataProvider() {
1524 return array(
1525 '100 kilo Bytes' => array('102400', '100k'),
1526 '100 mega Bytes' => array('104857600', '100m'),
1527 '100 giga Bytes' => array('107374182400', '100g')
1528 );
1529 }
1530
1531 /**
1532 * @test
1533 * @dataProvider getBytesFromSizeMeasurementDataProvider
1534 */
1535 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
1536 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::getBytesFromSizeMeasurement($byteString));
1537 }
1538
1539 //////////////////////////////////
1540 // Tests concerning getIndpEnv
1541 //////////////////////////////////
1542 /**
1543 * @test
1544 */
1545 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
1546 $this->assertTrue(strlen(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
1547 }
1548
1549 /**
1550 * @test
1551 */
1552 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
1553 $result = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
1554 $this->assertEquals('/', $result[0]);
1555 }
1556
1557 /**
1558 * @test
1559 */
1560 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
1561 $result = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
1562 $this->assertEquals('/', $result[strlen($result) - 1]);
1563 }
1564
1565 /**
1566 * @return array
1567 */
1568 static public function hostnameAndPortDataProvider() {
1569 return array(
1570 'localhost ipv4 without port' => array('127.0.0.1', '127.0.0.1', ''),
1571 'localhost ipv4 with port' => array('127.0.0.1:81', '127.0.0.1', '81'),
1572 'localhost ipv6 without port' => array('[::1]', '[::1]', ''),
1573 'localhost ipv6 with port' => array('[::1]:81', '[::1]', '81'),
1574 'ipv6 without port' => array('[2001:DB8::1]', '[2001:DB8::1]', ''),
1575 'ipv6 with port' => array('[2001:DB8::1]:81', '[2001:DB8::1]', '81'),
1576 'hostname without port' => array('lolli.did.this', 'lolli.did.this', ''),
1577 'hostname with port' => array('lolli.did.this:42', 'lolli.did.this', '42')
1578 );
1579 }
1580
1581 /**
1582 * @test
1583 * @dataProvider hostnameAndPortDataProvider
1584 */
1585 public function getIndpEnvTypo3HostOnlyParsesHostnamesAndIpAdresses($httpHost, $expectedIp) {
1586 $_SERVER['HTTP_HOST'] = $httpHost;
1587 $this->assertEquals($expectedIp, \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY'));
1588 }
1589
1590 /**
1591 * @test
1592 * @dataProvider hostnameAndPortDataProvider
1593 */
1594 public function getIndpEnvTypo3PortParsesHostnamesAndIpAdresses($httpHost, $dummy, $expectedPort) {
1595 $_SERVER['HTTP_HOST'] = $httpHost;
1596 $this->assertEquals($expectedPort, \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_PORT'));
1597 }
1598
1599 //////////////////////////////////
1600 // Tests concerning underscoredToUpperCamelCase
1601 //////////////////////////////////
1602 /**
1603 * Data provider for underscoredToUpperCamelCase
1604 *
1605 * @return array expected, input string
1606 */
1607 public function underscoredToUpperCamelCaseDataProvider() {
1608 return array(
1609 'single word' => array('Blogexample', 'blogexample'),
1610 'multiple words' => array('BlogExample', 'blog_example')
1611 );
1612 }
1613
1614 /**
1615 * @test
1616 * @dataProvider underscoredToUpperCamelCaseDataProvider
1617 */
1618 public function underscoredToUpperCamelCase($expected, $inputString) {
1619 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToUpperCamelCase($inputString));
1620 }
1621
1622 //////////////////////////////////
1623 // Tests concerning underscoredToLowerCamelCase
1624 //////////////////////////////////
1625 /**
1626 * Data provider for underscoredToLowerCamelCase
1627 *
1628 * @return array expected, input string
1629 */
1630 public function underscoredToLowerCamelCaseDataProvider() {
1631 return array(
1632 'single word' => array('minimalvalue', 'minimalvalue'),
1633 'multiple words' => array('minimalValue', 'minimal_value')
1634 );
1635 }
1636
1637 /**
1638 * @test
1639 * @dataProvider underscoredToLowerCamelCaseDataProvider
1640 */
1641 public function underscoredToLowerCamelCase($expected, $inputString) {
1642 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::underscoredToLowerCamelCase($inputString));
1643 }
1644
1645 //////////////////////////////////
1646 // Tests concerning camelCaseToLowerCaseUnderscored
1647 //////////////////////////////////
1648 /**
1649 * Data provider for camelCaseToLowerCaseUnderscored
1650 *
1651 * @return array expected, input string
1652 */
1653 public function camelCaseToLowerCaseUnderscoredDataProvider() {
1654 return array(
1655 'single word' => array('blogexample', 'blogexample'),
1656 'single word starting upper case' => array('blogexample', 'Blogexample'),
1657 'two words starting lower case' => array('minimal_value', 'minimalValue'),
1658 'two words starting upper case' => array('blog_example', 'BlogExample')
1659 );
1660 }
1661
1662 /**
1663 * @test
1664 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
1665 */
1666 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
1667 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::camelCaseToLowerCaseUnderscored($inputString));
1668 }
1669
1670 //////////////////////////////////
1671 // Tests concerning lcFirst
1672 //////////////////////////////////
1673 /**
1674 * Data provider for lcFirst
1675 *
1676 * @return array expected, input string
1677 */
1678 public function lcfirstDataProvider() {
1679 return array(
1680 'single word' => array('blogexample', 'blogexample'),
1681 'single Word starting upper case' => array('blogexample', 'Blogexample'),
1682 'two words' => array('blogExample', 'BlogExample')
1683 );
1684 }
1685
1686 /**
1687 * @test
1688 * @dataProvider lcfirstDataProvider
1689 */
1690 public function lcFirst($expected, $inputString) {
1691 $this->assertEquals($expected, \TYPO3\CMS\Core\Utility\GeneralUtility::lcfirst($inputString));
1692 }
1693
1694 //////////////////////////////////
1695 // Tests concerning encodeHeader
1696 //////////////////////////////////
1697 /**
1698 * @test
1699 */
1700 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
1701 $this->assertEquals('=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=', \TYPO3\CMS\Core\Utility\GeneralUtility::encodeHeader('We test whether the copyright character © is encoded correctly', 'quoted-printable', 'utf-8'));
1702 }
1703
1704 /**
1705 * @test
1706 */
1707 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
1708 $this->assertEquals('=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=', \TYPO3\CMS\Core\Utility\GeneralUtility::encodeHeader('Is the copyright character © really encoded correctly? Really?', 'quoted-printable', 'utf-8'));
1709 }
1710
1711 //////////////////////////////////
1712 // Tests concerning isValidUrl
1713 //////////////////////////////////
1714 /**
1715 * Data provider for valid isValidUrl's
1716 *
1717 * @return array Valid ressource
1718 */
1719 public function validUrlValidRessourceDataProvider() {
1720 return array(
1721 'http' => array('http://www.example.org/'),
1722 'http without trailing slash' => array('http://qwe'),
1723 'http directory with trailing slash' => array('http://www.example/img/dir/'),
1724 'http directory without trailing slash' => array('http://www.example/img/dir'),
1725 'http index.html' => array('http://example.com/index.html'),
1726 'http index.php' => array('http://www.example.com/index.php'),
1727 'http test.png' => array('http://www.example/img/test.png'),
1728 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
1729 'file' => array('file:///tmp/test.c'),
1730 'file directory' => array('file://foo/bar'),
1731 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
1732 'mailto' => array('mailto:foo@bar.com'),
1733 'news' => array('news:news.php.net'),
1734 'telnet' => array('telnet://192.0.2.16:80/'),
1735 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
1736 'http punycode domain name' => array('http://www.xn--bb-eka.at'),
1737 'http punicode subdomain' => array('http://xn--h-zfa.oebb.at'),
1738 'http domain-name umlauts' => array('http://www.öbb.at'),
1739 'http subdomain umlauts' => array('http://äh.oebb.at'),
1740 'http directory umlauts' => array('http://www.oebb.at/äöü/')
1741 );
1742 }
1743
1744 /**
1745 * @test
1746 * @dataProvider validUrlValidRessourceDataProvider
1747 */
1748 public function validURLReturnsTrueForValidRessource($url) {
1749 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($url));
1750 }
1751
1752 /**
1753 * Data provider for invalid isValidUrl's
1754 *
1755 * @return array Invalid ressource
1756 */
1757 public function isValidUrlInvalidRessourceDataProvider() {
1758 return array(
1759 'http missing colon' => array('http//www.example/wrong/url/'),
1760 'http missing slash' => array('http:/www.example'),
1761 'hostname only' => array('www.example.org/'),
1762 'file missing protocol specification' => array('/tmp/test.c'),
1763 'slash only' => array('/'),
1764 'string http://' => array('http://'),
1765 'string http:/' => array('http:/'),
1766 'string http:' => array('http:'),
1767 'string http' => array('http'),
1768 'empty string' => array(''),
1769 'string -1' => array('-1'),
1770 'string array()' => array('array()'),
1771 'random string' => array('qwe')
1772 );
1773 }
1774
1775 /**
1776 * @test
1777 * @dataProvider isValidUrlInvalidRessourceDataProvider
1778 */
1779 public function validURLReturnsFalseForInvalidRessoure($url) {
1780 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::isValidUrl($url));
1781 }
1782
1783 //////////////////////////////////
1784 // Tests concerning isOnCurrentHost
1785 //////////////////////////////////
1786 /**
1787 * @test
1788 */
1789 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
1790 $testUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
1791 $this->assertTrue(\TYPO3\CMS\Core\Utility\GeneralUtility::isOnCurrentHost($testUrl));
1792 }
1793
1794 /**
1795 * Data provider for invalid isOnCurrentHost's
1796 *
1797 * @return array Invalid Hosts
1798 */
1799 public function checkisOnCurrentHostInvalidHosts() {
1800 return array(
1801 'empty string' => array(''),
1802 'arbitrary string' => array('arbitrary string'),
1803 'localhost IP' => array('127.0.0.1'),
1804 'relative path' => array('./relpath/file.txt'),
1805 'absolute path' => array('/abspath/file.txt?arg=value'),
1806 'differnt host' => array(\TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org')
1807 );
1808 }
1809
1810 ////////////////////////////////////////
1811 // Tests concerning sanitizeLocalUrl
1812 ////////////////////////////////////////
1813 /**
1814 * Data provider for valid sanitizeLocalUrl's
1815 *
1816 * @return array Valid url
1817 */
1818 public function sanitizeLocalUrlValidUrlDataProvider() {
1819 $subDirectory = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
1820 $typo3SiteUrl = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_SITE_URL');
1821 $typo3RequestHost = \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('TYPO3_REQUEST_HOST');
1822 return array(
1823 'alt_intro.php' => array('alt_intro.php'),
1824 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
1825 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
1826 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
1827 '../index.php' => array('../index.php'),
1828 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
1829 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
1830 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
1831 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
1832 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
1833 ($typo3RequestHost . $subDirectory) . '/index.php' => array(($typo3RequestHost . $subDirectory) . '/index.php')
1834 );
1835 }
1836
1837 /**
1838 * @test
1839 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1840 */
1841 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
1842 $this->assertEquals($url, \TYPO3\CMS\Core\Utility\GeneralUtility::sanitizeLocalUrl($url));
1843 }
1844
1845 /**
1846 * @test
1847 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1848 */
1849 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
1850 $this->assertEquals(rawurlencode($url), \TYPO3\CMS\Core\Utility\GeneralUtility::sanitizeLocalUrl(rawurlencode($url)));
1851 }
1852
1853 /**
1854 * Data provider for invalid sanitizeLocalUrl's
1855 *
1856 * @return array Valid url
1857 */
1858 public function sanitizeLocalUrlInvalidDataProvider() {
1859 return array(
1860 'empty string' => array(''),
1861 'http domain' => array('http://www.google.de/'),
1862 'https domain' => array('https://www.google.de/'),
1863 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)')
1864 );
1865 }
1866
1867 /**
1868 * @test
1869 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1870 */
1871 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
1872 $this->assertEquals('', \TYPO3\CMS\Core\Utility\GeneralUtility::sanitizeLocalUrl($url));
1873 }
1874
1875 /**
1876 * @test
1877 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1878 */
1879 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
1880 $this->assertEquals('', \TYPO3\CMS\Core\Utility\GeneralUtility::sanitizeLocalUrl(rawurlencode($url)));
1881 }
1882
1883 //////////////////////////////////////
1884 // Tests concerning addSlashesOnArray
1885 //////////////////////////////////////
1886 /**
1887 * @test
1888 */
1889 public function addSlashesOnArrayAddsSlashesRecursive() {
1890 $inputArray = array(
1891 'key1' => array(
1892 'key11' => 'val\'ue1',
1893 'key12' => 'val"ue2'
1894 ),
1895 'key2' => 'val\\ue3'
1896 );
1897 $expectedResult = array(
1898 'key1' => array(
1899 'key11' => 'val\\\'ue1',
1900 'key12' => 'val\\"ue2'
1901 ),
1902 'key2' => 'val\\\\ue3'
1903 );
1904 \TYPO3\CMS\Core\Utility\GeneralUtility::addSlashesOnArray($inputArray);
1905 $this->assertEquals($expectedResult, $inputArray);
1906 }
1907
1908 //////////////////////////////////////
1909 // Tests concerning addSlashesOnArray
1910 //////////////////////////////////////
1911 /**
1912 * @test
1913 */
1914 public function stripSlashesOnArrayStripsSlashesRecursive() {
1915 $inputArray = array(
1916 'key1' => array(
1917 'key11' => 'val\\\'ue1',
1918 'key12' => 'val\\"ue2'
1919 ),
1920 'key2' => 'val\\\\ue3'
1921 );
1922 $expectedResult = array(
1923 'key1' => array(
1924 'key11' => 'val\'ue1',
1925 'key12' => 'val"ue2'
1926 ),
1927 'key2' => 'val\\ue3'
1928 );
1929 \TYPO3\CMS\Core\Utility\GeneralUtility::stripSlashesOnArray($inputArray);
1930 $this->assertEquals($expectedResult, $inputArray);
1931 }
1932
1933 //////////////////////////////////////
1934 // Tests concerning arrayDiffAssocRecursive
1935 //////////////////////////////////////
1936 /**
1937 * @test
1938 */
1939 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
1940 $array1 = array(
1941 'key1' => 'value1',
1942 'key2' => 'value2',
1943 'key3' => 'value3'
1944 );
1945 $array2 = array(
1946 'key1' => 'value1',
1947 'key3' => 'value3'
1948 );
1949 $expectedResult = array(
1950 'key2' => 'value2'
1951 );
1952 $actualResult = \TYPO3\CMS\Core\Utility\GeneralUtility::arrayDiffAssocRecursive($array1, $array2);
1953 $this->assertEquals($expectedResult, $actualResult);
1954 }
1955
1956 /**
1957 * @test
1958 */
1959 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
1960 $array1 = array(
1961 'key1' => 'value1',
1962 'key2' => array(
1963 'key21' => 'value21',
1964 'key22' => 'value22',
1965 'key23' => array(
1966 'key231' => 'value231',
1967 'key232' => 'value232'
1968 )
1969 )
1970 );
1971 $array2 = array(
1972 'key1' => 'value1',
1973 'key2' => array(
1974 'key21' => 'value21',
1975 'key23' => array(
1976 'key231' => 'value231'
1977 )
1978 )
1979 );
1980 $expectedResult = array(
1981 'key2' => array(
1982 'key22' => 'value22',
1983 'key23' => array(
1984 'key232' => 'value232'
1985 )
1986 )
1987 );
1988 $actualResult = \TYPO3\CMS\Core\Utility\GeneralUtility::arrayDiffAssocRecursive($array1, $array2);
1989 $this->assertEquals($expectedResult, $actualResult);
1990 }
1991
1992 /**
1993 * @test
1994 */
1995 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1996 $array1 = array(
1997 'key1' => array(
1998 'key11' => 'value11',
1999 'key12' => 'value12'
2000 ),
2001 'key2' => 'value2',
2002 'key3' => 'value3'
2003 );
2004 $array2 = array(
2005 'key1' => 'value1',
2006 'key2' => array(
2007 'key21' => 'value21'
2008 )
2009 );
2010 $expectedResult = array(
2011 'key3' => 'value3'
2012 );
2013 $actualResult = \TYPO3\CMS\Core\Utility\GeneralUtility::arrayDiffAssocRecursive($array1, $array2);
2014 $this->assertEquals($expectedResult, $actualResult);
2015 }
2016
2017 //////////////////////////////////////
2018 // Tests concerning removeDotsFromTS
2019 //////////////////////////////////////
2020 /**
2021 * @test
2022 */
2023 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
2024 $typoScript = array(
2025 'propertyA.' => array(
2026 'keyA.' => array(
2027 'valueA' => 1
2028 ),
2029 'keyB' => 2
2030 ),
2031 'propertyB' => 3
2032 );
2033 $expectedResult = array(
2034 'propertyA' => array(
2035 'keyA' => array(
2036 'valueA' => 1
2037 ),
2038 'keyB' => 2
2039 ),
2040 'propertyB' => 3
2041 );
2042 $this->assertEquals($expectedResult, \TYPO3\CMS\Core\Utility\GeneralUtility::removeDotsFromTS($typoScript));
2043 }
2044
2045 /**
2046 * @test
2047 */
2048 public function removeDotsFromTypoScriptOverridesSubArray() {
2049 $typoScript = array(
2050 'propertyA.' => array(
2051 'keyA' => 'getsOverridden',
2052 'keyA.' => array(
2053 'valueA' => 1
2054 ),
2055 'keyB' => 2
2056 ),
2057 'propertyB' => 3
2058 );
2059 $expectedResult = array(
2060 'propertyA' => array(
2061 'keyA' => array(
2062 'valueA' => 1
2063 ),
2064 'keyB' => 2
2065 ),
2066 'propertyB' => 3
2067 );
2068 $this->assertEquals($expectedResult, \TYPO3\CMS\Core\Utility\GeneralUtility::removeDotsFromTS($typoScript));
2069 }
2070
2071 /**
2072 * @test
2073 */
2074 public function removeDotsFromTypoScriptOverridesWithScalar() {
2075 $typoScript = array(
2076 'propertyA.' => array(
2077 'keyA.' => array(
2078 'valueA' => 1
2079 ),
2080 'keyA' => 'willOverride',
2081 'keyB' => 2
2082 ),
2083 'propertyB' => 3
2084 );
2085 $expectedResult = array(
2086 'propertyA' => array(
2087 'keyA' => 'willOverride',
2088 'keyB' => 2
2089 ),
2090 'propertyB' => 3
2091 );
2092 $this->assertEquals($expectedResult, \TYPO3\CMS\Core\Utility\GeneralUtility::removeDotsFromTS($typoScript));
2093 }
2094
2095 //////////////////////////////////////
2096 // Tests concerning naturalKeySortRecursive
2097 //////////////////////////////////////
2098 /**
2099 * @test
2100 */
2101 public function naturalKeySortRecursiveReturnsFalseIfInputIsNotAnArray() {
2102 $testValues = array(
2103 1,
2104 'string',
2105 FALSE
2106 );
2107 foreach ($testValues as $testValue) {
2108 $this->assertFalse(\TYPO3\CMS\Core\Utility\GeneralUtility::naturalKeySortRecursive($testValue));
2109 }
2110 }
2111
2112 /**
2113 * @test
2114 */
2115 public function naturalKeySortRecursiveSortsOneDimensionalArrayByNaturalOrder() {
2116 $testArray = array(
2117 'bb' => 'bb',
2118 'ab' => 'ab',
2119 '123' => '123',
2120 'aaa' => 'aaa',
2121 'abc' => 'abc',
2122 '23' => '23',
2123 'ba' => 'ba',
2124 'bad' => 'bad',
2125 '2' => '2',
2126 'zap' => 'zap',
2127 '210' => '210'
2128 );
2129 $expectedResult = array(
2130 '2',
2131 '23',
2132 '123',
2133 '210',
2134 'aaa',
2135 'ab',
2136 'abc',
2137 'ba',
2138 'bad',
2139 'bb',
2140 'zap'
2141 );
2142 \TYPO3\CMS\Core\Utility\GeneralUtility::naturalKeySortRecursive($testArray);
2143 $this->assertEquals($expectedResult, array_values($testArray));
2144 }
2145
2146 /**
2147 * @test
2148 */
2149 public function naturalKeySortRecursiveSortsMultiDimensionalArrayByNaturalOrder() {
2150 $testArray = array(
2151 '2' => '2',
2152 'bb' => 'bb',
2153 'ab' => 'ab',
2154 '23' => '23',
2155 'aaa' => array(
2156 'bb' => 'bb',
2157 'ab' => 'ab',
2158 '123' => '123',
2159 'aaa' => 'aaa',
2160 '2' => '2',
2161 'abc' => 'abc',
2162 'ba' => 'ba',
2163 '23' => '23',
2164 'bad' => array(
2165 'bb' => 'bb',
2166 'ab' => 'ab',
2167 '123' => '123',
2168 'aaa' => 'aaa',
2169 'abc' => 'abc',
2170 '23' => '23',
2171 'ba' => 'ba',
2172 'bad' => 'bad',
2173 '2' => '2',
2174 'zap' => 'zap',
2175 '210' => '210'
2176 ),
2177 '210' => '210',
2178 'zap' => 'zap'
2179 ),
2180 'abc' => 'abc',
2181 'ba' => 'ba',
2182 '210' => '210',
2183 'bad' => 'bad',
2184 '123' => '123',
2185 'zap' => 'zap'
2186 );
2187 $expectedResult = array(
2188 '2',
2189 '23',
2190 '123',
2191 '210',
2192 'aaa',
2193 'ab',
2194 'abc',
2195 'ba',
2196 'bad',
2197 'bb',
2198 'zap'
2199 );
2200 \TYPO3\CMS\Core\Utility\GeneralUtility::naturalKeySortRecursive($testArray);
2201 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa']['bad'])));
2202 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa'])));
2203 $this->assertEquals($expectedResult, array_values(array_keys($testArray)));
2204 }
2205
2206 //////////////////////////////////////
2207 // Tests concerning get_dirs
2208 //////////////////////////////////////
2209 /**
2210 * @test
2211 */
2212 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
2213 $path = PATH_t3lib;
2214 $directories = \TYPO3\CMS\Core\Utility\GeneralUtility::get_dirs($path);
2215 $this->assertInternalType(\PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $directories);
2216 }
2217
2218 /**
2219 * @test
2220 */
2221 public function getDirsReturnsStringErrorOnPathFailure() {
2222 $path = 'foo';
2223 $result = \TYPO3\CMS\Core\Utility\GeneralUtility::get_dirs($path);
2224 $expectedResult = 'error';
2225 $this->assertEquals($expectedResult, $result);
2226 }
2227
2228 //////////////////////////////////
2229 // Tests concerning hmac
2230 //////////////////////////////////
2231 /**
2232 * @test
2233 */
2234 public function hmacReturnsHashOfProperLength() {
2235 $hmac = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac('message');
2236 $this->assertTrue(!empty($hmac) && is_string($hmac));
2237 $this->assertTrue(strlen($hmac) == 40);
2238 }
2239
2240 /**
2241 * @test
2242 */
2243 public function hmacReturnsEqualHashesForEqualInput() {
2244 $msg0 = 'message';
2245 $msg1 = 'message';
2246 $this->assertEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::hmac($msg0), \TYPO3\CMS\Core\Utility\GeneralUtility::hmac($msg1));
2247 }
2248
2249 /**
2250 * @test
2251 */
2252 public function hmacReturnsNoEqualHashesForNonEqualInput() {
2253 $msg0 = 'message0';
2254 $msg1 = 'message1';
2255 $this->assertNotEquals(\TYPO3\CMS\Core\Utility\GeneralUtility::hmac($msg0), \TYPO3\CMS\Core\Utility\GeneralUtility::hmac($msg1));
2256 }
2257
2258 //////////////////////////////////
2259 // Tests concerning quoteJSvalue
2260 //////////////////////////////////
2261 /**
2262 * Data provider for quoteJSvalueTest.
2263 *
2264 * @return array
2265 */
2266 public function quoteJsValueDataProvider() {
2267 return array(
2268 'Immune characters are returned as is' => array(
2269 '._,',
2270 '._,'
2271 ),
2272 'Alphanumerical characters are returned as is' => array(
2273 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
2274 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
2275 ),
2276 'Angel brackets and ampersand are encoded' => array(
2277 '<>&',
2278 '\\x3C\\x3E\\x26'
2279 ),
2280 'Quotes and slashes are encoded' => array(
2281 '"\'\\/',
2282 '\\x22\\x27\\x5C\\x2F'
2283 ),
2284 'Empty string stays empty' => array(
2285 '',
2286 ''
2287 ),
2288 'Exclamation mark and space are properly encoded' => array(
2289 'Hello World!',
2290 'Hello\\x20World\\x21'
2291 ),
2292 'Whitespaces are properly encoded' => array(
2293 ((TAB . LF) . CR) . ' ',
2294 '\\x09\\x0A\\x0D\\x20'
2295 ),
2296 'Null byte is properly encoded' => array(
2297 chr(0),
2298 '\\x00'
2299 ),
2300 'Umlauts are properly encoded' => array(
2301 'ÜüÖöÄä',
2302 '\\xDC\\xFC\\xD6\\xF6\\xC4\\xE4'
2303 )
2304 );
2305 }
2306
2307 /**
2308 * @test
2309 * @param string $input
2310 * @param string $expected
2311 * @dataProvider quoteJsValueDataProvider
2312 */
2313 public function quoteJsValueTest($input, $expected) {
2314 $this->assertSame(('\'' . $expected) . '\'', \TYPO3\CMS\Core\Utility\GeneralUtility::quoteJSvalue($input));
2315 }
2316
2317 //////////////////////////////////
2318 // Tests concerning readLLfile
2319 //////////////////////////////////
2320 /**
2321 * @test
2322 */
2323 public function readLLfileHandlesLocallangXMLOverride() {
2324 $unique = uniqid('locallangXMLOverrideTest');
2325 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2326 <T3locallang>
2327 <data type="array">
2328 <languageKey index="default" type="array">
2329 <label index="buttons.logout">EXIT</label>
2330 </languageKey>
2331 </data>
2332 </T3locallang>';
2333 $file = ((PATH_site . 'typo3temp/') . $unique) . '.xml';
2334 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($file, $xml);
2335 // Make sure there is no cached version of the label
2336 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2337 // Get default value
2338 $defaultLL = \TYPO3\CMS\Core\Utility\GeneralUtility::readLLfile('EXT:lang/locallang_core.xml', 'default');
2339 // Clear language cache again
2340 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2341 // Set override file
2342 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
2343 /** @var $store \TYPO3\CMS\Core\Localization\LanguageStore */
2344 $store = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Localization\\LanguageStore');
2345 $store->flushData('EXT:lang/locallang_core.xml');
2346 // Get override value
2347 $overrideLL = \TYPO3\CMS\Core\Utility\GeneralUtility::readLLfile('EXT:lang/locallang_core.xml', 'default');
2348 // Clean up again
2349 unlink($file);
2350 $this->assertNotEquals($overrideLL['default']['buttons.logout'][0]['target'], '');
2351 $this->assertNotEquals($defaultLL['default']['buttons.logout'][0]['target'], $overrideLL['default']['buttons.logout'][0]['target']);
2352 $this->assertEquals($overrideLL['default']['buttons.logout'][0]['target'], 'EXIT');
2353 }
2354
2355 ///////////////////////////////
2356 // Tests concerning _GETset()
2357 ///////////////////////////////
2358 /**
2359 * @test
2360 */
2361 public function getSetWritesArrayToGetSystemVariable() {
2362 $_GET = array();
2363 $GLOBALS['HTTP_GET_VARS'] = array();
2364 $getParameters = array('foo' => 'bar');
2365 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset($getParameters);
2366 $this->assertSame($getParameters, $_GET);
2367 }
2368
2369 /**
2370 * @test
2371 */
2372 public function getSetWritesArrayToGlobalsHttpGetVars() {
2373 $_GET = array();
2374 $GLOBALS['HTTP_GET_VARS'] = array();
2375 $getParameters = array('foo' => 'bar');
2376 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset($getParameters);
2377 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
2378 }
2379
2380 /**
2381 * @test
2382 */
2383 public function getSetForArrayDropsExistingValues() {
2384 $_GET = array();
2385 $GLOBALS['HTTP_GET_VARS'] = array();
2386 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset(array('foo' => 'bar'));
2387 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset(array('oneKey' => 'oneValue'));
2388 $this->assertEquals(array('oneKey' => 'oneValue'), $GLOBALS['HTTP_GET_VARS']);
2389 }
2390
2391 /**
2392 * @test
2393 */
2394 public function getSetAssignsOneValueToOneKey() {
2395 $_GET = array();
2396 $GLOBALS['HTTP_GET_VARS'] = array();
2397 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset('oneValue', 'oneKey');
2398 $this->assertEquals('oneValue', $GLOBALS['HTTP_GET_VARS']['oneKey']);
2399 }
2400
2401 /**
2402 * @test
2403 */
2404 public function getSetForOneValueDoesNotDropUnrelatedValues() {
2405 $_GET = array();
2406 $GLOBALS['HTTP_GET_VARS'] = array();
2407 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset(array('foo' => 'bar'));
2408 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset('oneValue', 'oneKey');
2409 $this->assertEquals(array('foo' => 'bar', 'oneKey' => 'oneValue'), $GLOBALS['HTTP_GET_VARS']);
2410 }
2411
2412 /**
2413 * @test
2414 */
2415 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
2416 $_GET = array();
2417 $GLOBALS['HTTP_GET_VARS'] = array();
2418 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset(array('childKey' => 'oneValue'), 'parentKey');
2419 $this->assertEquals(array('parentKey' => array('childKey' => 'oneValue')), $GLOBALS['HTTP_GET_VARS']);
2420 }
2421
2422 /**
2423 * @test
2424 */
2425 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
2426 $_GET = array();
2427 $GLOBALS['HTTP_GET_VARS'] = array();
2428 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset('oneValue', 'parentKey|childKey');
2429 $this->assertEquals(array('parentKey' => array('childKey' => 'oneValue')), $GLOBALS['HTTP_GET_VARS']);
2430 }
2431
2432 /**
2433 * @test
2434 */
2435 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
2436 $_GET = array();
2437 $GLOBALS['HTTP_GET_VARS'] = array();
2438 \TYPO3\CMS\Core\Utility\GeneralUtility::_GETset(array('key1' => 'value1', 'key2' => 'value2'), 'parentKey|childKey');
2439 $this->assertEquals(array(
2440 'parentKey' => array(
2441 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
2442 )
2443 ), $GLOBALS['HTTP_GET_VARS']);
2444 }
2445
2446 ///////////////////////////
2447 // Tests concerning minifyJavaScript
2448 ///////////////////////////
2449 /**
2450 * @test
2451 */
2452 public function minifyJavaScriptReturnsInputStringIfNoHookIsRegistered() {
2453 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['minifyJavaScript']);
2454 $testString = uniqid('string');
2455 $this->assertSame($testString, \TYPO3\CMS\Core\Utility\GeneralUtility::minifyJavaScript($testString));
2456 }
2457
2458 /**
2459 * Create an own hook callback class, register as hook, and check
2460 * if given string to compress is given to hook method
2461 *
2462 * @test
2463 */
2464 public function minifyJavaScriptCallsRegisteredHookWithInputString() {
2465 $hookClassName = uniqid('tx_coretest');
2466 $minifyHookMock = $this->getMock('stdClass', array('minify'), array(), $hookClassName);
2467 $functionName = ('&' . $hookClassName) . '->minify';
2468 $GLOBALS['T3_VAR']['callUserFunction'][$functionName] = array();
2469 $GLOBALS['T3_VAR']['callUserFunction'][$functionName]['obj'] = $minifyHookMock;
2470 $GLOBALS['T3_VAR']['callUserFunction'][$functionName]['method'] = 'minify';
2471 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['minifyJavaScript'][] = $functionName;
2472 $minifyHookMock->expects($this->once())->method('minify')->will($this->returnCallback(array($this, 'isMinifyJavaScriptHookCalledCallback')));
2473 \TYPO3\CMS\Core\Utility\GeneralUtility::minifyJavaScript('foo');
2474 }
2475
2476 /**
2477 * Callback function used in minifyJavaScriptCallsRegisteredHookWithInputString test
2478 *
2479 * @param array $params
2480 */
2481 public function isMinifyJavaScriptHookCalledCallback(array $params) {
2482 // We can not throw an exception here, because that would be caught by the
2483 // minifyJavaScript method under test itself. Thus, we just die if the
2484 // input string is not ok.
2485 if ($params['script'] !== 'foo') {
2486 die('broken');
2487 }
2488 }
2489
2490 /**
2491 * Create a hook callback, use callback to throw an exception and check
2492 * if the exception is given as error parameter to the calling method.
2493 *
2494 * @test
2495 */
2496 public function minifyJavaScriptReturnsErrorStringOfHookException() {
2497 $hookClassName = uniqid('tx_coretest');
2498 $minifyHookMock = $this->getMock('stdClass', array('minify'), array(), $hookClassName);
2499 $functionName = ('&' . $hookClassName) . '->minify';
2500 $GLOBALS['T3_VAR']['callUserFunction'][$functionName] = array();
2501 $GLOBALS['T3_VAR']['callUserFunction'][$functionName]['obj'] = $minifyHookMock;
2502 $GLOBALS['T3_VAR']['callUserFunction'][$functionName]['method'] = 'minify';
2503 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['minifyJavaScript'][] = $functionName;
2504 $minifyHookMock->expects($this->any())->method('minify')->will($this->returnCallback(array($this, 'minifyJavaScriptErroneousCallback')));
2505 $error = '';
2506 \TYPO3\CMS\Core\Utility\GeneralUtility::minifyJavaScript('string to compress', $error);
2507 $this->assertSame('Error minifying java script: foo', $error);
2508 }
2509
2510 /**
2511 * Check if the error message that is returned by the hook callback
2512 * is logged to t3lib_div::devLog.
2513 *
2514 * @test
2515 */
2516 public function minifyJavaScriptWritesExceptionMessageToDevLog() {
2517 $namespace = 'TYPO3\\CMS\\Core\\Utility';
2518 $t3libDivMock = uniqid('GeneralUtility');
2519 eval((((((((('namespace ' . $namespace . '; class ' . $t3libDivMock) . ' extends \\TYPO3\\CMS\\Core\\Utility\\GeneralUtility {') . ' public static function devLog($errorMessage) {') . ' if (!($errorMessage === \'Error minifying java script: foo\')) {') . ' throw new \\UnexpectedValue(\'broken\');') . ' }') . ' throw new \\RuntimeException();') . ' }') . '}');
2520 $t3libDivMock = $namespace . '\\' . $t3libDivMock;
2521 $hookClassName = uniqid('tx_coretest');
2522 $minifyHookMock = $this->getMock('stdClass', array('minify'), array(), $hookClassName);
2523 $functionName = ('&' . $hookClassName) . '->minify';
2524 $GLOBALS['T3_VAR']['callUserFunction'][$functionName] = array();
2525 $GLOBALS['T3_VAR']['callUserFunction'][$functionName]['obj'] = $minifyHookMock;
2526 $GLOBALS['T3_VAR']['callUserFunction'][$functionName]['method'] = 'minify';
2527 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['minifyJavaScript'][] = $functionName;
2528 $minifyHookMock->expects($this->any())->method('minify')->will($this->returnCallback(array($this, 'minifyJavaScriptErroneousCallback')));
2529 $this->setExpectedException('\\RuntimeException');
2530 $t3libDivMock::minifyJavaScript('string to compress');
2531 }
2532
2533 /**
2534 * Callback function used in
2535 * minifyJavaScriptReturnsErrorStringOfHookException and
2536 * minifyJavaScriptWritesExceptionMessageToDevLog
2537 *
2538 * @throws \RuntimeException
2539 */
2540 public function minifyJavaScriptErroneousCallback() {
2541 throw new \RuntimeException('foo', 1344888548);
2542 }
2543
2544 ///////////////////////////
2545 // Tests concerning getUrl
2546 ///////////////////////////
2547 /**
2548 * @test
2549 */
2550 public function getUrlWithAdditionalRequestHeadersProvidesHttpHeaderOnError() {
2551 $url = 'http://typo3.org/i-do-not-exist-' . time();
2552 $report = array();
2553 \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($url, 0, array(), $report);
2554 $this->assertContains('404', $report['message']);
2555 }
2556
2557 /**
2558 * @test
2559 */
2560 public function getUrlProvidesWithoutAdditionalRequestHeadersHttpHeaderOnError() {
2561 $url = 'http://typo3.org/i-do-not-exist-' . time();
2562 $report = array();
2563 \TYPO3\CMS\Core\Utility\GeneralUtility::getUrl($url, 0, FALSE, $report);
2564 $this->assertContains('404', $report['message'], 'Did not provide the HTTP response header when requesting a failing URL.');
2565 }
2566
2567 ///////////////////////////////
2568 // Tests concerning fixPermissions
2569 ///////////////////////////////
2570 /**
2571 * @test
2572 */
2573 public function fixPermissionsSetsGroup() {
2574 if (TYPO3_OS == 'WIN') {
2575 $this->markTestSkipped('fixPermissionsSetsGroup() tests not available on Windows');
2576 }
2577 if (!function_exists('posix_getegid')) {
2578 $this->markTestSkipped('Function posix_getegid() not available, fixPermissionsSetsGroup() tests skipped');
2579 }
2580 if (posix_getegid() === -1) {
2581 $this->markTestSkipped('The fixPermissionsSetsGroup() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.');
2582 }
2583 // Create and prepare test file
2584 $filename = (PATH_site . 'typo3temp/') . uniqid('test_');
2585 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
2586 $currentGroupId = posix_getegid();
2587 // Set target group and run method
2588 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $currentGroupId;
2589 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($filename);
2590 clearstatcache();
2591 $resultFileGroup = filegroup($filename);
2592 unlink($filename);
2593 $this->assertEquals($currentGroupId, $resultFileGroup);
2594 }
2595
2596 /**
2597 * @test
2598 */
2599 public function fixPermissionsSetsPermissionsToFile() {
2600 if (TYPO3_OS == 'WIN') {
2601 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2602 }
2603 // Create and prepare test file
2604 $filename = (PATH_site . 'typo3temp/') . uniqid('test_');
2605 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
2606 chmod($filename, 482);
2607 // Set target permissions and run method
2608 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2609 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($filename);
2610 // Get actual permissions and clean up
2611 clearstatcache();
2612 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2613 unlink($filename);
2614 // Test if everything was ok
2615 $this->assertTrue($fixPermissionsResult);
2616 $this->assertEquals($resultFilePermissions, '0660');
2617 }
2618
2619 /**
2620 * @test
2621 */
2622 public function fixPermissionsSetsPermissionsToHiddenFile() {
2623 if (TYPO3_OS == 'WIN') {
2624 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2625 }
2626 // Create and prepare test file
2627 $filename = (PATH_site . 'typo3temp/') . uniqid('.test_');
2628 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($filename, '42');
2629 chmod($filename, 482);
2630 // Set target permissions and run method
2631 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2632 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($filename);
2633 // Get actual permissions and clean up
2634 clearstatcache();
2635 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2636 unlink($filename);
2637 // Test if everything was ok
2638 $this->assertTrue($fixPermissionsResult);
2639 $this->assertEquals($resultFilePermissions, '0660');
2640 }
2641
2642 /**
2643 * @test
2644 */
2645 public function fixPermissionsSetsPermissionsToDirectory() {
2646 if (TYPO3_OS == 'WIN') {
2647 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2648 }
2649 // Create and prepare test directory
2650 $directory = (PATH_site . 'typo3temp/') . uniqid('test_');
2651 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2652 chmod($directory, 1551);
2653 // Set target permissions and run method
2654 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2655 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($directory);
2656 // Get actual permissions and clean up
2657 clearstatcache();
2658 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2659 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($directory);
2660 // Test if everything was ok
2661 $this->assertTrue($fixPermissionsResult);
2662 $this->assertEquals($resultDirectoryPermissions, '0770');
2663 }
2664
2665 /**
2666 * @test
2667 */
2668 public function fixPermissionsSetsPermissionsToDirectoryWithTrailingSlash() {
2669 if (TYPO3_OS == 'WIN') {
2670 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2671 }
2672 // Create and prepare test directory
2673 $directory = (PATH_site . 'typo3temp/') . uniqid('test_');
2674 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2675 chmod($directory, 1551);
2676 // Set target permissions and run method
2677 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2678 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($directory . '/');
2679 // Get actual permissions and clean up
2680 clearstatcache();
2681 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2682 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($directory);
2683 // Test if everything was ok
2684 $this->assertTrue($fixPermissionsResult);
2685 $this->assertEquals($resultDirectoryPermissions, '0770');
2686 }
2687
2688 /**
2689 * @test
2690 */
2691 public function fixPermissionsSetsPermissionsToHiddenDirectory() {
2692 if (TYPO3_OS == 'WIN') {
2693 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2694 }
2695 // Create and prepare test directory
2696 $directory = (PATH_site . 'typo3temp/') . uniqid('.test_');
2697 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2698 chmod($directory, 1551);
2699 // Set target permissions and run method
2700 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2701 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($directory);
2702 // Get actual permissions and clean up
2703 clearstatcache();
2704 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2705 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($directory);
2706 // Test if everything was ok
2707 $this->assertTrue($fixPermissionsResult);
2708 $this->assertEquals($resultDirectoryPermissions, '0770');
2709 }
2710
2711 /**
2712 * @test
2713 */
2714 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
2715 if (TYPO3_OS == 'WIN') {
2716 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2717 }
2718 // Create and prepare test directory and file structure
2719 $baseDirectory = (PATH_site . 'typo3temp/') . uniqid('test_');
2720 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($baseDirectory);
2721 chmod($baseDirectory, 1751);
2722 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
2723 chmod($baseDirectory . '/file', 482);
2724 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($baseDirectory . '/foo');
2725 chmod($baseDirectory . '/foo', 1751);
2726 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
2727 chmod($baseDirectory . '/foo/file', 482);
2728 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($baseDirectory . '/.bar');
2729 chmod($baseDirectory . '/.bar', 1751);
2730 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
2731 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
2732 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
2733 touch($baseDirectory . '/.bar/.file', '42');
2734 chmod($baseDirectory . '/.bar/.file', 482);
2735 touch($baseDirectory . '/.bar/..file2', '42');
2736 chmod($baseDirectory . '/.bar/..file2', 482);
2737 // Set target permissions and run method
2738 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2739 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2740 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($baseDirectory, TRUE);
2741 // Get actual permissions
2742 clearstatcache();
2743 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
2744 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
2745 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
2746 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
2747 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
2748 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
2749 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
2750 // Clean up
2751 unlink($baseDirectory . '/file');
2752 unlink($baseDirectory . '/foo/file');
2753 unlink($baseDirectory . '/.bar/.file');
2754 unlink($baseDirectory . '/.bar/..file2');
2755 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($baseDirectory . '/foo');
2756 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($baseDirectory . '/.bar');
2757 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($baseDirectory);
2758 // Test if everything was ok
2759 $this->assertTrue($fixPermissionsResult);
2760 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
2761 $this->assertEquals($resultBaseFilePermissions, '0660');
2762 $this->assertEquals($resultFooDirectoryPermissions, '0770');
2763 $this->assertEquals($resultFooFilePermissions, '0660');
2764 $this->assertEquals($resultBarDirectoryPermissions, '0770');
2765 $this->assertEquals($resultBarFilePermissions, '0660');
2766 $this->assertEquals($resultBarFile2Permissions, '0660');
2767 }
2768
2769 /**
2770 * @test
2771 */
2772 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
2773 if (TYPO3_OS == 'WIN') {
2774 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2775 }
2776 // Create and prepare test file
2777 $filename = (PATH_site . 'typo3temp/../typo3temp/') . uniqid('test_');
2778 touch($filename);
2779 chmod($filename, 482);
2780 // Set target permissions and run method
2781 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2782 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($filename);
2783 // Get actual permissions and clean up
2784 clearstatcache();
2785 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2786 unlink($filename);
2787 // Test if everything was ok
2788 $this->assertFalse($fixPermissionsResult);
2789 }
2790
2791 /**
2792 * @test
2793 */
2794 public function fixPermissionsSetsPermissionsWithRelativeFileReference() {
2795 if (TYPO3_OS == 'WIN') {
2796 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2797 }
2798 $filename = 'typo3temp/' . uniqid('test_');
2799 \TYPO3\CMS\Core\Utility\GeneralUtility::writeFileToTypo3tempDir(PATH_site . $filename, '42');
2800 chmod(PATH_site . $filename, 482);
2801 // Set target permissions and run method
2802 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2803 $fixPermissionsResult = \TYPO3\CMS\Core\Utility\GeneralUtility::fixPermissions($filename);
2804 // Get actual permissions and clean up
2805 clearstatcache();
2806 $resultFilePermissions = substr(decoct(fileperms(PATH_site . $filename)), 2);
2807 unlink(PATH_site . $filename);
2808 // Test if everything was ok
2809 $this->assertTrue($fixPermissionsResult);
2810 $this->assertEquals($resultFilePermissions, '0660');
2811 }
2812
2813 ///////////////////////////////
2814 // Tests concerning mkdir
2815 ///////////////////////////////
2816 /**
2817 * @test
2818 */
2819 public function mkdirCreatesDirectory() {
2820 $directory = (PATH_site . 'typo3temp/') . uniqid('test_');
2821 $mkdirResult = \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2822 clearstatcache();
2823 $directoryCreated = is_dir($directory);
2824 @rmdir($directory);
2825 $this->assertTrue($mkdirResult);
2826 $this->assertTrue($directoryCreated);
2827 }
2828
2829 /**
2830 * @test
2831 */
2832 public function mkdirCreatesHiddenDirectory() {
2833 $directory = (PATH_site . 'typo3temp/') . uniqid('.test_');
2834 $mkdirResult = \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2835 clearstatcache();
2836 $directoryCreated = is_dir($directory);
2837 @rmdir($directory);
2838 $this->assertTrue($mkdirResult);
2839 $this->assertTrue($directoryCreated);
2840 }
2841
2842 /**
2843 * @test
2844 */
2845 public function mkdirCreatesDirectoryWithTrailingSlash() {
2846 $directory = ((PATH_site . 'typo3temp/') . uniqid('test_')) . '/';
2847 $mkdirResult = \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2848 clearstatcache();
2849 $directoryCreated = is_dir($directory);
2850 @rmdir($directory);
2851 $this->assertTrue($mkdirResult);
2852 $this->assertTrue($directoryCreated);
2853 }
2854
2855 /**
2856 * @test
2857 */
2858 public function mkdirSetsPermissionsOfCreatedDirectory() {
2859 if (TYPO3_OS == 'WIN') {
2860 $this->markTestSkipped('mkdirSetsPermissionsOfCreatedDirectory() test not available on Windows');
2861 }
2862 $directory = (PATH_site . 'typo3temp/') . uniqid('test_');
2863 $oldUmask = umask(19);
2864 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0772';
2865 \TYPO3\CMS\Core\Utility\GeneralUtility::mkdir($directory);
2866 clearstatcache();
2867 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2868 umask($oldUmask);
2869 rmdir($directory);
2870 $this->assertEquals($resultDirectoryPermissions, '0772');
2871 }
2872
2873 /**
2874 * @test
2875 */
2876 public function mkdirSetsGroupOwnershipOfCreatedDirectory() {
2877 if (!function_exists('posix_getegid')) {
2878 $this->markTestSkipped('Function posix_getegid() not available, mkdirSetsGroupOwnershipOfCreatedDirectory() tests skipped');
2879 }
2880 if (posix_getegid() === -1) {
2881 $this->markTestSkipped('The mkdirSetsGroupOwnershipOfCreatedDirectory() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.');