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