[TASK] Re-work/simplify copyright header in PHP files - Part 4
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Resource / Driver / LocalDriverTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Resource\Driver;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use \org\bovigo\vfs\vfsStream;
19 use \org\bovigo\vfs\vfsStreamWrapper;
20
21 /**
22 * Testcase for the local storage driver class of the TYPO3 VFS
23 *
24 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
25 */
26 class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
27
28 /**
29 * @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver
30 */
31 protected $localDriver = NULL;
32
33 /**
34 * @var array A backup of registered singleton instances
35 */
36 protected $singletonInstances = array();
37
38 /**
39 * @var array
40 */
41 protected $testDirs = array();
42
43 /**
44 * @var string
45 */
46 protected $iso88591GreaterThan127 = '';
47
48 /**
49 * @var string
50 */
51 protected $utf8Latin1Supplement = '';
52
53 /**
54 * @var string
55 */
56 protected $utf8Latin1ExtendedA = '';
57
58 /**
59 * Tear down
60 */
61 public function tearDown() {
62 foreach ($this->testDirs as $dir) {
63 chmod($dir, 0777);
64 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($dir, TRUE);
65 }
66 parent::tearDown();
67 }
68
69 /**
70 * Creates a "real" directory for doing tests. This is necessary because some file system properties (e.g. permissions)
71 * cannot be reflected by vfsStream, and some methods (like touch()) don't work there either.
72 *
73 * Created directories are automatically destroyed during tearDown()
74 *
75 * @return string
76 */
77 protected function createRealTestdir() {
78 $basedir = PATH_site . 'typo3temp/' . uniqid('fal-test-');
79 mkdir($basedir);
80 $this->testDirs[] = $basedir;
81 return $basedir;
82 }
83
84 /**
85 * Create a "real" directory together with a driverFixture configured
86 * for this directory.
87 *
88 * @return array With path to base directory and driver fixture
89 */
90 protected function prepareRealTestEnvironment() {
91 $basedir = $this->createRealTestdir();
92 $fixture = $this->createDriverFixture(array(
93 'basePath' => $basedir
94 ));
95 return array($basedir, $fixture);
96 }
97
98 /**
99 * Creates a driver fixture object, optionally using a given mount object.
100 *
101 * IMPORTANT: Call this only after setting up the virtual file system (with the addTo* methods)!
102 *
103 * @param array $driverConfiguration
104 * @param array $mockedDriverMethods
105 * @return \TYPO3\CMS\Core\Resource\Driver\LocalDriver
106 */
107 protected function createDriverFixture($driverConfiguration = array(), $mockedDriverMethods = array()) {
108 // it's important to do that here, so vfsContents could have been set before
109 if (!isset($driverConfiguration['basePath'])) {
110 $this->initializeVfs();
111 $driverConfiguration['basePath'] = $this->getMountRootUrl();
112 }
113 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $driver */
114 $mockedDriverMethods[] = 'isPathValid';
115 $driver = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', $mockedDriverMethods, array($driverConfiguration));
116 $driver->expects($this->any())
117 ->method('isPathValid')
118 ->will(
119 $this->returnValue(TRUE)
120 );
121
122 $driver->setStorageUid(5);
123 $driver->processConfiguration();
124 $driver->initialize();
125 return $driver;
126 }
127
128 /**
129 * @test
130 */
131 public function createFolderRecursiveSanitizesFilename() {
132 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $driver */
133 $driver = $this->createDriverFixture(array(), array('sanitizeFilename'));
134 $driver->expects($this->exactly(2))
135 ->method('sanitizeFileName')
136 ->will(
137 $this->returnValue('sanitized')
138 );
139 $driver->createFolder('newFolder/andSubfolder', '/', TRUE);
140 $this->assertFileExists($this->getUrlInMount('/sanitized/sanitized/'));
141 }
142
143 /**
144 * @test
145 */
146 public function determineBaseUrlUrlEncodesUriParts() {
147 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface $driver */
148 $driver = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('hasCapability'), array(), '', FALSE);
149 $driver->expects($this->once())
150 ->method('hasCapability')
151 ->with(\TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC)
152 ->will(
153 $this->returnValue(TRUE)
154 );
155 $driver->_set('absoluteBasePath', PATH_site . 'un encö/ded %path/');
156 $driver->_call('determineBaseUrl');
157 $baseUri = $driver->_get('baseUri');
158 $this->assertEquals(rawurlencode('un encö') . '/' . rawurlencode('ded %path') . '/', $baseUri);
159 }
160
161 /**
162 * @test
163 */
164 public function getDefaultFolderReturnsFolderForUserUploadPath() {
165 $fixture = $this->createDriverFixture();
166 $folderIdentifier = $fixture->getDefaultFolder();
167 $this->assertEquals('/user_upload/', $folderIdentifier);
168 }
169
170 /**
171 * @test
172 */
173 public function defaultLevelFolderFolderIsCreatedIfItDoesntExist() {
174 $fixture = $this->createDriverFixture();
175 $this->assertFileExists($this->getUrlInMount($fixture->getDefaultFolder()));
176 }
177
178 /**
179 * @test
180 */
181 public function getFolderInFolderReturnsCorrectFolderObject() {
182 $this->addToMount(array(
183 'someDir' => array(
184 'someSubdir' => array()
185 )
186 ));
187 $fixture = $this->createDriverFixture();
188 $folder = $fixture->getFolderInFolder('someSubdir', '/someDir/');
189 $this->assertEquals('/someDir/someSubdir/', $folder);
190 }
191
192 /**
193 * @test
194 */
195 public function createFolderCreatesFolderOnDisk() {
196 $this->addToMount(array('some' => array('folder' => array())));
197 $fixture = $this->createDriverFixture();
198 $fixture->createFolder('path', '/some/folder/');
199 $this->assertFileExists($this->getUrlInMount('/some/folder/'));
200 $this->assertFileExists($this->getUrlInMount('/some/folder/path'));
201 }
202
203 /**
204 * @test
205 */
206 public function createFolderReturnsFolderObject() {
207 $this->addToMount(array('some' => array('folder' => array())));
208 $fixture = $this->createDriverFixture();
209 $createdFolder = $fixture->createFolder('path', '/some/folder/');
210 $this->assertEquals('/some/folder/path/', $createdFolder);
211 }
212
213 public static function createFolderSanitizesFolderNameBeforeCreationDataProvider() {
214 return array(
215 'folder name with NULL character' => array(
216 'some' . chr(0) . 'Folder',
217 'some_Folder'
218 ),
219 'folder name with directory part' => array(
220 '../someFolder',
221 '.._someFolder'
222 )
223 );
224 }
225
226 /**
227 * @test
228 * @dataProvider createFolderSanitizesFolderNameBeforeCreationDataProvider
229 */
230 public function createFolderSanitizesFolderNameBeforeCreation($newFolderName, $expectedFolderName) {
231 $this->addToMount(array('some' => array('folder' => array())));
232 $fixture = $this->createDriverFixture();
233 $fixture->createFolder($newFolderName, '/some/folder/');
234 $this->assertFileExists($this->getUrlInMount('/some/folder/' . $expectedFolderName));
235 }
236
237 /**
238 * @test
239 */
240 public function basePathIsNormalizedWithTrailingSlash() {
241 $fixture = $this->createDriverFixture();
242 $this->assertEquals('/', substr($fixture->_call('getAbsoluteBasePath'), -1));
243 }
244
245 /**
246 * @test
247 */
248 public function noSecondSlashIsAddedIfBasePathAlreadyHasTrailingSlash() {
249 $fixture = $this->createDriverFixture();
250 $this->assertNotEquals('/', substr($fixture->_call('getAbsoluteBasePath'), -2, 1));
251 }
252
253 /**
254 * @test
255 */
256 public function getAbsolutePathReturnsCorrectPath() {
257 $this->addToMount(array(
258 'someFolder' => array(
259 'file1.ext' => 'asdfg'
260 )
261 ));
262 $fixture = $this->createDriverFixture();
263 $path = $fixture->_call('getAbsolutePath', '/someFolder/file1.ext');
264 $this->assertTrue(file_exists($path));
265 $this->assertEquals($this->getUrlInMount('/someFolder/file1.ext'), $path);
266 }
267
268 /**
269 * @test
270 */
271 public function addFileMovesFileToCorrectLocation() {
272 $this->addToMount(array('targetFolder' => array()));
273 $this->addToVfs(array(
274 'sourceFolder' => array(
275 'file' => 'asdf'
276 )
277 ));
278 $fixture = $this->createDriverFixture(
279 array(),
280 array('getMimeTypeOfFile')
281 );
282 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
283 $fixture->addFile($this->getUrl('sourceFolder/file'), '/targetFolder/', 'file');
284 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/file')));
285 }
286
287 /**
288 * @test
289 */
290 public function addFileUsesFilenameIfGiven() {
291 $this->addToMount(array('targetFolder' => array()));
292 $this->addToVfs(array(
293 'sourceFolder' => array(
294 'file' => 'asdf'
295 )
296 ));
297 $fixture = $this->createDriverFixture(
298 array(),
299 array('getMimeTypeOfFile')
300 );
301 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
302 $fixture->addFile($this->getUrl('sourceFolder/file'), '/targetFolder/', 'targetFile');
303 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/targetFile')));
304 }
305
306 /**
307 * @test
308 */
309 public function addFileFailsIfFileIsInDriverStorage() {
310 $this->setExpectedException('InvalidArgumentException', '', 1314778269);
311 $this->addToMount(array(
312 'targetFolder' => array(
313 'file' => 'asdf'
314 )
315 ));
316 $fixture = $this->createDriverFixture();
317 $fixture->addFile($this->getUrlInMount('/targetFolder/file'), '/targetFolder/', 'file');
318 }
319
320 /**
321 * @test
322 */
323 public function addFileReturnsFileIdentifier() {
324 $this->addToMount(array('targetFolder' => array()));
325 $this->addToVfs(array(
326 'sourceFolder' => array(
327 'file' => 'asdf'
328 )
329 ));
330 $fixture = $this->createDriverFixture(
331 array(),
332 array('getMimeTypeOfFile')
333 );
334 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
335 $fileIdentifier = $fixture->addFile($this->getUrl('sourceFolder/file'), '/targetFolder/', 'file');
336 $this->assertEquals('file', basename($fileIdentifier));
337 $this->assertEquals('/targetFolder/file', $fileIdentifier);
338 }
339
340 /**
341 * @test
342 */
343 public function existenceChecksWorkForFilesAndFolders() {
344 $this->addToMount(array(
345 'file' => 'asdf',
346 'folder' => array()
347 ));
348 $fixture = $this->createDriverFixture();
349 // Using slashes at the beginning of paths because they will be stored in the DB this way.
350 $this->assertTrue($fixture->fileExists('/file'));
351 $this->assertTrue($fixture->folderExists('/folder/'));
352 $this->assertFalse($fixture->fileExists('/nonexistingFile'));
353 $this->assertFalse($fixture->folderExists('/nonexistingFolder/'));
354 }
355
356 /**
357 * @test
358 */
359 public function existenceChecksInFolderWorkForFilesAndFolders() {
360 $this->addToMount(array(
361 'subfolder' => array(
362 'file' => 'asdf',
363 'folder' => array()
364 )
365 ));
366 $fixture = $this->createDriverFixture();
367 $this->assertTrue($fixture->fileExistsInFolder('file', '/subfolder/'));
368 $this->assertTrue($fixture->folderExistsInFolder('folder', '/subfolder/'));
369 $this->assertFalse($fixture->fileExistsInFolder('nonexistingFile', '/subfolder/'));
370 $this->assertFalse($fixture->folderExistsInFolder('nonexistingFolder', '/subfolder/'));
371 }
372
373 /**
374 * @test
375 */
376 public function getPublicUrlReturnsCorrectUriForConfiguredBaseUri() {
377 $baseUri = 'http://example.org/foobar/' . uniqid();
378 $this->addToMount(array(
379 'file.ext' => 'asdf',
380 'subfolder' => array(
381 'file2.ext' => 'asdf'
382 )
383 ));
384 $fixture = $this->createDriverFixture(array(
385 'baseUri' => $baseUri
386 ));
387 $this->assertEquals($baseUri . '/file.ext', $fixture->getPublicUrl('/file.ext'));
388 $this->assertEquals($baseUri . '/subfolder/file2.ext', $fixture->getPublicUrl('/subfolder/file2.ext'));
389 }
390
391 /**
392 * Data provider for getPublicUrlReturnsValidUrlContainingSpecialCharacters().
393 *
394 * @return array
395 */
396 public function getPublicUrlReturnsValidUrlContainingSpecialCharacters_dataProvider() {
397 return array(
398 array('/single file with some special chars äüö!.txt'),
399 array('/on subfolder/with special chars äüö!.ext'),
400 array('/who names a file like !"§$%&()=?*+~"#\'´`<>-.ext'),
401 array('no leading slash !"§$%&()=?*+~#\'"´`"<>-.txt')
402 );
403 }
404
405 /**
406 * @test
407 * @dataProvider getPublicUrlReturnsValidUrlContainingSpecialCharacters_dataProvider
408 */
409 public function getPublicUrlReturnsValidUrlContainingSpecialCharacters($fileIdentifier) {
410 $baseUri = 'http://example.org/foobar/' . uniqid();
411 $fixture = $this->createDriverFixture(array(
412 'baseUri' => $baseUri
413 ));
414 $publicUrl = $fixture->getPublicUrl($fileIdentifier);
415 $this->assertTrue(GeneralUtility::isValidUrl($publicUrl), 'getPublicUrl did not return a valid URL:' . $publicUrl);
416 }
417
418 /**
419 * @test
420 */
421 public function fileContentsCanBeWrittenAndRead() {
422 $fileContents = 'asdf';
423 $this->addToMount(array(
424 'file.ext' => $fileContents
425 ));
426 $fixture = $this->createDriverFixture();
427 $this->assertEquals($fileContents, $fixture->getFileContents('/file.ext'), 'File contents could not be read');
428 $newFileContents = 'asdfgh';
429 $fixture->setFileContents('/file.ext', $newFileContents);
430 $this->assertEquals($newFileContents, $fixture->getFileContents('/file.ext'), 'New file contents could not be read.');
431 }
432
433 /**
434 * @test
435 */
436 public function setFileContentsReturnsNumberOfBytesWrittenToFile() {
437 $fileContents = 'asdf';
438 $this->addToMount(array(
439 'file.ext' => $fileContents
440 ));
441 $fixture = $this->createDriverFixture();
442 $newFileContents = 'asdfgh';
443 $bytesWritten = $fixture->setFileContents('/file.ext', $newFileContents);
444 $this->assertEquals(strlen($newFileContents), $bytesWritten);
445 }
446
447 /**
448 * @test
449 * @see http://phpmagazin.de/vfsStream-1.1.0-nutzt-PHP-5.4-M%C3%B6glichkeiten-064406.html
450 */
451 public function newFilesCanBeCreated() {
452 if (version_compare(PHP_VERSION, '5.4.0', '<')) {
453 $this->markTestSkipped('touch() does not work with vfsStream in PHP 5.3 and below.');
454 }
455 $fixture = $this->createDriverFixture();
456 $fixture->createFile('testfile.txt', '/');
457 $this->assertTrue($fixture->fileExists('/testfile.txt'));
458 }
459
460 /**
461 * @test
462 * @see http://phpmagazin.de/vfsStream-1.1.0-nutzt-PHP-5.4-M%C3%B6glichkeiten-064406.html
463 */
464 public function createdFilesAreEmpty() {
465 if (version_compare(PHP_VERSION, '5.4.0', '<')) {
466 $this->markTestSkipped('touch() does not work with vfsStream in PHP 5.3 and below.');
467 }
468 $fixture = $this->createDriverFixture();
469 $fixture->createFile('testfile.txt', '/');
470 $this->assertTrue($fixture->fileExists('/testfile.txt'));
471 $fileData = $fixture->getFileContents('/testfile.txt');
472 $this->assertEquals(0, strlen($fileData));
473 }
474
475 /**
476 * @test
477 */
478 public function createFileFixesPermissionsOnCreatedFile() {
479 if (TYPO3_OS == 'WIN') {
480 $this->markTestSkipped('createdFilesHaveCorrectRights() tests not available on Windows');
481 }
482
483 // No one will use this as his default file create mask so we hopefully don't get any false positives
484 $testpattern = '0646';
485 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = $testpattern;
486
487 $this->addToMount(
488 array(
489 'someDir' => array()
490 )
491 );
492 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
493 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
494 mkdir($basedir . '/someDir');
495 $fixture->createFile('testfile.txt', '/someDir');
496 $this->assertEquals($testpattern, decoct(fileperms($basedir . '/someDir/testfile.txt') & 0777));
497 }
498
499 /**********************************
500 * File and directory listing
501 **********************************/
502 /**
503 * @test
504 */
505 public function getFileReturnsCorrectIdentifier() {
506 $this->addToMount(array(
507 'someDir' => array(
508 'someFile' => 'asdfg'
509 ),
510 'someFileAtRootLevel' => 'foobar'
511 ));
512 $fixture = $this->createDriverFixture(
513 array(),
514 array('getMimeTypeOfFile')
515 );
516 $subdirFileInfo = $fixture->getFileInfoByIdentifier('/someDir/someFile');
517 $this->assertEquals('/someDir/someFile', $subdirFileInfo['identifier']);
518 $rootFileInfo = $fixture->getFileInfoByIdentifier('/someFileAtRootLevel');
519 $this->assertEquals('/someFileAtRootLevel', $rootFileInfo['identifier']);
520 }
521
522 /**
523 * @test
524 */
525 public function getFileThrowsExceptionIfFileDoesNotExist() {
526 $this->setExpectedException('InvalidArgumentException', '', 1314516809);
527 $fixture = $this->createDriverFixture();
528 $fixture->getFileInfoByIdentifier('/some/file/at/a/random/path');
529 }
530
531 /**
532 * @test
533 */
534 public function getFilesInFolderReturnsEmptyArrayForEmptyDirectory() {
535 $fixture = $this->createDriverFixture();
536 $fileList = $fixture->getFilesInFolder('/');
537 $this->assertEmpty($fileList);
538 }
539
540 /**
541 * @test
542 */
543 public function getFileListReturnsAllFilesInDirectory() {
544 $dirStructure = array(
545 'aDir' => array(),
546 'file1' => 'asdfg',
547 'file2' => 'fdsa'
548 );
549 $this->addToMount($dirStructure);
550 $fixture = $this->createDriverFixture(
551 array(),
552 // Mocked because finfo() can not deal with vfs streams and throws warnings
553 array('getMimeTypeOfFile')
554 );
555 $fileList = $fixture->getFilesInFolder('/');
556 $this->assertEquals(array('/file1', '/file2'), array_keys($fileList));
557 }
558
559 /**
560 * @test
561 */
562 public function getFileListReturnsAllFilesInSubdirectoryIfRecursiveParameterIsSet() {
563 $dirStructure = array(
564 'aDir' => array(
565 'file3' => 'asdfgh',
566 'subdir' => array(
567 'file4' => 'asklfjklasjkl'
568 )
569 ),
570 'file1' => 'asdfg',
571 'file2' => 'fdsa'
572 );
573 $this->addToMount($dirStructure);
574 $fixture = $this->createDriverFixture(
575 array(),
576 // Mocked because finfo() can not deal with vfs streams and throws warnings
577 array('getMimeTypeOfFile')
578 );
579 $fileList = $fixture->getFilesInFolder('/', 0, 0, TRUE);
580 $this->assertEquals(array('/aDir/subdir/file4', '/aDir/file3', '/file1', '/file2'), array_keys($fileList));
581 }
582
583 /**
584 * @test
585 */
586 public function getFileListFailsIfDirectoryDoesNotExist() {
587 $this->setExpectedException('InvalidArgumentException', '', 1314349666);
588 $this->addToMount(array('somefile' => ''));
589 $fixture = $this->createDriverFixture();
590 $fixture->getFilesInFolder('somedir/');
591 }
592
593 /**
594 * @test
595 */
596 public function getFileInFolderCallsConfiguredCallbackFunctionWithGivenItemName() {
597 $dirStructure = array(
598 'file2' => 'fdsa'
599 );
600 // register static callback to self
601 $callback = array(
602 array(
603 get_class($this),
604 'callbackStaticTestFunction'
605 )
606 );
607 $this->addToMount($dirStructure);
608 $fixture = $this->createDriverFixture();
609 // the callback function will throw an exception used to check if it was called with correct $itemName
610 $this->setExpectedException('InvalidArgumentException', '$itemName', 1336159604);
611 $fixture->getFilesInFolder('/', 0, 0, FALSE, $callback);
612 }
613
614 /**
615 * Static callback function used to test if the filter callbacks work
616 * As it is static we are using an exception to test if it is really called and works
617 *
618 * @static
619 * @throws \InvalidArgumentException
620 * @see getFileListCallsConfiguredCallbackFunction
621 */
622 static public function callbackStaticTestFunction() {
623 list($itemName) = func_get_args();
624 if ($itemName === 'file2') {
625 throw new \InvalidArgumentException('$itemName', 1336159604);
626 }
627 }
628
629 /**
630 * @test
631 */
632 public function getFileListFiltersItemsWithGivenFilterMethods() {
633 $dirStructure = array(
634 'fileA' => 'asdfg',
635 'fileB' => 'fdsa'
636 );
637 $this->addToMount($dirStructure);
638 $fixture = $this->createDriverFixture(
639 array(),
640 // Mocked because finfo() can not deal with vfs streams and throws warnings
641 array('getMimeTypeOfFile')
642 );
643 $filterCallbacks = array(
644 array(
645 'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
646 'filterFilename',
647 ),
648 );
649 $fileList = $fixture->getFilesInFolder('/', 0, 0, FALSE, $filterCallbacks);
650 $this->assertNotContains('/fileA', array_keys($fileList));
651 }
652
653 /**
654 * @test
655 */
656 public function getFolderListReturnsAllDirectoriesInDirectory() {
657 $dirStructure = array(
658 'dir1' => array(),
659 'dir2' => array(),
660 'file' => 'asdfg'
661 );
662 $this->addToMount($dirStructure);
663 $fixture = $this->createDriverFixture();
664 $fileList = $fixture->getFoldersInFolder('/');
665 $this->assertEquals(array('/dir1/', '/dir2/'), array_keys($fileList));
666 }
667
668 /**
669 * @test
670 */
671 public function getFolderListReturnsHiddenFoldersByDefault() {
672 $dirStructure = array(
673 '.someHiddenDir' => array(),
674 'aDir' => array(),
675 'file1' => ''
676 );
677 $this->addToMount($dirStructure);
678 $fixture = $this->createDriverFixture();
679
680 $fileList = $fixture->getFoldersInFolder('/');
681
682 $this->assertEquals(array('/.someHiddenDir/', '/aDir/'), array_keys($fileList));
683 }
684
685 /**
686 * Checks if the folder names . and .. are ignored when listing subdirectories
687 *
688 * @test
689 */
690 public function getFolderListLeavesOutNavigationalEntries() {
691 // we have to add .. and . manually, as these are not included in vfsStream directory listings (as opposed
692 // to normal file listings)
693 $this->addToMount(array(
694 '..' => array(),
695 '.' => array()
696 ));
697 $fixture = $this->createDriverFixture();
698 $fileList = $fixture->getFoldersInFolder('/');
699 $this->assertEmpty($fileList);
700 }
701
702 /**
703 * @test
704 */
705 public function getFolderListFiltersItemsWithGivenFilterMethods() {
706 $dirStructure = array(
707 'folderA' => array(),
708 'folderB' => array()
709 );
710 $this->addToMount($dirStructure);
711 $fixture = $this->createDriverFixture();
712 $filterCallbacks = array(
713 array(
714 'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
715 'filterFilename',
716 ),
717 );
718 $folderList = $fixture->getFoldersInFolder('/', 0, 0, $filterCallbacks);
719 $this->assertNotContains('folderA', array_keys($folderList));
720 }
721
722 /**
723 * @test
724 */
725 public function getFolderListFailsIfDirectoryDoesNotExist() {
726 $this->setExpectedException('InvalidArgumentException', '', 1314349666);
727 $fixture = $this->createDriverFixture();
728 vfsStream::create(array($this->basedir => array('somefile' => '')));
729 $fixture->getFoldersInFolder('somedir/');
730 }
731
732 /**
733 * @test
734 */
735 public function hashReturnsCorrectHashes() {
736 $contents = '68b329da9893e34099c7d8ad5cb9c940';
737 $expectedMd5Hash = '8c67dbaf0ba22f2e7fbc26413b86051b';
738 $expectedSha1Hash = 'a60cd808ba7a0bcfa37fa7f3fb5998e1b8dbcd9d';
739 $this->addToMount(array('hashFile' => $contents));
740 $fixture = $this->createDriverFixture();
741 $this->assertEquals($expectedSha1Hash, $fixture->hash('/hashFile', 'sha1'));
742 $this->assertEquals($expectedMd5Hash, $fixture->hash('/hashFile', 'md5'));
743 }
744
745 /**
746 * @test
747 */
748 public function hashingWithUnsupportedAlgorithmFails() {
749 $this->setExpectedException('InvalidArgumentException', '', 1304964032);
750 $fixture = $this->createDriverFixture();
751 $fixture->hash('/hashFile', uniqid());
752 }
753
754 /**
755 * @test
756 * @covers TYPO3\CMS\Core\Resource\Driver\LocalDriver::getFileForLocalProcessing
757 */
758 public function getFileForLocalProcessingCreatesCopyOfFileByDefault() {
759 $fileContents = 'asdfgh';
760 $this->addToMount(array(
761 'someDir' => array(
762 'someFile' => $fileContents
763 )
764 ));
765 $fixture = $this->createDriverFixture(array(), array('copyFileToTemporaryPath'));
766 $fixture->expects($this->once())->method('copyFileToTemporaryPath');
767 $fixture->getFileForLocalProcessing('/someDir/someFile');
768 }
769
770 /**
771 * @test
772 */
773 public function getFileForLocalProcessingReturnsOriginalFilepathForReadonlyAccess() {
774 $fileContents = 'asdfgh';
775 $this->addToMount(array(
776 'someDir' => array(
777 'someFile' => $fileContents
778 )
779 ));
780 $fixture = $this->createDriverFixture();
781 $filePath = $fixture->getFileForLocalProcessing('/someDir/someFile', FALSE);
782 $this->assertEquals($filePath, $this->getUrlInMount('someDir/someFile'));
783 }
784
785 /**
786 * @test
787 */
788 public function filesCanBeCopiedToATemporaryPath() {
789 $fileContents = 'asdfgh';
790 $this->addToMount(array(
791 'someDir' => array(
792 'someFile' => $fileContents
793 )
794 ));
795 $fixture = $this->createDriverFixture();
796 $filePath = GeneralUtility::fixWindowsFilePath($fixture->_call('copyFileToTemporaryPath', '/someDir/someFile'));
797 $this->assertContains('/typo3temp/', $filePath);
798 $this->assertEquals($fileContents, file_get_contents($filePath));
799 }
800
801 /**
802 * @test
803 */
804 public function permissionsAreCorrectlyRetrievedForAllowedFile() {
805 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
806 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
807 touch($basedir . '/someFile');
808 chmod($basedir . '/someFile', 448);
809 clearstatcache();
810 $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getPermissions('/someFile'));
811 }
812
813 /**
814 * @test
815 */
816 public function permissionsAreCorrectlyRetrievedForForbiddenFile() {
817 if (function_exists('posix_getegid') && posix_getegid() === 0) {
818 $this->markTestSkipped('Test skipped if run on linux as root');
819 } elseif (TYPO3_OS === 'WIN') {
820 $this->markTestSkipped('Test skipped if run on Windows system');
821 }
822 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
823 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
824 touch($basedir . '/someForbiddenFile');
825 chmod($basedir . '/someForbiddenFile', 0);
826 clearstatcache();
827 $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $fixture->getPermissions('/someForbiddenFile'));
828 }
829
830 /**
831 * @test
832 */
833 public function permissionsAreCorrectlyRetrievedForAllowedFolder() {
834 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
835 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
836 mkdir($basedir . '/someFolder');
837 chmod($basedir . '/someFolder', 448);
838 clearstatcache();
839 $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getPermissions('/someFolder'));
840 }
841
842 /**
843 * @test
844 */
845 public function permissionsAreCorrectlyRetrievedForForbiddenFolder() {
846 if (function_exists('posix_getegid') && posix_getegid() === 0) {
847 $this->markTestSkipped('Test skipped if run on linux as root');
848 } elseif (TYPO3_OS === 'WIN') {
849 $this->markTestSkipped('Test skipped if run on Windows system');
850 }
851 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
852 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
853 mkdir($basedir . '/someForbiddenFolder');
854 chmod($basedir . '/someForbiddenFolder', 0);
855 clearstatcache();
856 $result = $fixture->getPermissions('/someForbiddenFolder');
857 // Change permissions back to writable, so the sub-folder can be removed in tearDown
858 chmod($basedir . '/someForbiddenFolder', 0777);
859 $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $result);
860 }
861
862 /**
863 * Dataprovider for getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser test
864 *
865 * @return array group, filemode and expected result
866 */
867 public function getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser_dataProvider() {
868 $data = array();
869 // On some OS, the posix_* functions do not exits
870 if (function_exists('posix_getgid')) {
871 $data = array(
872 'current group, readable/writable' => array(
873 posix_getgid(),
874 48,
875 array('r' => TRUE, 'w' => TRUE)
876 ),
877 'current group, readable/not writable' => array(
878 posix_getgid(),
879 32,
880 array('r' => TRUE, 'w' => FALSE)
881 ),
882 'current group, not readable/not writable' => array(
883 posix_getgid(),
884 0,
885 array('r' => FALSE, 'w' => FALSE)
886 )
887 );
888 }
889 $data = array_merge_recursive($data, array(
890 'arbitrary group, readable/writable' => array(
891 vfsStream::GROUP_USER_1,
892 6,
893 array('r' => TRUE, 'w' => TRUE)
894 ),
895 'arbitrary group, readable/not writable' => array(
896 vfsStream::GROUP_USER_1,
897 436,
898 array('r' => TRUE, 'w' => FALSE)
899 ),
900 'arbitrary group, not readable/not writable' => array(
901 vfsStream::GROUP_USER_1,
902 432,
903 array('r' => FALSE, 'w' => FALSE)
904 )
905 ));
906 return $data;
907 }
908
909 /**
910 * @test
911 * @dataProvider getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser_dataProvider
912 */
913 public function getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser($group, $permissions, $expectedResult) {
914 if (TYPO3_OS === 'WIN') {
915 $this->markTestSkipped('Test skipped if run on Windows system');
916 }
917 $this->addToMount(array(
918 'testfile' => 'asdfg'
919 ));
920 $fixture = $this->createDriverFixture();
921 /** @var $fileObject vfsStreamContent */
922 $fileObject = vfsStreamWrapper::getRoot()->getChild($this->mountDir)->getChild('testfile');
923 // just use an "arbitrary" user here - it is only important that
924 $fileObject->chown(vfsStream::OWNER_USER_1);
925 $fileObject->chgrp($group);
926 $fileObject->chmod($permissions);
927 $this->assertEquals($expectedResult, $fixture->getPermissions('/testfile'));
928 }
929
930 /**
931 * @test
932 */
933 public function isWithinRecognizesFilesWithinFolderAndInOtherFolders() {
934 $fixture = $this->createDriverFixture();
935 $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/test.jpg'));
936 $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/subFolder/test.jpg'));
937 $this->assertFalse($fixture->isWithin('/someFolder/', '/someFolderWithALongName/test.jpg'));
938 }
939
940 /**
941 * @test
942 */
943 public function isWithinAcceptsFileAndFolderObjectsAsContent() {
944 $fixture = $this->createDriverFixture();
945 $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/test.jpg'));
946 $this->assertTrue($fixture->isWithin('/someFolder/', '/someFolder/subfolder/'));
947 }
948
949 /**********************************
950 * Copy/move file
951 **********************************/
952
953 /**
954 * @test
955 */
956 public function filesCanBeCopiedWithinStorage() {
957 $fileContents = uniqid();
958 $this->addToMount(array(
959 'someFile' => $fileContents,
960 'targetFolder' => array()
961 ));
962 $fixture = $this->createDriverFixture(
963 array(),
964 array('getMimeTypeOfFile')
965 );
966 $fixture->copyFileWithinStorage('/someFile', '/targetFolder/', 'someFile');
967 $this->assertFileEquals($this->getUrlInMount('/someFile'), $this->getUrlInMount('/targetFolder/someFile'));
968 }
969
970 /**
971 * @test
972 */
973 public function filesCanBeMovedWithinStorage() {
974 $fileContents = uniqid();
975 $this->addToMount(array(
976 'targetFolder' => array(),
977 'someFile' => $fileContents
978 ));
979 $fixture = $this->createDriverFixture();
980 $newIdentifier = $fixture->moveFileWithinStorage('/someFile', '/targetFolder/', 'file');
981 $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/file')));
982 $this->assertFileNotExists($this->getUrlInMount('/someFile'));
983 $this->assertEquals('/targetFolder/file', $newIdentifier);
984 }
985
986 /**
987 * @test
988 */
989 public function fileMetadataIsChangedAfterMovingFile() {
990 $fileContents = uniqid();
991 $this->addToMount(array(
992 'targetFolder' => array(),
993 'someFile' => $fileContents
994 ));
995 $fixture = $this->createDriverFixture(
996 array(),
997 // Mocked because finfo() can not deal with vfs streams and throws warnings
998 array('getMimeTypeOfFile')
999 );
1000 $newIdentifier = $fixture->moveFileWithinStorage('/someFile', '/targetFolder/', 'file');
1001 $fileMetadata = $fixture->getFileInfoByIdentifier($newIdentifier);
1002 $this->assertEquals($newIdentifier, $fileMetadata['identifier']);
1003 }
1004
1005 public function renamingFiles_dataProvider() {
1006 return array(
1007 'file in subfolder' => array(
1008 array(
1009 'targetFolder' => array('file' => '')
1010 ),
1011 '/targetFolder/file',
1012 'newFile',
1013 '/targetFolder/newFile'
1014 ),
1015 'file in rootfolder' => array(
1016 array(
1017 'fileInRoot' => ''
1018 ),
1019 '/fileInRoot',
1020 'newFile',
1021 '/newFile'
1022 )
1023 );
1024 }
1025
1026 /**
1027 * @test
1028 * @dataProvider renamingFiles_dataProvider
1029 */
1030 public function renamingFilesChangesFilenameOnDisk(array $filesystemStructure, $oldFileIdentifier, $newFileName, $expectedNewIdentifier) {
1031 $this->addToMount($filesystemStructure);
1032 $fixture = $this->createDriverFixture();
1033 $newIdentifier = $fixture->renameFile($oldFileIdentifier, $newFileName);
1034 $this->assertFalse($fixture->fileExists($oldFileIdentifier));
1035 $this->assertTrue($fixture->fileExists($newIdentifier));
1036 $this->assertEquals($expectedNewIdentifier, $newIdentifier);
1037 }
1038
1039 /**
1040 * @test
1041 */
1042 public function renamingFilesFailsIfTargetFileExists() {
1043 $this->setExpectedException('TYPO3\\CMS\\Core\\Resource\\Exception\\ExistingTargetFileNameException', '', 1320291063);
1044 $this->addToMount(array(
1045 'targetFolder' => array('file' => '', 'newFile' => '')
1046 ));
1047 $fixture = $this->createDriverFixture();
1048 $fixture->renameFile('/targetFolder/file', 'newFile');
1049 }
1050
1051 /**
1052 * We use this data provider for testing move methods because there are some issues with the
1053 *
1054 * @return array
1055 */
1056 public function renamingFolders_dataProvider() {
1057 return array(
1058 'folder in root folder' => array(
1059 array(
1060 'someFolder' => array()
1061 ),
1062 '/someFolder/',
1063 'newFolder',
1064 '/newFolder/'
1065 ),
1066 'file in subfolder' => array(
1067 array(
1068 'subfolder' => array(
1069 'someFolder' => array()
1070 )
1071 ),
1072 '/subfolder/someFolder/',
1073 'newFolder',
1074 '/subfolder/newFolder/'
1075 )
1076 );
1077 }
1078
1079 /**
1080 * @test
1081 * @dataProvider renamingFolders_dataProvider
1082 */
1083 public function renamingFoldersChangesFolderNameOnDisk(array $filesystemStructure, $oldFolderIdentifier, $newFolderName, $expectedNewIdentifier) {
1084 $this->addToMount($filesystemStructure);
1085 $fixture = $this->createDriverFixture();
1086 $mapping = $fixture->renameFolder($oldFolderIdentifier, $newFolderName);
1087 $this->assertFalse($fixture->folderExists($oldFolderIdentifier));
1088 $this->assertTrue($fixture->folderExists($expectedNewIdentifier));
1089 $this->assertEquals($expectedNewIdentifier, $mapping[$oldFolderIdentifier]);
1090 }
1091
1092 /**
1093 * @test
1094 */
1095 public function renameFolderReturnsCorrectMappingInformationForAllFiles() {
1096 $fileContents = 'asdfg';
1097 $this->addToMount(array(
1098 'sourceFolder' => array(
1099 'subFolder' => array('file' => $fileContents),
1100 'file2' => 'asdfg'
1101 )
1102 ));
1103 $fixture = $this->createDriverFixture();
1104 $mappingInformation = $fixture->renameFolder('/sourceFolder/', 'newFolder');
1105 $this->isTrue(is_array($mappingInformation));
1106 $this->assertEquals('/newFolder/', $mappingInformation['/sourceFolder/']);
1107 $this->assertEquals('/newFolder/file2', $mappingInformation['/sourceFolder/file2']);
1108 $this->assertEquals('/newFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
1109 $this->assertEquals('/newFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
1110 }
1111
1112 /**
1113 * @test
1114 */
1115 public function renameFolderRevertsRenamingIfFilenameMapCannotBeCreated() {
1116 $this->setExpectedException('\\RuntimeException', '', 1334160746);
1117 $this->addToMount(array(
1118 'sourceFolder' => array(
1119 'file' => 'asdfg'
1120 )
1121 ));
1122 $fixture = $this->createDriverFixture(array(), array('createIdentifierMap'));
1123 $fixture->expects($this->atLeastOnce())->method('createIdentifierMap')->will($this->throwException(new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException()));
1124 $fixture->renameFolder('/sourceFolder/', 'newFolder');
1125 $this->assertFileExists($this->getUrlInMount('/sourceFolder/file'));
1126 }
1127
1128 /**
1129 * @test
1130 */
1131 public function isFolderEmptyReturnsTrueForEmptyFolder() {
1132 // This also prepares the next few tests, so add more info than required for this test
1133 $this->addToMount(array(
1134 'emptyFolder' => array()
1135 ));
1136 $fixture = $this->createDriverFixture();
1137 $this->assertTrue($fixture->isFolderEmpty('/emptyFolder/'));
1138 return $fixture;
1139 }
1140
1141 /**
1142 * @test
1143 */
1144 public function isFolderEmptyReturnsFalseIfFolderHasFile() {
1145 $this->addToMount(array(
1146 'folderWithFile' => array(
1147 'someFile' => ''
1148 )
1149 ));
1150 $fixture = $this->createDriverFixture();
1151 $this->assertFalse($fixture->isFolderEmpty('/folderWithFile/'));
1152 }
1153
1154 /**
1155 * @test
1156 */
1157 public function isFolderEmptyReturnsFalseIfFolderHasSubfolder() {
1158 $this->addToMount(array(
1159 'folderWithSubfolder' => array(
1160 'someFolder' => array()
1161 )
1162 ));
1163 $fixture = $this->createDriverFixture();
1164 $this->assertFalse($fixture->isFolderEmpty('/folderWithSubfolder/'));
1165 }
1166
1167 /**********************************
1168 * Copy/move folder
1169 **********************************/
1170 /**
1171 * @test
1172 */
1173 public function foldersCanBeMovedWithinStorage() {
1174 $fileContents = uniqid();
1175 $this->addToMount(array(
1176 'sourceFolder' => array(
1177 'file' => $fileContents,
1178 ),
1179 'targetFolder' => array(),
1180 ));
1181 $fixture = $this->createDriverFixture();
1182 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
1183 $fixture->moveFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'someFolder');
1184 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/someFolder/')));
1185 $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/someFolder/file')));
1186 $this->assertFileNotExists($this->getUrlInMount('/sourceFolder'));
1187 }
1188
1189 /**
1190 * @test
1191 */
1192 public function moveFolderWithinStorageReturnsCorrectMappingInformationForAllFiles() {
1193 $fileContents = 'asdfg';
1194 $this->addToMount(array(
1195 'targetFolder' => array(),
1196 'sourceFolder' => array(
1197 'subFolder' => array('file' => $fileContents),
1198 'file' => 'asdfg'
1199 )
1200 ));
1201 $fixture = $this->createDriverFixture();
1202 $mappingInformation = $fixture->moveFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'sourceFolder');
1203 $this->assertEquals('/targetFolder/sourceFolder/file', $mappingInformation['/sourceFolder/file']);
1204 $this->assertEquals('/targetFolder/sourceFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
1205 $this->assertEquals('/targetFolder/sourceFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
1206 }
1207
1208 /**
1209 * @test
1210 */
1211 public function folderCanBeRenamedWhenMoving() {
1212 $this->addToMount(array(
1213 'sourceFolder' => array(
1214 'file' => uniqid(),
1215 ),
1216 'targetFolder' => array(),
1217 ));
1218 $fixture = $this->createDriverFixture();
1219 $fixture->moveFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolder');
1220 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/newFolder/')));
1221 }
1222
1223 /**
1224 * @test
1225 */
1226 public function copyFolderWithinStorageCopiesSingleFileToNewFolderName() {
1227 $this->addToMount(array(
1228 'sourceFolder' => array(
1229 'file' => uniqid(),
1230 ),
1231 'targetFolder' => array(),
1232 ));
1233 $fixture = $this->createDriverFixture();
1234 $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName');
1235 $this->assertTrue(is_file($this->getUrlInMount('/targetFolder/newFolderName/file')));
1236 }
1237
1238 /**
1239 * @test
1240 */
1241 public function copyFolderWithinStorageCopiesSingleSubFolderToNewFolderName() {
1242 list($basePath, $fixture) = $this->prepareRealTestEnvironment();
1243 GeneralUtility::mkdir_deep($basePath, '/sourceFolder/subFolder');
1244 GeneralUtility::mkdir_deep($basePath, '/targetFolder');
1245
1246 $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName');
1247 $this->isTrue(is_dir($basePath . '/targetFolder/newFolderName/subFolder'));
1248 }
1249
1250 /**
1251 * @test
1252 */
1253 public function copyFolderWithinStorageCopiesFileInSingleSubFolderToNewFolderName() {
1254 list($basePath, $fixture) = $this->prepareRealTestEnvironment();
1255 GeneralUtility::mkdir_deep($basePath, '/sourceFolder/subFolder');
1256 GeneralUtility::mkdir_deep($basePath, '/targetFolder');
1257 file_put_contents($basePath . '/sourceFolder/subFolder/file', uniqid());
1258 GeneralUtility::fixPermissions($basePath . '/sourceFolder/subFolder/file');
1259
1260 $fixture->copyFolderWithinStorage('/sourceFolder/', '/targetFolder/', 'newFolderName');
1261 $this->assertTrue(is_file($basePath . '/targetFolder/newFolderName/subFolder/file'));
1262 }
1263
1264 ///////////////////////
1265 // Tests concerning sanitizeFileName
1266 ///////////////////////
1267
1268 /**
1269 * Set up data for sanitizeFileName tests
1270 */
1271 public function setUpCharacterStrings() {
1272 // Generate string containing all characters for the iso8859-1 charset, charcode greater than 127
1273 $this->iso88591GreaterThan127 = '';
1274 for ($i = 0xA0; $i <= 0xFF; $i++) {
1275 $this->iso88591GreaterThan127 .= chr($i);
1276 }
1277
1278 // Generate string containing all characters for the utf-8 Latin-1 Supplement (U+0080 to U+00FF)
1279 // without U+0080 to U+009F: control characters
1280 // Based on http://www.utf8-chartable.de/unicode-utf8-table.pl
1281 $this->utf8Latin1Supplement = '';
1282 for ($i = 0xA0; $i <= 0xBF; $i++) {
1283 $this->utf8Latin1Supplement .= chr(0xC2) . chr($i);
1284 }
1285 for ($i = 0x80; $i <= 0xBF; $i++) {
1286 $this->utf8Latin1Supplement .= chr(0xC3) . chr($i);
1287 }
1288
1289 // Generate string containing all characters for the utf-8 Latin-1 Extended-A (U+0100 to U+017F)
1290 $this->utf8Latin1ExtendedA = '';
1291 for ($i = 0x80; $i <= 0xBF; $i++) {
1292 $this->utf8Latin1ExtendedA .= chr(0xC4) . chr($i);
1293 }
1294 for ($i = 0x80; $i <= 0xBF; $i++) {
1295 $this->utf8Latin1ExtendedA .= chr(0xC5) . chr($i);
1296 }
1297 }
1298
1299 /**
1300 * Data provider for sanitizeFileNameUTF8FilesystemDataProvider
1301 *
1302 * Every array splits into:
1303 * - String value fileName
1304 * - String value charset (none = '', utf-8, latin1, etc.)
1305 * - Expected result (cleaned fileName)
1306 *
1307 * @return array
1308 */
1309 public function sanitizeFileNameUTF8FilesystemDataProvider() {
1310 $this->setUpCharacterStrings();
1311 return array(
1312 // Characters ordered by ASCII table
1313 'allowed characters utf-8 (ASCII part)' => array(
1314 '-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
1315 '-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
1316 ),
1317 // Characters ordered by ASCII table (except for space-character, because space-character ist trimmed)
1318 'replace special characters with _ (not allowed characters) utf-8 (ASCII part)' => array(
1319 '! "#$%&\'()*+,/:;<=>?[\\]^`{|}~',
1320 '_____________________________'
1321 ),
1322 'utf-8 (Latin-1 Supplement)' => array(
1323 $this->utf8Latin1Supplement,
1324 '________________________________ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
1325 ),
1326 'trim leading and tailing spaces utf-8' => array(
1327 ' test.txt ',
1328 'test.txt'
1329 ),
1330 'remove tailing dot' => array(
1331 'test.txt.',
1332 'test.txt'
1333 ),
1334 );
1335 }
1336
1337 /**
1338 * @test
1339 * @dataProvider sanitizeFileNameUTF8FilesystemDataProvider
1340 */
1341 public function sanitizeFileNameUTF8Filesystem($fileName, $expectedResult) {
1342 $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem'] = 1;
1343 $this->assertEquals(
1344 $expectedResult,
1345 $this->createDriverFixture()->sanitizeFileName($fileName)
1346 );
1347 }
1348
1349
1350 /**
1351 * Data provider for sanitizeFileNameNonUTF8Filesystem
1352 *
1353 * Every array splits into:
1354 * - String value fileName
1355 * - String value charset (none = '', utf-8, latin1, etc.)
1356 * - Expected result (cleaned fileName)
1357 *
1358 * @return array
1359 */
1360 public function sanitizeFileNameNonUTF8FilesystemDataProvider() {
1361 $this->setUpCharacterStrings();
1362 return array(
1363 // Characters ordered by ASCII table
1364 'allowed characters iso-8859-1' => array(
1365 '-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
1366 'iso-8859-1',
1367 '-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
1368 ),
1369 // Characters ordered by ASCII table
1370 'allowed characters utf-8' => array(
1371 '-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz',
1372 'utf-8',
1373 '-.0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
1374 ),
1375 // Characters ordered by ASCII table (except for space-character, because space-character ist trimmed)
1376 'replace special characters with _ (not allowed characters) iso-8859-1' => array(
1377 '! "#$%&\'()*+,/:;<=>?[\\]^`{|}~',
1378 'iso-8859-1',
1379 '_____________________________'
1380 ),
1381 // Characters ordered by ASCII table (except for space-character, because space-character ist trimmed)
1382 'replace special characters with _ (not allowed characters) utf-8' => array(
1383 '! "#$%&\'()*+,/:;<=>?[\\]^`{|}~',
1384 'utf-8',
1385 '_____________________________'
1386 ),
1387 'iso-8859-1 (code > 127)' => array(
1388 // http://de.wikipedia.org/wiki/ISO_8859-1
1389 // chr(0xA0) = NBSP (no-break space) => gets trimmed
1390 $this->iso88591GreaterThan127,
1391 'iso-8859-1',
1392 '_centpound_yen____c_a_____R_____-23_u___1o__1_41_23_4_AAAAAEAAAECEEEEIIIIDNOOOOOExOEUUUUEYTHssaaaaaeaaaeceeeeiiiidnoooooe_oeuuuueythy'
1393 ),
1394 'utf-8 (Latin-1 Supplement)' => array(
1395 // chr(0xC2) . chr(0x0A) = NBSP (no-break space) => gets trimmed
1396 $this->utf8Latin1Supplement,
1397 'utf-8',
1398 '_centpound__yen______c_a_______R_______-23__u_____1o__1_41_23_4_AAAAAEAAAECEEEEIIIIDNOOOOOExOEUUUUEYTHssaaaaaeaaaeceeeeiiiidnoooooe_oeuuuueythy'
1399 ),
1400 'utf-8 (Latin-1 Extended A)' => array(
1401 $this->utf8Latin1ExtendedA,
1402 'utf-8',
1403 'AaAaAaCcCcCcCcDdDdEeEeEeEeEeGgGgGgGgHhHhIiIiIiIiIiIJijJjKk__LlLlLlL_l_LlNnNnNn_n____OOooOoOoOEoeRrRrRrSsSsSsSsTtTtTtUuUuUuUuUuUuWwYyYZzZzZzs'
1404 ),
1405 'trim leading and tailing spaces iso-8859-1' => array(
1406 ' test.txt ',
1407 'iso-8859-1',
1408 'test.txt'
1409 ),
1410 'trim leading and tailing spaces utf-8' => array(
1411 ' test.txt ',
1412 'utf-8',
1413 'test.txt'
1414 ),
1415 'remove tailing dot iso-8859-1' => array(
1416 'test.txt.',
1417 'iso-8859-1',
1418 'test.txt'
1419 ),
1420 'remove tailing dot utf-8' => array(
1421 'test.txt.',
1422 'utf-8',
1423 'test.txt'
1424 ),
1425 );
1426 }
1427
1428 /**
1429 * @test
1430 * @dataProvider sanitizeFileNameNonUTF8FilesystemDataProvider
1431 */
1432 public function sanitizeFileNameNonUTF8Filesystem($fileName, $charset, $expectedResult) {
1433 $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem'] = 0;
1434 $this->assertEquals(
1435 $expectedResult,
1436 $this->createDriverFixture()->sanitizeFileName($fileName, $charset)
1437 );
1438 }
1439
1440 /**
1441 * @test
1442 * @expectedException \TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException
1443 */
1444 public function sanitizeFileNameThrowsExceptionOnInvalidFileName() {
1445 $GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem'] = 1;
1446 $this->createDriverFixture()->sanitizeFileName('');
1447 }
1448
1449 }