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