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