[!!!][TASK] Extract testing framework for TYPO3
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Functional / Resource / ResourceStorageTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Functional\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\Resource\File;
18 use TYPO3\CMS\Core\Resource\Folder;
19 use TYPO3\CMS\Core\Resource\FolderInterface;
20 use TYPO3\CMS\Core\Resource\ResourceFactory;
21 use TYPO3\CMS\Core\Resource\ResourceStorage;
22 use TYPO3\CMS\Core\Resource\StorageRepository;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Test case
27 */
28 class ResourceStorageTest extends \TYPO3\CMS\Components\TestingFramework\Core\FunctionalTestCase
29 {
30 protected function tearDown()
31 {
32 // cleanup manually created folders
33 foreach (glob(PATH_site . 'fileadmin/*') as $folderToRemove) {
34 GeneralUtility::rmdir($folderToRemove, true);
35 }
36 }
37
38 /**
39 * @test
40 */
41 public function getNestedProcessingFolderTest()
42 {
43 $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/core/Functional/Fixtures/sys_file_storage.xml');
44 $this->setUpBackendUserFromFixture(1);
45 $subject = (new StorageRepository())->findByUid(1);
46 $subject->setEvaluatePermissions(false);
47
48 GeneralUtility::mkdir_deep(PATH_site . 'fileadmin/_processed_');
49 GeneralUtility::mkdir_deep(PATH_site . 'fileadmin/adirectory');
50 GeneralUtility::mkdir_deep(PATH_site . 'typo3temp/assets/_processed_/');
51 file_put_contents(PATH_site . 'fileadmin/adirectory/bar.txt', 'myData');
52 clearstatcache();
53 $subject->addFileMount('/adirectory/', ['read_only' => false]);
54 $file = ResourceFactory::getInstance()->getFileObjectFromCombinedIdentifier('1:/adirectory/bar.txt');
55
56 $rootProcessingFolder = $subject->getProcessingFolder();
57 $processingFolder = $subject->getProcessingFolder($file);
58
59 $this->assertInstanceOf(Folder::class, $processingFolder);
60 $this->assertNotEquals($rootProcessingFolder, $processingFolder);
61
62 for ($i = ResourceStorage::PROCESSING_FOLDER_LEVELS; $i>0; $i--) {
63 $processingFolder = $processingFolder->getParentFolder();
64 }
65 $this->assertEquals($rootProcessingFolder, $processingFolder);
66 }
67
68 /**
69 * @param string $targetDirectory
70 * @param string $fileMountFolder
71 * @param bool $isFileMountReadOnly
72 * @param bool $checkWriteAccess
73 * @param bool $expectedResult
74 * @test
75 * @dataProvider isWithinFileMountBoundariesDataProvider
76 */
77 public function isWithinFileMountBoundariesRespectsReadOnlyFileMounts($targetDirectory, $fileMountFolder, $isFileMountReadOnly, $checkWriteAccess, $expectedResult)
78 {
79 $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/core/Functional/Fixtures/sys_file_storage.xml');
80 $fileName = 'bar.txt';
81 $this->setUpBackendUserFromFixture(1);
82 GeneralUtility::mkdir_deep(PATH_site . 'fileadmin/_processed_');
83 GeneralUtility::mkdir_deep(PATH_site . 'fileadmin/' . $targetDirectory);
84 if ($fileMountFolder !== $targetDirectory) {
85 GeneralUtility::mkdir_deep(PATH_site . 'fileadmin/' . $fileMountFolder);
86 }
87 file_put_contents(PATH_site . 'fileadmin/' . $targetDirectory . '/' . $fileName, 'myData');
88 clearstatcache();
89 $file = ResourceFactory::getInstance()->getFileObjectFromCombinedIdentifier('1:/' . $targetDirectory . '/' . $fileName);
90
91 $subject = (new StorageRepository())->findByUid(1);
92 $subject->setEvaluatePermissions(true);
93
94 // read_only = true -> no write access for user, so checkinf for second argument true should assert false
95 $subject->addFileMount('/' . $fileMountFolder . '/', ['read_only' => $isFileMountReadOnly]);
96 $this->assertSame($expectedResult, $subject->isWithinFileMountBoundaries($file, $checkWriteAccess));
97 }
98
99 /**
100 * @return array
101 */
102 public function isWithinFileMountBoundariesDataProvider()
103 {
104 return [
105 'Access to file in ro file mount denied for write request' => [
106 '$targetDirectory' => 'fooBaz',
107 '$fileMountFolder' => 'fooBaz',
108 '$isFileMountReadOnly' => true,
109 '$checkWriteAccess' => true,
110 '$expectedResult' => false,
111 ],
112 'Access to file in ro file mount allowed for read request' => [
113 '$targetDirectory' => 'fooBaz',
114 '$fileMountFolder' => 'fooBaz',
115 '$isFileMountReadOnly' => true,
116 '$checkWriteAccess' => false,
117 '$expectedResult' => true,
118 ],
119 'Access to file in rw file mount allowed for write request' => [
120 '$targetDirectory' => 'fooBaz',
121 '$fileMountFolder' => 'fooBaz',
122 '$isFileMountReadOnly' => false,
123 '$checkWriteAccess' => true,
124 '$expectedResult' => true,
125 ],
126 'Access to file in rw file mount allowed for read request' => [
127 '$targetDirectory' => 'fooBaz',
128 '$fileMountFolder' => 'fooBaz',
129 '$isFileMountReadOnly' => false,
130 '$checkWriteAccess' => false,
131 '$expectedResult' => true,
132 ],
133 'Access to file not in file mount denied for write request' => [
134 '$targetDirectory' => 'fooBaz',
135 '$fileMountFolder' => 'barBaz',
136 '$isFileMountReadOnly' => false,
137 '$checkWriteAccess' => true,
138 '$expectedResult' => false,
139 ],
140 'Access to file not in file mount denied for read request' => [
141 '$targetDirectory' => 'fooBaz',
142 '$fileMountFolder' => 'barBaz',
143 '$isFileMountReadOnly' => false,
144 '$checkWriteAccess' => false,
145 '$expectedResult' => false,
146 ],
147 ];
148 }
149
150 /**
151 * @test
152 */
153 public function getProcessingRootFolderTest()
154 {
155 $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/core/Functional/Fixtures/sys_file_storage.xml');
156 $this->setUpBackendUserFromFixture(1);
157
158 $subject = (new StorageRepository())->findByUid(1);
159 $processingFolder = $subject->getProcessingFolder();
160
161 $this->assertInstanceOf(Folder::class, $processingFolder);
162 }
163
164 /**
165 * @test
166 */
167 public function getRoleReturnsDefaultForRegularFolders()
168 {
169 $folderIdentifier = $this->getUniqueId();
170 $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/core/Functional/Fixtures/sys_file_storage.xml');
171 $this->setUpBackendUserFromFixture(1);
172
173 $subject = (new StorageRepository())->findByUid(1);
174 $folder = new Folder($subject, '/foo/' . $folderIdentifier . '/', $folderIdentifier);
175
176 $role = $subject->getRole($folder);
177
178 $this->assertSame(FolderInterface::ROLE_DEFAULT, $role);
179 }
180
181 /**
182 * @test
183 */
184 public function replaceFileFailsIfLocalFileDoesNotExist()
185 {
186 $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/core/Functional/Fixtures/sys_file_storage.xml');
187 $this->setUpBackendUserFromFixture(1);
188 $subject = (new StorageRepository())->findByUid(1);
189
190 GeneralUtility::mkdir_deep(PATH_site . 'fileadmin/foo');
191 file_put_contents(PATH_site . 'fileadmin/foo/bar.txt', 'myData');
192 clearstatcache();
193 $file = ResourceFactory::getInstance()->getFileObjectFromCombinedIdentifier('1:/foo/bar.txt');
194
195 $this->expectException(\InvalidArgumentException::class);
196 $this->expectExceptionCode(1325842622);
197 $subject->replaceFile($file, PATH_site . $this->getUniqueId());
198 }
199
200 /**
201 * @test
202 */
203 public function createFolderThrowsExceptionIfParentFolderDoesNotExist()
204 {
205 $this->importDataSet(ORIGINAL_ROOT . 'components/testing_framework/core/Functional/Fixtures/sys_file_storage.xml');
206 $this->setUpBackendUserFromFixture(1);
207 $subject = (new StorageRepository())->findByUid(1);
208
209 $this->expectException(\InvalidArgumentException::class);
210 $this->expectExceptionCode(1325689164);
211 $subject->createFolder('newFolder', new Folder($subject, '/foo/', 'foo'));
212 }
213 }