[BUGFIX] Allow processed folders in different storage
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Resource / ResourceStorageTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Resource;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Database\DatabaseConnection;
18 use TYPO3\CMS\Core\Resource\Driver\AbstractDriver;
19 use TYPO3\CMS\Core\Resource\Driver\LocalDriver;
20 use TYPO3\CMS\Core\Resource\File;
21 use TYPO3\CMS\Core\Resource\FileRepository;
22 use TYPO3\CMS\Core\Resource\Folder;
23 use TYPO3\CMS\Core\Resource\FolderInterface;
24 use TYPO3\CMS\Core\Resource\Index\FileIndexRepository;
25 use TYPO3\CMS\Core\Resource\ResourceStorage;
26 use TYPO3\CMS\Core\Resource\ResourceStorageInterface;
27 use TYPO3\CMS\Core\Utility\ArrayUtility;
28 use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30 /**
31 * Test case for ResourceStorage class
32 *
33 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
34 */
35 class ResourceStorageTest extends BaseTestCase {
36
37 /**
38 * @var array A backup of registered singleton instances
39 */
40 protected $singletonInstances = array();
41
42 /**
43 * @var ResourceStorage|\PHPUnit_Framework_MockObject_MockObject
44 */
45 protected $subject;
46
47 protected function setUp() {
48 parent::setUp();
49 $this->singletonInstances = GeneralUtility::getSingletonInstances();
50 /** @var FileRepository|\PHPUnit_Framework_MockObject_MockObject $fileRepositoryMock */
51 $fileRepositoryMock = $this->getMock(FileRepository::class);
52 GeneralUtility::setSingletonInstance(
53 FileRepository::class,
54 $fileRepositoryMock
55 );
56 $databaseMock = $this->getMock(DatabaseConnection::class);
57 $databaseMock->expects($this->any())->method('exec_SELECTgetRows')->with('*', 'sys_file_storage', '1=1', '', 'name', '', 'uid')->willReturn(array());
58 $GLOBALS['TYPO3_DB'] = $databaseMock;
59 }
60
61 protected function tearDown() {
62 GeneralUtility::resetSingletonInstances($this->singletonInstances);
63 parent::tearDown();
64 }
65
66 /**
67 * Prepare ResourceStorage
68 *
69 * @param array $configuration
70 * @param bool $mockPermissionChecks
71 * @param AbstractDriver|\PHPUnit_Framework_MockObject_MockObject $driverObject
72 * @param array $storageRecord
73 */
74 protected function prepareSubject(array $configuration, $mockPermissionChecks = FALSE, AbstractDriver $driverObject = NULL, array $storageRecord = array()) {
75 $permissionMethods = array('assureFileAddPermissions', 'checkFolderActionPermission', 'checkFileActionPermission', 'checkUserActionPermission', 'checkFileExtensionPermission', 'isWithinFileMountBoundaries');
76 $mockedMethods = array();
77 $configuration = $this->convertConfigurationArrayToFlexformXml($configuration);
78 $overruleArray = array('configuration' => $configuration);
79 ArrayUtility::mergeRecursiveWithOverrule($storageRecord, $overruleArray);
80 if ($driverObject == NULL) {
81 $driverObject = $this->getMockForAbstractClass(AbstractDriver::class, array(), '', FALSE);
82 }
83 if ($mockPermissionChecks) {
84 $mockedMethods = $permissionMethods;
85 }
86 $mockedMethods[] = 'getIndexer';
87
88 $this->subject = $this->getMock(ResourceStorage::class, $mockedMethods, array($driverObject, $storageRecord));
89 $this->subject->expects($this->any())->method('getIndexer')->will($this->returnValue($this->getMock(\TYPO3\CMS\Core\Resource\Index\Indexer::class, array(), array(), '', FALSE)));
90 foreach ($permissionMethods as $method) {
91 $this->subject->expects($this->any())->method($method)->will($this->returnValue(TRUE));
92 }
93 }
94
95 /**
96 * Converts a simple configuration array into a FlexForm data structure serialized as XML
97 *
98 * @param array $configuration
99 * @return string
100 * @see GeneralUtility::array2xml()
101 */
102 protected function convertConfigurationArrayToFlexformXml(array $configuration) {
103 $flexFormArray = array('data' => array('sDEF' => array('lDEF' => array())));
104 foreach ($configuration as $key => $value) {
105 $flexFormArray['data']['sDEF']['lDEF'][$key] = array('vDEF' => $value);
106 }
107 $configuration = GeneralUtility::array2xml($flexFormArray);
108 return $configuration;
109 }
110
111 /**
112 * Creates a driver fixture object, optionally using a given mount object.
113 *
114 * IMPORTANT: Call this only after setting up the virtual file system (with the addTo* methods)!
115 *
116 * @param $driverConfiguration
117 * @param ResourceStorage $storageObject
118 * @param array $mockedDriverMethods
119 * @return \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject
120 */
121 protected function createDriverMock($driverConfiguration, ResourceStorage $storageObject = NULL, $mockedDriverMethods = array()) {
122 $this->initializeVfs();
123
124 if (!isset($driverConfiguration['basePath'])) {
125 $driverConfiguration['basePath'] = $this->getMountRootUrl();
126 }
127
128 if ($mockedDriverMethods === NULL) {
129 $driver = new LocalDriver($driverConfiguration);
130 } else {
131 // We are using the LocalDriver here because PHPUnit can't mock concrete methods in abstract classes, so
132 // when using the AbstractDriver we would be in trouble when wanting to mock away some concrete method
133 $driver = $this->getMock(LocalDriver::class, $mockedDriverMethods, array($driverConfiguration));
134 }
135 if ($storageObject !== NULL) {
136 $storageObject->setDriver($driver);
137 }
138 $driver->setStorageUid(6);
139 $driver->processConfiguration();
140 $driver->initialize();
141 return $driver;
142 }
143
144 /**
145 * @return array
146 */
147 public function isWithinFileMountBoundariesDataProvider() {
148 return array(
149 'Access to file in ro file mount denied for write request' => array(
150 '$fileIdentifier' => '/fooBaz/bar.txt',
151 '$fileMountFolderIdentifier' => '/fooBaz/',
152 '$isFileMountReadOnly' => TRUE,
153 '$checkWriteAccess' => TRUE,
154 '$expectedResult' => FALSE,
155 ),
156 'Access to file in ro file mount allowed for read request' => array(
157 '$fileIdentifier' => '/fooBaz/bar.txt',
158 '$fileMountFolderIdentifier' => '/fooBaz/',
159 '$isFileMountReadOnly' => TRUE,
160 '$checkWriteAccess' => FALSE,
161 '$expectedResult' => TRUE,
162 ),
163 'Access to file in rw file mount allowed for write request' => array(
164 '$fileIdentifier' => '/fooBaz/bar.txt',
165 '$fileMountFolderIdentifier' => '/fooBaz/',
166 '$isFileMountReadOnly' => FALSE,
167 '$checkWriteAccess' => TRUE,
168 '$expectedResult' => TRUE,
169 ),
170 'Access to file in rw file mount allowed for read request' => array(
171 '$fileIdentifier' => '/fooBaz/bar.txt',
172 '$fileMountFolderIdentifier' => '/fooBaz/',
173 '$isFileMountReadOnly' => FALSE,
174 '$checkWriteAccess' => FALSE,
175 '$expectedResult' => TRUE,
176 ),
177 'Access to file not in file mount denied for write request' => array(
178 '$fileIdentifier' => '/fooBaz/bar.txt',
179 '$fileMountFolderIdentifier' => '/barBaz/',
180 '$isFileMountReadOnly' => FALSE,
181 '$checkWriteAccess' => TRUE,
182 '$expectedResult' => FALSE,
183 ),
184 'Access to file not in file mount denied for read request' => array(
185 '$fileIdentifier' => '/fooBaz/bar.txt',
186 '$fileMountFolderIdentifier' => '/barBaz/',
187 '$isFileMountReadOnly' => FALSE,
188 '$checkWriteAccess' => FALSE,
189 '$expectedResult' => FALSE,
190 ),
191 );
192 }
193
194 /**
195 * @param string $fileIdentifier
196 * @param string $fileMountFolderIdentifier
197 * @param bool $isFileMountReadOnly
198 * @param bool $checkWriteAccess
199 * @param bool $expectedResult
200 * @throws \TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException
201 * @test
202 * @dataProvider isWithinFileMountBoundariesDataProvider
203 */
204 public function isWithinFileMountBoundariesRespectsReadOnlyFileMounts($fileIdentifier, $fileMountFolderIdentifier, $isFileMountReadOnly, $checkWriteAccess, $expectedResult) {
205 /** @var AbstractDriver|\PHPUnit_Framework_MockObject_MockObject $driverMock */
206 $driverMock = $this->getMockForAbstractClass(AbstractDriver::class, array(), '', FALSE);
207 $driverMock->expects($this->any())
208 ->method('getFolderInfoByIdentifier')
209 ->willReturnCallback(function($identifier) use ($isFileMountReadOnly) {
210 return array(
211 'identifier' => $identifier,
212 'name' => trim($identifier, '/'),
213 );
214 });
215 $driverMock->expects($this->any())
216 ->method('isWithin')
217 ->willReturnCallback(function($folderIdentifier, $fileIdentifier) {
218 if ($fileIdentifier === ResourceStorageInterface::DEFAULT_ProcessingFolder . '/') {
219 return FALSE;
220 } else {
221 return strpos($fileIdentifier, $folderIdentifier) === 0;
222 }
223 });
224 $this->prepareSubject(array(), FALSE, $driverMock);
225 $fileMock = $this->getSimpleFileMock($fileIdentifier);
226 $this->subject->setEvaluatePermissions(TRUE);
227 $this->subject->addFileMount('/' . $this->getUniqueId('random') . '/', array('read_only' => FALSE));
228 $this->subject->addFileMount($fileMountFolderIdentifier, array('read_only' => $isFileMountReadOnly));
229 $this->subject->addFileMount('/' . $this->getUniqueId('random') . '/', array('read_only' => FALSE));
230 $this->assertSame($expectedResult, $this->subject->isWithinFileMountBoundaries($fileMock, $checkWriteAccess));
231 }
232
233 /**
234 * @return array
235 */
236 public function capabilitiesDataProvider() {
237 return array(
238 'only public' => array(
239 array(
240 'public' => TRUE,
241 'writable' => FALSE,
242 'browsable' => FALSE
243 )
244 ),
245 'only writable' => array(
246 array(
247 'public' => FALSE,
248 'writable' => TRUE,
249 'browsable' => FALSE
250 )
251 ),
252 'only browsable' => array(
253 array(
254 'public' => FALSE,
255 'writable' => FALSE,
256 'browsable' => TRUE
257 )
258 ),
259 'all capabilities' => array(
260 array(
261 'public' => TRUE,
262 'writable' => TRUE,
263 'browsable' => TRUE
264 )
265 ),
266 'none' => array(
267 array(
268 'public' => FALSE,
269 'writable' => FALSE,
270 'browsable' => FALSE
271 )
272 )
273 );
274 }
275
276 /**
277 * @test
278 * @dataProvider capabilitiesDataProvider
279 * @TODO: Rewrite or move to functional suite
280 */
281 public function capabilitiesOfStorageObjectAreCorrectlySet(array $capabilities) {
282 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
283 $storageRecord = array(
284 'is_public' => $capabilities['public'],
285 'is_writable' => $capabilities['writable'],
286 'is_browsable' => $capabilities['browsable'],
287 'is_online' => TRUE
288 );
289 $mockedDriver = $this->createDriverMock(
290 array(
291 'pathType' => 'relative',
292 'basePath' => 'fileadmin/',
293 ),
294 $this->subject,
295 NULL
296 );
297 $this->prepareSubject(array(), FALSE, $mockedDriver, $storageRecord);
298 $this->assertEquals($capabilities['public'], $this->subject->isPublic(), 'Capability "public" is not correctly set.');
299 $this->assertEquals($capabilities['writable'], $this->subject->isWritable(), 'Capability "writable" is not correctly set.');
300 $this->assertEquals($capabilities['browsable'], $this->subject->isBrowsable(), 'Capability "browsable" is not correctly set.');
301 }
302
303 /**
304 * @test
305 * @TODO: Rewrite or move to functional suite
306 */
307 public function fileAndFolderListFiltersAreInitializedWithDefaultFilters() {
308 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
309 $this->prepareSubject(array());
310 $this->assertEquals($GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['defaultFilterCallbacks'], $this->subject->getFileAndFolderNameFilters());
311 }
312
313 /**
314 * @test
315 */
316 public function addFileFailsIfFileDoesNotExist() {
317 /** @var Folder|\PHPUnit_Framework_MockObject_MockObject $mockedFolder */
318 $mockedFolder = $this->getMock(Folder::class, array(), array(), '', FALSE);
319 $this->setExpectedException('InvalidArgumentException', '', 1319552745);
320 $this->prepareSubject(array());
321 $this->subject->addFile('/some/random/file', $mockedFolder);
322 }
323
324 /**
325 * @test
326 */
327 public function getPublicUrlReturnsNullIfStorageIsNotOnline() {
328 /** @var $driver LocalDriver|\PHPUnit_Framework_MockObject_MockObject */
329 $driver = $this->getMock(LocalDriver::class, array(), array(array('basePath' => $this->getMountRootUrl())));
330 /** @var $subject ResourceStorage|\PHPUnit_Framework_MockObject_MockObject */
331 $subject = $this->getMock(ResourceStorage::class, array('isOnline'), array($driver, array('configuration' => array())));
332 $subject->expects($this->once())->method('isOnline')->will($this->returnValue(FALSE));
333
334 $sourceFileIdentifier = '/sourceFile.ext';
335 $sourceFile = $this->getSimpleFileMock($sourceFileIdentifier);
336 $result = $subject->getPublicUrl($sourceFile);
337 $this->assertSame($result, NULL);
338 }
339
340 /**
341 * Data provider for checkFolderPermissionsRespectsFilesystemPermissions
342 *
343 * @return array
344 */
345 public function checkFolderPermissionsFilesystemPermissionsDataProvider() {
346 return array(
347 'read action on readable/writable folder' => array(
348 'read',
349 array('r' => TRUE, 'w' => TRUE),
350 TRUE
351 ),
352 'read action on unreadable folder' => array(
353 'read',
354 array('r' => FALSE, 'w' => TRUE),
355 FALSE
356 ),
357 'write action on read-only folder' => array(
358 'write',
359 array('r' => TRUE, 'w' => FALSE),
360 FALSE
361 )
362 );
363 }
364
365 /**
366 * @test
367 * @dataProvider checkFolderPermissionsFilesystemPermissionsDataProvider
368 * @param string $action 'read' or 'write'
369 * @param array $permissionsFromDriver The permissions as returned from the driver
370 * @param bool $expectedResult
371 */
372 public function checkFolderPermissionsRespectsFilesystemPermissions($action, $permissionsFromDriver, $expectedResult) {
373 /** @var $mockedDriver LocalDriver|\PHPUnit_Framework_MockObject_MockObject */
374 $mockedDriver = $this->getMock(LocalDriver::class);
375 $mockedDriver->expects($this->any())->method('getPermissions')->will($this->returnValue($permissionsFromDriver));
376 /** @var $mockedFolder Folder|\PHPUnit_Framework_MockObject_MockObject */
377 $mockedFolder = $this->getMock(Folder::class, array(), array(), '', FALSE);
378 // Let all other checks pass
379 /** @var $subject ResourceStorage|\PHPUnit_Framework_MockObject_MockObject */
380 $subject = $this->getMock(ResourceStorage::class, array('isWritable', 'isBrowsable', 'checkUserActionPermission'), array($mockedDriver, array()), '', FALSE);
381 $subject->expects($this->any())->method('isWritable')->will($this->returnValue(TRUE));
382 $subject->expects($this->any())->method('isBrowsable')->will($this->returnValue(TRUE));
383 $subject->expects($this->any())->method('checkUserActionPermission')->will($this->returnValue(TRUE));
384 $subject->setDriver($mockedDriver);
385
386 $this->assertSame($expectedResult, $subject->checkFolderActionPermission($action, $mockedFolder));
387 }
388
389 /**
390 * @test
391 */
392 public function checkUserActionPermissionsAlwaysReturnsTrueIfNoUserPermissionsAreSet() {
393 $this->prepareSubject(array());
394 $this->assertTrue($this->subject->checkUserActionPermission('read', 'folder'));
395 }
396
397 /**
398 * @test
399 */
400 public function checkUserActionPermissionReturnsFalseIfPermissionIsSetToZero() {
401 $this->prepareSubject(array());
402 $this->subject->setUserPermissions(array('readFolder' => TRUE, 'writeFile' => TRUE));
403 $this->assertTrue($this->subject->checkUserActionPermission('read', 'folder'));
404 }
405
406 public function checkUserActionPermission_arbitraryPermissionDataProvider() {
407 return array(
408 'all lower cased' => array(
409 array('readFolder' => TRUE),
410 'read',
411 'folder'
412 ),
413 'all upper case' => array(
414 array('readFolder' => TRUE),
415 'READ',
416 'FOLDER'
417 ),
418 'mixed case' => array(
419 array('readFolder' => TRUE),
420 'ReaD',
421 'FoLdEr'
422 )
423 );
424 }
425
426 /**
427 * @param array $permissions
428 * @param string $action
429 * @param string $type
430 * @test
431 * @dataProvider checkUserActionPermission_arbitraryPermissionDataProvider
432 */
433 public function checkUserActionPermissionAcceptsArbitrarilyCasedArguments(array $permissions, $action, $type) {
434 $this->prepareSubject(array());
435 $this->subject->setUserPermissions($permissions);
436 $this->assertTrue($this->subject->checkUserActionPermission($action, $type));
437 }
438
439 /**
440 * @test
441 */
442 public function userActionIsDisallowedIfPermissionIsSetToFalse() {
443 $this->prepareSubject(array());
444 $this->subject->setEvaluatePermissions(TRUE);
445 $this->subject->setUserPermissions(array('readFolder' => FALSE));
446 $this->assertFalse($this->subject->checkUserActionPermission('read', 'folder'));
447 }
448
449 /**
450 * @test
451 */
452 public function userActionIsDisallowedIfPermissionIsNotSet() {
453 $this->prepareSubject(array());
454 $this->subject->setEvaluatePermissions(TRUE);
455 $this->subject->setUserPermissions(array('readFolder' => TRUE));
456 $this->assertFalse($this->subject->checkUserActionPermission('write', 'folder'));
457 }
458
459 /**
460 * @test
461 */
462 public function getEvaluatePermissionsWhenSetFalse() {
463 $this->prepareSubject(array());
464 $this->subject->setEvaluatePermissions(FALSE);
465 $this->assertFalse($this->subject->getEvaluatePermissions());
466 }
467
468 /**
469 * @test
470 */
471 public function getEvaluatePermissionsWhenSetTrue() {
472 $this->prepareSubject(array());
473 $this->subject->setEvaluatePermissions(TRUE);
474 $this->assertTrue($this->subject->getEvaluatePermissions());
475 }
476
477 /**
478 * @test
479 * @group integration
480 * @TODO: Rewrite or move to functional suite
481 */
482 public function setFileContentsUpdatesObjectProperties() {
483 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
484 $this->initializeVfs();
485 $driverObject = $this->getMockForAbstractClass(AbstractDriver::class, array(), '', FALSE);
486 $this->subject = $this->getMock(ResourceStorage::class, array('getFileIndexRepository', 'checkFileActionPermission'), array($driverObject, array()));
487 $this->subject->expects($this->any())->method('checkFileActionPermission')->will($this->returnValue(TRUE));
488 $fileInfo = array(
489 'storage' => 'A',
490 'identifier' => 'B',
491 'mtime' => 'C',
492 'ctime' => 'D',
493 'mimetype' => 'E',
494 'size' => 'F',
495 'name' => 'G',
496 );
497 $newProperties = array(
498 'storage' => $fileInfo['storage'],
499 'identifier' => $fileInfo['identifier'],
500 'tstamp' => $fileInfo['mtime'],
501 'crdate' => $fileInfo['ctime'],
502 'mime_type' => $fileInfo['mimetype'],
503 'size' => $fileInfo['size'],
504 'name' => $fileInfo['name']
505 );
506 $hash = 'asdfg';
507 /** @var $mockedDriver LocalDriver|\PHPUnit_Framework_MockObject_MockObject */
508 $mockedDriver = $this->getMock(LocalDriver::class, array(), array(array('basePath' => $this->getMountRootUrl())));
509 $mockedDriver->expects($this->once())->method('getFileInfoByIdentifier')->will($this->returnValue($fileInfo));
510 $mockedDriver->expects($this->once())->method('hash')->will($this->returnValue($hash));
511 $this->subject->setDriver($mockedDriver);
512 $indexFileRepositoryMock = $this->getMock(FileIndexRepository::class);
513 $this->subject->expects($this->any())->method('getFileIndexRepository')->will($this->returnValue($indexFileRepositoryMock));
514 /** @var $mockedFile File|\PHPUnit_Framework_MockObject_MockObject */
515 $mockedFile = $this->getMock(File::class, array(), array(), '', FALSE);
516 $mockedFile->expects($this->any())->method('getIdentifier')->will($this->returnValue($fileInfo['identifier']));
517 // called by indexer because the properties are updated
518 $this->subject->expects($this->any())->method('getFileInfoByIdentifier')->will($this->returnValue($newProperties));
519 $mockedFile->expects($this->any())->method('getStorage')->will($this->returnValue($this->subject));
520 $mockedFile->expects($this->any())->method('getProperties')->will($this->returnValue(array_keys($fileInfo)));
521 $mockedFile->expects($this->any())->method('getUpdatedProperties')->will($this->returnValue(array_keys($newProperties)));
522 // do not update directly; that's up to the indexer
523 $indexFileRepositoryMock->expects($this->never())->method('update');
524 $this->subject->setFileContents($mockedFile, $this->getUniqueId());
525 }
526
527 /**
528 * @test
529 * @group integration
530 * @TODO: Rewrite or move to functional suite
531 */
532 public function moveFileCallsDriversMethodsWithCorrectArguments() {
533 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
534 $localFilePath = '/path/to/localFile';
535 $sourceFileIdentifier = '/sourceFile.ext';
536 $fileInfoDummy = array(
537 'storage' => 'A',
538 'identifier' => 'B',
539 'mtime' => 'C',
540 'ctime' => 'D',
541 'mimetype' => 'E',
542 'size' => 'F',
543 'name' => 'G',
544 );
545 $this->addToMount(array(
546 'targetFolder' => array()
547 ));
548 $this->initializeVfs();
549 $targetFolder = $this->getSimpleFolderMock('/targetFolder/');
550 /** @var $sourceDriver LocalDriver|\PHPUnit_Framework_MockObject_MockObject */
551 $sourceDriver = $this->getMock(LocalDriver::class);
552 $sourceDriver->expects($this->once())->method('deleteFile')->with($this->equalTo($sourceFileIdentifier));
553 $configuration = $this->convertConfigurationArrayToFlexformXml(array());
554 $sourceStorage = new ResourceStorage($sourceDriver, array('configuration' => $configuration));
555 $sourceFile = $this->getSimpleFileMock($sourceFileIdentifier);
556 $sourceFile->expects($this->once())->method('getForLocalProcessing')->will($this->returnValue($localFilePath));
557 $sourceFile->expects($this->any())->method('getStorage')->will($this->returnValue($sourceStorage));
558 $sourceFile->expects($this->once())->method('getUpdatedProperties')->will($this->returnValue(array_keys($fileInfoDummy)));
559 $sourceFile->expects($this->once())->method('getProperties')->will($this->returnValue($fileInfoDummy));
560 /** @var $mockedDriver \TYPO3\CMS\Core\Resource\Driver\LocalDriver|\PHPUnit_Framework_MockObject_MockObject */
561 $mockedDriver = $this->getMock(LocalDriver::class, array(), array(array('basePath' => $this->getMountRootUrl())));
562 $mockedDriver->expects($this->once())->method('getFileInfoByIdentifier')->will($this->returnValue($fileInfoDummy));
563 $mockedDriver->expects($this->once())->method('addFile')->with($localFilePath, '/targetFolder/', $this->equalTo('file.ext'))->will($this->returnValue('/targetFolder/file.ext'));
564 /** @var $subject ResourceStorage */
565 $subject = $this->getMock(ResourceStorage::class, array('assureFileMovePermissions'), array($mockedDriver, array('configuration' => $configuration)));
566 $subject->moveFile($sourceFile, $targetFolder, 'file.ext');
567 }
568
569 /**
570 * @test
571 * @group integration
572 * @TODO: Rewrite or move to functional suite
573 */
574 public function storageUsesInjectedFilemountsToCheckForMountBoundaries() {
575 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
576 $mockedFile = $this->getSimpleFileMock('/mountFolder/file');
577 $this->addToMount(array(
578 'mountFolder' => array(
579 'file' => 'asdfg'
580 )
581 ));
582 $mockedDriver = $this->createDriverMock(array('basePath' => $this->getMountRootUrl()), NULL, NULL);
583 $this->initializeVfs();
584 $this->prepareSubject(array(), NULL, $mockedDriver);
585 $this->subject->addFileMount('/mountFolder');
586 $this->assertEquals(1, count($this->subject->getFileMounts()));
587 $this->subject->isWithinFileMountBoundaries($mockedFile);
588 }
589
590
591 /**
592 * @test
593 * @TODO: Rewrite or move to functional suite
594 */
595 public function createFolderChecksIfParentFolderExistsBeforeCreatingFolder() {
596 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
597 $mockedParentFolder = $this->getSimpleFolderMock('/someFolder/');
598 $mockedDriver = $this->createDriverMock(array());
599 $mockedDriver->expects($this->once())->method('folderExists')->with($this->equalTo('/someFolder/'))->will($this->returnValue(TRUE));
600 $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('newFolder'))->will($this->returnValue($mockedParentFolder));
601 $this->prepareSubject(array(), TRUE);
602 $this->subject->setDriver($mockedDriver);
603 $this->subject->createFolder('newFolder', $mockedParentFolder);
604 }
605
606 /**
607 * @test
608 * @expectedException \RuntimeException
609 */
610 public function deleteFolderThrowsExceptionIfFolderIsNotEmptyAndRecursiveDeleteIsDisabled() {
611 /** @var \TYPO3\CMS\Core\Resource\Folder|\PHPUnit_Framework_MockObject_MockObject $folderMock */
612 $folderMock = $this->getMock(Folder::class, array(), array(), '', FALSE);
613 /** @var $mockedDriver \TYPO3\CMS\Core\Resource\Driver\AbstractDriver|\PHPUnit_Framework_MockObject_MockObject */
614 $mockedDriver = $this->getMockForAbstractClass(AbstractDriver::class);
615 $mockedDriver->expects($this->once())->method('isFolderEmpty')->will($this->returnValue(FALSE));
616 /** @var $subject ResourceStorage|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
617 $subject = $this->getAccessibleMock(ResourceStorage::class, array('checkFolderActionPermission'), array(), '', FALSE);
618 $subject->expects($this->any())->method('checkFolderActionPermission')->will($this->returnValue(TRUE));
619 $subject->_set('driver', $mockedDriver);
620 $subject->deleteFolder($folderMock, FALSE);
621 }
622
623 /**
624 * @test
625 * @TODO: Rewrite or move to functional suite
626 */
627 public function createFolderCallsDriverForFolderCreation() {
628 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
629 $mockedParentFolder = $this->getSimpleFolderMock('/someFolder/');
630 $this->prepareSubject(array(), TRUE);
631 $mockedDriver = $this->createDriverMock(array(), $this->subject);
632 $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('newFolder'), $this->equalTo('/someFolder/'))->will($this->returnValue(TRUE));
633 $mockedDriver->expects($this->once())->method('folderExists')->with($this->equalTo('/someFolder/'))->will($this->returnValue(TRUE));
634 $this->subject->createFolder('newFolder', $mockedParentFolder);
635 }
636
637 /**
638 * @test
639 * @TODO: Rewrite or move to functional suite
640 */
641 public function createFolderCanRecursivelyCreateFolders() {
642 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
643 $this->addToMount(array('someFolder' => array()));
644 $mockedDriver = $this->createDriverMock(array('basePath' => $this->getMountRootUrl()), NULL, NULL);
645 $this->prepareSubject(array(), TRUE, $mockedDriver);
646 $parentFolder = $this->subject->getFolder('/someFolder/');
647 $newFolder = $this->subject->createFolder('subFolder/secondSubfolder', $parentFolder);
648 $this->assertEquals('secondSubfolder', $newFolder->getName());
649 $this->assertFileExists($this->getUrlInMount('/someFolder/subFolder/'));
650 $this->assertFileExists($this->getUrlInMount('/someFolder/subFolder/secondSubfolder/'));
651 }
652
653 /**
654 * @test
655 * @TODO: Rewrite or move to functional suite
656 */
657 public function createFolderUsesRootFolderAsParentFolderIfNotGiven() {
658 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
659 $this->prepareSubject(array(), TRUE);
660 $mockedDriver = $this->createDriverMock(array(), $this->subject);
661 $mockedDriver->expects($this->once())->method('getRootLevelFolder')->with()->will($this->returnValue('/'));
662 $mockedDriver->expects($this->once())->method('createFolder')->with($this->equalTo('someFolder'));
663 $this->subject->createFolder('someFolder');
664 }
665
666 /**
667 * @test
668 * @TODO: Rewrite or move to functional suite
669 */
670 public function createFolderCreatesNestedStructureEvenIfPartsAlreadyExist() {
671 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
672 $this->addToMount(array(
673 'existingFolder' => array()
674 ));
675 $this->initializeVfs();
676 $mockedDriver = $this->createDriverMock(array('basePath' => $this->getMountRootUrl()), NULL, NULL);
677 $this->prepareSubject(array(), TRUE, $mockedDriver);
678 $rootFolder = $this->subject->getFolder('/');
679 $newFolder = $this->subject->createFolder('existingFolder/someFolder', $rootFolder);
680 $this->assertEquals('someFolder', $newFolder->getName());
681 $this->assertFileExists($this->getUrlInMount('existingFolder/someFolder'));
682 }
683
684 /**
685 * @test
686 */
687 public function createFolderThrowsExceptionIfParentFolderDoesNotExist() {
688 $this->setExpectedException('InvalidArgumentException', '', 1325689164);
689 $mockedParentFolder = $this->getSimpleFolderMock('/someFolder/');
690 $this->prepareSubject(array(), TRUE);
691 $mockedDriver = $this->createDriverMock(array(), $this->subject);
692 $mockedDriver->expects($this->once())->method('folderExists')->with($this->equalTo('/someFolder/'))->will($this->returnValue(FALSE));
693 $this->subject->createFolder('newFolder', $mockedParentFolder);
694 }
695
696 /**
697 * @test
698 */
699 public function replaceFileFailsIfLocalFileDoesNotExist() {
700 $this->setExpectedException('InvalidArgumentException', '', 1325842622);
701 $this->prepareSubject(array(), TRUE);
702 $mockedFile = $this->getSimpleFileMock('/someFile');
703 $this->subject->replaceFile($mockedFile, PATH_site . $this->getUniqueId());
704 }
705
706 /**
707 * @test
708 * @TODO: Rewrite or move to functional suite
709 */
710 public function getRoleReturnsDefaultForRegularFolders() {
711 $this->markTestSkipped('This test does way to much and is mocked incomplete. Skipped for now.');
712 $folderIdentifier = $this->getUniqueId();
713 $this->addToMount(array(
714 $folderIdentifier => array()
715 ));
716 $this->prepareSubject(array());
717
718 $role = $this->subject->getRole($this->getSimpleFolderMock('/' . $folderIdentifier . '/'));
719
720 $this->assertSame(FolderInterface::ROLE_DEFAULT, $role);
721 }
722
723 }