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