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