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