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