[BUGFIX] require_once of vfsStream triggers travis fail
[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 use TYPO3\CMS\Core\Utility\GeneralUtility;
4
5 /***************************************************************
6 * Copyright notice
7 *
8 * (c) 2011-2013 Andreas Wolf <andreas.wolf@ikt-werk.de>
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 * A copy is found in the textfile GPL.txt and important notices to the license
20 * from the author is found in LICENSE.txt distributed with these scripts.
21 *
22 *
23 * This script is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * This copyright notice MUST APPEAR in all copies of the script!
29 ***************************************************************/
30
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 getDefaultFolderReturnsFolderForUserUploadPath() {
145 $fixture = $this->createDriverFixture(array(
146 'basePath' => $this->getMountRootUrl()
147 ));
148 $folder = $fixture->getDefaultFolder();
149 $this->assertStringEndsWith('user_upload/', $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('/user_upload/'));
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 * @test
651 */
652 public function createFileFixesPermissionsOnCreatedFile() {
653 if (TYPO3_OS == 'WIN') {
654 $this->markTestSkipped('createdFilesHaveCorrectRights() tests not available on Windows');
655 }
656
657 // No one will use this as his default file create mask so we hopefully don't get any false positives
658 $testpattern = '0646';
659 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = $testpattern;
660
661 $this->addToMount(
662 array(
663 'someDir' => array()
664 )
665 );
666 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
667 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
668 mkdir($basedir . '/someDir');
669 $fixture->createFile('testfile.txt', $fixture->getFolder('/someDir'));
670 $this->assertEquals($testpattern, decoct(fileperms($basedir . '/someDir/testfile.txt') & 0777));
671 }
672
673 /**********************************
674 * File and directory listing
675 **********************************/
676 /**
677 * @test
678 */
679 public function getFileReturnsCorrectIdentifier() {
680 $this->addToMount(array(
681 'someDir' => array(
682 'someFile' => 'asdfg'
683 ),
684 'someFileAtRootLevel' => 'foobar'
685 ));
686 $fixture = $this->createDriverFixture(
687 array('basePath' => $this->getMountRootUrl()),
688 NULL,
689 // Mocked because finfo() can not deal with vfs streams and throws warnings
690 array('getMimeTypeOfFile')
691 );
692 $subdirFileInfo = $fixture->getFileInfoByIdentifier('/someDir/someFile');
693 $this->assertEquals('/someDir/someFile', $subdirFileInfo['identifier']);
694 $rootFileInfo = $fixture->getFileInfoByIdentifier('/someFileAtRootLevel');
695 $this->assertEquals('/someFileAtRootLevel', $rootFileInfo['identifier']);
696 }
697
698 /**
699 * @test
700 */
701 public function getFileThrowsExceptionIfFileDoesNotExist() {
702 $this->setExpectedException('InvalidArgumentException', '', 1314516809);
703 $fixture = $this->createDriverFixture(array(
704 'basePath' => $this->getMountRootUrl()
705 ));
706 $fixture->getFileInfoByIdentifier('/some/file/at/a/random/path');
707 }
708
709 /**
710 * @test
711 */
712 public function getFileListReturnsEmptyArrayForEmptyDirectory() {
713 $fixture = $this->createDriverFixture(array(
714 'basePath' => $this->getMountRootUrl()
715 ));
716 $fileList = $fixture->getFileList('/');
717 $this->assertEmpty($fileList);
718 }
719
720 /**
721 * @test
722 */
723 public function getFileListReturnsAllFilesInDirectory() {
724 $dirStructure = array(
725 'aDir' => array(),
726 'file1' => 'asdfg',
727 'file2' => 'fdsa'
728 );
729 $this->addToMount($dirStructure);
730 $fixture = $this->createDriverFixture(
731 array('basePath' => $this->getMountRootUrl()),
732 NULL,
733 // Mocked because finfo() can not deal with vfs streams and throws warnings
734 array('getMimeTypeOfFile')
735 );
736 $fileList = $fixture->getFileList('/');
737 $this->assertEquals(array('file1', 'file2'), array_keys($fileList));
738 }
739
740 /**
741 * @test
742 */
743 public function getFileListReturnsAllFilesInSubdirectoryIfRecursiveParameterIsSet() {
744 $dirStructure = array(
745 'aDir' => array(
746 'file3' => 'asdfgh',
747 'subdir' => array(
748 'file4' => 'asklfjklasjkl'
749 )
750 ),
751 'file1' => 'asdfg',
752 'file2' => 'fdsa'
753 );
754 $this->addToMount($dirStructure);
755 $fixture = $this->createDriverFixture(
756 array('basePath' => $this->getMountRootUrl()),
757 NULL,
758 // Mocked because finfo() can not deal with vfs streams and throws warnings
759 array('getMimeTypeOfFile')
760 );
761 $fileList = $fixture->getFileList('/', 0, 0, array(), array(), TRUE);
762 $this->assertEquals(array('aDir/subdir/file4', 'aDir/file3', 'file1', 'file2'), array_keys($fileList));
763 }
764
765 /**
766 * @test
767 */
768 public function getFileListFailsIfDirectoryDoesNotExist() {
769 $this->setExpectedException('InvalidArgumentException', '', 1314349666);
770 $this->addToMount(array('somefile' => ''));
771 $fixture = $this->createDriverFixture(array(
772 'basePath' => $this->getMountRootUrl()
773 ));
774 $fixture->getFileList('somedir/');
775 }
776
777 /**
778 * @test
779 */
780 public function getFileListCallsConfiguredCallbackFunctionWithGivenItemName() {
781 $dirStructure = array(
782 'file2' => 'fdsa'
783 );
784 // register static callback to self
785 $callback = array(
786 array(
787 get_class($this),
788 'callbackStaticTestFunction'
789 )
790 );
791 $this->addToMount($dirStructure);
792 $fixture = $this->createDriverFixture(array(
793 'basePath' => $this->getMountRootUrl()
794 ));
795 // the callback function will throw an exception used to check if it was called with correct $itemName
796 $this->setExpectedException('InvalidArgumentException', '$itemName', 1336159604);
797 $fixture->getFileList('/', 0, 0, $callback);
798 }
799
800 /**
801 * Static callback function used to test if the filter callbacks work
802 * As it is static we are using an exception to test if it is really called and works
803 *
804 * @static
805 * @throws \InvalidArgumentException
806 * @see getFileListCallsConfiguredCallbackFunction
807 */
808 static public function callbackStaticTestFunction() {
809 list($itemName) = func_get_args();
810 if ($itemName === 'file2') {
811 throw new \InvalidArgumentException('$itemName', 1336159604);
812 }
813 }
814
815 /**
816 * @test
817 */
818 public function getFileListFiltersItemsWithGivenFilterMethods() {
819 $dirStructure = array(
820 'fileA' => 'asdfg',
821 'fileB' => 'fdsa'
822 );
823 $this->addToMount($dirStructure);
824 $fixture = $this->createDriverFixture(
825 array('basePath' => $this->getMountRootUrl()),
826 NULL,
827 // Mocked because finfo() can not deal with vfs streams and throws warnings
828 array('getMimeTypeOfFile')
829 );
830 $filterCallbacks = array(
831 array(
832 'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
833 'filterFilename',
834 ),
835 );
836 $fileList = $fixture->getFileList('/', 0, 0, $filterCallbacks);
837 $this->assertNotContains('fileA', array_keys($fileList));
838 }
839
840 /**
841 * @test
842 */
843 public function getFolderListReturnsAllDirectoriesInDirectory() {
844 $dirStructure = array(
845 'dir1' => array(),
846 'dir2' => array(),
847 'file' => 'asdfg'
848 );
849 $this->addToMount($dirStructure);
850 $fixture = $this->createDriverFixture(array(
851 'basePath' => $this->getMountRootUrl()
852 ));
853 $fileList = $fixture->getFolderList('/');
854 $this->assertEquals(array('dir1', 'dir2'), array_keys($fileList));
855 }
856
857 /**
858 * @test
859 */
860 public function getFolderListReturnsHiddenFoldersByDefault() {
861 $dirStructure = array(
862 '.someHiddenDir' => array(),
863 'aDir' => array(),
864 'file1' => ''
865 );
866 $this->addToMount($dirStructure);
867 $fixture = $this->createDriverFixture(array(
868 'basePath' => $this->getMountRootUrl()
869 ));
870
871 $fileList = $fixture->getFolderList('/');
872
873 $this->assertEquals(array('.someHiddenDir', 'aDir'), array_keys($fileList));
874 }
875
876 /**
877 * @test
878 */
879 public function getFolderListUsesCorrectPathForItems() {
880 $this->addToMount(array(
881 'dir1' => array(
882 'subdir1' => array()
883 )
884 ));
885 $fixture = $this->createDriverFixture(array(
886 'basePath' => $this->getMountRootUrl()
887 ));
888 $folderList = $fixture->getFolderList('/');
889 $this->assertEquals('/dir1/', $folderList['dir1']['identifier']);
890 $folderList = $fixture->getFolderList('/dir1/');
891 $this->assertEquals('/dir1/subdir1/', $folderList['subdir1']['identifier']);
892 }
893
894 /**
895 * Checks if the folder names . and .. are ignored when listing subdirectories
896 *
897 * @test
898 */
899 public function getFolderListLeavesOutNavigationalEntries() {
900 // we have to add .. and . manually, as these are not included in vfsStream directory listings (as opposed
901 // to normal file listings)
902 $this->addToMount(array(
903 '..' => array(),
904 '.' => array()
905 ));
906 $fixture = $this->createDriverFixture(array(
907 'basePath' => $this->getMountRootUrl()
908 ));
909 $fileList = $fixture->getFolderList('/');
910 $this->assertEmpty($fileList);
911 }
912
913 /**
914 * @test
915 */
916 public function getFolderListFiltersItemsWithGivenFilterMethods() {
917 $dirStructure = array(
918 'folderA' => array(),
919 'folderB' => array()
920 );
921 $this->addToMount($dirStructure);
922 $fixture = $this->createDriverFixture(array(
923 'basePath' => $this->getMountRootUrl()
924 ));
925 $filterCallbacks = array(
926 array(
927 'TYPO3\CMS\Core\Tests\Unit\Resource\Driver\Fixtures\LocalDriverFilenameFilter',
928 'filterFilename',
929 ),
930 );
931 $folderList = $fixture->getFolderList('/', 0, 0, $filterCallbacks);
932 $this->assertNotContains('folderA', array_keys($folderList));
933 }
934
935 /**
936 * @test
937 */
938 public function getFolderListFailsIfDirectoryDoesNotExist() {
939 $this->setExpectedException('InvalidArgumentException', '', 1314349666);
940 $fixture = $this->createDriverFixture(array(
941 'basePath' => $this->getMountRootUrl()
942 ));
943 \vfsStream::create(array($this->basedir => array('somefile' => '')));
944 $fixture->getFolderList('somedir/');
945 }
946
947 /**
948 * @test
949 */
950 public function hashReturnsCorrectHashes() {
951 $contents = '68b329da9893e34099c7d8ad5cb9c940';
952 $expectedMd5Hash = '8c67dbaf0ba22f2e7fbc26413b86051b';
953 $expectedSha1Hash = 'a60cd808ba7a0bcfa37fa7f3fb5998e1b8dbcd9d';
954 $mockedFile = $this->getSimpleFileMock('/hashFile');
955 $this->addToMount(array('hashFile' => $contents));
956 $fixture = $this->createDriverFixture(array(
957 'basePath' => $this->getMountRootUrl()
958 ));
959 $this->assertEquals($expectedSha1Hash, $fixture->hash($mockedFile, 'sha1'));
960 $this->assertEquals($expectedMd5Hash, $fixture->hash($mockedFile, 'md5'));
961 }
962
963 /**
964 * @test
965 */
966 public function hashingWithUnsupportedAlgorithmFails() {
967 $this->setExpectedException('InvalidArgumentException', '', 1304964032);
968 $fixture = $this->createDriverFixture(array(
969 'basePath' => $this->getMountRootUrl()
970 ));
971 $fixture->hash($this->getSimpleFileMock('/hashFile'), uniqid());
972 }
973
974 /**
975 * @test
976 * @covers TYPO3\CMS\Core\Resource\Driver\LocalDriver::getFileForLocalProcessing
977 */
978 public function getFileForLocalProcessingCreatesCopyOfFileByDefault() {
979 $fileContents = 'asdfgh';
980 $this->addToMount(array(
981 'someDir' => array(
982 'someFile' => $fileContents
983 )
984 ));
985 $fixture = $this->createDriverFixture(array(
986 'basePath' => $this->getMountRootUrl()
987 ), NULL, array('copyFileToTemporaryPath'));
988 $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
989 // TODO add parameter expectation for $mockedFile as soon as PHPUnit supports object identity matching in parameter expectations
990 $fixture->expects($this->once())->method('copyFileToTemporaryPath');
991 $fixture->getFileForLocalProcessing($mockedFile);
992 }
993
994 /**
995 * @test
996 */
997 public function getFileForLocalProcessingReturnsOriginalFilepathForReadonlyAccess() {
998 $fileContents = 'asdfgh';
999 $this->addToMount(array(
1000 'someDir' => array(
1001 'someFile' => $fileContents
1002 )
1003 ));
1004 $fixture = $this->createDriverFixture(array(
1005 'basePath' => $this->getMountRootUrl()
1006 ));
1007 $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
1008 $filePath = $fixture->getFileForLocalProcessing($mockedFile, FALSE);
1009 $this->assertEquals($filePath, $this->getMountRootUrl() . 'someDir/someFile');
1010 }
1011
1012 /**
1013 * @test
1014 */
1015 public function filesCanBeCopiedToATemporaryPath() {
1016 $fileContents = 'asdfgh';
1017 $this->addToMount(array(
1018 'someDir' => array(
1019 'someFile' => $fileContents
1020 )
1021 ));
1022 $fixture = $this->createDriverFixture(array(
1023 'basePath' => $this->getMountRootUrl()
1024 ));
1025 $mockedFile = $this->getSimpleFileMock('/someDir/someFile');
1026 $filePath = GeneralUtility::fixWindowsFilePath($fixture->copyFileToTemporaryPath($mockedFile));
1027 $this->assertContains('/typo3temp/', $filePath);
1028 $this->assertEquals($fileContents, file_get_contents($filePath));
1029 }
1030
1031 /**
1032 * @test
1033 */
1034 public function permissionsAreCorrectlyRetrievedForAllowedFile() {
1035 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1036 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1037 touch($basedir . '/someFile');
1038 chmod($basedir . '/someFile', 448);
1039 clearstatcache();
1040 $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getFilePermissions($this->getSimpleFileMock('/someFile')));
1041 }
1042
1043 /**
1044 * @test
1045 */
1046 public function permissionsAreCorrectlyRetrievedForForbiddenFile() {
1047 if (function_exists('posix_getegid') && posix_getegid() === 0) {
1048 $this->markTestSkipped('Test skipped if run on linux as root');
1049 } elseif (TYPO3_OS === 'WIN') {
1050 $this->markTestSkipped('Test skipped if run on Windows system');
1051 }
1052 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1053 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1054 touch($basedir . '/someForbiddenFile');
1055 chmod($basedir . '/someForbiddenFile', 0);
1056 clearstatcache();
1057 $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $fixture->getFilePermissions($this->getSimpleFileMock('/someForbiddenFile')));
1058 }
1059
1060 /**
1061 * @test
1062 */
1063 public function permissionsAreCorrectlyRetrievedForAllowedFolder() {
1064 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1065 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1066 mkdir($basedir . '/someFolder');
1067 chmod($basedir . '/someFolder', 448);
1068 clearstatcache();
1069 $this->assertEquals(array('r' => TRUE, 'w' => TRUE), $fixture->getFolderPermissions($this->getSimpleFolderMock('/someFolder')));
1070 }
1071
1072 /**
1073 * @test
1074 */
1075 public function permissionsAreCorrectlyRetrievedForForbiddenFolder() {
1076 if (function_exists('posix_getegid') && posix_getegid() === 0) {
1077 $this->markTestSkipped('Test skipped if run on linux as root');
1078 } elseif (TYPO3_OS === 'WIN') {
1079 $this->markTestSkipped('Test skipped if run on Windows system');
1080 }
1081 /** @var $fixture \TYPO3\CMS\Core\Resource\Driver\LocalDriver */
1082 list($basedir, $fixture) = $this->prepareRealTestEnvironment();
1083 mkdir($basedir . '/someForbiddenFolder');
1084 chmod($basedir . '/someForbiddenFolder', 0);
1085 clearstatcache();
1086 $result = $fixture->getFolderPermissions($this->getSimpleFolderMock('/someForbiddenFolder'));
1087 // Change permissions back to writable, so the sub-folder can be removed in tearDown
1088 chmod($basedir . '/someForbiddenFolder', 0777);
1089 $this->assertEquals(array('r' => FALSE, 'w' => FALSE), $result);
1090 }
1091
1092 /**
1093 * Dataprovider for getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser test
1094 *
1095 * @return array group, filemode and expected result
1096 */
1097 public function getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser_dataProvider() {
1098 $data = array();
1099 // On some OS, the posix_* functions do not exits
1100 if (function_exists('posix_getgid')) {
1101 $data = array(
1102 'current group, readable/writable' => array(
1103 posix_getgid(),
1104 48,
1105 array('r' => TRUE, 'w' => TRUE)
1106 ),
1107 'current group, readable/not writable' => array(
1108 posix_getgid(),
1109 32,
1110 array('r' => TRUE, 'w' => FALSE)
1111 ),
1112 'current group, not readable/not writable' => array(
1113 posix_getgid(),
1114 0,
1115 array('r' => FALSE, 'w' => FALSE)
1116 )
1117 );
1118 }
1119 $data = array_merge_recursive($data, array(
1120 'arbitrary group, readable/writable' => array(
1121 \vfsStream::GROUP_USER_1,
1122 6,
1123 array('r' => TRUE, 'w' => TRUE)
1124 ),
1125 'arbitrary group, readable/not writable' => array(
1126 \vfsStream::GROUP_USER_1,
1127 436,
1128 array('r' => TRUE, 'w' => FALSE)
1129 ),
1130 'arbitrary group, not readable/not writable' => array(
1131 \vfsStream::GROUP_USER_1,
1132 432,
1133 array('r' => FALSE, 'w' => FALSE)
1134 )
1135 ));
1136 return $data;
1137 }
1138
1139 /**
1140 * @test
1141 * @dataProvider getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser_dataProvider
1142 */
1143 public function getFilePermissionsReturnsCorrectPermissionsForFilesNotOwnedByCurrentUser($group, $permissions, $expectedResult) {
1144 if (TYPO3_OS === 'WIN') {
1145 $this->markTestSkipped('Test skipped if run on Windows system');
1146 }
1147 $this->addToMount(array(
1148 'testfile' => 'asdfg'
1149 ));
1150 $fixture = $this->createDriverFixture(array(
1151 'basePath' => $this->getMountRootUrl()
1152 ));
1153 /** @var $fileObject vfsStreamContent */
1154 $fileObject = \vfsStreamWrapper::getRoot()->getChild($this->mountDir)->getChild('testfile');
1155 // just use an "arbitrary" user here - it is only important that
1156 $fileObject->chown(\vfsStream::OWNER_USER_1);
1157 $fileObject->chgrp($group);
1158 $fileObject->chmod($permissions);
1159 $this->assertEquals($expectedResult, $fixture->getFilePermissions($this->getSimpleFileMock('/testfile')));
1160 }
1161
1162 /**
1163 * @test
1164 */
1165 public function isWithinRecognizesFilesWithinFolderAndInOtherFolders() {
1166 $mockedStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1167 $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage, '/someFolder/', 'someFolder');
1168 $fixture = $this->createDriverFixture(array(
1169 'basePath' => $this->getMountRootUrl()
1170 ), $mockedStorage);
1171 $this->assertTrue($fixture->isWithin($mockedFolder, '/someFolder/test.jpg'));
1172 $this->assertTrue($fixture->isWithin($mockedFolder, '/someFolder/subFolder/test.jpg'));
1173 $this->assertFalse($fixture->isWithin($mockedFolder, '/someFolderWithALongName/test.jpg'));
1174 }
1175
1176 /**
1177 * @test
1178 */
1179 public function isWithinAcceptsFileAndFolderObjectsAsContent() {
1180 $mockedStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1181 $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage, '/someFolder/', 'someFolder');
1182 $fixture = $this->createDriverFixture(array(
1183 'basePath' => $this->getMountRootUrl()
1184 ), $mockedStorage);
1185 $mockedSubfolder = $this->getSimpleFolderMock('/someFolder/subfolder/');
1186 $mockedFile = $this->getSimpleFileMock('/someFolder/test.jpg');
1187 $this->assertTrue($fixture->isWithin($mockedFolder, $mockedFile));
1188 $this->assertTrue($fixture->isWithin($mockedFolder, $mockedSubfolder));
1189 }
1190
1191 /**
1192 * @test
1193 */
1194 public function isWithinAlwaysReturnsFalseIfFolderIsWithinDifferentStorage() {
1195 $mockedStorage1 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1196 $mockedStorage2 = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1197 $mockedFolder = new \TYPO3\CMS\Core\Resource\Folder($mockedStorage1, '/someFolder/', 'someFolder');
1198 $fixture = $this->createDriverFixture(array(
1199 'basePath' => $this->getMountRootUrl()
1200 ), $mockedStorage2);
1201 $fileIdentifier = '/someFolder/test.jpg';
1202 $subfolderIdentifier = '/someFolder/subfolder/';
1203 $mockedFile = $this->getSimpleFileMock($fileIdentifier);
1204 $mockedSubfolder = $this->getSimpleFolderMock($subfolderIdentifier);
1205 $this->assertFalse($fixture->isWithin($mockedFolder, $mockedFile));
1206 $this->assertFalse($fixture->isWithin($mockedFolder, $fileIdentifier));
1207 $this->assertFalse($fixture->isWithin($mockedFolder, $mockedSubfolder));
1208 $this->assertFalse($fixture->isWithin($mockedFolder, $subfolderIdentifier));
1209 }
1210
1211 /**********************************
1212 * Copy/move file
1213 **********************************/
1214 /**
1215 * @param $identifier
1216 * @param null|\TYPO3\CMS\Core\Resource\ResourceStorage $storage
1217 * @return \TYPO3\CMS\Core\Resource\File
1218 */
1219 protected function mockFileForCopyingAndMoving($identifier, \TYPO3\CMS\Core\Resource\ResourceStorage $storage = NULL) {
1220 if (!$storage) {
1221 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1222 }
1223 $fileObject = new \TYPO3\CMS\Core\Resource\File(array('identifier' => $identifier, 'name' => basename($identifier), 'storage' => $storage));
1224 return $fileObject;
1225 }
1226
1227 /**
1228 * @param $identifier
1229 * @param null|\TYPO3\CMS\Core\Resource\ResourceStorage $storage
1230 * @return \TYPO3\CMS\Core\Resource\Folder
1231 */
1232 protected function mockFolderForCopyingAndMoving($identifier, \TYPO3\CMS\Core\Resource\ResourceStorage $storage = NULL) {
1233 if (!$storage) {
1234 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1235 }
1236 $folderObject = new \TYPO3\CMS\Core\Resource\Folder($storage, $identifier, basename($identifier), 0);
1237 return $folderObject;
1238 }
1239
1240 /**
1241 * Prepares a simple two-folder environment with /someFolder/ and /targetFolder/. /someFolder contains a file with random
1242 * contents
1243 *
1244 * @return array $mockedFolder, $sourceFolder, $fileContents, $fixture
1245 */
1246 protected function _prepareFolderEnvironmentForMoveTest() {
1247 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
1248 $sourceFolder = $this->getSimpleFolderMock('/someFolder/');
1249 $fileContents = uniqid();
1250 $this->addToMount(array(
1251 'targetFolder' => array(),
1252 'someFolder' => array('file' => $fileContents)
1253 ));
1254 $fixture = $this->createDriverFixture(array(
1255 'basePath' => $this->getMountRootUrl()
1256 ));
1257 return array($mockedFolder, $sourceFolder, $fileContents, $fixture);
1258 }
1259
1260 /**
1261 * @test
1262 */
1263 public function filesCanBeCopiedWithinStorage() {
1264 $fileContents = uniqid();
1265 $this->addToMount(array(
1266 'someFile' => $fileContents,
1267 'targetFolder' => array()
1268 ));
1269 $fixture = $this->createDriverFixture(
1270 array('basePath' => $this->getMountRootUrl()),
1271 NULL,
1272 // Mocked because finfo() can not deal with vfs streams and throws warnings
1273 array('getMimeTypeOfFile')
1274 );
1275 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1276 $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
1277 $targetFolder = $this->mockFolderForCopyingAndMoving('/targetFolder/', $storage);
1278 $fixture->copyFileWithinStorage($sourceFile, $targetFolder, 'someFile');
1279 $this->assertFileEquals($this->getUrlInMount('/someFile'), $this->getUrlInMount('/targetFolder/someFile'));
1280 }
1281
1282 /**
1283 * @test
1284 */
1285 public function filesCanBeMovedWithinStorage() {
1286 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
1287 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1288 $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
1289 $fileContents = uniqid();
1290 $this->addToMount(array(
1291 'targetFolder' => array(),
1292 'someFile' => $fileContents
1293 ));
1294 $fixture = $this->createDriverFixture(array(
1295 'basePath' => $this->getMountRootUrl()
1296 ));
1297 $newIdentifier = $fixture->moveFileWithinStorage($sourceFile, $mockedFolder, 'file');
1298 $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/file')));
1299 $this->assertFileNotExists($this->getUrlInMount('/someFile'));
1300 $this->assertEquals('/targetFolder/file', $newIdentifier);
1301 }
1302
1303 /**
1304 * @test
1305 */
1306 public function fileMetadataIsChangedAfterMovingFile() {
1307 $mockedFolder = $this->getSimpleFolderMock('/targetFolder/');
1308 $storage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
1309 $sourceFile = $this->mockFileForCopyingAndMoving('/someFile', $storage);
1310 $fileContents = uniqid();
1311 $this->addToMount(array(
1312 'targetFolder' => array(),
1313 'someFile' => $fileContents
1314 ));
1315 $fixture = $this->createDriverFixture(
1316 array('basePath' => $this->getMountRootUrl()),
1317 NULL,
1318 // Mocked because finfo() can not deal with vfs streams and throws warnings
1319 array('getMimeTypeOfFile')
1320 );
1321 $newIdentifier = $fixture->moveFileWithinStorage($sourceFile, $mockedFolder, 'file');
1322 $fileMetadata = $fixture->getFileInfoByIdentifier($newIdentifier);
1323 $this->assertEquals($newIdentifier, $fileMetadata['identifier']);
1324 }
1325
1326 public function renamingFiles_dataProvider() {
1327 return array(
1328 'file in subfolder' => array(
1329 array(
1330 'targetFolder' => array('file' => '')
1331 ),
1332 '/targetFolder/file',
1333 'newFile',
1334 '/targetFolder/newFile'
1335 ),
1336 'file in rootfolder' => array(
1337 array(
1338 'fileInRoot' => ''
1339 ),
1340 '/fileInRoot',
1341 'newFile',
1342 '/newFile'
1343 )
1344 );
1345 }
1346
1347 /**
1348 * @test
1349 * @dataProvider renamingFiles_dataProvider
1350 */
1351 public function renamingFilesChangesFilenameOnDisk(array $filesystemStructure, $oldFileIdentifier, $newFileName, $expectedNewIdentifier) {
1352 $this->addToMount($filesystemStructure);
1353 $fixture = $this->createDriverFixture(array(
1354 'basePath' => $this->getMountRootUrl()
1355 ));
1356 $file = $this->getSimpleFileMock($oldFileIdentifier);
1357 $newIdentifier = $fixture->renameFile($file, $newFileName);
1358 $this->assertFalse($fixture->fileExists($oldFileIdentifier));
1359 $this->assertTrue($fixture->fileExists($newIdentifier));
1360 $this->assertEquals($expectedNewIdentifier, $newIdentifier);
1361 }
1362
1363 /**
1364 * @test
1365 */
1366 public function renamingFilesFailsIfTargetFileExists() {
1367 $this->setExpectedException('TYPO3\\CMS\\Core\\Resource\\Exception\\ExistingTargetFileNameException', '', 1320291063);
1368 $this->addToMount(array(
1369 'targetFolder' => array('file' => '', 'newFile' => '')
1370 ));
1371 $fixture = $this->createDriverFixture(array(
1372 'basePath' => $this->getMountRootUrl()
1373 ));
1374 $file = $this->getSimpleFileMock('/targetFolder/file');
1375 $fixture->renameFile($file, 'newFile');
1376 }
1377
1378 /**
1379 * We use this data provider for testing move methods because there are some issues with the
1380 *
1381 * @return array
1382 */
1383 public function renamingFolders_dataProvider() {
1384 return array(
1385 'folder in root folder' => array(
1386 array(
1387 'someFolder' => array()
1388 ),
1389 '/someFolder/',
1390 'newFolder',
1391 '/newFolder/'
1392 ),
1393 'file in subfolder' => array(
1394 array(
1395 'subfolder' => array(
1396 'someFolder' => array()
1397 )
1398 ),
1399 '/subfolder/someFolder/',
1400 'newFolder',
1401 '/subfolder/newFolder/'
1402 )
1403 );
1404 }
1405
1406 /**
1407 * @test
1408 * @dataProvider renamingFolders_dataProvider
1409 */
1410 public function renamingFoldersChangesFolderNameOnDisk(array $filesystemStructure, $oldFolderIdentifier, $newFolderName, $expectedNewIdentifier) {
1411 $this->addToMount($filesystemStructure);
1412 $fixture = $this->createDriverFixture(array(
1413 'basePath' => $this->getMountRootUrl()
1414 ));
1415 $mockedFolder = $this->getSimpleFolderMock($oldFolderIdentifier);
1416 $mapping = $fixture->renameFolder($mockedFolder, $newFolderName);
1417 $this->assertFalse($fixture->folderExists($oldFolderIdentifier));
1418 $this->assertTrue($fixture->folderExists($expectedNewIdentifier));
1419 $this->assertEquals($expectedNewIdentifier, $mapping[$oldFolderIdentifier]);
1420 }
1421
1422 /**
1423 * @test
1424 */
1425 public function renameFolderReturnsCorrectMappingInformationForAllFiles() {
1426 $fileContents = 'asdfg';
1427 $this->addToMount(array(
1428 'sourceFolder' => array(
1429 'subFolder' => array('file' => $fileContents),
1430 'file' => 'asdfg'
1431 )
1432 ));
1433 $fixture = $this->createDriverFixture(array(
1434 'basePath' => $this->getMountRootUrl()
1435 ));
1436 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1437 $mappingInformation = $fixture->renameFolder($sourceFolder, 'newFolder');
1438 $this->assertEquals('/newFolder/', $mappingInformation['/sourceFolder/']);
1439 $this->assertEquals('/newFolder/file', $mappingInformation['/sourceFolder/file']);
1440 $this->assertEquals('/newFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
1441 $this->assertEquals('/newFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
1442 }
1443
1444 /**
1445 * @test
1446 */
1447 public function renameFolderRevertsRenamingIfFilenameMapCannotBeCreated() {
1448 $this->setExpectedException('\RuntimeException', '', 1334160746);
1449 $this->addToMount(array(
1450 'sourceFolder' => array(
1451 'file' => 'asdfg'
1452 )
1453 ));
1454 $fixture = $this->createDriverFixture(array(
1455 'basePath' => $this->getMountRootUrl()
1456 ), NULL, array('createIdentifierMap'));
1457 $fixture->expects($this->atLeastOnce())->method('createIdentifierMap')->will($this->throwException(new \TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException()));
1458 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1459 $fixture->renameFolder($sourceFolder, 'newFolder');
1460 $this->assertFileExists($this->getUrlInMount('/sourceFolder/file'));
1461 }
1462
1463 /**
1464 * @test
1465 */
1466 public function isFolderEmptyReturnsTrueForEmptyFolder() {
1467 // This also prepares the next few tests, so add more info than required for this test
1468 $this->addToMount(array(
1469 'emptyFolder' => array()
1470 ));
1471 $fixture = $this->createDriverFixture(array(
1472 'basePath' => $this->getMountRootUrl()
1473 ));
1474 $mockedFolder = $this->getSimpleFolderMock('/emptyFolder/');
1475 $this->assertTrue($fixture->isFolderEmpty($mockedFolder));
1476 return $fixture;
1477 }
1478
1479 /**
1480 * @test
1481 */
1482 public function isFolderEmptyReturnsFalseIfFolderHasFile() {
1483 $this->addToMount(array(
1484 'folderWithFile' => array(
1485 'someFile' => ''
1486 )
1487 ));
1488 $fixture = $this->createDriverFixture(array(
1489 'basePath' => $this->getMountRootUrl()
1490 ));
1491 $mockedFolder = $this->getSimpleFolderMock('/folderWithFile/');
1492 $this->assertFalse($fixture->isFolderEmpty($mockedFolder));
1493 }
1494
1495 /**
1496 * @test
1497 */
1498 public function isFolderEmptyReturnsFalseIfFolderHasSubfolder() {
1499 $this->addToMount(array(
1500 'folderWithSubfolder' => array(
1501 'someFolder' => array()
1502 )
1503 ));
1504 $fixture = $this->createDriverFixture(array(
1505 'basePath' => $this->getMountRootUrl()
1506 ));
1507 $mockedFolder = $this->getSimpleFolderMock('/folderWithSubfolder/');
1508 $this->assertFalse($fixture->isFolderEmpty($mockedFolder));
1509 }
1510
1511 /**********************************
1512 * Copy/move folder
1513 **********************************/
1514 /**
1515 * @test
1516 */
1517 public function foldersCanBeMovedWithinStorage() {
1518 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
1519 list($mockedFolder, $sourceFolder, $fileContents, $fixture) = $this->_prepareFolderEnvironmentForMoveTest();
1520 $fixture->moveFolderWithinStorage($sourceFolder, $mockedFolder, 'someFolder');
1521 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/someFolder/')));
1522 $this->assertEquals($fileContents, file_get_contents($this->getUrlInMount('/targetFolder/someFolder/file')));
1523 $this->assertFileNotExists($this->getUrlInMount('/someFile'));
1524 }
1525
1526 /**
1527 * @test
1528 */
1529 public function moveFolderWithinStorageReturnsCorrectMappingInformationForAllFiles() {
1530 $fileContents = 'asdfg';
1531 $this->addToMount(array(
1532 'targetFolder' => array(),
1533 'sourceFolder' => array(
1534 'subFolder' => array('file' => $fileContents),
1535 'file' => 'asdfg'
1536 )
1537 ));
1538 $fixture = $this->createDriverFixture(array(
1539 'basePath' => $this->getMountRootUrl()
1540 ));
1541 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1542 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
1543 $mappingInformation = $fixture->moveFolderWithinStorage($sourceFolder, $targetFolder, 'sourceFolder');
1544 $this->assertEquals('/targetFolder/sourceFolder/file', $mappingInformation['/sourceFolder/file']);
1545 $this->assertEquals('/targetFolder/sourceFolder/subFolder/file', $mappingInformation['/sourceFolder/subFolder/file']);
1546 $this->assertEquals('/targetFolder/sourceFolder/subFolder/', $mappingInformation['/sourceFolder/subFolder/']);
1547 }
1548
1549 /**
1550 * @test
1551 */
1552 public function folderCanBeRenamedWhenMoving() {
1553 /** @var \TYPO3\CMS\Core\Resource\Driver\LocalDriver $fixture */
1554 list($mockedFolder, $sourceFolder, $fileContents, $fixture) = $this->_prepareFolderEnvironmentForMoveTest();
1555 $fixture->moveFolderWithinStorage($sourceFolder, $mockedFolder, 'newFolder');
1556 $this->assertTrue(file_exists($this->getUrlInMount('/targetFolder/newFolder/')));
1557 }
1558
1559 protected function _setupFolderForCopyTest() {
1560 $fileContents1 = uniqid();
1561 $fileContents2 = uniqid();
1562 $this->addToMount(array(
1563 'targetFolder' => array(),
1564 'sourceFolder' => array(
1565 'subFolder' => array('file' => $fileContents1),
1566 'file' => $fileContents2
1567 )
1568 ));
1569 $fixture = $this->createDriverFixture(array(
1570 'basePath' => $this->getMountRootUrl()
1571 ));
1572 return $fixture;
1573 }
1574
1575 /**
1576 * @test
1577 * @see _setupFolderForCopyTest
1578 */
1579 public function foldersCanBeCopiedWithinSameStorage() {
1580 $fixture = $this->_setupFolderForCopyTest();
1581 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1582 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
1583 $fixture->copyFolderWithinStorage($sourceFolder, $targetFolder, 'sourceFolder');
1584 $this->assertTrue($fixture->folderExists('/targetFolder/sourceFolder/'));
1585 $this->assertTrue($fixture->fileExists('/targetFolder/sourceFolder/file'));
1586 $this->assertTrue($fixture->folderExists('/targetFolder/sourceFolder/subFolder/'));
1587 $this->assertTrue($fixture->fileExists('/targetFolder/sourceFolder/subFolder/file'));
1588 }
1589
1590 /**
1591 * @test
1592 * @see _setupFolderForCopyTest
1593 */
1594 public function folderNameCanBeChangedWhileCopying() {
1595 $fixture = $this->_setupFolderForCopyTest();
1596 $sourceFolder = $this->getSimpleFolderMock('/sourceFolder/');
1597 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
1598 $fixture->copyFolderWithinStorage($sourceFolder, $targetFolder, 'newFolder');
1599 $this->assertTrue($fixture->folderExists('/targetFolder/newFolder/'));
1600 $this->assertTrue($fixture->fileExists('/targetFolder/newFolder/file'));
1601 $this->assertFalse($fixture->folderExists('/targetFolder/sourceFolder/'));
1602 }
1603
1604 }
1605 ?>