Follow-up to #15383: [Unit tests] Uncomment three tests which fail for php 5.3.0...
[Packages/TYPO3.CMS.git] / tests / t3lib / t3lib_divTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2010 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 /**
27 * Testcase for class t3lib_div
28 *
29 * @author Ingo Renner <ingo@typo3.org>
30 * @author Oliver Klee <typo3-coding@oliverklee.de>
31 *
32 * @package TYPO3
33 * @subpackage t3lib
34 */
35 class t3lib_divTest extends tx_phpunit_testcase {
36 /**
37 * Enable backup of global and system variables
38 */
39 protected $backupGlobals = TRUE;
40
41
42 ///////////////////////////////
43 // Tests concerning validIP
44 ///////////////////////////////
45
46 /**
47 * Data provider for checkValidIpReturnsTrueForValidIp
48 *
49 * @return array Data sets
50 */
51 public static function validIpDataProvider() {
52 return array(
53 '0.0.0.0' => array('0.0.0.0'),
54 'private IPv4 class C' => array('192.168.0.1'),
55 'private IPv4 class A' => array('10.0.13.1'),
56 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb'),
57 );
58 }
59
60 /**
61 * @test
62 * @dataProvider validIpDataProvider
63 */
64 public function validIpReturnsTrueForValidIp($ip) {
65 $this->assertTrue(t3lib_div::validIP($ip));
66 }
67
68 /**
69 * Data provider for checkValidIpReturnsFalseForInvalidIp
70 *
71 * @return array Data sets
72 */
73 public static function invalidIpDataProvider() {
74 return array(
75 'null' => array(null),
76 'zero' => array(0),
77 'string' => array('test'),
78 'string empty' => array(''),
79 'string null' => array('null'),
80 'out of bounds IPv4' => array('300.300.300.300'),
81 'dotted decimal notation with only two dots' => array('127.0.1'),
82 );
83 }
84
85 /**
86 * @test
87 * @dataProvider invalidIpDataProvider
88 */
89 public function validIpReturnsFalseForInvalidIp($ip) {
90 $this->assertFalse(t3lib_div::validIP($ip));
91 }
92
93
94 ///////////////////////////////
95 // Tests concerning isFirstPartOfStr
96 ///////////////////////////////
97
98 /**
99 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
100 *
101 * @return array
102 */
103 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
104 return array(
105 'match first part of string' => array('hello world', 'hello'),
106 'match whole string' => array('hello', 'hello'),
107 );
108 }
109
110 /**
111 * @test
112 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
113 */
114 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
115 $this->assertTrue(t3lib_div::isFirstPartOfStr($string, $part));
116 }
117
118 /**
119 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
120 *
121 * @return array
122 */
123 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
124 return array(
125 'no string match' => array('hello', 'bye'),
126 'no case sensitive string match' => array('hello world', 'Hello'),
127 'array is not part of string' => array('string', array()),
128 'string is not part of array' => array(array(), 'string'),
129 'null is not part of string' => array('string', NULL),
130 'string is not part of array' => array(NULL, 'string'),
131 'null is not part of array' => array(array(), NULL),
132 'array is not part of string' => array(NULL, array()),
133 'empty string is not part of empty string' => array('', ''),
134 'null is not part of empty string' => array('', NULL),
135 'false is not part of empty string' => array('', FALSE),
136 'empty string is not part of null' => array(NULL, ''),
137 'empty string is not part of false' => array(FALSE, ''),
138 'empty string is not part of zero integer' => array(0, ''),
139 );
140 }
141
142 /**
143 * @test
144 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
145 */
146 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
147 $this->assertFalse(t3lib_div::isFirstPartOfStr($string, $part));
148 }
149
150
151 ///////////////////////////////
152 // Tests concerning splitCalc
153 ///////////////////////////////
154
155 /**
156 * Data provider for splitCalc
157 *
158 * @return array expected values, arithmetic expression
159 */
160 public function splitCalcDataProvider() {
161 return array(
162 'empty string returns empty array' => array(
163 array(),
164 '',
165 ),
166 'number without operator returns array with plus and number' => array(
167 array(array('+', 42)),
168 '42',
169 ),
170 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
171 array(array('+', 42), array('*', 31)),
172 '42 * 31',
173 ),
174 );
175 }
176
177 /**
178 * @test
179 * @dataProvider splitCalcDataProvider
180 */
181 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
182 $this->assertEquals($expected, t3lib_div::splitCalc($expression, '+-*/'));
183 }
184
185
186 //////////////////////////////////
187 // Tests concerning calcPriority
188 //////////////////////////////////
189
190 /**
191 * Data provider for calcPriority
192 *
193 * @return array expected values, arithmetic expression
194 */
195 public function calcPriorityDataProvider() {
196 return array(
197 'add' => array(9, '6 + 3'),
198 'substract with positive result' => array(3, '6 - 3'),
199 'substract with negative result' => array(-3, '3 - 6'),
200 'multiply' => array(6, '2 * 3'),
201 'divide' => array(2.5, '5 / 2'),
202 'modulus' => array(1, '5 % 2'),
203 'power' => array(8, '2 ^ 3'),
204 'three operands with non integer result' => array(6.5, '5 + 3 / 2'),
205 'three operands with power' => array(14, '5 + 3 ^ 2'),
206 'three operads with modulus' => array(4, '5 % 2 + 3'),
207 'four operands' => array(3, '2 + 6 / 2 - 2'),
208 );
209 }
210
211 /**
212 * @test
213 * @dataProvider calcPriorityDataProvider
214 */
215 public function calcPriorityCorrectlyCalculatesExpression($expected, $expression) {
216 $this->assertEquals($expected, t3lib_div::calcPriority($expression));
217 }
218
219
220 //////////////////////////////////
221 // Tests concerning calcPriority
222 //////////////////////////////////
223
224 /**
225 * Data provider for valid validEmail's
226 *
227 * @return array Valid email addresses
228 */
229 public function validEmailValidDataProvider() {
230 return array(
231 'short mail address' => array('a@b.c'),
232 'simple mail address' => array('test@example.com'),
233 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
234 // 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
235 // 'equal sign in local part' => array('test=mail@example.com'),
236 'dash in local part' => array('test-mail@example.com'),
237 'plus in local part' => array('test+mail@example.com'),
238 // 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
239 // 'question mark in local part' => array('test?mail@example.com'),
240 'slash in local part' => array('foo/bar@example.com'),
241 'hash in local part' => array('foo#bar@example.com'),
242 // 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
243 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
244 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
245 // 'dash as local part' => array('-@foo.com'),
246 );
247 }
248
249 /**
250 * @test
251 * @dataProvider validEmailValidDataProvider
252 */
253 public function validEmailReturnsTrueForValidMailAddress($address) {
254 $this->assertTrue(t3lib_div::validEmail($address));
255 }
256
257 /**
258 * Data provider for invalid validEmail's
259 *
260 * @return array Invalid email addresses
261 */
262 public function validEmailInvalidDataProvider() {
263 return array(
264 '@ sign only' => array('@'),
265 'duplicate @' => array('test@@example.com'),
266 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
267 'opening parenthesis in local part' => array('foo(bar@example.com'),
268 'closing parenthesis in local part' => array('foo)bar@example.com'),
269 'opening square bracket in local part' => array('foo[bar@example.com'),
270 'closing square bracket as local part' => array(']@example.com'),
271 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
272 // 'top level domain only' => array('test@com'),
273 'dash as second level domain' => array('foo@-.com'),
274 'domain part starting with dash' => array('foo@-foo.com'),
275 'domain part ending with dash' => array('foo@foo-.com'),
276 'number as top level domain' => array('foo@bar.123'),
277 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
278 // 'dash as top level domain' => array('foo@bar.-'),
279 'dot at beginning of domain part' => array('test@.com'),
280 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
281 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
282 'trailing whitespace' => array('test@example.com '),
283 'trailing carriage return' => array('test@example.com' . CR),
284 'trailing linefeed' => array('test@example.com' . LF),
285 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
286 'trailing tab' => array('test@example.com' . TAB),
287 );
288 }
289
290 /**
291 * @test
292 * @dataProvider validEmailInvalidDataProvider
293 */
294 public function validEmailReturnsFalseForInvalidMailAddress($address) {
295 $this->assertFalse(t3lib_div::validEmail($address));
296 }
297
298
299 //////////////////////////////////
300 // Tests concerning intExplode
301 //////////////////////////////////
302
303 /**
304 * @test
305 */
306 public function intExplodeConvertsStringsToInteger() {
307 $testString = '1,foo,2';
308 $expectedArray = array(1, 0, 2);
309 $actualArray = t3lib_div::intExplode(',', $testString);
310
311 $this->assertEquals($expectedArray, $actualArray);
312 }
313
314
315 //////////////////////////////////
316 // Tests concerning revExplode
317 //////////////////////////////////
318
319 /**
320 * @test
321 */
322 public function revExplodeExplodesString() {
323 $testString = 'my:words:here';
324 $expectedArray = array('my:words', 'here');
325 $actualArray = t3lib_div::revExplode(':', $testString, 2);
326
327 $this->assertEquals($expectedArray, $actualArray);
328 }
329
330
331 //////////////////////////////////
332 // Tests concerning trimExplode
333 //////////////////////////////////
334
335 /**
336 * @test
337 */
338 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
339 $testString = ' a , b , c ,d ,, e,f,';
340 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
341 $actualArray = t3lib_div::trimExplode(',', $testString);
342
343 $this->assertEquals($expectedArray, $actualArray);
344 }
345
346 /**
347 * @test
348 */
349 public function checkTrimExplodeRemovesNewLines() {
350 $testString = ' a , b , ' . LF . ' ,d ,, e,f,';
351 $expectedArray = array('a', 'b', 'd', 'e', 'f');
352 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
353
354 $this->assertEquals($expectedArray, $actualArray);
355 }
356
357 /**
358 * @test
359 */
360 public function checkTrimExplodeRemovesEmptyElements() {
361 $testString = 'a , b , c , ,d ,, ,e,f,';
362 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
363 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
364
365 $this->assertEquals($expectedArray, $actualArray);
366 }
367
368 /**
369 * @test
370 */
371 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
372 $testString = ' a , b , c , , d,, ,e ';
373 $expectedArray = array('a', 'b', 'c,,d,,,e');
374 // Limiting returns the rest of the string as the last element
375 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, 3);
376
377 $this->assertEquals($expectedArray, $actualArray);
378 }
379
380 /**
381 * @test
382 */
383 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
384 $testString = ' a , b , c , , d,, ,e ';
385 $expectedArray = array('a', 'b', 'c,d,e');
386 // Limiting returns the rest of the string as the last element
387 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 3);
388
389 $this->assertEquals($expectedArray, $actualArray);
390 }
391
392 /**
393 * @test
394 */
395 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
396 $testString = ' a , b , c , d, ,e, f , , ';
397 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
398 // limiting returns the rest of the string as the last element
399 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, -3);
400
401 $this->assertEquals($expectedArray, $actualArray);
402 }
403
404 /**
405 * @test
406 */
407 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
408 $testString = ' a , b , c , d, ,e, f , , ';
409 $expectedArray = array('a', 'b', 'c');
410 // Limiting returns the rest of the string as the last element
411 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, -3);
412
413 $this->assertEquals($expectedArray, $actualArray);
414 }
415
416 /**
417 * @test
418 */
419 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
420 $testString = ' a , b , , c , , , ';
421 $expectedArray = array('a', 'b', 'c');
422 // Limiting returns the rest of the string as the last element
423 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 4);
424
425 $this->assertEquals($expectedArray, $actualArray);
426 }
427
428 /**
429 * @test
430 */
431 public function checkTrimExplodeKeepsZeroAsString() {
432 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
433 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
434 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
435
436 $this->assertEquals($expectedArray, $actualArray);
437 }
438
439
440 //////////////////////////////////
441 // Tests concerning removeArrayEntryByValue
442 //////////////////////////////////
443
444 /**
445 * @test
446 */
447 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
448 $inputArray = array(
449 '0' => 'test1',
450 '1' => 'test2',
451 '2' => 'test3',
452 '3' => 'test2',
453 );
454 $compareValue = 'test2';
455 $expectedResult = array(
456 '0' => 'test1',
457 '2' => 'test3',
458 );
459 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
460 $this->assertEquals($expectedResult, $actualResult);
461 }
462
463 /**
464 * @test
465 */
466 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
467 $inputArray = array(
468 '0' => 'foo',
469 '1' => array(
470 '10' => 'bar',
471 ),
472 '2' => 'bar',
473 );
474 $compareValue = 'bar';
475 $expectedResult = array(
476 '0' => 'foo',
477 '1' => array(),
478 );
479 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
480 $this->assertEquals($expectedResult, $actualResult);
481 }
482
483 /**
484 * @test
485 */
486 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
487 $inputArray = array(
488 '0' => 'foo',
489 '1' => '',
490 '2' => 'bar',
491 );
492 $compareValue = '';
493 $expectedResult = array(
494 '0' => 'foo',
495 '2' => 'bar',
496 );
497 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
498 $this->assertEquals($expectedResult, $actualResult);
499 }
500
501 //////////////////////////////////
502 // Tests concerning getBytesFromSizeMeasurement
503 //////////////////////////////////
504
505 /**
506 * Data provider for getBytesFromSizeMeasurement
507 *
508 * @return array expected value, input string
509 */
510 public function getBytesFromSizeMeasurementDataProvider() {
511 return array(
512 '100 kilo Bytes' => array('102400', '100k'),
513 '100 mega Bytes' => array('104857600', '100m'),
514 '100 giga Bytes' => array('107374182400', '100g'),
515 );
516 }
517
518 /**
519 * @test
520 * @dataProvider getBytesFromSizeMeasurementDataProvider
521 */
522 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
523 $this->assertEquals($expected, t3lib_div::getBytesFromSizeMeasurement($byteString));
524 }
525
526
527 //////////////////////////////////
528 // Tests concerning getIndpEnv
529 //////////////////////////////////
530
531 /**
532 * @test
533 */
534 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
535 $this->assertTrue(strlen(t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
536 }
537
538 /**
539 * @test
540 */
541 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
542 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
543 $this->assertEquals('/', $result[0]);
544 }
545
546 /**
547 * @test
548 */
549 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
550 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
551 $this->assertEquals('/', $result[strlen($result) - 1]);
552 }
553
554
555 //////////////////////////////////
556 // Tests concerning underscoredToUpperCamelCase
557 //////////////////////////////////
558
559 /**
560 * Data provider for underscoredToUpperCamelCase
561 *
562 * @return array expected, input string
563 */
564 public function underscoredToUpperCamelCaseDataProvider() {
565 return array(
566 'single word' => array('Blogexample', 'blogexample'),
567 'multiple words' => array('BlogExample', 'blog_example'),
568 );
569 }
570
571 /**
572 * @test
573 * @dataProvider underscoredToUpperCamelCaseDataProvider
574 */
575 public function underscoredToUpperCamelCase($expected, $inputString) {
576 $this->assertEquals($expected, t3lib_div::underscoredToUpperCamelCase($inputString));
577 }
578
579
580 //////////////////////////////////
581 // Tests concerning underscoredToLowerCamelCase
582 //////////////////////////////////
583
584 /**
585 * Data provider for underscoredToLowerCamelCase
586 *
587 * @return array expected, input string
588 */
589 public function underscoredToLowerCamelCaseDataProvider() {
590 return array(
591 'single word' => array('minimalvalue', 'minimalvalue'),
592 'multiple words' => array('minimalValue', 'minimal_value'),
593 );
594 }
595
596 /**
597 * @test
598 * @dataProvider underscoredToLowerCamelCaseDataProvider
599 */
600 public function underscoredToLowerCamelCase($expected, $inputString) {
601 $this->assertEquals($expected, t3lib_div::underscoredToLowerCamelCase($inputString));
602 }
603
604 //////////////////////////////////
605 // Tests concerning camelCaseToLowerCaseUnderscored
606 //////////////////////////////////
607
608 /**
609 * Data provider for camelCaseToLowerCaseUnderscored
610 *
611 * @return array expected, input string
612 */
613 public function camelCaseToLowerCaseUnderscoredDataProvider() {
614 return array(
615 'single word' => array('blogexample', 'blogexample'),
616 'single word starting upper case' => array('blogexample', 'Blogexample'),
617 'two words starting lower case' => array('minimal_value', 'minimalValue'),
618 'two words starting upper case' => array('blog_example', 'BlogExample'),
619 );
620 }
621
622 /**
623 * @test
624 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
625 */
626 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
627 $this->assertEquals($expected, t3lib_div::camelCaseToLowerCaseUnderscored($inputString));
628 }
629
630
631 //////////////////////////////////
632 // Tests concerning lcFirst
633 //////////////////////////////////
634
635 /**
636 * Data provider for lcFirst
637 *
638 * @return array expected, input string
639 */
640 public function lcfirstDataProvider() {
641 return array(
642 'single word' => array('blogexample', 'blogexample'),
643 'single Word starting upper case' => array('blogexample', 'Blogexample'),
644 'two words' => array('blogExample', 'BlogExample'),
645 );
646 }
647
648 /**
649 * @test
650 * @dataProvider lcfirstDataProvider
651 */
652 public function lcFirst($expected, $inputString) {
653 $this->assertEquals($expected, t3lib_div::lcfirst($inputString));
654 }
655
656
657 //////////////////////////////////
658 // Tests concerning encodeHeader
659 //////////////////////////////////
660
661 /**
662 * @test
663 */
664 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
665 $this->assertEquals(
666 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
667 t3lib_div::encodeHeader(
668 "We test whether the copyright character \xc2\xa9 is encoded correctly",
669 'quoted-printable',
670 'utf-8'
671 )
672 );
673 }
674
675 /**
676 * @test
677 */
678 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
679 $this->assertEquals(
680 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
681 t3lib_div::encodeHeader(
682 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
683 'quoted-printable',
684 'utf-8'
685 )
686 );
687 }
688
689
690 //////////////////////////////////
691 // Tests concerning isValidUrl
692 //////////////////////////////////
693
694 /**
695 * Data provider for valid isValidUrl's
696 *
697 * @return array Valid ressource
698 */
699 public function validUrlValidRessourceDataProvider() {
700 return array(
701 'http' => array('http://www.example.org/'),
702 'http without trailing slash' => array('http://qwe'),
703 'http directory with trailing slash' => array('http://www.example/img/dir/'),
704 'http directory without trailing slash' => array('http://www.example/img/dir'),
705 'http index.html' => array('http://example.com/index.html'),
706 'http index.php' => array('http://www.example.com/index.php'),
707 'http test.png' => array('http://www.example/img/test.png'),
708 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
709 'file' => array('file:///tmp/test.c'),
710 'file directory' => array('file://foo/bar'),
711 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
712 'mailto' => array('mailto:foo@bar.com'),
713 'news' => array('news:news.php.net'),
714 'telnet'=> array('telnet://192.0.2.16:80/'),
715 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
716 );
717 }
718
719 /**
720 * @test
721 * @dataProvider validUrlValidRessourceDataProvider
722 */
723 public function validURLReturnsTrueForValidRessource($url) {
724 $this->assertTrue(t3lib_div::isValidUrl($url));
725 }
726
727 /**
728 * Data provider for invalid isValidUrl's
729 *
730 * @return array Invalid ressource
731 */
732 public function isValidUrlInvalidRessourceDataProvider() {
733 return array(
734 'http missing colon' => array('http//www.example/wrong/url/'),
735 'http missing slash' => array('http:/www.example'),
736 'hostname only' => array('www.example.org/'),
737 'file missing protocol specification' => array('/tmp/test.c'),
738 'slash only' => array('/'),
739 'string http://' => array('http://'),
740 'string http:/' => array('http:/'),
741 'string http:' => array('http:'),
742 'string http' => array('http'),
743 'empty string' => array(''),
744 'string -1' => array('-1'),
745 'string array()' => array('array()'),
746 'random string' => array('qwe'),
747 );
748 }
749
750 /**
751 * @test
752 * @dataProvider isValidUrlInvalidRessourceDataProvider
753 */
754 public function validURLReturnsFalseForInvalidRessoure($url) {
755 $this->assertFalse(t3lib_div::isValidUrl($url));
756 }
757
758
759 //////////////////////////////////
760 // Tests concerning isOnCurrentHost
761 //////////////////////////////////
762
763 /**
764 * @test
765 */
766 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
767 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
768 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
769 }
770
771 /**
772 * Data provider for invalid isOnCurrentHost's
773 *
774 * @return array Invalid Hosts
775 */
776 public function checkisOnCurrentHostInvalidHosts() {
777 return array(
778 'empty string' => array(''),
779 'arbitrary string' => array('arbitrary string'),
780 'localhost IP' => array('127.0.0.1'),
781 'relative path' => array('./relpath/file.txt'),
782 'absolute path' => array('/abspath/file.txt?arg=value'),
783 'differnt host' => array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
784 );
785 }
786
787
788 ////////////////////////////////////////
789 // Tests concerning sanitizeLocalUrl
790 ////////////////////////////////////////
791
792 /**
793 * Data provider for valid sanitizeLocalUrl's
794 *
795 * @return array Valid url
796 */
797 public function sanitizeLocalUrlValidUrlDataProvider() {
798 $subDirectory = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
799 $typo3SiteUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
800 $typo3RequestHost = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
801
802 return array(
803 'alt_intro.php' => array('alt_intro.php'),
804 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
805 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
806 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
807 '../index.php' => array('../index.php'),
808 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
809 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
810 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
811 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
812 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
813 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
814 );
815 }
816
817 /**
818 * @test
819 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
820 */
821 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
822 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
823 }
824
825 /**
826 * @test
827 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
828 */
829 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
830 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
831 }
832
833 /**
834 * Data provider for invalid sanitizeLocalUrl's
835 *
836 * @return array Valid url
837 */
838 public function sanitizeLocalUrlInvalidDataProvider() {
839 return array(
840 'empty string' => array(''),
841 'http domain' => array('http://www.google.de/'),
842 'https domain' => array('https://www.google.de/'),
843 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
844 );
845 }
846
847 /**
848 * @test
849 * @dataProvider sanitizeLocalUrlInvalidDataProvider
850 */
851 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
852 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
853 }
854
855 /**
856 * @test
857 * @dataProvider sanitizeLocalUrlInvalidDataProvider
858 */
859 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
860 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
861 }
862
863
864 //////////////////////////////////////
865 // Tests concerning arrayDiffAssocRecursive
866 //////////////////////////////////////
867
868 /**
869 * @test
870 */
871 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
872 $array1 = array(
873 'key1' => 'value1',
874 'key2' => 'value2',
875 'key3' => 'value3',
876 );
877 $array2 = array(
878 'key1' => 'value1',
879 'key3' => 'value3',
880 );
881 $expectedResult = array(
882 'key2' => 'value2',
883 );
884 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
885 $this->assertEquals($expectedResult, $actualResult);
886 }
887
888 /**
889 * @test
890 */
891 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
892 $array1 = array(
893 'key1' => 'value1',
894 'key2' => array(
895 'key21' => 'value21',
896 'key22' => 'value22',
897 'key23' => array(
898 'key231' => 'value231',
899 'key232' => 'value232',
900 ),
901 ),
902 );
903 $array2 = array(
904 'key1' => 'value1',
905 'key2' => array(
906 'key21' => 'value21',
907 'key23' => array(
908 'key231' => 'value231',
909 ),
910 ),
911 );
912 $expectedResult = array(
913 'key2' => array(
914 'key22' => 'value22',
915 'key23' => array(
916 'key232' => 'value232',
917 ),
918 ),
919 );
920 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
921 $this->assertEquals($expectedResult, $actualResult);
922 }
923
924 /**
925 * @test
926 */
927 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
928 $array1 = array(
929 'key1' => array(
930 'key11' => 'value11',
931 'key12' => 'value12',
932 ),
933 'key2' => 'value2',
934 'key3' => 'value3',
935 );
936 $array2 = array(
937 'key1' => 'value1',
938 'key2' => array(
939 'key21' => 'value21',
940 ),
941 );
942 $expectedResult = array(
943 'key3' => 'value3',
944 );
945 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
946 $this->assertEquals($expectedResult, $actualResult);
947 }
948
949
950 //////////////////////////////////////
951 // Tests concerning removeDotsFromTS
952 //////////////////////////////////////
953
954 /**
955 * @test
956 */
957 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
958 $typoScript = array(
959 'propertyA.' => array(
960 'keyA.' => array(
961 'valueA' => 1,
962 ),
963 'keyB' => 2,
964 ),
965 'propertyB' => 3,
966 );
967
968 $expectedResult = array(
969 'propertyA' => array(
970 'keyA' => array(
971 'valueA' => 1,
972 ),
973 'keyB' => 2,
974 ),
975 'propertyB' => 3,
976 );
977
978 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
979 }
980
981 /**
982 * @test
983 */
984 public function removeDotsFromTypoScriptOverridesSubArray() {
985 $typoScript = array(
986 'propertyA.' => array(
987 'keyA' => 'getsOverridden',
988 'keyA.' => array(
989 'valueA' => 1,
990 ),
991 'keyB' => 2,
992 ),
993 'propertyB' => 3,
994 );
995
996 $expectedResult = array(
997 'propertyA' => array(
998 'keyA' => array(
999 'valueA' => 1,
1000 ),
1001 'keyB' => 2,
1002 ),
1003 'propertyB' => 3,
1004 );
1005
1006 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1007 }
1008
1009 /**
1010 * @test
1011 */
1012 public function removeDotsFromTypoScriptOverridesWithScalar() {
1013 $typoScript = array(
1014 'propertyA.' => array(
1015 'keyA.' => array(
1016 'valueA' => 1,
1017 ),
1018 'keyA' => 'willOverride',
1019 'keyB' => 2,
1020 ),
1021 'propertyB' => 3,
1022 );
1023
1024 $expectedResult = array(
1025 'propertyA' => array(
1026 'keyA' => 'willOverride',
1027 'keyB' => 2,
1028 ),
1029 'propertyB' => 3,
1030 );
1031
1032 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1033 }
1034
1035
1036 //////////////////////////////////////
1037 // Tests concerning get_dirs
1038 //////////////////////////////////////
1039
1040 /**
1041 * @test
1042 */
1043 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1044 $path = PATH_t3lib;
1045 $directories = t3lib_div::get_dirs($path);
1046
1047 $this->assertType('array', $directories);
1048 }
1049
1050 /**
1051 * @test
1052 */
1053 public function getDirsReturnsStringErrorOnPathFailure() {
1054 $path = 'foo';
1055 $result = t3lib_div::get_dirs($path);
1056 $expectedResult = 'error';
1057
1058 $this->assertEquals($expectedResult, $result);
1059 }
1060
1061
1062 //////////////////////////////////
1063 // Tests concerning hmac
1064 //////////////////////////////////
1065
1066 /**
1067 * @test
1068 */
1069 public function hmacReturnsHashOfProperLength() {
1070 $hmac = t3lib_div::hmac('message');
1071 $this->assertTrue(!empty($hmac) && is_string($hmac));
1072 $this->assertTrue(strlen($hmac) == 40);
1073 }
1074
1075 /**
1076 * @test
1077 */
1078 public function hmacReturnsEqualHashesForEqualInput() {
1079 $msg0 = 'message';
1080 $msg1 = 'message';
1081 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1082 }
1083
1084 /**
1085 * @test
1086 */
1087 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1088 $msg0 = 'message0';
1089 $msg1 = 'message1';
1090 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1091 }
1092
1093
1094 //////////////////////////////////
1095 // Tests concerning quoteJSvalue
1096 //////////////////////////////////
1097
1098 /**
1099 * @test
1100 */
1101 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1102 $this->assertContains(
1103 '&gt;',
1104 t3lib_div::quoteJSvalue('>')
1105 );
1106 }
1107
1108 /**
1109 * @test
1110 */
1111 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1112 $this->assertContains(
1113 '&gt;',
1114 t3lib_div::quoteJSvalue('>', false)
1115 );
1116 }
1117
1118 /**
1119 * @test
1120 */
1121 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1122 $this->assertContains(
1123 '>',
1124 t3lib_div::quoteJSvalue('>', true)
1125 );
1126 }
1127
1128 /**
1129 * @test
1130 */
1131 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1132 $this->assertEquals(
1133 "''",
1134 t3lib_div::quoteJSvalue("", true)
1135 );
1136 }
1137
1138 /**
1139 * @test
1140 */
1141 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1142 $this->assertEquals(
1143 "'Hello world!'",
1144 t3lib_div::quoteJSvalue("Hello world!", true)
1145 );
1146 }
1147
1148 /**
1149 * @test
1150 */
1151 public function quoteJSvalueEscapesSingleQuote() {
1152 $this->assertEquals(
1153 "'\\''",
1154 t3lib_div::quoteJSvalue("'", true)
1155 );
1156 }
1157
1158 /**
1159 * @test
1160 */
1161 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1162 $this->assertEquals(
1163 "'\\\"'",
1164 t3lib_div::quoteJSvalue('"', true)
1165 );
1166 }
1167
1168 /**
1169 * @test
1170 */
1171 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1172 $this->assertEquals(
1173 "'\\&quot;'",
1174 t3lib_div::quoteJSvalue('"', false)
1175 );
1176 }
1177
1178 /**
1179 * @test
1180 */
1181 public function quoteJSvalueEscapesTab() {
1182 $this->assertEquals(
1183 "'" . '\t' . "'",
1184 t3lib_div::quoteJSvalue(TAB)
1185 );
1186 }
1187
1188 /**
1189 * @test
1190 */
1191 public function quoteJSvalueEscapesLinefeed() {
1192 $this->assertEquals(
1193 "'" . '\n' . "'",
1194 t3lib_div::quoteJSvalue(LF)
1195 );
1196 }
1197
1198 /**
1199 * @test
1200 */
1201 public function quoteJSvalueEscapesCarriageReturn() {
1202 $this->assertEquals(
1203 "'" . '\r' . "'",
1204 t3lib_div::quoteJSvalue(CR)
1205 );
1206 }
1207
1208 /**
1209 * @test
1210 */
1211 public function quoteJSvalueEscapesBackslah() {
1212 $this->assertEquals(
1213 "'\\\\'",
1214 t3lib_div::quoteJSvalue('\\')
1215 );
1216 }
1217
1218 //////////////////////////////////
1219 // Tests concerning readLLfile
1220 //////////////////////////////////
1221
1222 /**
1223 * @test
1224 */
1225 public function readLLfileHandlesLocallangXMLOverride() {
1226 $unique = uniqid('locallangXMLOverrideTest');
1227
1228 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
1229 <T3locallang>
1230 <data type="array">
1231 <languageKey index="default" type="array">
1232 <label index="buttons.logout">EXIT</label>
1233 </languageKey>
1234 </data>
1235 </T3locallang>';
1236
1237 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
1238 t3lib_div::writeFileToTypo3tempDir($file, $xml);
1239
1240 // Get default value
1241 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1242
1243 // Set override file
1244 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
1245
1246 // Get override value
1247 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1248
1249 // Clean up again
1250 unlink($file);
1251
1252 $this->assertNotEquals($overrideLL['default']['buttons.logout'], '');
1253 $this->assertNotEquals($defaultLL['default']['buttons.logout'], $overrideLL['default']['buttons.logout']);
1254 $this->assertEquals($overrideLL['default']['buttons.logout'], 'EXIT');
1255 }
1256
1257
1258 ///////////////////////////////
1259 // Tests concerning _GETset()
1260 ///////////////////////////////
1261
1262 /**
1263 * @test
1264 */
1265 public function getSetWritesArrayToGetSystemVariable() {
1266 $_GET = array();
1267 $GLOBALS['HTTP_GET_VARS'] = array();
1268
1269 $getParameters = array('foo' => 'bar');
1270 t3lib_div::_GETset($getParameters);
1271 $this->assertSame($getParameters, $_GET);
1272 }
1273
1274 /**
1275 * @test
1276 */
1277 public function getSetWritesArrayToGlobalsHttpGetVars() {
1278 $_GET = array();
1279 $GLOBALS['HTTP_GET_VARS'] = array();
1280
1281 $getParameters = array('foo' => 'bar');
1282 t3lib_div::_GETset($getParameters);
1283 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
1284 }
1285
1286 /**
1287 * @test
1288 */
1289 public function getSetForArrayDropsExistingValues() {
1290 $_GET = array();
1291 $GLOBALS['HTTP_GET_VARS'] = array();
1292
1293 t3lib_div::_GETset(array('foo' => 'bar'));
1294
1295 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
1296
1297 $this->assertEquals(
1298 array('oneKey' => 'oneValue'),
1299 $GLOBALS['HTTP_GET_VARS']
1300 );
1301 }
1302
1303 /**
1304 * @test
1305 */
1306 public function getSetAssignsOneValueToOneKey() {
1307 $_GET = array();
1308 $GLOBALS['HTTP_GET_VARS'] = array();
1309
1310 t3lib_div::_GETset('oneValue', 'oneKey');
1311
1312 $this->assertEquals(
1313 'oneValue',
1314 $GLOBALS['HTTP_GET_VARS']['oneKey']
1315 );
1316 }
1317
1318 /**
1319 * @test
1320 */
1321 public function getSetForOneValueDoesNotDropUnrelatedValues() {
1322 $_GET = array();
1323 $GLOBALS['HTTP_GET_VARS'] = array();
1324
1325 t3lib_div::_GETset(array('foo' => 'bar'));
1326 t3lib_div::_GETset('oneValue', 'oneKey');
1327
1328 $this->assertEquals(
1329 array('foo' => 'bar', 'oneKey' => 'oneValue'),
1330 $GLOBALS['HTTP_GET_VARS']
1331 );
1332 }
1333
1334 /**
1335 * @test
1336 */
1337 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
1338 $_GET = array();
1339 $GLOBALS['HTTP_GET_VARS'] = array();
1340
1341 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
1342
1343 $this->assertEquals(
1344 array('parentKey' => array('childKey' => 'oneValue')),
1345 $GLOBALS['HTTP_GET_VARS']
1346 );
1347 }
1348
1349 /**
1350 * @test
1351 */
1352 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
1353 $_GET = array();
1354 $GLOBALS['HTTP_GET_VARS'] = array();
1355
1356 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
1357
1358 $this->assertEquals(
1359 array('parentKey' => array('childKey' => 'oneValue')),
1360 $GLOBALS['HTTP_GET_VARS']
1361 );
1362 }
1363
1364 /**
1365 * @test
1366 */
1367 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
1368 $_GET = array();
1369 $GLOBALS['HTTP_GET_VARS'] = array();
1370
1371 t3lib_div::_GETset(
1372 array('key1' => 'value1', 'key2' => 'value2'),
1373 'parentKey|childKey'
1374 );
1375
1376 $this->assertEquals(
1377 array(
1378 'parentKey' => array(
1379 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
1380 )
1381 ),
1382 $GLOBALS['HTTP_GET_VARS']
1383 );
1384 }
1385
1386
1387 ///////////////////////////////
1388 // Tests concerning fixPermissions
1389 ///////////////////////////////
1390
1391 /**
1392 * @test
1393 */
1394 public function fixPermissionsCorrectlySetsPermissionsToFile() {
1395 if (TYPO3_OS == 'WIN') {
1396 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1397 }
1398
1399 // Create and prepare test file
1400 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
1401 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1402 chmod($filename, 0742);
1403
1404 // Set target permissions and run method
1405 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1406 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1407 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1408
1409 // Get actual permissions and clean up
1410 clearstatcache();
1411 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1412 $resultFileGroup = filegroup($filename);
1413 unlink($filename);
1414
1415 // Test if everything was ok
1416 $this->assertTrue($fixPermissionsResult);
1417 $this->assertEquals($resultFilePermissions, '0660');
1418 $this->assertEquals($resultFileGroup, posix_getegid());
1419 }
1420
1421 /**
1422 * @test
1423 */
1424 public function fixPermissionsCorrectlySetsPermissionsToHiddenFile() {
1425 if (TYPO3_OS == 'WIN') {
1426 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1427 }
1428
1429 // Create and prepare test file
1430 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
1431 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1432 chmod($filename, 0742);
1433
1434 // Set target permissions and run method
1435 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1436 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1437 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1438
1439 // Get actual permissions and clean up
1440 clearstatcache();
1441 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1442 $resultFileGroup = filegroup($filename);
1443 unlink($filename);
1444
1445 // Test if everything was ok
1446 $this->assertTrue($fixPermissionsResult);
1447 $this->assertEquals($resultFilePermissions, '0660');
1448 $this->assertEquals($resultFileGroup, posix_getegid());
1449 }
1450
1451 /**
1452 * @test
1453 */
1454 public function fixPermissionsCorrectlySetsPermissionsToDirectory() {
1455 if (TYPO3_OS == 'WIN') {
1456 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1457 }
1458
1459 // Create and prepare test directory
1460 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1461 t3lib_div::mkdir($directory);
1462 chmod($directory, 1551);
1463
1464 // Set target permissions and run method
1465 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1466 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1467 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
1468
1469 // Get actual permissions and clean up
1470 clearstatcache();
1471 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1472 $resultDirectoryGroup = filegroup($directory);
1473 t3lib_div::rmdir($directory);
1474
1475 // Test if everything was ok
1476 $this->assertTrue($fixPermissionsResult);
1477 $this->assertEquals($resultDirectoryPermissions, '0770');
1478 $this->assertEquals($resultDirectoryGroup, posix_getegid());
1479 }
1480
1481 /**
1482 * @test
1483 */
1484 public function fixPermissionsCorrectlySetsPermissionsToHiddenDirectory() {
1485 if (TYPO3_OS == 'WIN') {
1486 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1487 }
1488
1489 // Create and prepare test directory
1490 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1491 t3lib_div::mkdir($directory);
1492 chmod($directory, 1551);
1493
1494 // Set target permissions and run method
1495 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1496 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1497 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
1498
1499 // Get actual permissions and clean up
1500 clearstatcache();
1501 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1502 $resultDirectoryGroup = filegroup($directory);
1503 t3lib_div::rmdir($directory);
1504
1505 // Test if everything was ok
1506 $this->assertTrue($fixPermissionsResult);
1507 $this->assertEquals($resultDirectoryPermissions, '0770');
1508 $this->assertEquals($resultDirectoryGroup, posix_getegid());
1509 }
1510
1511 /**
1512 * @test
1513 */
1514 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
1515 if (TYPO3_OS == 'WIN') {
1516 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1517 }
1518
1519 // Create and prepare test directory and file structure
1520 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
1521 t3lib_div::mkdir($baseDirectory);
1522 chmod($baseDirectory, 1751);
1523 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
1524 chmod($baseDirectory . '/file', 0742);
1525 t3lib_div::mkdir($baseDirectory . '/foo');
1526 chmod($baseDirectory . '/foo', 1751);
1527 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
1528 chmod($baseDirectory . '/foo/file', 0742);
1529 t3lib_div::mkdir($baseDirectory . '/.bar');
1530 chmod($baseDirectory . '/.bar', 1751);
1531 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
1532 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
1533 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
1534 touch($baseDirectory . '/.bar/.file', '42');
1535 chmod($baseDirectory . '/.bar/.file', 0742);
1536 touch($baseDirectory . '/.bar/..file2', '42');
1537 chmod($baseDirectory . '/.bar/..file2', 0742);
1538
1539 // Set target permissions and run method
1540 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1541 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1542 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1543 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
1544
1545 // Get actual permissions
1546 clearstatcache();
1547 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
1548 $resultBaseDirectoryGroup = filegroup($baseDirectory);
1549 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
1550 $resultBaseFileGroup = filegroup($baseDirectory . '/file');
1551 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
1552 $resultFooDirectoryGroup = filegroup($baseDirectory . '/foo');
1553 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
1554 $resultFooFileGroup = filegroup($baseDirectory . '/foo/file');
1555 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
1556 $resultBarDirectoryGroup = filegroup($baseDirectory . '/.bar');
1557 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
1558 $resultBarFileGroup = filegroup($baseDirectory . '/.bar/.file');
1559 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
1560 $resultBarFile2Group = filegroup($baseDirectory . '/.bar/..file2');
1561
1562 // Clean up
1563 unlink($baseDirectory . '/file');
1564 unlink($baseDirectory . '/foo/file');
1565 unlink($baseDirectory . '/.bar/.file');
1566 unlink($baseDirectory . '/.bar/..file2');
1567 t3lib_div::rmdir($baseDirectory . '/foo');
1568 t3lib_div::rmdir($baseDirectory . '/.bar');
1569 t3lib_div::rmdir($baseDirectory);
1570
1571 // Test if everything was ok
1572 $this->assertTrue($fixPermissionsResult);
1573 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
1574 $this->assertEquals($resultBaseDirectoryGroup, posix_getegid());
1575 $this->assertEquals($resultBaseFilePermissions, '0660');
1576 $this->assertEquals($resultBaseFileGroup, posix_getegid());
1577 $this->assertEquals($resultFooDirectoryPermissions, '0770');
1578 $this->assertEquals($resultFooDirectoryGroup, posix_getegid());
1579 $this->assertEquals($resultFooFilePermissions, '0660');
1580 $this->assertEquals($resultFooFileGroup, posix_getegid());
1581 $this->assertEquals($resultBarDirectoryPermissions, '0770');
1582 $this->assertEquals($resultBarDirectoryGroup, posix_getegid());
1583 $this->assertEquals($resultBarFilePermissions, '0660');
1584 $this->assertEquals($resultBarFileGroup, posix_getegid());
1585 $this->assertEquals($resultBarFile2Permissions, '0660');
1586 $this->assertEquals($resultBarFile2Group, posix_getegid());
1587 }
1588
1589 /**
1590 * @test
1591 */
1592 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
1593 if (TYPO3_OS == 'WIN') {
1594 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1595 }
1596
1597 // Create and prepare test file
1598 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
1599 touch($filename);
1600 chmod($filename, 0742);
1601
1602 // Set target permissions and run method
1603 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1604 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1605
1606 // Get actual permissions and clean up
1607 clearstatcache();
1608 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1609 unlink($filename);
1610
1611 // Test if everything was ok
1612 $this->assertFalse($fixPermissionsResult);
1613 $this->assertEquals($resultFilePermissions, '0742');
1614 }
1615
1616
1617 ///////////////////////////////
1618 // Tests concerning mkdir
1619 ///////////////////////////////
1620
1621 /**
1622 * @test
1623 */
1624 public function mkdirCorrectlyCreatesDirectory() {
1625 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1626 $mkdirResult = t3lib_div::mkdir($directory);
1627 $directoryCreated = is_dir($directory);
1628 t3lib_div::rmdir($directory);
1629 $this->assertTrue($mkdirResult);
1630 $this->assertTrue($directoryCreated);
1631 }
1632
1633 /**
1634 * @test
1635 */
1636 public function mkdirCorrectlyCreatesHiddenDirectory() {
1637 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1638 $mkdirResult = t3lib_div::mkdir($directory);
1639 $directoryCreated = is_dir($directory);
1640 t3lib_div::rmdir($directory);
1641 $this->assertTrue($mkdirResult);
1642 $this->assertTrue($directoryCreated);
1643 }
1644
1645 /**
1646 * @test
1647 */
1648 public function mkdirCorrectlyCreatesDirectoryWithTrailingSlash() {
1649 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1650 $mkdirResult = t3lib_div::mkdir($directory);
1651 $directoryCreated = is_dir($directory);
1652 t3lib_div::rmdir($directory);
1653 $this->assertTrue($mkdirResult);
1654 $this->assertTrue($directoryCreated);
1655 }
1656
1657
1658 ///////////////////////////////
1659 // Tests concerning split_fileref
1660 ///////////////////////////////
1661
1662 /**
1663 * @test
1664 */
1665 public function splitFileRefReturnsFileTypeNotForFolders(){
1666 $directoryName = uniqid('test_') . '.com';
1667 $directoryPath = PATH_site . 'typo3temp/';
1668 $directory = $directoryPath . $directoryName;
1669 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
1670
1671 $fileInfo = t3lib_div::split_fileref($directory);
1672
1673 $directoryCreated = is_dir($directory);
1674 rmdir($directory);
1675
1676 $this->assertTrue($directoryCreated);
1677 $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
1678 $this->assertEquals($directoryPath, $fileInfo['path']);
1679 $this->assertEquals($directoryName, $fileInfo['file']);
1680 $this->assertEquals($directoryName, $fileInfo['filebody']);
1681 $this->assertEquals('', $fileInfo['fileext']);
1682 $this->assertArrayNotHasKey('realFileext', $fileInfo);
1683 }
1684
1685 /**
1686 * @test
1687 */
1688 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
1689 $testFile = 'fileadmin/media/someFile.png';
1690
1691 $fileInfo = t3lib_div::split_fileref($testFile);
1692 $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
1693 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
1694 $this->assertEquals('someFile.png', $fileInfo['file']);
1695 $this->assertEquals('someFile', $fileInfo['filebody']);
1696 $this->assertEquals('png', $fileInfo['fileext']);
1697 }
1698 }
1699 ?>