[BUGFIX] Warning in FAL LocalDriverTest
[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 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 textfile 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 require_once 'vfsStream/vfsStream.php';
31 require_once dirname(dirname(__FILE__)) . '/BaseTestCase.php';
32 require_once dirname(__FILE__) . '/Fixtures/LocalDriverFilenameFilter.php';
33
34 /**
35 * Testcase for the local storage driver class of the TYPO3 VFS
36 *
37 * @package TYPO3
38 * @subpackage t3lib
39 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
40 */
41 class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
42
43 /**
44 * @var array A backup of registered singleton instances
45 */
46 protected $singletonInstances = array();
47
48 /**
49 * @var array
50 */
51 static private $testDirs = array();
52
53 public function setUp() {
54 parent::setUp();
55 // use a mocked file repository to avoid updating the index when doing property update tests
56 $mockedRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileRepository');
57 $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
58 \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances();
59 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\FileRepository', $mockedRepository);
60 }
61
62 public function tearDown() {
63 \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
64 parent::tearDown();
65 }
66
67 static public function tearDownAfterClass() {
68 foreach (self::$testDirs as $dir) {
69 chmod($dir, 0777);
70 \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir($dir, TRUE);
71 }
72 }
73
74 /**
75 * Creates a "real" directory for doing tests. This is neccessary because some file system properties (e.g. permissions)
76 * cannot be reflected by vfsStream, and some methods (like touch()) don't work there either.
77 *
78 * Created directories are automatically destroyed by the tearDownAfterClass() method.
79 *
80 * @return string
81 */
82 protected function createRealTestdir() {
83 $basedir = PATH_site . 'typo3temp/' . uniqid('fal-test-');
84 mkdir($basedir);
85 self::$testDirs[] = $basedir;
86 return $basedir;
87 }
88
89 /**
90 * Create a "real" directory together with a driverFixture configured
91 * for this directory.
92 *
93 * @return array With path to base directory and driver fixture
94 */
95 protected function prepareRealTestEnvironment() {
96 $basedir = $this->createRealTestdir();
97 $fixture = $this->createDriverFixture(array(
98 'basePath' => $basedir
99 ));
100 return array($basedir, $fixture);
101 }
102
103 /**
104 * Creates a driver fixture object, optionally using a given mount object.
105 *
106 * IMPORTANT: Call this only after setting up the virtual file system (with the addTo* methods)!
107 *
108 * @param $driverConfiguration
109 * @param \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject
110 * @param array $mockedDriverMethods
111 * @return \TYPO3\CMS\Core\Resource\Driver\LocalDriver
112 */
113 protected function createDriverFixture($driverConfiguration, \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject = NULL, $mockedDriverMethods = array()) {
114 $this->initializeVfs();
115 if ($storageObject == NULL) {
116 $storageObject = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
117 }
118 if (count($mockedDriverMethods) == 0) {
119 $driver = new \TYPO3\CMS\Core\Resource\Driver\LocalDriver($driverConfiguration);
120 } else {
121 $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', $mockedDriverMethods, array($driverConfiguration));
122 }
123 $storageObject->setDriver($driver);
124 $driver->setStorage($storageObject);
125 $driver->processConfiguration();
126 $driver->initialize();
127 return $driver;
128 }
129
130 /**
131 * @test
132 */
133 public function rootLevelFolderIsCreatedWithCorrectArguments() {
134 $mockedMount = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
135 $fixture = $this->createDriverFixture(array('basePath' => $this->getMountRootUrl()), $mockedMount);
136 $mockedFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
137 $mockedFactory->expects($this->once())->method('createFolderObject')->with($this->equalTo($mockedMount), $this->equalTo('/'), $this->equalTo(''));
138 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', $mockedFactory);
139 $fixture->getRootLevelFolder();
140 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', new \TYPO3\CMS\Core\Resource\ResourceFactory());
141 }
142
143 /**
144 * @test
145 */
146 public function getDefaultFolderReturnsFolderForTemporaryPath() {
147 $fixture = $this->createDriverFixture(array(
148 'basePath' => $this->getMountRootUrl()
149 ));
150 $folder = $fixture->getDefaultFolder();
151 $this->assertStringEndsWith('_temp_/', $folder->getIdentifier());
152 }
153
154 /**
155 * @test
156 */
157 public function defaultLevelFolderFolderIsCreatedIfItDoesntExist() {
158 $fixture = $this->createDriverFixture(array(
159 'basePath' => $this->getMountRootUrl()
160 ));
161 $fixture->getDefaultFolder();
162 $this->assertFileExists($this->getUrlInMount('/_temp_/'));
163 }
164
165 /**
166 * @test
167 */
168 public function getFolderInFolderReturnsCorrectFolderObject() {
169 $this->addToMount(array(
170 'someDir' => array(
171 'someSubdir' => array()
172 )
173 ));
174 $fixture = $this->createDriverFixture(array(
175 'basePath' => $this->getMountRootUrl()
176 ));
177 $parentFolder = $fixture->getFolder('/someDir');
178 $folder = $fixture->getFolderInFolder('someSubdir', $parentFolder);
179 $this->assertEquals('/someDir/someSubdir/', $folder->getIdentifier());
180 }
181
182 /**
183 * @test
184 */
185 public function createFolderCreatesFolderOnDisk() {
186 $this->addToMount(array('some' => array('folder' => array())));
187 $fixture = $this->createDriverFixture(array(
188 'basePath' => $this->getMountRootUrl()
189 ));
190 $mockedFolder = $this->getSimpleFolderMock('/some/folder/');
191 $fixture->createFolder('path', $mockedFolder);
192 $this->assertFileExists($this->getUrlInMount('/some/folder/'));
193 $this->assertFileExists($this->getUrlInMount('/some/folder/path'));
194 }
195
196 /**
197 * @test
198 */
199 public function createFolderReturnsFolderObject() {
200 $this->addToMount(array('some' => array('folder' => array())));
201 $fixture = $this->createDriverFixture(array(
202 'basePath' => $this->getMountRootUrl()
203 ));
204 $mockedFolder = $this->getSimpleFolderMock('/some/folder/');
205 $createdFolder = $fixture->createFolder('path', $mockedFolder);
206 $this->assertEquals('/some/folder/path/', $createdFolder->getIdentifier());
207 }
208
209 public function createFolderSanitizesFolderNameBeforeCreationDataProvider() {
210 return array(
211 'folder name with NULL character' => array(
212 'some' . chr(0) . 'Folder',
213 'some_Folder'
214 ),
215 'folder name with directory part' => array(
216 '../someFolder',
217 '.._someFolder'
218 )
219 );
220 }
221
222 /**
223 * @test
224 * @dataProvider createFolderSanitizesFolderNameBeforeCreationDataProvider
225 */
226 public function createFolderSanitizesFolderNameBeforeCreation($newFolderName, $expectedFolderName) {
227 $this->addToMount(array('some' => array('folder' => array())));
228 $fixture = $this->createDriverFixture(array(
229 'basePath' => $this->getMountRootUrl()
230 ));
231 $mockedFolder = $this->getSimpleFolderMock('/some/folder/');
232 $fixture->createFolder($newFolderName, $mockedFolder);
233 $this->assertFileExists($this->getUrlInMount('/some/folder/' . $expectedFolderName));
234 }
235
236 /**
237 * @test
238 */
239 public function driverConfigVerificationFailsIfConfiguredBasePathDoesNotExist() {
240 $this->setExpectedException('TYPO3\\CMS\\Core\\Resource\\Exception\\InvalidConfigurationException', '', 1299233097);
241 $driverConfiguration = array(
242 'basePath' => \vfsStream::url($this->basedir . 'doesntexist/')
243 );
244 $this->assertFalse(file_exists($driverConfiguration['basePath']));
245 \TYPO3\CMS\Core\Resource\Driver\LocalDriver::verifyConfiguration($driverConfiguration);
246 }
247
248 /**
249 * @test
250 */
251 public function basePathIsNormalizedWithTrailingSlash() {
252 $driverConfiguration = array(
253 'basePath' => $this->getMountRootUrl()
254 );
255 $fixture = $this->createDriverFixture($driverConfiguration);
256 $this->assertEquals('/', substr($fixture->getAbsoluteBasePath(), -1));
257 }
258
259 /**
260 * @test
261 */
262 public function noSecondSlashIsAddedIfBasePathAlreadyHasTrailingSlash() {
263 $driverConfiguration = array(
264 'basePath' => $this->getMountRootUrl()
265 );
266 $fixture = $this->createDriverFixture($driverConfiguration);
267 $this->assertNotEquals('/', substr($fixture->getAbsoluteBasePath(), -2, 1));
268 }
269
270 /**
271 * @test
272 */
273 public function getAbsolutePathReturnsCorrectPath() {
274 $this->addToMount(array(
275 'someFolder' => array(
276 'file1.ext' => 'asdfg'
277 )
278 ));
279 $mockedFile = $this->getSimpleFileMock('someFolder/file1.ext');
280 $fixture = $this->createDriverFixture(array(
281 'basePath' => $this->getMountRootUrl()
282 ));
283 $path = $fixture->getAbsolutePath($mockedFile);
284 $this->assertTrue(file_exists($path));
285 $this->assertEquals($this->getUrlInMount('/someFolder/file1.ext'), $path);
286 }
287
288 /**
289 * @test
290 */
291 public function getLowLevelFileInfoReturnsCorrectFileSize() {
292 $contents = uniqid('foo');
293 $this->addToMount(array('file1.ext' => $contents));
294 $mockedFile = $this->getSimpleFileMock('file1.ext');
295 $fixture = $this->createDriverFixture(
296 array('basePath' => $this->getMountRootUrl()),
297 NULL,
298 // Mocked because finfo() can not deal with vfs streams and throws warnings
299 array('getMimeTypeOfFile')
300 );
301 $stat = $fixture->getLowLevelFileInfo($mockedFile);
302 $this->assertEquals(strlen($contents), $stat['size']);
303 }
304
305 /**
306 * @test
307 */
308 public function getLowLevelFileInfoReturnsCorrectFileCtime() {
309 $contents = uniqid('foo');
310 $this->addToMount(array('file1.ext' => $contents));
311 $mockedFile = $this->getSimpleFileMock('file1.ext');
312 $fixture = $this->createDriverFixture(
313 array('basePath' => $this->getMountRootUrl()),
314 NULL,
315 // Mocked because finfo() can not deal with vfs streams and throws warnings
316 array('getMimeTypeOfFile')
317 );
318 $path = $fixture->getAbsolutePath($mockedFile);
319 $stat = $fixture->getLowLevelFileInfo($mockedFile);
320 $this->assertEquals(filectime($path), $stat['ctime']);
321 }
322
323 /**
324 * @test
325 */
326 public function getLowLevelFileInfoReturnsCorrectFileMtime() {
327 $contents = uniqid('foo');
328 $this->addToMount(array('file1.ext' => $contents));
329 $mockedFile = $this->getSimpleFileMock('file1.ext');
330 $fixture = $this->createDriverFixture(
331 array('basePath' => $this->getMountRootUrl()),
332 NULL,
333 // Mocked because finfo() can not deal with vfs streams and throws warnings
334 array('getMimeTypeOfFile')
335 );
336 $path = $fixture->getAbsolutePath($mockedFile);
337 $stat = $fixture->getLowLevelFileInfo($mockedFile);
338 $this->assertEquals(fileatime($path), $stat['mtime']);
339 }
340
341 /**
342 * @test
343 */
344 public function getLowLevelFileInfoReturnsCorrectFileAtime() {
345 $contents = uniqid('foo');
346 $this->addToMount(array('file1.ext' => $contents));
347 $mockedFile = $this->getSimpleFileMock('file1.ext');
348 $fixture = $this->createDriverFixture(
349 array('basePath' => $this->getMountRootUrl()),
350 NULL,
351 // Mocked because finfo() can not deal with vfs streams and throws warnings
352 array('getMimeTypeOfFile')
353 );
354 $path = $fixture->getAbsolutePath($mockedFile);
355 $stat = $fixture->getLowLevelFileInfo($mockedFile);
356 $this->assertEquals(filemtime($path), $stat['atime']);
357 }
358
359 /**
360 * @test
361 */
362 public function getLowLevelFileInfoReturnsCorrectFileMimeType() {
363 $baseDir = $this->createRealTestdir();
364 /** @var $driverFixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
365 $driverFixture = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', array('getAbsolutePath'), array());
366 $fileMock = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileInterface');
367 copy(__DIR__ . '/Fixtures/Dummy.html', $baseDir . '/Dummy.html');
368 $driverFixture->expects($this->once())->method('getAbsolutePath')->will($this->returnValue($baseDir . '/Dummy.html'));
369 $stats = $driverFixture->getLowLevelFileInfo($fileMock);
370 $this->assertEquals('text/html', $stats['mimetype']);
371 }
372
373 /**
374 * @test
375 */
376 public function addFileMovesFileToCorrectLocation() {
377 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
378 $this->addToMount(array('targetFolder' => array()));
379 $this->addToVfs(array(
380 'sourceFolder' => array(
381 'file' => 'asdf'
382 )
383 ));
384 $fixture = $this->createDriverFixture(
385 array('basePath' => $this->getMountRootUrl()),
386 NULL,
387 // Mocked because finfo() can not deal with vfs streams and throws warnings
388 array('getMimeTypeOfFile')
389 );
390 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
391 $fixture->addFile($this->getUrl('sourceFolder/file'), $mockedFolder, 'file');
392 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/file')));
393 }
394
395 /**
396 * @test
397 */
398 public function addFileUsesFilenameIfGiven() {
399 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
400 $this->addToMount(array('targetFolder' => array()));
401 $this->addToVfs(array(
402 'sourceFolder' => array(
403 'file' => 'asdf'
404 )
405 ));
406 $fixture = $this->createDriverFixture(
407 array('basePath' => $this->getMountRootUrl()),
408 NULL,
409 // Mocked because finfo() can not deal with vfs streams and throws warnings
410 array('getMimeTypeOfFile')
411 );
412 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
413 $fixture->addFile($this->getUrl('sourceFolder/file'), $mockedFolder, 'targetFile');
414 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/targetFile')));
415 }
416
417 /**
418 * @test
419 */
420 public function addFileFailsIfFileIsInDriverStorage() {
421 $mockedFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
422 $mockedFolder->expects($this->any())->method('getIdentifier')->will($this->returnValue('/targetFolder/'));
423 $this->setExpectedException('InvalidArgumentException', '', 1314778269);
424 $this->addToMount(array(
425 'targetFolder' => array(
426 'file' => 'asdf'
427 )
428 ));
429 $storageObject = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
430 $storageObject->expects($this->any())->method('getUid')->will($this->returnValue('1'));
431 $fixture = $this->createDriverFixture(
432 array('basePath' => $this->getMountRootUrl()),
433 $storageObject
434 );
435 $fixture->addFile($this->getUrlInMount('/targetFolder/file'), $mockedFolder, 'file');
436 }
437
438 /**
439 * @test
440 */
441 public function addFileReturnsFileObject() {
442 $mockedFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
443 $mockedFolder->expects($this->any())->method('getIdentifier')->will($this->returnValue('/targetFolder/'));
444 $this->addToMount(array('targetFolder' => array()));
445 $this->addToVfs(array(
446 'sourceFolder' => array(
447 'file' => 'asdf'
448 )
449 ));
450 $fixture = $this->createDriverFixture(
451 array('basePath' => $this->getMountRootUrl()),
452 NULL,
453 // Mocked because finfo() can not deal with vfs streams and throws warnings
454 array('getMimeTypeOfFile')
455 );
456 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
457 $fileObject = $fixture->addFile($this->getUrl('sourceFolder/file'), $mockedFolder, 'file');
458 $this->assertInstanceOf('TYPO3\\CMS\\Core\\Resource\\File', $fileObject);
459 $this->assertEquals('file', $fileObject->getName());
460 $this->assertEquals('/targetFolder/file', $fileObject->getIdentifier());
461 }
462
463 /**
464 * @test
465 */
466 public function addFileRawCreatesCopyOfFile() {
467 $this->addToMount(array('targetFolder' => array()));
468 $this->addToVfs(array(
469 'sourceFolder' => array(
470 'file' => 'asdf'
471 )
472 ));
473 $fixture = $this->createDriverFixture(array(
474 'basePath' => $this->getMountRootUrl()
475 ));
476 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
477 $fileIdentifier = $fixture->addFileRaw($this->getUrl('sourceFolder/file'), $this->getSimpleFolderMock('/targetFolder/'), 'somefile');
478 $this->assertTrue(file_exists($this->getUrl('sourceFolder/file')));
479 $this->assertTrue(file_exists($this->getUrlInMount('targetFolder/somefile')));
480 $this->assertEquals('/targetFolder/somefile', $fileIdentifier);
481 }
482
483 /**
484 * @test
485 */
486 public function deleteFileRawRemovesFile() {
487 $this->addToMount(array(
488 'targetFolder' => array(
489 'file' => 'asdjlkfa'
490 )
491 ));
492 $fixture = $this->createDriverFixture(array(
493 'basePath' => $this->getMountRootUrl()
494 ));
495 $this->assertTrue(file_exists($this->getUrlInMount('targetFolder/file')));
496 $fixture->deleteFileRaw('/targetFolder/file');
497 $this->assertFalse(file_exists($this->getUrlInMount('targetFolder/file')));
498 }
499
500 /**
501 * @test
502 */
503 public function replacingFileUpdatesMetadataInFileObject() {
504 $this->addToMount(array(
505 'targetFolder' => array(
506 'file' => 'asdjlkfa'
507 )
508 ));
509 $this->addToVfs(array(
510 'sourceFolder' => array(
511 'file' => 'asjdalks'
512 )
513 ));
514 $fixture = $this->createDriverFixture(
515 array('basePath' => $this->getMountRootUrl()),
516 NULL,
517 // Mocked because finfo() can not deal with vfs streams and throws warnings
518 array('getMimeTypeOfFile')
519 );
520 $mockedFile = $this->getSimpleFileMock('/targetFolder/file', array('updateProperties'));
521 $mockedFile->expects($this->once())->method('updateProperties');
522 $fixture->replaceFile($mockedFile, $this->getUrl('sourceFolder/file'));
523 }
524
525 /**
526 * @test
527 */
528 public function existenceChecksWorkForFilesAndFolders() {
529 $this->addToMount(array(
530 'file' => 'asdf',
531 'folder' => array()
532 ));
533 $fixture = $this->createDriverFixture(array(
534 'basePath' => $this->getMountRootUrl()
535 ));
536 // Using slashes at the beginning of paths because they will be stored in the DB this way.
537 $this->assertTrue($fixture->fileExists('/file'));
538 $this->assertTrue($fixture->folderExists('/folder/'));
539 $this->assertFalse($fixture->fileExists('/nonexistingFile'));
540 $this->assertFalse($fixture->folderExists('/nonexistingFolder/'));
541 }
542
543 /**
544 * @test
545 */
546 public function existenceChecksInFolderWorkForFilesAndFolders() {
547 $mockedFolder = $this->getSimpleFolderMock('/subfolder/');
548 $this->addToMount(array(
549 'subfolder' => array(
550 'file' => 'asdf',
551 'folder' => array()
552 )
553 ));
554 $fixture = $this->createDriverFixture(array(
555 'basePath' => $this->getMountRootUrl()
556 ));
557 $this->assertTrue($fixture->fileExistsInFolder('file', $mockedFolder));
558 $this->assertTrue($fixture->folderExistsInFolder('folder', $mockedFolder));
559 $this->assertFalse($fixture->fileExistsInFolder('nonexistingFile', $mockedFolder));
560 $this->assertFalse($fixture->folderExistsInFolder('nonexistingFolder', $mockedFolder));
561 }
562
563 /**
564 * @test
565 */
566 public function getPublicUrlReturnsCorrectUriForConfiguredBaseUri() {
567 $baseUri = 'http://example.org/foobar/' . uniqid();
568 $this->addToMount(array(
569 'file.ext' => 'asdf',
570 'subfolder' => array(
571 'file2.ext' => 'asdf'
572 )
573 ));
574 $fixture = $this->createDriverFixture(array(
575 'basePath' => $this->getMountRootUrl(),
576 'baseUri' => $baseUri
577 ));
578 $mockedFile1 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
579 $mockedFile1->expects($this->any())->method('getIdentifier')->will($this->returnValue('/file.ext'));
580 $mockedFile2 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
581 $mockedFile2->expects($this->any())->method('getIdentifier')->will($this->returnValue('/subfolder/file2.ext'));
582 $this->assertEquals($baseUri . '/file.ext', $fixture->getPublicUrl($mockedFile1));
583 $this->assertEquals($baseUri . '/subfolder/file2.ext', $fixture->getPublicUrl($mockedFile2));
584 }
585
586 /**
587 * @test
588 */
589 public function fileContentsCanBeWrittenAndRead() {
590 $fileContents = 'asdf';
591 $this->addToMount(array(
592 'file.ext' => $fileContents
593 ));
594 $fixture = $this->createDriverFixture(array(
595 'basePath' => $this->getMountRootUrl()
596 ));
597 $mockedFile = $this->getMock('TYPO3\\CMS\\Core\\Resource\\File', array(), array(), '', FALSE);
598 $mockedFile->expects($this->any())->method('getIdentifier')->will($this->returnValue('/file.ext'));
599 $this->assertEquals($fileContents, $fixture->getFileContents($mockedFile), 'File contents could not be read');
600 $newFileContents = 'asdfgh';
601 $fixture->setFileContents($mockedFile, $newFileContents);
602 $this->assertEquals($newFileContents, $fixture->getFileContents($mockedFile), 'New file contents could not be read.');
603 }
604
605 /**
606 * @test
607 */
608 public function setFileContentsReturnsNumberOfBytesWrittenToFile() {
609 $fileContents = 'asdf';
610 $this->addToMount(array(
611 'file.ext' => $fileContents
612 ));
613 $fixture = $this->createDriverFixture(array(
614 'basePath' => $this->getMountRootUrl()
615 ));
616 $mockedFile = $this->getSimpleFileMock('/file.ext');
617 $newFileContents = 'asdfgh';
618 $bytesWritten = $fixture->setFileContents($mockedFile, $newFileContents);
619 $this->assertEquals(strlen($newFileContents), $bytesWritten);
620 }
621
622 /**
623 * @test
624 * @depends existenceChecksWorkForFilesAndFolders
625 * @return array The driver fixture, the mocked file
626 */
627 public function newFilesCanBeCreated() {
628 $this->addToMount(array(
629 'someDir' => array()
630 ));
631 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
632 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
633 mkdir($basedir . '/someDir');
634 $fixture->createFile('testfile.txt', $fixture->getFolder('someDir'));
635 $mockedFile = $this->getSimpleFileMock('/someDir/testfile.txt');
636 $this->assertTrue($fixture->fileExists('/someDir/testfile.txt'));
637 return array($fixture, $mockedFile);
638 }
639
640 /**
641 * @test
642 * @depends newFilesCanBeCreated
643 */
644 public function createdFilesAreEmpty(array $arguments) {
645 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
646 list($fixture, $mockedFile) = $arguments;
647 $fileData = $fixture->getFileContents($mockedFile);
648 $this->assertEquals(0, strlen($fileData));
649 }
650
651 /**********************************
652 * File and directory listing
653 **********************************/
654 /**
655 * @test
656 */
657 public function getFileReturnsCorrectIdentifier() {
658 $this->addToMount(array(
659 'someDir' => array(
660 'someFile' => 'asdfg'
661 ),
662 'someFileAtRootLevel' => 'foobar'
663 ));
664 $fixture = $this->createDriverFixture(
665 array('basePath' => $this->getMountRootUrl()),
666 NULL,
667 // Mocked because finfo() can not deal with vfs streams and throws warnings
668 array('getMimeTypeOfFile')
669 );
670 $subdirFileInfo = $fixture->getFileInfoByIdentifier('/someDir/someFile');
671 $this->assertEquals('/someDir/someFile', $subdirFileInfo['identifier']);
672 $rootFileInfo = $fixture->getFileInfoByIdentifier('/someFileAtRootLevel');
673 $this->assertEquals('/someFileAtRootLevel', $rootFileInfo['identifier']);
674 }
675
676 /**
677 * @test
678 */
679 public function getFileThrowsExceptionIfFileDoesNotExist() {
680 $this->setExpectedException('InvalidArgumentException', '', 1314516809);
681 $fixture = $this->createDriverFixture(array(
682 'basePath' => $this->getMountRootUrl()
683 ));
684 $fixture->getFileInfoByIdentifier('/some/file/at/a/random/path');
685 }
686
687 /**
688 * @test
689 */
690 public function getFileListReturnsEmptyArrayForEmptyDirectory() {
691 $fixture = $this->createDriverFixture(array(
692 'basePath' => $this->getMountRootUrl()
693 ));
694 $fileList = $fixture->getFileList('/');
695 $this->assertEmpty($fileList);
696 }
697
698 /**
699 * @test
700 */
701 public function getFileListReturnsAllFilesInDirectory() {
702 $dirStructure = array(
703 'aDir' => array(),
704 'file1' => 'asdfg',
705 'file2' => 'fdsa'
706 );
707 $this->addToMount($dirStructure);
708 $fixture = $this->createDriverFixture(
709 array('basePath' => $this->getMountRootUrl()),
710 NULL,
711 // Mocked because finfo() can not deal with vfs streams and throws warnings
712 array('getMimeTypeOfFile')
713 );
714 $fileList = $fixture->getFileList('/');
715 $this->assertEquals(array('file1', 'file2'), array_keys($fileList));
716 }
717
718 /**
719 * @test
720 */
721 public function getFileListFailsIfDirectoryDoesNotExist() {
722 $this->setExpectedException('InvalidArgumentException', '', 1314349666);
723 $this->addToMount(array('somefile' => ''));
724 $fixture = $this->createDriverFixture(array(
725 'basePath' => $this->getMountRootUrl()
726 ));
727 $fixture->getFileList('somedir/');
728 }
729
730 /**
731 * @test
732 */
733 public function getFileListCallsConfiguredCallbackFunctionWithGivenItemName() {
734 $dirStructure = array(
735 'file2' => 'fdsa'
736 );
737 // register static callback to self
738 $callback = array(
739 array(
740 get_class($this),
741 'callbackStaticTestFunction'
742 )
743 );
744 $this->addToMount($dirStructure);
745 $fixture = $this->createDriverFixture(array(
746 'basePath' => $this->getMountRootUrl()
747 ));
748 // the callback function will throw an exception used to check if it was called with correct $itemName
749 $this->setExpectedException('InvalidArgumentException', '$itemName', 1336159604);
750 $fixture->getFileList('/', 0, 0, $callback);
751 }
752
753 /**
754 * Static callback function used to test if the filter callbacks work
755 * As it is static we are using an exception to test if it is really called and works
756 *
757 * @static
758 * @throws \InvalidArgumentException
759 * @see getFileListCallsConfiguredCallbackFunction
760 */
761 static public function callbackStaticTestFunction() {
762 list($itemName) = func_get_args();
763 if ($itemName === 'file2') {
764 throw new \InvalidArgumentException('$itemName', 1336159604);
765 }
766 }
767
768 /**
769 * @test
770 */
771 public function getFileListFiltersItemsWithGivenFilterMethods() {
772 $dirStructure = array(
773 'fileA' => 'asdfg',
774 'fileB' => 'fdsa'
775 );
776 $this->addToMount($dirStructure);
777 $fixture = $this->createDriverFixture(
778 array('basePath' => $this->getMountRootUrl()),
779 NULL,
780 // Mocked because finfo() can not deal with vfs streams and throws warnings
781 array('getMimeTypeOfFile')
782 );
783 $filterCallbacks = array(
784 array(
785 'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
786 'filterFilename',
787 ),
788 );
789 $fileList = $fixture->getFileList('/', 0, 0, $filterCallbacks);
790 $this->assertNotContains('fileA', array_keys($fileList));
791 }
792
793 /**
794 * @test
795 */
796 public function getFolderListReturnsAllDirectoriesInDirectory() {
797 $dirStructure = array(
798 'dir1' => array(),
799 'dir2' => array(),
800 'file' => 'asdfg'
801 );
802 $this->addToMount($dirStructure);
803 $fixture = $this->createDriverFixture(array(
804 'basePath' => $this->getMountRootUrl()
805 ));
806 $fileList = $fixture->getFolderList('/');
807 $this->assertEquals(array('dir1', 'dir2'), array_keys($fileList));
808 }
809
810 /**
811 * @test
812 */
813 public function getFolderListReturnsHiddenFoldersByDefault() {
814 $dirStructure = array(
815 '.someHiddenDir' => array(),
816 'aDir' => array(),
817 'file1' => ''
818 );
819 $this->addToMount($dirStructure);
820 $fixture = $this->createDriverFixture(array(
821 'basePath' => $this->getMountRootUrl()
822 ));
823 $fileList = $fixture->getFolderList('/');
824 $this->assertEquals(array('.someHiddenDir', 'aDir'), array_keys($fileList));
825 }
826
827 /**
828 * @test
829 */
830 public function getFolderListUsesCorrectPathForItems() {
831 $this->addToMount(array(
832 'dir1' => array(
833 'subdir1' => array()
834 )
835 ));
836 $fixture = $this->createDriverFixture(array(
837 'basePath' => $this->getMountRootUrl()
838 ));
839 $FolderList = $fixture->getFolderList('/');
840 $this->assertEquals('/dir1/', $FolderList['dir1']['identifier']);
841 $FolderList = $fixture->getFolderList('/dir1/');
842 $this->assertEquals('/dir1/subdir1/', $FolderList['subdir1']['identifier']);
843 }
844
845 /**
846 * Checks if the folder names . and .. are ignored when listing subdirectories
847 *
848 * @test
849 */
850 public function getFolderListLeavesOutNavigationalEntries() {
851 // we have to add .. and . manually, as these are not included in vfsStream directory listings (as opposed
852 // to normal file listings)
853 $this->addToMount(array(
854 '..' => array(),
855 '.' => array()
856 ));
857 $fixture = $this->createDriverFixture(array(
858 'basePath' => $this->getMountRootUrl()
859 ));
860 $fileList = $fixture->getFolderList('/');
861 $this->assertEmpty($fileList);
862 }
863
864 /**
865 * @test
866 */
867 public function getFolderListFiltersItemsWithGivenFilterMethods() {
868 $dirStructure = array(
869 'folderA' => array(),
870 'folderB' => array()
871 );
872 $this->addToMount($dirStructure);
873 $fixture = $this->createDriverFixture(array(
874 'basePath' => $this->getMountRootUrl()
875 ));
876 $filterCallbacks = array(
877 array(
878 'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
879 'filterFilename',
880 ),
881 );
882 $folderList = $fixture->getFolderList('/', 0, 0, $filterCallbacks);
883 $this->assertNotContains('folderA', array_keys($folderList));
884 }
885
886 /**
887 * @test
888 */
889 public function getFolderListFailsIfDirectoryDoesNotExist() {
890 $this->setExpectedException('InvalidArgumentException', '', 1314349666);
891 $fixture = $this->createDriverFixture(array(
892 'basePath' => $this->getMountRootUrl()
893 ));
894 \vfsStream::create(array($this->basedir => array('somefile' => '')));
895 $fixture->getFolderList('somedir/');
896 }
897
898 /**
899 * @test
900 */
901 public function hashReturnsCorrectHashes() {
902 $contents = '68b329da9893e34099c7d8ad5cb9c940';
903 $expectedMd5Hash = '8c67dbaf0ba22f2e7fbc26413b86051b';
904 $expectedSha1Hash = 'a60cd808ba7a0bcfa37fa7f3fb5998e1b8dbcd9d';
905 $mockedFile = $this->getSimpleFileMock('/hashFile');
906 $this->addToMount(array('hashFile' => $contents));
907 $fixture = $this->createDriverFixture(array(
908 'basePath' => $this->getMountRootUrl()
909 ));
910 $this->assertEquals($expectedSha1Hash, $fixture->hash($mockedFile, 'sha1'));
911 $this->assertEquals($expectedMd5Hash, $fixture->hash($mockedFile, 'md5'));
912 }
913
914 /**
915 * @test
916 */
917 public function hashingWithUnsupportedAlgorithmFails() {
918 $this->setExpectedException('InvalidArgumentException', '', 1304964032);
919 $fixture = $this->createDriverFixture(array(
920 'basePath' => $this->getMountRootUrl()
921 ));
922 $fixture->hash($this->getSimpleFileMock('/hashFile'), uniqid());
923 }
924
925 /**
926 * @test
927 * @covers TYPO3\CMS\Core\Resource\Driver\LocalDriver::getFileForLocalProcessing
928 */
929 public function getFileForLocalProcessingCreatesCopyOfFileByDefault() {
930 $fileContents = 'asdfgh';
931 $this->addToMount(array(
932 'someDir' => array(
933 'someFile' => $fileContents
934 )
935 ));
936 $fixture = $this->createDriverFixture(array(
937 'basePath' => $this->getMountRootUrl()
938 ), NULL, array('copyFileToTemporaryPath'));
939 $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
940 // TODO add parameter expectation for $mockedFile as soon as PHPUnit supports object identity matching in parameter expectations
941 $fixture->expects($this->once())->method('copyFileToTemporaryPath');
942 $fixture->getFileForLocalProcessing($mockedFile);
943 }
944
945 /**
946 * @test
947 */
948 public function getFileForLocalProcessingReturnsOriginalFilepathForReadonlyAccess() {
949 $fileContents = 'asdfgh';
950 $this->addToMount(array(
951 'someDir' => array(
952 'someFile' => $fileContents
953 )
954 ));
955 $fixture = $this->createDriverFixture(array(
956 'basePath' => $this->getMountRootUrl()
957 ));
958 $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
959 $filePath = $fixture->getFileForLocalProcessing($mockedFile, FALSE);
960 $this->assertEquals($filePath, $this->getMountRootUrl() . 'someDir/someFile');
961 }
962
963 /**
964 * @test
965 */
966 public function filesCanBeCopiedToATemporaryPath() {
967 $fileContents = 'asdfgh';
968 $this->addToMount(array(
969 'someDir' => array(
970 'someFile' => $fileContents
971 )
972 ));
973 $fixture = $this->createDriverFixture(array(
974 'basePath' => $this->getMountRootUrl()
975 ));
976 $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
977 $filePath = $fixture->copyFileToTemporaryPath($mockedFile);
978 $this->assertContains('/typo3temp/', $filePath);
979 $this->assertEquals($fileContents, file_get_contents($filePath));
980 }
981
982 /**
983 * @test
984 */
985 public function permissionsAreCorrectlyRetrievedForAllowedFile() {
986 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
987 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
988 touch($basedir . '/someFile');
989 chmod($basedir . '/someFile', 448);
990 clearstatcache();
991 $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getFilePermissions($this->getSimpleFileMock('/someFile')));
992 }
993
994 /**
995 * @test
996 */
997 public function permissionsAreCorrectlyRetrievedForForbiddenFile() {
998 if (function_exists('posix_getegid') && posix_getegid() === 0) {
999 $this->markTestSkipped('Test skipped if run on linux as root');
1000 }
1001 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1002 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1003 touch($basedir . '/someForbiddenFile');
1004 chmod($basedir . '/someForbiddenFile', 0);
1005 clearstatcache();
1006 $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $fixture->getFilePermissions($this->getSimpleFileMock('/someForbiddenFile')));
1007 }
1008
1009 /**
1010 * @test
1011 */
1012 public function permissionsAreCorrectlyRetrievedForAllowedFolder() {
1013 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1014 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1015 mkdir($basedir . '/someFolder');
1016 chmod($basedir . '/someFolder', 448);
1017 clearstatcache();
1018 $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getFolderPermissions($this->getSimpleFolderMock('/someFolder')));
1019 }
1020
1021 /**
1022 * @test
1023 */
1024 public function permissionsAreCorrectlyRetrievedForForbiddenFolder() {
1025 if (function_exists('posix_getegid') && posix_getegid() === 0) {
1026 $this->markTestSkipped('Test skipped if run on linux as root');
1027 }
1028 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1029 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1030 mkdir($basedir . '/someForbiddenFolder');
1031 chmod($basedir . '/someForbiddenFolder', 0);
1032 clearstatcache();
1033 $result = $fixture->getFolderPermissions($this->getSimpleFolderMock('/someForbiddenFolder'));
1034 // Change permissions back to writable, so the sub-folder can be removed in tearDown
1035 chmod($basedir . '/someForbiddenFolder', 0777);
1036 $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $result);
1037 }
1038
1039 /**
1040 * Dataprovider for getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser test
1041 *
1042 * @return array group, filemode and expected result
1043 */
1044 public function getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser_dataProvider() {
1045 $data = array();
1046 // On some OS, the posix_* functions do not exits
1047 if (function_exists('posix_getgid')) {
1048 $data = array(
1049 'current group, readable/writable' => array(
1050 posix_getgid(),
1051 48,
1052 array('r' => TRUE, 'w' => TRUE)
1053 ),
1054 'current group, readable/not writable' => array(
1055 posix_getgid(),
1056 32,
1057 array('r' => TRUE, 'w' => FALSE)
1058 ),
1059 'current group, not readable/not writable' => array(
1060 posix_getgid(),
1061 0,
1062 array('r' => FALSE, 'w' => FALSE)
1063 )
1064 );
1065 }
1066 $data = array_merge_recursive($data, array(
1067 'arbitrary group, readable/writable' => array(
1068 \vfsStream::GROUP_USER_1,
1069 6,
1070 array('r' => TRUE, 'w' => TRUE)
1071 ),
1072 'arbitrary group, readable/not writable' => array(
1073 \vfsStream::GROUP_USER_1,
1074 436,
1075 array('r' => TRUE, 'w' => FALSE)
1076 ),
1077 'arbitrary group, not readable/not writable' => array(
1078 \vfsStream::GROUP_USER_1,
1079 432,
1080 array('r' => FALSE, 'w' => FALSE)
1081 )
1082 ));
1083 return $data;
1084 }
1085
1086 /**
1087 * @test
1088 * @dataProvider getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser_dataProvider
1089 */
1090 public function getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser($group, $permissions, $expectedResult) {
1091 $this->addToMount(array(
1092 'testfile' => 'asdfg'
1093 ));
1094 $fixture = $this->createDriverFixture(array(
1095 'basePath' => $this->getMountRootUrl()
1096 ));
1097 /** @var $fileObject vfsStreamContent */
1098 $fileObject = \vfsStreamWrapper::getRoot()->getChild($this->mountDir)->getChild('testfile');
1099 // just use an "arbitrary" user here - it is only important that
1100 $fileObject->chown(\vfsStream::OWNER_USER_1);
1101 $fileObject->chgrp($group);
1102 $fileObject->chmod($permissions);
1103 $this->assertEquals($expectedResult, $fixture->getFilePermissions($this->getSimpleFileMock('/testfile')));
1104 }
1105
1106 /**
1107 * @test
1108 */
1109 public function isWithinRecognizesFilesWithinFolderAndInOtherFolders() {
1110 $mockedStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1111 $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage, '/someFolder/', 'someFolder');
1112 $fixture = $this->createDriverFixture(array(
1113 'basePath' => $this->getMountRootUrl()
1114 ), $mockedStorage);
1115 $this->assertTrue($fixture->isWithin($mockedFolder, '/someFolder/test.jpg'));
1116 $this->assertTrue($fixture->isWithin($mockedFolder, '/someFolder/subFolder/test.jpg'));
1117 $this->assertFalse($fixture->isWithin($mockedFolder, '/someFolderWithALongName/test.jpg'));
1118 }
1119
1120 /**
1121 * @test
1122 */
1123 public function isWithinAcceptsFileAndFolderObjectsAsContent() {
1124 $mockedStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1125 $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage, '/someFolder/', 'someFolder');
1126 $fixture = $this->createDriverFixture(array(
1127 'basePath' => $this->getMountRootUrl()
1128 ), $mockedStorage);
1129 $mockedSubfolder = $this->getSimpleFolderMock('/someFolder/subfolder/');
1130 $mockedFile = $this->getSimpleFileMock('/someFolder/test.jpg');
1131 $this->assertTrue($fixture->isWithin($mockedFolder, $mockedFile));
1132 $this->assertTrue($fixture->isWithin($mockedFolder, $mockedSubfolder));
1133 }
1134
1135 /**
1136 * @test
1137 */
1138 public function isWithinAlwaysReturnsFalseIfFolderIsWithinDifferentStorage() {
1139 $mockedStorage1 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1140 $mockedStorage2 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1141 $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage1, '/someFolder/', 'someFolder');
1142 $fixture = $this->createDriverFixture(array(
1143 'basePath' => $this->getMountRootUrl()
1144 ), $mockedStorage2);
1145 $fileIdentifier = '/someFolder/test.jpg';
1146 $subfolderIdentifier = '/someFolder/subfolder/';
1147 $mockedFile = $this->getSimpleFileMock($fileIdentifier);
1148 $mockedSubfolder = $this->getSimpleFolderMock($subfolderIdentifier);
1149 $this->assertFalse($fixture->isWithin($mockedFolder, $mockedFile));
1150 $this->assertFalse($fixture->isWithin($mockedFolder, $fileIdentifier));
1151 $this->assertFalse($fixture->isWithin($mockedFolder, $mockedSubfolder));
1152 $this->assertFalse($fixture->isWithin($mockedFolder, $subfolderIdentifier));
1153 }
1154
1155 /**********************************
1156 * Copy/move file
1157 **********************************/
1158 /**
1159 * @param $identifier
1160 * @param null|\TYPO3\CMS\Core\Resource\ResourceStorage $storage
1161 * @return \TYPO3\CMS\Core\Resource\File
1162 */
1163 protected function mockFileForCopyingAndMoving($identifier, \TYPO3\CMS\Core\Resource\ResourceStorage $storage = NULL) {
1164 if (!$storage) {
1165 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1166 }
1167 $fileObject = new \TYPO3\CMS\Core\Resource\File(array('identifier' => $identifier, 'name' => basename($identifier), 'storage' => $storage));
1168 return $fileObject;
1169 }
1170
1171 /**
1172 * @param $identifier
1173 * @param null|\TYPO3\CMS\Core\Resource\ResourceStorage $storage
1174 * @return \TYPO3\CMS\Core\Resource\Folder
1175 */
1176 protected function mockFolderForCopyingAndMoving($identifier, \TYPO3\CMS\Core\Resource\ResourceStorage $storage = NULL) {
1177 if (!$storage) {
1178 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1179 }
1180 $folderObject = new \TYPO3\CMS\Core\Resource\Folder($storage, $identifier, basename($identifier), 0);
1181 return $folderObject;
1182 }
1183
1184 /**
1185 * Prepares a simple two-folder environment with /someFolder/ and /targetFolder/. /someFolder contains a file with random
1186 * contents
1187 *
1188 * @return array $mockedFolder, $sourceFolder, $fileContents, $fixture
1189 */
1190 protected function _prepareFolderEnvironmentForMoveTest() {
1191 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
1192 $sourceFolder = $this->getSimpleFolderMock('/someFolder/');
1193 $fileContents = uniqid();
1194 $this->addToMount(array(
1195 'targetFolder' => array(),
1196 'someFolder' => array('file' => $fileContents)
1197 ));
1198 $fixture = $this->createDriverFixture(array(
1199 'basePath' => $this->getMountRootUrl()
1200 ));
1201 return array($mockedFolder, $sourceFolder, $fileContents, $fixture);
1202 }
1203
1204 /**
1205 * @test
1206 */
1207 public function filesCanBeCopiedWithinStorage() {
1208 $fileContents = uniqid();
1209 $this->addToMount(array(
1210 'someFile' => $fileContents,
1211 'targetFolder' => array()
1212 ));
1213 $fixture = $this->createDriverFixture(
1214 array('basePath' => $this->getMountRootUrl()),
1215 NULL,
1216 // Mocked because finfo() can not deal with vfs streams and throws warnings
1217 array('getMimeTypeOfFile')
1218 );
1219 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1220 $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
1221 $targetFolder = $this->mockFolderForCopyingAndMoving('/targetFolder/', $storage);
1222 $fixture->copyFileWithinStorage($sourceFile, $targetFolder, 'someFile');
1223 $this->assertFileEquals($this->getUrlInMount('/someFile'), $this->getUrlInMount('/targetFolder/someFile'));
1224 }
1225
1226 /**
1227 * @test
1228 */
1229 public function filesCanBeMovedWithinStorage() {
1230 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
1231 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1232 $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
1233 $fileContents = uniqid();
1234 $this->addToMount(array(
1235 'targetFolder' => array(),
1236 'someFile' => $fileContents
1237 ));
1238 $fixture = $this->createDriverFixture(array(
1239 'basePath' => $this->getMountRootUrl()
1240 ));
1241 $newIdentifier = $fixture->moveFileWithinStorage($sourceFile, $mockedFolder, 'file');
1242 $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/file')));
1243 $this->assertFileNotExists($this->getUrlInMount('/someFile'));
1244 $this->assertEquals('/targetFolder/file', $newIdentifier);
1245 }
1246
1247 /**
1248 * @test
1249 */
1250 public function fileMetadataIsChangedAfterMovingFile() {
1251 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
1252 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1253 $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
1254 $fileContents = uniqid();
1255 $this->addToMount(array(
1256 'targetFolder' => array(),
1257 'someFile' => $fileContents
1258 ));
1259 $fixture = $this->createDriverFixture(
1260 array('basePath' => $this->getMountRootUrl()),
1261 NULL,
1262 // Mocked because finfo() can not deal with vfs streams and throws warnings
1263 array('getMimeTypeOfFile')
1264 );
1265 $newIdentifier = $fixture->moveFileWithinStorage($sourceFile, $mockedFolder, 'file');
1266 $fileMetadata = $fixture->getFileInfoByIdentifier($newIdentifier);
1267 $this->assertEquals($newIdentifier, $fileMetadata['identifier']);
1268 }
1269
1270 public function renamingFiles_dataProvider() {
1271 return array(
1272 'file in subfolder' => array(
1273 array(
1274 'targetFolder' => array('file' => '')
1275 ),
1276 '/targetFolder/file',
1277 'newFile',
1278 '/targetFolder/newFile'
1279 ),
1280 'file in rootfolder' => array(
1281 array(
1282 'fileInRoot' => ''
1283 ),
1284 '/fileInRoot',
1285 'newFile',
1286 '/newFile'
1287 )
1288 );
1289 }
1290
1291 /**
1292 * @test
1293 * @dataProvider renamingFiles_dataProvider
1294 */
1295 public function renamingFilesChangesFilenameOnDisk(array $filesystemStructure, $oldFileIdentifier, $newFileName, $expectedNewIdentifier) {
1296 $this->addToMount($filesystemStructure);
1297 $fixture = $this->createDriverFixture(array(
1298 'basePath' => $this->getMountRootUrl()
1299 ));
1300 $file = $this->getSimpleFileMock($oldFileIdentifier);
1301 $newIdentifier = $fixture->renameFile($file, $newFileName);
1302 $this->assertFalse($fixture->fileExists($oldFileIdentifier));
1303 $this->assertTrue($fixture->fileExists($newIdentifier));
1304 $this->assertEquals($expectedNewIdentifier, $newIdentifier);
1305 }
1306
1307 /**
1308 * @test
1309 */
1310 public function renamingFilesFailsIfTargetFileExists() {
1311 $this->setExpectedException('TYPO3\\CMS\\Core\\Resource\\Exception\\ExistingTargetFileNameException', '', 1320291063);
1312 $this->addToMount(array(
1313 'targetFolder' => array('file' => '', 'newFile' => '')
1314 ));
1315 $fixture = $this->createDriverFixture(array(
1316 'basePath' => $this->getMountRootUrl()
1317 ));
1318 $file = $this->getSimpleFileMock('/targetFolder/file');
1319 $fixture->renameFile($file, 'newFile');
1320 }
1321
1322 /**
1323 * We use this data provider for testing move methods because there are some issues with the
1324 *
1325 * @return array
1326 */
1327 public function renamingFolders_dataProvider() {
1328 return array(
1329 'folder in root folder' => array(
1330 array(
1331 'someFolder' => array()
1332 ),
1333 '/someFolder/',
1334 'newFolder',
1335 '/newFolder/'
1336 ),
1337 'file in subfolder' => array(
1338 array(
1339 'subfolder' => array(
1340 'someFolder' => array()
1341 )
1342 ),
1343 '/subfolder/someFolder/',
1344 'newFolder',
1345 '/subfolder/newFolder/'
1346 )
1347 );
1348 }
1349
1350 /**
1351 * @test
1352 * @dataProvider renamingFolders_dataProvider
1353 */
1354 public function renamingFoldersChangesFolderNameOnDisk(array $filesystemStructure, $oldFolderIdentifier, $newFolderName, $expectedNewIdentifier) {
1355 $this->addToMount($filesystemStructure);
1356 $fixture = $this->createDriverFixture(array(
1357 'basePath' => $this->getMountRootUrl()
1358 ));
1359 $mockedFolder = $this->getSimpleFolderMock($oldFolderIdentifier);
1360 $mapping = $fixture->renameFolder($mockedFolder, $newFolderName);
1361 $this->assertFalse($fixture->folderExists($oldFolderIdentifier));
1362 $this->assertTrue($fixture->folderExists($expectedNewIdentifier));
1363 $this->assertEquals($expectedNewIdentifier, $mapping[$oldFolderIdentifier]);
1364 }
1365
1366 /**
1367 * @test
1368 */
1369 public function renameFolderReturnsCorrectMappingInformationForAllFiles() {
1370 $fileContents = 'asdfg';
1371 $this->addToMount(array(
1372 'sourceFolder' => array(
1373 'subFolder' => array('file' => $fileContents),
1374 'file' => 'asdfg'
1375 )
1376 ));
1377 $fixture = $this->createDriverFixture(array(
1378 'basePath' => $this->getMountRootUrl()
1379 ));
1380 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1381 $mappingInformation = $fixture->renameFolder($sourceFolder, 'newFolder');
1382 $this->assertEquals('/newFolder/', $mappingInformation['/sourceFolder/']);
1383 $this->assertEquals('/newFolder/file', $mappingInformation['/sourceFolder/file']);
1384 $this->assertEquals('/newFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
1385 $this->assertEquals('/newFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
1386 }
1387
1388 /**
1389 * @test
1390 */
1391 public function renameFolderRevertsRenamingIfFilenameMapCannotBeCreated() {
1392 $this->setExpectedException('\RuntimeException', '', 1334160746);
1393 $this->addToMount(array(
1394 'sourceFolder' => array(
1395 'file' => 'asdfg'
1396 )
1397 ));
1398 $fixture = $this->createDriverFixture(array(
1399 'basePath' => $this->getMountRootUrl()
1400 ), NULL, array('createIdentifierMap'));
1401 $fixture->expects($this->atLeastOnce())->method('createIdentifierMap')->will($this->throwException(new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException()));
1402 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1403 $fixture->renameFolder($sourceFolder, 'newFolder');
1404 $this->assertFileExists($this->getUrlInMount('/sourceFolder/file'));
1405 }
1406
1407 /**
1408 * @test
1409 */
1410 public function isFolderEmptyReturnsTrueForEmptyFolder() {
1411 // This also prepares the next few tests, so add more info than required for this test
1412 $this->addToMount(array(
1413 'emptyFolder' => array()
1414 ));
1415 $fixture = $this->createDriverFixture(array(
1416 'basePath' => $this->getMountRootUrl()
1417 ));
1418 $mockedFolder = $this->getSimpleFolderMock('/emptyFolder/');
1419 $this->assertTrue($fixture->isFolderEmpty($mockedFolder));
1420 return $fixture;
1421 }
1422
1423 /**
1424 * @test
1425 */
1426 public function isFolderEmptyReturnsFalseIfFolderHasFile() {
1427 $this->addToMount(array(
1428 'folderWithFile' => array(
1429 'someFile' => ''
1430 )
1431 ));
1432 $fixture = $this->createDriverFixture(array(
1433 'basePath' => $this->getMountRootUrl()
1434 ));
1435 $mockedFolder = $this->getSimpleFolderMock('/folderWithFile/');
1436 $this->assertFalse($fixture->isFolderEmpty($mockedFolder));
1437 }
1438
1439 /**
1440 * @test
1441 */
1442 public function isFolderEmptyReturnsFalseIfFolderHasSubfolder() {
1443 $this->addToMount(array(
1444 'folderWithSubfolder' => array(
1445 'someFolder' => array()
1446 )
1447 ));
1448 $fixture = $this->createDriverFixture(array(
1449 'basePath' => $this->getMountRootUrl()
1450 ));
1451 $mockedFolder = $this->getSimpleFolderMock('/folderWithSubfolder/');
1452 $this->assertFalse($fixture->isFolderEmpty($mockedFolder));
1453 }
1454
1455 /**********************************
1456 * Copy/move folder
1457 **********************************/
1458 /**
1459 * @test
1460 */
1461 public function foldersCanBeMovedWithinStorage() {
1462 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
1463 list($mockedFolder, $sourceFolder, $fileContents, $fixture) = $this->_prepareFolderEnvironmentForMoveTest();
1464 $fixture->moveFolderWithinStorage($sourceFolder, $mockedFolder, 'someFolder');
1465 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/someFolder/')));
1466 $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/someFolder/file')));
1467 $this->assertFileNotExists($this->getUrlInMount('/someFile'));
1468 }
1469
1470 /**
1471 * @test
1472 */
1473 public function moveFolderWithinStorageReturnsCorrectMappingInformationForAllFiles() {
1474 $fileContents = 'asdfg';
1475 $this->addToMount(array(
1476 'targetFolder' => array(),
1477 'sourceFolder' => array(
1478 'subFolder' => array('file' => $fileContents),
1479 'file' => 'asdfg'
1480 )
1481 ));
1482 $fixture = $this->createDriverFixture(array(
1483 'basePath' => $this->getMountRootUrl()
1484 ));
1485 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1486 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
1487 $mappingInformation = $fixture->moveFolderWithinStorage($sourceFolder, $targetFolder, 'sourceFolder');
1488 $this->assertEquals('/targetFolder/sourceFolder/file', $mappingInformation['/sourceFolder/file']);
1489 $this->assertEquals('/targetFolder/sourceFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
1490 $this->assertEquals('/targetFolder/sourceFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
1491 }
1492
1493 /**
1494 * @test
1495 */
1496 public function folderCanBeRenamedWhenMoving() {
1497 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
1498 list($mockedFolder, $sourceFolder, $fileContents, $fixture) = $this->_prepareFolderEnvironmentForMoveTest();
1499 $fixture->moveFolderWithinStorage($sourceFolder, $mockedFolder, 'newFolder');
1500 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/newFolder/')));
1501 }
1502
1503 protected function _setupFolderForCopyTest() {
1504 $fileContents1 = uniqid();
1505 $fileContents2 = uniqid();
1506 $this->addToMount(array(
1507 'targetFolder' => array(),
1508 'sourceFolder' => array(
1509 'subFolder' => array('file' => $fileContents1),
1510 'file' => $fileContents2
1511 )
1512 ));
1513 $fixture = $this->createDriverFixture(array(
1514 'basePath' => $this->getMountRootUrl()
1515 ));
1516 return $fixture;
1517 }
1518
1519 /**
1520 * @test
1521 * @see _setupFolderForCopyTest
1522 */
1523 public function foldersCanBeCopiedWithinSameStorage() {
1524 $fixture = $this->_setupFolderForCopyTest();
1525 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1526 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
1527 $fixture->copyFolderWithinStorage($sourceFolder, $targetFolder, 'sourceFolder');
1528 $this->assertTrue($fixture->folderExists('/targetFolder/sourceFolder/'));
1529 $this->assertTrue($fixture->fileExists('/targetFolder/sourceFolder/file'));
1530 $this->assertTrue($fixture->folderExists('/targetFolder/sourceFolder/subFolder/'));
1531 $this->assertTrue($fixture->fileExists('/targetFolder/sourceFolder/subFolder/file'));
1532 }
1533
1534 /**
1535 * @test
1536 * @see _setupFolderForCopyTest
1537 */
1538 public function folderNameCanBeChangedWhileCopying() {
1539 $fixture = $this->_setupFolderForCopyTest();
1540 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1541 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
1542 $fixture->copyFolderWithinStorage($sourceFolder, $targetFolder, 'newFolder');
1543 $this->assertTrue($fixture->folderExists('/targetFolder/newFolder/'));
1544 $this->assertTrue($fixture->fileExists('/targetFolder/newFolder/file'));
1545 $this->assertFalse($fixture->folderExists('/targetFolder/sourceFolder/'));
1546 }
1547
1548 }
1549 ?>