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