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