5044174a0577a5c42228e66b470e2b02cd798fa2
[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 arrayDiffAssocRecursive
1115 //////////////////////////////////////
1116
1117 /**
1118 * @test
1119 */
1120 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
1121 $array1 = array(
1122 'key1' => 'value1',
1123 'key2' => 'value2',
1124 'key3' => 'value3',
1125 );
1126 $array2 = array(
1127 'key1' => 'value1',
1128 'key3' => 'value3',
1129 );
1130 $expectedResult = array(
1131 'key2' => 'value2',
1132 );
1133 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1134 $this->assertEquals($expectedResult, $actualResult);
1135 }
1136
1137 /**
1138 * @test
1139 */
1140 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
1141 $array1 = array(
1142 'key1' => 'value1',
1143 'key2' => array(
1144 'key21' => 'value21',
1145 'key22' => 'value22',
1146 'key23' => array(
1147 'key231' => 'value231',
1148 'key232' => 'value232',
1149 ),
1150 ),
1151 );
1152 $array2 = array(
1153 'key1' => 'value1',
1154 'key2' => array(
1155 'key21' => 'value21',
1156 'key23' => array(
1157 'key231' => 'value231',
1158 ),
1159 ),
1160 );
1161 $expectedResult = array(
1162 'key2' => array(
1163 'key22' => 'value22',
1164 'key23' => array(
1165 'key232' => 'value232',
1166 ),
1167 ),
1168 );
1169 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1170 $this->assertEquals($expectedResult, $actualResult);
1171 }
1172
1173 /**
1174 * @test
1175 */
1176 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1177 $array1 = array(
1178 'key1' => array(
1179 'key11' => 'value11',
1180 'key12' => 'value12',
1181 ),
1182 'key2' => 'value2',
1183 'key3' => 'value3',
1184 );
1185 $array2 = array(
1186 'key1' => 'value1',
1187 'key2' => array(
1188 'key21' => 'value21',
1189 ),
1190 );
1191 $expectedResult = array(
1192 'key3' => 'value3',
1193 );
1194 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1195 $this->assertEquals($expectedResult, $actualResult);
1196 }
1197
1198
1199 //////////////////////////////////////
1200 // Tests concerning removeDotsFromTS
1201 //////////////////////////////////////
1202
1203 /**
1204 * @test
1205 */
1206 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
1207 $typoScript = array(
1208 'propertyA.' => array(
1209 'keyA.' => array(
1210 'valueA' => 1,
1211 ),
1212 'keyB' => 2,
1213 ),
1214 'propertyB' => 3,
1215 );
1216
1217 $expectedResult = array(
1218 'propertyA' => array(
1219 'keyA' => array(
1220 'valueA' => 1,
1221 ),
1222 'keyB' => 2,
1223 ),
1224 'propertyB' => 3,
1225 );
1226
1227 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1228 }
1229
1230 /**
1231 * @test
1232 */
1233 public function removeDotsFromTypoScriptOverridesSubArray() {
1234 $typoScript = array(
1235 'propertyA.' => array(
1236 'keyA' => 'getsOverridden',
1237 'keyA.' => array(
1238 'valueA' => 1,
1239 ),
1240 'keyB' => 2,
1241 ),
1242 'propertyB' => 3,
1243 );
1244
1245 $expectedResult = array(
1246 'propertyA' => array(
1247 'keyA' => array(
1248 'valueA' => 1,
1249 ),
1250 'keyB' => 2,
1251 ),
1252 'propertyB' => 3,
1253 );
1254
1255 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1256 }
1257
1258 /**
1259 * @test
1260 */
1261 public function removeDotsFromTypoScriptOverridesWithScalar() {
1262 $typoScript = array(
1263 'propertyA.' => array(
1264 'keyA.' => array(
1265 'valueA' => 1,
1266 ),
1267 'keyA' => 'willOverride',
1268 'keyB' => 2,
1269 ),
1270 'propertyB' => 3,
1271 );
1272
1273 $expectedResult = array(
1274 'propertyA' => array(
1275 'keyA' => 'willOverride',
1276 'keyB' => 2,
1277 ),
1278 'propertyB' => 3,
1279 );
1280
1281 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1282 }
1283
1284
1285 //////////////////////////////////////
1286 // Tests concerning get_dirs
1287 //////////////////////////////////////
1288
1289 /**
1290 * @test
1291 */
1292 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1293 $path = PATH_t3lib;
1294 $directories = t3lib_div::get_dirs($path);
1295
1296 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $directories);
1297 }
1298
1299 /**
1300 * @test
1301 */
1302 public function getDirsReturnsStringErrorOnPathFailure() {
1303 $path = 'foo';
1304 $result = t3lib_div::get_dirs($path);
1305 $expectedResult = 'error';
1306
1307 $this->assertEquals($expectedResult, $result);
1308 }
1309
1310
1311 //////////////////////////////////
1312 // Tests concerning hmac
1313 //////////////////////////////////
1314
1315 /**
1316 * @test
1317 */
1318 public function hmacReturnsHashOfProperLength() {
1319 $hmac = t3lib_div::hmac('message');
1320 $this->assertTrue(!empty($hmac) && is_string($hmac));
1321 $this->assertTrue(strlen($hmac) == 40);
1322 }
1323
1324 /**
1325 * @test
1326 */
1327 public function hmacReturnsEqualHashesForEqualInput() {
1328 $msg0 = 'message';
1329 $msg1 = 'message';
1330 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1331 }
1332
1333 /**
1334 * @test
1335 */
1336 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1337 $msg0 = 'message0';
1338 $msg1 = 'message1';
1339 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1340 }
1341
1342
1343 //////////////////////////////////
1344 // Tests concerning quoteJSvalue
1345 //////////////////////////////////
1346
1347 /**
1348 * @test
1349 */
1350 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1351 $this->assertContains(
1352 '&gt;',
1353 t3lib_div::quoteJSvalue('>')
1354 );
1355 }
1356
1357 /**
1358 * @test
1359 */
1360 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1361 $this->assertContains(
1362 '&gt;',
1363 t3lib_div::quoteJSvalue('>', false)
1364 );
1365 }
1366
1367 /**
1368 * @test
1369 */
1370 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1371 $this->assertContains(
1372 '>',
1373 t3lib_div::quoteJSvalue('>', true)
1374 );
1375 }
1376
1377 /**
1378 * @test
1379 */
1380 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1381 $this->assertEquals(
1382 "''",
1383 t3lib_div::quoteJSvalue("", true)
1384 );
1385 }
1386
1387 /**
1388 * @test
1389 */
1390 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1391 $this->assertEquals(
1392 "'Hello world!'",
1393 t3lib_div::quoteJSvalue("Hello world!", true)
1394 );
1395 }
1396
1397 /**
1398 * @test
1399 */
1400 public function quoteJSvalueEscapesSingleQuote() {
1401 $this->assertEquals(
1402 "'\\''",
1403 t3lib_div::quoteJSvalue("'", true)
1404 );
1405 }
1406
1407 /**
1408 * @test
1409 */
1410 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1411 $this->assertEquals(
1412 "'\\\"'",
1413 t3lib_div::quoteJSvalue('"', true)
1414 );
1415 }
1416
1417 /**
1418 * @test
1419 */
1420 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1421 $this->assertEquals(
1422 "'\\&quot;'",
1423 t3lib_div::quoteJSvalue('"', false)
1424 );
1425 }
1426
1427 /**
1428 * @test
1429 */
1430 public function quoteJSvalueEscapesTab() {
1431 $this->assertEquals(
1432 "'" . '\t' . "'",
1433 t3lib_div::quoteJSvalue(TAB)
1434 );
1435 }
1436
1437 /**
1438 * @test
1439 */
1440 public function quoteJSvalueEscapesLinefeed() {
1441 $this->assertEquals(
1442 "'" . '\n' . "'",
1443 t3lib_div::quoteJSvalue(LF)
1444 );
1445 }
1446
1447 /**
1448 * @test
1449 */
1450 public function quoteJSvalueEscapesCarriageReturn() {
1451 $this->assertEquals(
1452 "'" . '\r' . "'",
1453 t3lib_div::quoteJSvalue(CR)
1454 );
1455 }
1456
1457 /**
1458 * @test
1459 */
1460 public function quoteJSvalueEscapesBackslah() {
1461 $this->assertEquals(
1462 "'\\\\'",
1463 t3lib_div::quoteJSvalue('\\')
1464 );
1465 }
1466
1467 //////////////////////////////////
1468 // Tests concerning readLLfile
1469 //////////////////////////////////
1470
1471 /**
1472 * @test
1473 */
1474 public function readLLfileHandlesLocallangXMLOverride() {
1475 $unique = uniqid('locallangXMLOverrideTest');
1476
1477 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
1478 <T3locallang>
1479 <data type="array">
1480 <languageKey index="default" type="array">
1481 <label index="buttons.logout">EXIT</label>
1482 </languageKey>
1483 </data>
1484 </T3locallang>';
1485
1486 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
1487 t3lib_div::writeFileToTypo3tempDir($file, $xml);
1488
1489 // Get default value
1490 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1491
1492 // Set override file
1493 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
1494
1495 // Get override value
1496 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1497
1498 // Clean up again
1499 unlink($file);
1500
1501 $this->assertNotEquals($overrideLL['default']['buttons.logout'], '');
1502 $this->assertNotEquals($defaultLL['default']['buttons.logout'], $overrideLL['default']['buttons.logout']);
1503 $this->assertEquals($overrideLL['default']['buttons.logout'], 'EXIT');
1504 }
1505
1506
1507 ///////////////////////////////
1508 // Tests concerning _GETset()
1509 ///////////////////////////////
1510
1511 /**
1512 * @test
1513 */
1514 public function getSetWritesArrayToGetSystemVariable() {
1515 $_GET = array();
1516 $GLOBALS['HTTP_GET_VARS'] = array();
1517
1518 $getParameters = array('foo' => 'bar');
1519 t3lib_div::_GETset($getParameters);
1520 $this->assertSame($getParameters, $_GET);
1521 }
1522
1523 /**
1524 * @test
1525 */
1526 public function getSetWritesArrayToGlobalsHttpGetVars() {
1527 $_GET = array();
1528 $GLOBALS['HTTP_GET_VARS'] = array();
1529
1530 $getParameters = array('foo' => 'bar');
1531 t3lib_div::_GETset($getParameters);
1532 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
1533 }
1534
1535 /**
1536 * @test
1537 */
1538 public function getSetForArrayDropsExistingValues() {
1539 $_GET = array();
1540 $GLOBALS['HTTP_GET_VARS'] = array();
1541
1542 t3lib_div::_GETset(array('foo' => 'bar'));
1543
1544 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
1545
1546 $this->assertEquals(
1547 array('oneKey' => 'oneValue'),
1548 $GLOBALS['HTTP_GET_VARS']
1549 );
1550 }
1551
1552 /**
1553 * @test
1554 */
1555 public function getSetAssignsOneValueToOneKey() {
1556 $_GET = array();
1557 $GLOBALS['HTTP_GET_VARS'] = array();
1558
1559 t3lib_div::_GETset('oneValue', 'oneKey');
1560
1561 $this->assertEquals(
1562 'oneValue',
1563 $GLOBALS['HTTP_GET_VARS']['oneKey']
1564 );
1565 }
1566
1567 /**
1568 * @test
1569 */
1570 public function getSetForOneValueDoesNotDropUnrelatedValues() {
1571 $_GET = array();
1572 $GLOBALS['HTTP_GET_VARS'] = array();
1573
1574 t3lib_div::_GETset(array('foo' => 'bar'));
1575 t3lib_div::_GETset('oneValue', 'oneKey');
1576
1577 $this->assertEquals(
1578 array('foo' => 'bar', 'oneKey' => 'oneValue'),
1579 $GLOBALS['HTTP_GET_VARS']
1580 );
1581 }
1582
1583 /**
1584 * @test
1585 */
1586 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
1587 $_GET = array();
1588 $GLOBALS['HTTP_GET_VARS'] = array();
1589
1590 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
1591
1592 $this->assertEquals(
1593 array('parentKey' => array('childKey' => 'oneValue')),
1594 $GLOBALS['HTTP_GET_VARS']
1595 );
1596 }
1597
1598 /**
1599 * @test
1600 */
1601 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
1602 $_GET = array();
1603 $GLOBALS['HTTP_GET_VARS'] = array();
1604
1605 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
1606
1607 $this->assertEquals(
1608 array('parentKey' => array('childKey' => 'oneValue')),
1609 $GLOBALS['HTTP_GET_VARS']
1610 );
1611 }
1612
1613 /**
1614 * @test
1615 */
1616 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
1617 $_GET = array();
1618 $GLOBALS['HTTP_GET_VARS'] = array();
1619
1620 t3lib_div::_GETset(
1621 array('key1' => 'value1', 'key2' => 'value2'),
1622 'parentKey|childKey'
1623 );
1624
1625 $this->assertEquals(
1626 array(
1627 'parentKey' => array(
1628 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
1629 )
1630 ),
1631 $GLOBALS['HTTP_GET_VARS']
1632 );
1633 }
1634
1635
1636 ///////////////////////////////
1637 // Tests concerning fixPermissions
1638 ///////////////////////////////
1639
1640 /**
1641 * @test
1642 */
1643 public function fixPermissionsSetsGroup() {
1644 if (TYPO3_OS == 'WIN') {
1645 $this->markTestSkipped('fixPermissionsCorrectlySetsGroupOwnerOfFile() tests not available on Windows');
1646 }
1647 if (!function_exists('posix_getegid')) {
1648 $this->markTestSkipped('Function posix_getegid() not available, fixPermissionsCorrectlySetsGroupOwnerOfFile() tests skipped');
1649 }
1650
1651 // Create and prepare test file
1652 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
1653 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1654
1655 // Set target group and run method
1656 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1657 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1658
1659 clearstatcache();
1660 $resultFileGroup = filegroup($filename);
1661 unlink($filename);
1662
1663 $this->assertEquals($resultFileGroup, posix_getegid());
1664 }
1665
1666 /**
1667 * @test
1668 */
1669 public function fixPermissionsSetsPermissionsToFile() {
1670 if (TYPO3_OS == 'WIN') {
1671 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1672 }
1673
1674 // Create and prepare test file
1675 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
1676 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1677 chmod($filename, 0742);
1678
1679 // Set target permissions and run method
1680 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1681 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1682
1683 // Get actual permissions and clean up
1684 clearstatcache();
1685 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1686 unlink($filename);
1687
1688 // Test if everything was ok
1689 $this->assertTrue($fixPermissionsResult);
1690 $this->assertEquals($resultFilePermissions, '0660');
1691 }
1692
1693 /**
1694 * @test
1695 */
1696 public function fixPermissionsSetsPermissionsToHiddenFile() {
1697 if (TYPO3_OS == 'WIN') {
1698 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1699 }
1700
1701 // Create and prepare test file
1702 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
1703 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1704 chmod($filename, 0742);
1705
1706 // Set target permissions and run method
1707 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1708 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1709
1710 // Get actual permissions and clean up
1711 clearstatcache();
1712 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1713 unlink($filename);
1714
1715 // Test if everything was ok
1716 $this->assertTrue($fixPermissionsResult);
1717 $this->assertEquals($resultFilePermissions, '0660');
1718 }
1719
1720 /**
1721 * @test
1722 */
1723 public function fixPermissionsSetsPermissionsToDirectory() {
1724 if (TYPO3_OS == 'WIN') {
1725 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1726 }
1727
1728 // Create and prepare test directory
1729 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1730 t3lib_div::mkdir($directory);
1731 chmod($directory, 1551);
1732
1733 // Set target permissions and run method
1734 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1735 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
1736
1737 // Get actual permissions and clean up
1738 clearstatcache();
1739 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1740 t3lib_div::rmdir($directory);
1741
1742 // Test if everything was ok
1743 $this->assertTrue($fixPermissionsResult);
1744 $this->assertEquals($resultDirectoryPermissions, '0770');
1745 }
1746
1747 /**
1748 * @test
1749 */
1750 public function fixPermissionsSetsPermissionsToDirectoryWithTrailingSlash() {
1751 if (TYPO3_OS == 'WIN') {
1752 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1753 }
1754
1755 // Create and prepare test directory
1756 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1757 t3lib_div::mkdir($directory);
1758 chmod($directory, 1551);
1759
1760 // Set target permissions and run method
1761 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1762 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
1763
1764 // Get actual permissions and clean up
1765 clearstatcache();
1766 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1767 t3lib_div::rmdir($directory);
1768
1769 // Test if everything was ok
1770 $this->assertTrue($fixPermissionsResult);
1771 $this->assertEquals($resultDirectoryPermissions, '0770');
1772 }
1773
1774 /**
1775 * @test
1776 */
1777 public function fixPermissionsSetsPermissionsToHiddenDirectory() {
1778 if (TYPO3_OS == 'WIN') {
1779 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1780 }
1781
1782 // Create and prepare test directory
1783 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1784 t3lib_div::mkdir($directory);
1785 chmod($directory, 1551);
1786
1787 // Set target permissions and run method
1788 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1789 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
1790
1791 // Get actual permissions and clean up
1792 clearstatcache();
1793 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1794 t3lib_div::rmdir($directory);
1795
1796 // Test if everything was ok
1797 $this->assertTrue($fixPermissionsResult);
1798 $this->assertEquals($resultDirectoryPermissions, '0770');
1799 }
1800
1801 /**
1802 * @test
1803 */
1804 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
1805 if (TYPO3_OS == 'WIN') {
1806 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1807 }
1808
1809 // Create and prepare test directory and file structure
1810 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
1811 t3lib_div::mkdir($baseDirectory);
1812 chmod($baseDirectory, 1751);
1813 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
1814 chmod($baseDirectory . '/file', 0742);
1815 t3lib_div::mkdir($baseDirectory . '/foo');
1816 chmod($baseDirectory . '/foo', 1751);
1817 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
1818 chmod($baseDirectory . '/foo/file', 0742);
1819 t3lib_div::mkdir($baseDirectory . '/.bar');
1820 chmod($baseDirectory . '/.bar', 1751);
1821 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
1822 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
1823 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
1824 touch($baseDirectory . '/.bar/.file', '42');
1825 chmod($baseDirectory . '/.bar/.file', 0742);
1826 touch($baseDirectory . '/.bar/..file2', '42');
1827 chmod($baseDirectory . '/.bar/..file2', 0742);
1828
1829 // Set target permissions and run method
1830 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1831 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1832 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
1833
1834 // Get actual permissions
1835 clearstatcache();
1836 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
1837 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
1838 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
1839 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
1840 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
1841 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
1842 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
1843
1844 // Clean up
1845 unlink($baseDirectory . '/file');
1846 unlink($baseDirectory . '/foo/file');
1847 unlink($baseDirectory . '/.bar/.file');
1848 unlink($baseDirectory . '/.bar/..file2');
1849 t3lib_div::rmdir($baseDirectory . '/foo');
1850 t3lib_div::rmdir($baseDirectory . '/.bar');
1851 t3lib_div::rmdir($baseDirectory);
1852
1853 // Test if everything was ok
1854 $this->assertTrue($fixPermissionsResult);
1855 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
1856 $this->assertEquals($resultBaseFilePermissions, '0660');
1857 $this->assertEquals($resultFooDirectoryPermissions, '0770');
1858 $this->assertEquals($resultFooFilePermissions, '0660');
1859 $this->assertEquals($resultBarDirectoryPermissions, '0770');
1860 $this->assertEquals($resultBarFilePermissions, '0660');
1861 $this->assertEquals($resultBarFile2Permissions, '0660');
1862 }
1863
1864 /**
1865 * @test
1866 */
1867 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
1868 if (TYPO3_OS == 'WIN') {
1869 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1870 }
1871
1872 // Create and prepare test file
1873 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
1874 touch($filename);
1875 chmod($filename, 0742);
1876
1877 // Set target permissions and run method
1878 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1879 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1880
1881 // Get actual permissions and clean up
1882 clearstatcache();
1883 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1884 unlink($filename);
1885
1886 // Test if everything was ok
1887 $this->assertFalse($fixPermissionsResult);
1888 }
1889
1890 /**
1891 * @test
1892 */
1893 public function fixPermissionsSetsPermissionsWithRelativeFileReference() {
1894 if (TYPO3_OS == 'WIN') {
1895 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1896 }
1897
1898 $filename = 'typo3temp/' . uniqid('test_');
1899 t3lib_div::writeFileToTypo3tempDir(PATH_site . $filename, '42');
1900 chmod($filename, 0742);
1901
1902 // Set target permissions and run method
1903 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1904 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1905
1906 // Get actual permissions and clean up
1907 clearstatcache();
1908 $resultFilePermissions = substr(decoct(fileperms(PATH_site . $filename)), 2);
1909 unlink(PATH_site . $filename);
1910
1911 // Test if everything was ok
1912 $this->assertTrue($fixPermissionsResult);
1913 $this->assertEquals($resultFilePermissions, '0660');
1914 }
1915
1916
1917 ///////////////////////////////
1918 // Tests concerning mkdir
1919 ///////////////////////////////
1920
1921 /**
1922 * @test
1923 */
1924 public function mkdirCreatesDirectory() {
1925 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1926 $mkdirResult = t3lib_div::mkdir($directory);
1927 clearstatcache();
1928 $directoryCreated = is_dir($directory);
1929 @rmdir($directory);
1930 $this->assertTrue($mkdirResult);
1931 $this->assertTrue($directoryCreated);
1932 }
1933
1934 /**
1935 * @test
1936 */
1937 public function mkdirCreatesHiddenDirectory() {
1938 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1939 $mkdirResult = t3lib_div::mkdir($directory);
1940 clearstatcache();
1941 $directoryCreated = is_dir($directory);
1942 @rmdir($directory);
1943 $this->assertTrue($mkdirResult);
1944 $this->assertTrue($directoryCreated);
1945 }
1946
1947 /**
1948 * @test
1949 */
1950 public function mkdirCreatesDirectoryWithTrailingSlash() {
1951 $directory = PATH_site . 'typo3temp/' . uniqid('test_') . '/';
1952 $mkdirResult = t3lib_div::mkdir($directory);
1953 clearstatcache();
1954 $directoryCreated = is_dir($directory);
1955 @rmdir($directory);
1956 $this->assertTrue($mkdirResult);
1957 $this->assertTrue($directoryCreated);
1958 }
1959
1960 /**
1961 * @test
1962 */
1963 public function mkdirSetsPermissionsOfCreatedDirectory() {
1964 if (TYPO3_OS == 'WIN') {
1965 $this->markTestSkipped('mkdirSetsPermissionsOfCreatedDirectory() test not available on Windows');
1966 }
1967
1968 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1969 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1970 t3lib_div::mkdir($directory);
1971 clearstatcache();
1972 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1973 rmdir($directory);
1974 $this->assertEquals($resultDirectoryPermissions, '0770');
1975 }
1976
1977
1978 ///////////////////////////////
1979 // Tests concerning mkdir_deep
1980 ///////////////////////////////
1981
1982 /**
1983 * @test
1984 */
1985 public function mkdirDeepCreatesDirectory() {
1986 $directory = 'typo3temp/' . uniqid('test_');
1987 t3lib_div::mkdir_deep(PATH_site, $directory);
1988 $isDirectoryCreated = is_dir(PATH_site . $directory);
1989 rmdir(PATH_site . $directory);
1990 $this->assertTrue($isDirectoryCreated);
1991 }
1992
1993 /**
1994 * @test
1995 */
1996 public function mkdirDeepCreatesSubdirectoriesRecursive() {
1997 $directory = 'typo3temp/' . uniqid('test_');
1998 $subDirectory = $directory . '/foo';
1999 t3lib_div::mkdir_deep(PATH_site, $subDirectory);
2000 $isDirectoryCreated = is_dir(PATH_site . $subDirectory);
2001 rmdir(PATH_site . $subDirectory);
2002 rmdir(PATH_site . $directory);
2003 $this->assertTrue($isDirectoryCreated);
2004 }
2005
2006 /**
2007 * @test
2008 */
2009 public function mkdirDeepFixesPermissionsOnNewDirectory() {
2010 if (TYPO3_OS == 'WIN') {
2011 $this->markTestSkipped('mkdirDeepFixesPermissionsOnNewDirectory() test not available on Windows.');
2012 }
2013
2014 $directory = uniqid('mkdirdeeptest_');
2015 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0750';
2016 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2017 clearstatcache();
2018 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2019 @rmdir(PATH_site . 'typo3temp/' . $directory);
2020 $this->assertEquals($resultDirectoryPermissions, '750');
2021 }
2022
2023 /**
2024 * @test
2025 */
2026 public function mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() {
2027 if (TYPO3_OS == 'WIN') {
2028 $this->markTestSkipped('mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() test not available on Windows.');
2029 }
2030
2031 $baseDirectory = PATH_site . 'typo3temp/';
2032 $existingDirectory = uniqid('test_existing_') . '/';
2033 $newSubDirectory = uniqid('test_new_');
2034 @mkdir($baseDirectory . $existingDirectory);
2035 chmod($baseDirectory . $existingDirectory, 0742);
2036 t3lib_div::mkdir_deep($baseDirectory, $existingDirectory . $newSubDirectory);
2037 $resultExistingDirectoryPermissions = substr(decoct(fileperms($baseDirectory . $existingDirectory)), 2);
2038 @rmdir($baseDirectory, $existingDirectory . $newSubDirectory);
2039 @rmdir($baseDirectory, $existingDirectory);
2040 $this->assertEquals($resultExistingDirectoryPermissions, '0742');
2041 }
2042
2043 /**
2044 * @test
2045 */
2046 public function mkdirDeepCreatesDirectoryInVfsStream() {
2047 if (!class_exists('\vfsStreamWrapper')) {
2048 $this->markTestSkipped('mkdirDeepCreatesDirectoryInVfsStream() test not available with this phpunit version.');
2049 }
2050
2051 \vfsStreamWrapper::register();
2052 $baseDirectory = uniqid('test_');
2053 \vfsStreamWrapper::setRoot(new \vfsStreamDirectory($baseDirectory));
2054 t3lib_div::mkdir_deep('vfs://' . $baseDirectory . '/', 'sub');
2055 $this->assertTrue(is_dir('vfs://' . $baseDirectory . '/sub'));
2056 }
2057
2058 /**
2059 * @test
2060 * @expectedException \RuntimeException
2061 */
2062 public function mkdirDeepThrowsExceptionIfDirectoryCreationFails() {
2063 t3lib_div::mkdir_deep('http://localhost');
2064 }
2065
2066 /**
2067 * @test
2068 * @expectedException \InvalidArgumentException
2069 */
2070 public function mkdirDeepThrowsExceptionIfBaseDirectoryIsNotOfTypeString() {
2071 t3lib_div::mkdir_deep(array());
2072 }
2073
2074 /**
2075 * @test
2076 * @expectedException \InvalidArgumentException
2077 */
2078 public function mkdirDeepThrowsExceptionIfDeepDirectoryIsNotOfTypeString() {
2079 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/foo', array());
2080 }
2081
2082
2083 ///////////////////////////////
2084 // Tests concerning unQuoteFilenames
2085 ///////////////////////////////
2086
2087 /**
2088 * Data provider for ImageMagick shell commands
2089 * @see explodeAndUnquoteImageMagickCommands
2090 */
2091 public function imageMagickCommandsDataProvider() {
2092 return array(
2093 // Some theoretical tests first
2094 array(
2095 'aa bb "cc" "dd"',
2096 array('aa', 'bb', '"cc"', '"dd"'),
2097 array('aa', 'bb', 'cc', 'dd'),
2098 ),
2099 array(
2100 'aa bb "cc dd"',
2101 array('aa', 'bb', '"cc dd"'),
2102 array('aa', 'bb', 'cc dd'),
2103 ),
2104 array(
2105 '\'aa bb\' "cc dd"',
2106 array('\'aa bb\'', '"cc dd"'),
2107 array('aa bb', 'cc dd'),
2108 ),
2109 array(
2110 '\'aa bb\' cc "dd"',
2111 array('\'aa bb\'', 'cc', '"dd"'),
2112 array('aa bb', 'cc', 'dd'),
2113 ),
2114 // Now test against some real world examples
2115 array(
2116 '/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"',
2117 array(
2118 '/opt/local/bin/gm.exe',
2119 'convert',
2120 '+profile',
2121 '\'*\'',
2122 '-geometry',
2123 '170x136!',
2124 '-negate',
2125 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2126 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2127 ),
2128 array(
2129 '/opt/local/bin/gm.exe',
2130 'convert',
2131 '+profile',
2132 '*',
2133 '-geometry',
2134 '170x136!',
2135 '-negate',
2136 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2137 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2138 ),
2139 ),
2140 array(
2141 '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"',
2142 array(
2143 'C:/opt/local/bin/gm.exe',
2144 'convert',
2145 '+profile',
2146 '\'*\'',
2147 '-geometry',
2148 '170x136!',
2149 '-negate',
2150 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2151 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2152 ),
2153 array(
2154 'C:/opt/local/bin/gm.exe',
2155 'convert',
2156 '+profile',
2157 '*',
2158 '-geometry',
2159 '170x136!',
2160 '-negate',
2161 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2162 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2163 ),
2164 ),
2165 array(
2166 '/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"',
2167 array(
2168 '/usr/bin/gm',
2169 'convert',
2170 '+profile',
2171 '\'*\'',
2172 '-geometry',
2173 '170x136!',
2174 '-negate',
2175 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2176 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2177 ),
2178 array(
2179 '/usr/bin/gm',
2180 'convert',
2181 '+profile',
2182 '*',
2183 '-geometry',
2184 '170x136!',
2185 '-negate',
2186 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2187 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2188 ),
2189 ),
2190 array(
2191 '/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"',
2192 array(
2193 '/usr/bin/gm',
2194 'convert',
2195 '+profile',
2196 '\'*\'',
2197 '-geometry',
2198 '170x136!',
2199 '-negate',
2200 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2201 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2202 ),
2203 array(
2204 '/usr/bin/gm',
2205 'convert',
2206 '+profile',
2207 '*',
2208 '-geometry',
2209 '170x136!',
2210 '-negate',
2211 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2212 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2213 ),
2214 ),
2215 array(
2216 '/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\'',
2217 array(
2218 '/usr/bin/gm',
2219 'convert',
2220 '+profile',
2221 '\'*\'',
2222 '-geometry',
2223 '170x136!',
2224 '-negate',
2225 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\'',
2226 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\''
2227 ),
2228 array(
2229 '/usr/bin/gm',
2230 'convert',
2231 '+profile',
2232 '*',
2233 '-geometry',
2234 '170x136!',
2235 '-negate',
2236 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2237 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2238 ),
2239 ),
2240 );
2241 }
2242
2243 /**
2244 * Tests if the commands are exploded and unquoted correctly
2245 *
2246 * @dataProvider imageMagickCommandsDataProvider
2247 * @test
2248 */
2249 public function explodeAndUnquoteImageMagickCommands($source, $expectedQuoted, $expectedUnquoted) {
2250 $actualQuoted = t3lib_div::unQuoteFilenames($source);
2251 $acutalUnquoted = t3lib_div::unQuoteFilenames($source, TRUE);
2252
2253 $this->assertEquals($expectedQuoted, $actualQuoted, 'The exploded command does not match the expected');
2254 $this->assertEquals($expectedUnquoted, $acutalUnquoted, 'The exploded and unquoted command does not match the expected');
2255 }
2256
2257
2258 ///////////////////////////////
2259 // Tests concerning split_fileref
2260 ///////////////////////////////
2261
2262 /**
2263 * @test
2264 */
2265 public function splitFileRefReturnsFileTypeNotForFolders(){
2266 $directoryName = uniqid('test_') . '.com';
2267 $directoryPath = PATH_site . 'typo3temp/';
2268 $directory = $directoryPath . $directoryName;
2269 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
2270
2271 $fileInfo = t3lib_div::split_fileref($directory);
2272
2273 $directoryCreated = is_dir($directory);
2274 rmdir($directory);
2275
2276 $this->assertTrue($directoryCreated);
2277 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2278 $this->assertEquals($directoryPath, $fileInfo['path']);
2279 $this->assertEquals($directoryName, $fileInfo['file']);
2280 $this->assertEquals($directoryName, $fileInfo['filebody']);
2281 $this->assertEquals('', $fileInfo['fileext']);
2282 $this->assertArrayNotHasKey('realFileext', $fileInfo);
2283 }
2284
2285 /**
2286 * @test
2287 */
2288 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
2289 $testFile = 'fileadmin/media/someFile.png';
2290
2291 $fileInfo = t3lib_div::split_fileref($testFile);
2292 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2293 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
2294 $this->assertEquals('someFile.png', $fileInfo['file']);
2295 $this->assertEquals('someFile', $fileInfo['filebody']);
2296 $this->assertEquals('png', $fileInfo['fileext']);
2297 }
2298
2299
2300 /////////////////////////////
2301 // Tests concerning dirname
2302 /////////////////////////////
2303
2304 /**
2305 * @see dirnameWithDataProvider
2306 *
2307 * @return array<array>
2308 */
2309 public function dirnameDataProvider() {
2310 return array(
2311 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
2312 'absolute path with one part' => array('/dir1/', '/dir1'),
2313 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
2314 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
2315 'relative one-character path with one part and file' => array('d/script.php', 'd'),
2316 'absolute zero-part path with file' => array('/script.php', ''),
2317 'empty string' => array('', ''),
2318 );
2319 }
2320
2321 /**
2322 * @test
2323 *
2324 * @dataProvider dirnameDataProvider
2325 *
2326 * @param string $input the input for dirname
2327 * @param string $expectedValue the expected return value expected from dirname
2328 */
2329 public function dirnameWithDataProvider($input, $expectedValue) {
2330 $this->assertEquals(
2331 $expectedValue,
2332 t3lib_div::dirname($input)
2333 );
2334 }
2335
2336
2337 /////////////////////////////////////
2338 // Tests concerning resolveBackPath
2339 /////////////////////////////////////
2340
2341 /**
2342 * @see resolveBackPathWithDataProvider
2343 *
2344 * @return array<array>
2345 */
2346 public function resolveBackPathDataProvider() {
2347 return array(
2348 'empty path' => array('', ''),
2349 'this directory' => array('./', './'),
2350 'relative directory without ..' => array('dir1/dir2/dir3/', 'dir1/dir2/dir3/'),
2351 'relative path without ..' => array('dir1/dir2/script.php', 'dir1/dir2/script.php'),
2352 'absolute directory without ..' => array('/dir1/dir2/dir3/', '/dir1/dir2/dir3/'),
2353 'absolute path without ..' => array('/dir1/dir2/script.php', '/dir1/dir2/script.php'),
2354 'only one directory upwards without trailing slash' => array('..', '..'),
2355 'only one directory upwards with trailing slash' => array('../', '../'),
2356 'one level with trailing ..' => array('dir1/..', ''),
2357 'one level with trailing ../' => array('dir1/../', ''),
2358 'two levels with trailing ..' => array('dir1/dir2/..', 'dir1'),
2359 'two levels with trailing ../' => array('dir1/dir2/../', 'dir1/'),
2360 'leading ../ without trailing /' => array('../dir1', '../dir1'),
2361 'leading ../ with trailing /' => array('../dir1/', '../dir1/'),
2362 'leading ../ and inside path' => array('../dir1/dir2/../dir3/', '../dir1/dir3/'),
2363 'one times ../ in relative directory' => array('dir1/../dir2/', 'dir2/'),
2364 'one times ../ in absolute directory' => array('/dir1/../dir2/', '/dir2/'),
2365 'one times ../ in relative path' => array('dir1/../dir2/script.php', 'dir2/script.php'),
2366 'one times ../ in absolute path' => array('/dir1/../dir2/script.php', '/dir2/script.php'),
2367 'consecutive ../' => array('dir1/dir2/dir3/../../../dir4', 'dir4'),
2368 'distrubuted ../ with trailing /' => array('dir1/../dir2/dir3/../', 'dir2/'),
2369 'distributed ../ without trailing /' => array('dir1/../dir2/dir3/..', 'dir2'),
2370 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
2371 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
2372 'dirname with leading ..' => array('dir1/..dir2/dir3/', 'dir1/..dir2/dir3/'),
2373 'dirname with trailing ..' => array('dir1/dir2../dir3/', 'dir1/dir2../dir3/'),
2374 'more times upwards than downwards in directory' => array('dir1/../../', '../'),
2375 'more times upwards than downwards in path' => array('dir1/../../script.php', '../script.php'),
2376 );
2377 }
2378
2379 /**
2380 * @test
2381 *
2382 * @dataProvider resolveBackPathDataProvider
2383 *
2384 * @param string $input the input for resolveBackPath
2385 * @param $expectedValue the expected return value from resolveBackPath
2386 */
2387 public function resolveBackPathWithDataProvider($input, $expectedValue) {
2388 $this->assertEquals(
2389 $expectedValue,
2390 t3lib_div::resolveBackPath($input)
2391 );
2392 }
2393
2394
2395 /////////////////////////////////////////////////////////////////////////////////////
2396 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
2397 /////////////////////////////////////////////////////////////////////////////////////
2398
2399 /**
2400 * @test
2401 *
2402 * @expectedException InvalidArgumentException
2403 */
2404 public function makeInstanceWithEmptyClassNameThrowsException() {
2405 t3lib_div::makeInstance('');
2406 }
2407
2408 /**
2409 * @test
2410 */
2411 public function makeInstanceReturnsClassInstance() {
2412 $className = get_class($this->getMock('foo'));
2413
2414 $this->assertTrue(
2415 t3lib_div::makeInstance($className) instanceof $className
2416 );
2417 }
2418
2419 /**
2420 * @test
2421 */
2422 public function makeInstancePassesParametersToConstructor() {
2423 $className = 'testingClass' . uniqid();
2424 if (!class_exists($className, FALSE)) {
2425 eval(
2426 'class ' . $className . ' {' .
2427 ' public $constructorParameter1;' .
2428 ' public $constructorParameter2;' .
2429 ' public function __construct($parameter1, $parameter2) {' .
2430 ' $this->constructorParameter1 = $parameter1;' .
2431 ' $this->constructorParameter2 = $parameter2;' .
2432 ' }' .
2433 '}'
2434 );
2435 }
2436
2437 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
2438
2439 $this->assertEquals(
2440 'one parameter',
2441 $instance->constructorParameter1,
2442 'The first constructor parameter has not been set.'
2443 );
2444 $this->assertEquals(
2445 'another parameter',
2446 $instance->constructorParameter2,
2447 'The second constructor parameter has not been set.'
2448 );
2449 }
2450
2451 /**
2452 * @test
2453 */
2454 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
2455 $className = get_class($this->getMock('foo'));
2456
2457 $this->assertNotSame(
2458 t3lib_div::makeInstance($className),
2459 t3lib_div::makeInstance($className)
2460 );
2461 }
2462
2463 /**
2464 * @test
2465 */
2466 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
2467 $className = get_class($this->getMock('t3lib_Singleton'));
2468
2469 $this->assertSame(
2470 t3lib_div::makeInstance($className),
2471 t3lib_div::makeInstance($className)
2472 );
2473 }
2474
2475 /**
2476 * @test
2477 */
2478 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
2479 $className = get_class($this->getMock('t3lib_Singleton'));
2480
2481 $instance = t3lib_div::makeInstance($className);
2482 t3lib_div::purgeInstances();
2483
2484 $this->assertNotSame(
2485 $instance,
2486 t3lib_div::makeInstance($className)
2487 );
2488 }
2489
2490 /**
2491 * @test
2492 * @expectedException InvalidArgumentException
2493 */
2494 public function setSingletonInstanceForEmptyClassNameThrowsException() {
2495 $instance = $this->getMock('t3lib_Singleton');
2496
2497 t3lib_div::setSingletonInstance('', $instance);
2498 }
2499
2500 /**
2501 * @test
2502 * @expectedException InvalidArgumentException
2503 */
2504 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
2505 $instance = $this->getMock('t3lib_Singleton', array('foo'));
2506 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
2507
2508 t3lib_div::setSingletonInstance($singletonClassName, $instance);
2509 }
2510
2511 /**
2512 * @test
2513 */
2514 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
2515 $instance = $this->getMock('t3lib_Singleton');
2516 $singletonClassName = get_class($instance);
2517
2518 t3lib_div::setSingletonInstance($singletonClassName, $instance);
2519
2520 $this->assertSame(
2521 $instance,
2522 t3lib_div::makeInstance($singletonClassName)
2523 );
2524 }
2525
2526 /**
2527 * @test
2528 */
2529 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
2530 $instance1 = $this->getMock('t3lib_Singleton');
2531 $singletonClassName = get_class($instance1);
2532 $instance2 = new $singletonClassName();
2533
2534 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
2535 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
2536
2537 $this->assertSame(
2538 $instance2,
2539 t3lib_div::makeInstance($singletonClassName)
2540 );
2541 }
2542
2543 /**
2544 * @test
2545 * @expectedException InvalidArgumentException
2546 */
2547 public function addInstanceForEmptyClassNameThrowsException() {
2548 $instance = $this->getMock('foo');
2549
2550 t3lib_div::addInstance('', $instance);
2551 }
2552
2553 /**
2554 * @test
2555 * @expectedException InvalidArgumentException
2556 */
2557 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
2558 $instance = $this->getMock('foo', array('bar'));
2559 $singletonClassName = get_class($this->getMock('foo'));
2560
2561 t3lib_div::addInstance($singletonClassName, $instance);
2562 }
2563
2564 /**
2565 * @test
2566 * @expectedException InvalidArgumentException
2567 */
2568 public function addInstanceWithSingletonInstanceThrowsException() {
2569 $instance = $this->getMock('t3lib_Singleton');
2570
2571 t3lib_div::addInstance(get_class($instance), $instance);
2572 }
2573
2574 /**
2575 * @test
2576 */
2577 public function addInstanceMakesMakeInstanceReturnThatInstance() {
2578 $instance = $this->getMock('foo');
2579 $className = get_class($instance);
2580
2581 t3lib_div::addInstance($className, $instance);
2582
2583 $this->assertSame(
2584 $instance,
2585 t3lib_div::makeInstance($className)
2586 );
2587 }
2588
2589 /**
2590 * @test
2591 */
2592 public function makeInstanceCalledTwoTimesAfterAddInstanceReturnTwoDifferentInstances() {
2593 $instance = $this->getMock('foo');
2594 $className = get_class($instance);
2595
2596 t3lib_div::addInstance($className, $instance);
2597
2598 $this->assertNotSame(
2599 t3lib_div::makeInstance($className),
2600 t3lib_div::makeInstance($className)
2601 );
2602 }
2603
2604 /**
2605 * @test
2606 */
2607 public function addInstanceCalledTwoTimesMakesMakeInstanceReturnBothInstancesInAddingOrder() {
2608 $instance1 = $this->getMock('foo');
2609 $className = get_class($instance1);
2610 t3lib_div::addInstance($className, $instance1);
2611
2612 $instance2 = new $className();
2613 t3lib_div::addInstance($className, $instance2);
2614
2615 $this->assertSame(
2616 $instance1,
2617 t3lib_div::makeInstance($className),
2618 'The first returned instance does not match the first added instance.'
2619 );
2620 $this->assertSame(
2621 $instance2,
2622 t3lib_div::makeInstance($className),
2623 'The second returned instance does not match the second added instance.'
2624 );
2625 }
2626
2627 /**
2628 * @test
2629 */
2630 public function purgeInstancesDropsAddedInstance() {
2631 $instance = $this->getMock('foo');
2632 $className = get_class($instance);
2633
2634 t3lib_div::addInstance($className, $instance);
2635 t3lib_div::purgeInstances();
2636
2637 $this->assertNotSame(
2638 $instance,
2639 t3lib_div::makeInstance($className)
2640 );
2641 }
2642
2643 /**
2644 * Data provider for validPathStrDetectsInvalidCharacters.
2645 *
2646 * @return array
2647 */
2648 public function validPathStrInvalidCharactersDataProvider() {
2649 return array(
2650 'double slash in path' => array('path//path'),
2651 'backslash in path' => array('path\\path'),
2652 'directory up in path' => array('path/../path'),
2653 'directory up at the beginning' => array('../path'),
2654 'NUL character in path' => array("path\x00path"),
2655 'BS character in path' => array("path\x08path"),
2656 );
2657 }
2658
2659 /**
2660 * Tests whether invalid characters are detected.
2661 *
2662 * @param string $path
2663 * @dataProvider validPathStrInvalidCharactersDataProvider
2664 * @test
2665 */
2666 public function validPathStrDetectsInvalidCharacters($path) {
2667 $this->assertNull(t3lib_div::validPathStr($path));
2668 }
2669
2670 /**
2671 * Tests whether verifyFilenameAgainstDenyPattern detects the null character.
2672 *
2673 * @test
2674 */
2675 public function verifyFilenameAgainstDenyPatternDetectsNullCharacter() {
2676 $this->assertFalse(t3lib_div::verifyFilenameAgainstDenyPattern("image\x00.gif"));
2677 }
2678
2679
2680 /////////////////////////////////////////////////////////////////////////////////////
2681 // Tests concerning sysLog
2682 /////////////////////////////////////////////////////////////////////////////////////
2683
2684 /**
2685 * @test
2686 */
2687 public function syslogFixesPermissionsOnFileIfUsingFileLogging() {
2688 if (TYPO3_OS == 'WIN') {
2689 $this->markTestSkipped('syslogFixesPermissionsOnFileIfUsingFileLogging() test not available on Windows.');
2690 }
2691
2692 // Fake all required settings
2693 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLogLevel'] = 0;
2694 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit'] = TRUE;
2695 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']);
2696 $testLogFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.txt';
2697 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'] = 'file,' . $testLogFilename . ',0';
2698 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
2699
2700 // Call method, get actual permissions and clean up
2701 t3lib_div::syslog('testLog', 'test', 1);
2702 clearstatcache();
2703 $resultFilePermissions = substr(decoct(fileperms($testLogFilename)), 2);
2704 t3lib_div::unlink_tempfile($testLogFilename);
2705
2706 $this->assertEquals($resultFilePermissions, '0777');
2707 }
2708
2709 /**
2710 * @test
2711 */
2712 public function deprecationLogFixesPermissionsOnLogFile() {
2713 if (TYPO3_OS == 'WIN') {
2714 $this->markTestSkipped('deprecationLogFixesPermissionsOnLogFile() test not available on Windows.');
2715 }
2716
2717 // Fake all required settings and get an unique logfilename
2718 $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = uniqid('test_');
2719 $deprecationLogFilename = t3lib_div::getDeprecationLogFileName();
2720 $GLOBALS['TYPO3_CONF_VARS']['SYS']['enableDeprecationLog'] = TRUE;
2721 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
2722
2723 // Call method, get actual permissions and clean up
2724 t3lib_div::deprecationLog('foo');
2725 clearstatcache();
2726 $resultFilePermissions = substr(decoct(fileperms($deprecationLogFilename)), 2);
2727 @unlink($deprecationLogFilename);
2728
2729 $this->assertEquals($resultFilePermissions, '0777');
2730 }
2731 }
2732 ?>