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