Fixed #11206: Cleaned up test "t3lib_extmgm_testcase" (Thanks to Oliver Klee)
[Packages/TYPO3.CMS.git] / tests / t3lib / t3lib_div_testcase.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 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_div_testcase extends tx_phpunit_testcase {
36 /**
37 * @test
38 */
39 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
40 $testString = ' a , b , c ,d ,, e,f,';
41 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
42 $actualArray = t3lib_div::trimExplode(',', $testString);
43
44 $this->assertEquals($expectedArray, $actualArray);
45 }
46
47 /**
48 * @test
49 */
50 public function checkTrimExplodeRemovesNewLines() {
51 $testString = ' a , b , ' . chr(10) . ' ,d ,, e,f,';
52 $expectedArray = array('a', 'b', 'd', 'e', 'f');
53 $actualArray = t3lib_div::trimExplode(',', $testString, true);
54
55 $this->assertEquals($expectedArray, $actualArray);
56 }
57
58 /**
59 * @test
60 */
61 public function checkTrimExplodeRemovesEmptyElements() {
62 $testString = 'a , b , c , ,d ,, ,e,f,';
63 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
64 $actualArray = t3lib_div::trimExplode(',', $testString, true);
65
66 $this->assertEquals($expectedArray, $actualArray);
67 }
68
69 /**
70 * @test
71 */
72 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
73 $testString = ' a , b , c , , d,, ,e ';
74 $expectedArray = array('a', 'b', 'c,,d,,,e'); // limiting returns the rest of the string as the last element
75 $actualArray = t3lib_div::trimExplode(',', $testString, false, 3);
76
77 $this->assertEquals($expectedArray, $actualArray);
78 }
79
80 /**
81 * @test
82 */
83 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
84 $testString = ' a , b , c , , d,, ,e ';
85 $expectedArray = array('a', 'b', 'c,d,e'); // limiting returns the rest of the string as the last element
86 $actualArray = t3lib_div::trimExplode(',', $testString, true, 3);
87
88 $this->assertEquals($expectedArray, $actualArray);
89 }
90
91 /**
92 * @test
93 */
94 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
95 $testString = ' a , b , c , d, ,e, f , , ';
96 $expectedArray = array('a', 'b', 'c', 'd', '', 'e'); // limiting returns the rest of the string as the last element
97 $actualArray = t3lib_div::trimExplode(',', $testString, false, -3);
98
99 $this->assertEquals($expectedArray, $actualArray);
100 }
101
102 /**
103 * @test
104 */
105 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
106 $testString = ' a , b , c , d, ,e, f , , ';
107 $expectedArray = array('a', 'b', 'c'); // limiting returns the rest of the string as the last element
108 $actualArray = t3lib_div::trimExplode(',', $testString, true, -3);
109
110 $this->assertEquals($expectedArray, $actualArray);
111 }
112
113 /**
114 * @test
115 */
116 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
117 $testString = ' a , b , , c , , , ';
118 $expectedArray = array('a', 'b', 'c'); // limiting returns the rest of the string as the last element
119 $actualArray = t3lib_div::trimExplode(',', $testString, true, 4);
120
121 $this->assertEquals($expectedArray, $actualArray);
122 }
123
124 /**
125 * @test
126 */
127 public function checkTrimExplodeKeepsZeroAsString() {
128 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
129 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
130 $actualArray = t3lib_div::trimExplode(',', $testString, true);
131
132 $this->assertEquals($expectedArray, $actualArray);
133 }
134
135 /**
136 * Checks whether measurement strings like "100k" return the accordant
137 * byte representation like 102400 in this case.
138 *
139 * @test
140 */
141 public function checkGetBytesFromSizeMeasurement() {
142 $this->assertEquals(
143 '102400',
144 t3lib_div::getBytesFromSizeMeasurement('100k')
145 );
146
147 $this->assertEquals(
148 '104857600',
149 t3lib_div::getBytesFromSizeMeasurement('100m')
150 );
151
152 $this->assertEquals(
153 '107374182400',
154 t3lib_div::getBytesFromSizeMeasurement('100g')
155 );
156 }
157
158 /**
159 * @test
160 */
161 public function checkIndpEnvTypo3SitePathNotEmpty() {
162 $actualEnv = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
163 $this->assertTrue(strlen($actualEnv) >= 1);
164 $this->assertEquals('/', $actualEnv{0});
165 $this->assertEquals('/', $actualEnv{strlen($actualEnv) - 1});
166 }
167
168 /**
169 * @test
170 * @see t3lib_div::underscoredToUpperCamelCase
171 */
172 public function canConvertFromUnderscoredToUpperCamelCase() {
173 $this->assertEquals('BlogExample', t3lib_div::underscoredToUpperCamelCase('blog_example'));
174 $this->assertEquals('Blogexample', t3lib_div::underscoredToUpperCamelCase('blogexample'));
175 }
176
177 /**
178 * @test
179 * @see t3lib_div::underscoredToLowerCamelCase
180 */
181 public function canConvertFromUnderscoredToLowerCamelCase() {
182 $this->assertEquals('minimalValue', t3lib_div::underscoredToLowerCamelCase('minimal_value'));
183 $this->assertEquals('minimalvalue', t3lib_div::underscoredToLowerCamelCase('minimalvalue'));
184 }
185
186 /**
187 * @test
188 * @see t3lib_div::camelCaseToLowerCaseUnderscored
189 */
190 public function canConvertFromCamelCaseToLowerCaseUnderscored() {
191 $this->assertEquals('blog_example', t3lib_div::camelCaseToLowerCaseUnderscored('BlogExample'));
192 $this->assertEquals('blogexample', t3lib_div::camelCaseToLowerCaseUnderscored('Blogexample'));
193 $this->assertEquals('blogexample', t3lib_div::camelCaseToLowerCaseUnderscored('blogexample'));
194
195 $this->assertEquals('minimal_value', t3lib_div::camelCaseToLowerCaseUnderscored('minimalValue'));
196 }
197
198 /**
199 * @test
200 * @see t3lib_div::lcfirst
201 */
202 public function canConvertFirstCharacterToBeLowerCase() {
203 $this->assertEquals('blogexample', t3lib_div::lcfirst('Blogexample'));
204 $this->assertEquals('blogExample', t3lib_div::lcfirst('BlogExample'));
205 $this->assertEquals('blogexample', t3lib_div::lcfirst('blogexample'));
206 }
207
208 /**
209 * Tests whether whitespaces are encoded correctly in a quoted-printable mail header.
210 * @test
211 */
212 public function areWhitespacesEncodedInQuotedPrintableMailHeader() {
213 $this->assertEquals(
214 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
215 t3lib_div::encodeHeader(
216 "We test whether the copyright character \xc2\xa9 is encoded correctly",
217 'quoted-printable',
218 'utf-8'
219 )
220 );
221 }
222
223 /**
224 * Tests whether question marks are encoded correctly in a quoted-printable mail header.
225 * @test
226 */
227 public function areQuestionMarksEncodedInQuotedPrintableMailHeader() {
228 $this->assertEquals(
229 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
230 t3lib_div::encodeHeader(
231 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
232 'quoted-printable',
233 'utf-8'
234 )
235 );
236 }
237
238 /**
239 * @test
240 * @see t3lib_div::isValidUrl()
241 */
242 public function checkisValidURLSucceedsWithWebRessource() {
243 $testUrl = 'http://www.example.org/';
244 $this->assertTrue(t3lib_div::isValidUrl($testUrl));
245 }
246
247 /**
248 * @test
249 * @see t3lib_div::isValidUrl()
250 */
251 public function checkisValidURLSucceedsWithExtentedWebRessource() {
252 $testUrl = 'https://user:pw@www.example.org:80/path?arg=value#fragment';
253 $this->assertTrue(t3lib_div::isValidUrl($testUrl));
254 }
255
256 /**
257 * @test
258 * @see t3lib_div::isValidUrl()
259 */
260 public function checkisValidURLSucceedsWithTelnetRessource() {
261 $testUrl = 'telnet://192.0.2.16:80/';
262 $this->assertTrue(t3lib_div::isValidUrl($testUrl));
263 }
264
265 /**
266 * @test
267 */
268 public function checkisValidURLSucceedsWithLdapRessource() {
269 $testUrl = 'ldap://[2001:db8::7]/c=GB?objectClass?one';
270 $this->assertTrue(t3lib_div::isValidUrl($testUrl));
271 }
272
273 /**
274 * @test
275 * @see t3lib_div::isValidUrl()
276 */
277 public function checkisValidURLSucceedsWithFileRessource() {
278 $testUrl = 'file:///etc/passwd';
279 $this->assertTrue(t3lib_div::isValidUrl($testUrl));
280 }
281
282 /**
283 * @test
284 * @see t3lib_div::isValidUrl()
285 */
286 public function checkisValidURLFailsWithHostnameOnly() {
287 $testUrl = 'www.example.org/';
288 $this->assertFalse(t3lib_div::isValidUrl($testUrl));
289 }
290
291 /**
292 * @test
293 * @see t3lib_div::isOnCurrentHost()
294 */
295 public function checkisOnCurrentHostFailsWithLocalhostIPOnly() {
296 $testUrl = '127.0.0.1';
297 $this->assertFalse(t3lib_div::isOnCurrentHost($testUrl));
298 }
299
300 /**
301 * @test
302 * @see t3lib_div::isOnCurrentHost()
303 */
304 public function checkisOnCurrentHostFailsWithPathsOnly() {
305 $testUrl = './relpath/file.txt';
306 $this->assertFalse(t3lib_div::isOnCurrentHost($testUrl));
307 $testUrl = '/abspath/file.txt?arg=value';
308 $this->assertFalse(t3lib_div::isOnCurrentHost($testUrl));
309 }
310
311 /**
312 * @test
313 * @see t3lib_div::isOnCurrentHost()
314 */
315 public function checkisOnCurrentHostFailsWithArbitraryString() {
316 $testUrl = 'arbitrary string';
317 $this->assertFalse(t3lib_div::isOnCurrentHost($testUrl));
318 }
319
320 /**
321 * @test
322 * @see t3lib_div::isOnCurrentHost()
323 */
324 public function checkisOnCurrentHostFailsWithEmptyUrl() {
325 $testUrl = '';
326 $this->assertFalse(t3lib_div::isOnCurrentHost($testUrl));
327 }
328
329 /**
330 * @test
331 * @see t3lib_div::isOnCurrentHost()
332 */
333 public function checkisOnCurrentHostFailsWithDifferentHost() {
334 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org';
335 $this->assertFalse(t3lib_div::isOnCurrentHost($testUrl));
336 }
337
338 /**
339 * @test
340 * @see t3lib_div::isOnCurrentHost()
341 */
342 public function checkisOnCurrentHostSucceedsWithCurrentHost() {
343 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
344 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
345 }
346
347
348 ////////////////////////////////////////
349 // Tests concerning sanitizeLocalUrl
350 ////////////////////////////////////////
351
352 /**
353 * Data provider for valid URLs.
354 * @see sanitizeLocalUrlAcceptsValidUrls
355 */
356 public function validLocalUrlDataProvider() {
357 return array(
358 array('alt_intro.php'),
359 array('alt_intro.php?foo=1&bar=2'),
360 array('/typo3/alt_intro.php'),
361 array('/index.php'),
362 array('../index.php'),
363 array('../typo3/alt_intro.php'),
364 array('../~userDirectory/index.php'),
365 array('../typo3/mod.php?var1=test-case&var2=~user'),
366 array(PATH_site . 'typo3/alt_intro.php'),
367 array(t3lib_div::getIndpEnv('TYPO3_SITE_URL') . 'typo3/alt_intro.php'),
368 array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '/index.php'),
369 );
370 }
371
372 /**
373 * Data provider for invalid URLs.
374 * @see sanitizeLocalUrlDeniesInvalidUrls
375 */
376 public function invalidLocalUrlDataProvider() {
377 return array(
378 array(''),
379 array('http://www.google.de/'),
380 array('https://www.google.de/'),
381 array('../typo3/whatever.php?argument=javascript:alert(0)'),
382 );
383 }
384
385 /**
386 * Tests whether valid local URLs are handled correctly.
387 * @dataProvider validLocalUrlDataProvider
388 * @test
389 */
390 public function sanitizeLocalUrlAcceptsPlainValidUrls($url) {
391 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
392 }
393
394 /**
395 * Tests whether valid local URLs are handled correctly.
396 * @dataProvider validLocalUrlDataProvider
397 * @test
398 */
399 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
400 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
401 }
402
403 /**
404 * Tests whether valid local URLs are handled correctly.
405 * @dataProvider invalidLocalUrlDataProvider
406 * @test
407 */
408 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
409 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
410 }
411
412 /**
413 * Tests whether valid local URLs are handled correctly.
414 * @dataProvider invalidLocalUrlDataProvider
415 * @test
416 */
417 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
418 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
419 }
420
421 //////////////////////////////////////
422 // Tests concerning removeDotsFromTS
423 //////////////////////////////////////
424
425 /**
426 * Tests whether removeDotsFromTS() behaves correctly.
427 * @test
428 * @see t3lib_div::removeDotsFromTS()
429 */
430 public function doesRemoveDotsFromTypoScriptSucceed() {
431 $typoScript = array(
432 'propertyA.' => array(
433 'keyA.' => array(
434 'valueA' => 1,
435 ),
436 'keyB' => 2,
437 ),
438 'propertyB' => 3,
439 );
440
441 $expectedResult = array(
442 'propertyA' => array(
443 'keyA' => array(
444 'valueA' => 1,
445 ),
446 'keyB' => 2,
447 ),
448 'propertyB' => 3,
449 );
450
451 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
452 }
453
454 /**
455 * Tests whether removeDotsFromTS() behaves correctly.
456 * @test
457 * @see t3lib_div::removeDotsFromTS()
458 */
459 public function doesRemoveDotsFromTypoScriptCorrectlyOverrideWithArray() {
460 $typoScript = array(
461 'propertyA.' => array(
462 'keyA' => 'getsOverridden',
463 'keyA.' => array(
464 'valueA' => 1,
465 ),
466 'keyB' => 2,
467 ),
468 'propertyB' => 3,
469 );
470
471 $expectedResult = array(
472 'propertyA' => array(
473 'keyA' => array(
474 'valueA' => 1,
475 ),
476 'keyB' => 2,
477 ),
478 'propertyB' => 3,
479 );
480
481 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
482 }
483
484 /**
485 * Tests whether removeDotsFromTS() behaves correctly.
486 * @test
487 * @see t3lib_div::removeDotsFromTS()
488 */
489 public function doesRemoveDotsFromTypoScriptCorrectlyOverrideWithScalar() {
490 $typoScript = array(
491 'propertyA.' => array(
492 'keyA.' => array(
493 'valueA' => 1,
494 ),
495 'keyA' => 'willOverride',
496 'keyB' => 2,
497 ),
498 'propertyB' => 3,
499 );
500
501 $expectedResult = array(
502 'propertyA' => array(
503 'keyA' => 'willOverride',
504 'keyB' => 2,
505 ),
506 'propertyB' => 3,
507 );
508
509 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
510 }
511
512 /**
513 * Tests whether getDirs() returns an array of diretories from a given path
514 * @test
515 * @see t3lib_div::getDirs($path)
516 */
517 public function checkGetDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
518 $path = PATH_t3lib;
519 $directories = t3lib_div::get_dirs($path);
520
521 $this->assertType('array', $directories);
522 }
523
524 /**
525 * Tests whether getDirs() returns the string 'error' in case of problems reading from the given path
526 * @test
527 * @see t3lib_div::getDirs($path)
528 */
529 public function checkGetDirsReturnsStringErrorOnPathFailure() {
530 $path = 'foo';
531 $result = t3lib_div::get_dirs($path);
532 $expectedResult = 'error';
533
534 $this->assertEquals($expectedResult, $result);
535 }
536
537
538 //////////////////////////////////
539 // Tests concerning quoteJSvalue
540 //////////////////////////////////
541
542 /**
543 * @test
544 */
545 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
546 $this->assertContains(
547 '&gt;',
548 t3lib_div::quoteJSvalue('>')
549 );
550 }
551
552 /**
553 * @test
554 */
555 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
556 $this->assertContains(
557 '&gt;',
558 t3lib_div::quoteJSvalue('>', false)
559 );
560 }
561
562 /**
563 * @test
564 */
565 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
566 $this->assertContains(
567 '>',
568 t3lib_div::quoteJSvalue('>', true)
569 );
570 }
571
572 /**
573 * @test
574 */
575 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
576 $this->assertEquals(
577 "''",
578 t3lib_div::quoteJSvalue("", true)
579 );
580 }
581
582 /**
583 * @test
584 */
585 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
586 $this->assertEquals(
587 "'Hello world!'",
588 t3lib_div::quoteJSvalue("Hello world!", true)
589 );
590 }
591
592 /**
593 * @test
594 */
595 public function quoteJSvalueEscapesSingleQuote() {
596 $this->assertEquals(
597 "'\\''",
598 t3lib_div::quoteJSvalue("'", true)
599 );
600 }
601
602 /**
603 * @test
604 */
605 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
606 $this->assertEquals(
607 "'\\\"'",
608 t3lib_div::quoteJSvalue('"', true)
609 );
610 }
611
612 /**
613 * @test
614 */
615 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
616 $this->assertEquals(
617 "'\\&quot;'",
618 t3lib_div::quoteJSvalue('"', false)
619 );
620 }
621
622 /**
623 * @test
624 */
625 public function quoteJSvalueEscapesTab() {
626 $this->assertEquals(
627 "'" . '\t' . "'",
628 t3lib_div::quoteJSvalue(chr(9))
629 );
630 }
631
632 /**
633 * @test
634 */
635 public function quoteJSvalueEscapesLinefeed() {
636 $this->assertEquals(
637 "'" . '\n' . "'",
638 t3lib_div::quoteJSvalue(chr(10))
639 );
640 }
641
642 /**
643 * @test
644 */
645 public function quoteJSvalueEscapesCarriageReturn() {
646 $this->assertEquals(
647 "'" . '\r' . "'",
648 t3lib_div::quoteJSvalue(chr(13))
649 );
650 }
651
652 /**
653 * @test
654 */
655 public function quoteJSvalueEscapesBackslah() {
656 $this->assertEquals(
657 "'\\\\'",
658 t3lib_div::quoteJSvalue('\\')
659 );
660 }
661
662 /**
663 * Tests the locallangXMLOverride feature of readLLfile()
664 * @test
665 */
666 public function readLLfileLocallangXMLOverride() {
667 $unique = uniqid('locallangXMLOverrideTest');
668
669 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
670 <T3locallang>
671 <data type="array">
672 <languageKey index="default" type="array">
673 <label index="buttons.logout">EXIT</label>
674 </languageKey>
675 </data>
676 </T3locallang>';
677
678 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
679 t3lib_div::writeFileToTypo3tempDir($file, $xml);
680
681 // get default value
682 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
683
684 // set override file
685 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
686
687 // get override value
688 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
689
690 $this->assertNotEquals($overrideLL['default']['buttons.logout'], '');
691 $this->assertNotEquals($defaultLL['default']['buttons.logout'], $overrideLL['default']['buttons.logout']);
692 $this->assertEquals($overrideLL['default']['buttons.logout'], 'EXIT');
693
694 unlink($file);
695 }
696 }
697
698 ?>