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