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