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