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