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