[BUGFIX] Use AjaxDataHandler to delete records from context menu
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Resource / FileTest.php
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Core\Tests\Unit\Resource;
4
5 /*
6 * This file is part of the TYPO3 CMS project.
7 *
8 * It is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, either version 2
10 * of the License, or any later version.
11 *
12 * For the full copyright and license information, please read the
13 * LICENSE.txt file that was distributed with this source code.
14 *
15 * The TYPO3 project - inspiring people to share!
16 */
17
18 use TYPO3\CMS\Core\Resource\File;
19 use TYPO3\CMS\Core\Resource\Index\MetaDataRepository;
20 use TYPO3\CMS\Core\Resource\MetaDataAspect;
21 use TYPO3\CMS\Core\Resource\ResourceStorage;
22 use TYPO3\CMS\Core\Utility\GeneralUtility;
23 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
24
25 /**
26 * Testcase for the file class of the TYPO3 FAL
27 */
28 class FileTest extends UnitTestCase
29 {
30 /**
31 * @var bool Reset singletons created by subject
32 */
33 protected $resetSingletonInstances = true;
34
35 /**
36 * @var ResourceStorage
37 */
38 protected $storageMock;
39
40 protected function setUp(): void
41 {
42 parent::setUp();
43 $this->storageMock = $this->createMock(ResourceStorage::class);
44 $this->storageMock->expects($this->any())->method('getUid')->will($this->returnValue(5));
45
46 $mockedMetaDataRepository = $this->createMock(MetaDataRepository::class);
47 $mockedMetaDataRepository->expects($this->any())->method('findByFile')->will($this->returnValue(['file' => 1]));
48 GeneralUtility::setSingletonInstance(MetaDataRepository::class, $mockedMetaDataRepository);
49 }
50
51 /**
52 * @return File
53 */
54 protected function prepareFixture(): File
55 {
56 $fixture = new File(['testfile'], $this->storageMock);
57 return $fixture;
58 }
59
60 /**
61 * @test
62 */
63 public function commonPropertiesAreAvailableWithOwnGetters(): void
64 {
65 $properties = [
66 'name' => $this->getUniqueId(),
67 'storage' => $this->storageMock,
68 'size' => 1024
69 ];
70 $fixture = new File($properties, $this->storageMock);
71 foreach ($properties as $key => $value) {
72 $this->assertEquals($value, call_user_func([$fixture, 'get' . $key]));
73 }
74 }
75
76 /**
77 * Tests if a file is seen as indexed if the record has a uid
78 *
79 * @test
80 */
81 public function fileIndexStatusIsTrueIfUidIsSet(): void
82 {
83 $fixture = new File(['uid' => 1], $this->storageMock);
84 $this->assertTrue($fixture->isIndexed());
85 }
86
87 /**
88 * @test
89 */
90 public function updatePropertiesUpdatesFileProperties(): void
91 {
92 $identifier = '/' . $this->getUniqueId();
93 $fixture = new File(['uid' => 1, 'identifier' => '/test'], $this->storageMock);
94 $fixture->updateProperties(['identifier' => $identifier]);
95 $this->assertEquals($identifier, $fixture->getIdentifier());
96 }
97
98 /**
99 * @test
100 */
101 public function updatePropertiesLeavesPropertiesUntouchedIfNotSetInNewProperties(): void
102 {
103 $fixture = new File(['uid' => 1, 'foo' => 'asdf', 'identifier' => '/test'], $this->storageMock);
104 $fixture->updateProperties(['foo' => 'foobar']);
105 $this->assertEquals('/test', $fixture->getIdentifier());
106 $this->assertEquals('/test', $fixture->getProperty('identifier'));
107 }
108
109 /**
110 * @test
111 */
112 public function updatePropertiesDiscardsUidIfAlreadySet(): void
113 {
114 $fixture = new File(['uid' => 1, 'identifier' => '/test'], $this->storageMock);
115 $fixture->updateProperties(['uid' => 3]);
116 $this->assertEquals(1, $fixture->getUid());
117 }
118
119 /**
120 * @test
121 */
122 public function updatePropertiesRecordsNamesOfChangedProperties(): void
123 {
124 $fixture = new File(['uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test'], $this->storageMock);
125 $fixture->updateProperties(['foo' => 'foobar', 'baz' => 'foobaz']);
126 $this->assertEquals(['foo', 'baz'], $fixture->getUpdatedProperties());
127 }
128
129 /**
130 * @test
131 */
132 public function updatePropertiesDoesNotRecordPropertyNameIfSameValueIsProvided(): void
133 {
134 $fixture = new File(['uid' => 1, 'foo' => 'asdf', 'identifier' => '/test'], $this->storageMock);
135 $fixture->updateProperties(['foo' => 'asdf']);
136 $this->assertEmpty($fixture->getUpdatedProperties());
137 }
138
139 /**
140 * @test
141 */
142 public function updatePropertiesMarksPropertyAsChangedOnlyOnce(): void
143 {
144 $fixture = new File(['uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test'], $this->storageMock);
145 $fixture->updateProperties(['foo' => 'foobar', 'baz' => 'foobaz']);
146 $fixture->updateProperties(['foo' => 'fdsw', 'baz' => 'asdf']);
147 $this->assertEquals(['foo', 'baz'], $fixture->getUpdatedProperties());
148 }
149
150 /**
151 * @test
152 */
153 public function updatePropertiesReloadsStorageObjectIfStorageChanges(): void
154 {
155 $fileProperties = [
156 'uid' => 1,
157 'storage' => 'first',
158 ];
159 $subject = $this->getMockBuilder(File::class)
160 ->setMethods(['loadStorage'])
161 ->setConstructorArgs([$fileProperties, $this->storageMock])
162 ->getMock();
163 $mockedNewStorage = $this->createMock(\TYPO3\CMS\Core\Resource\ResourceStorage::class);
164 $mockedResourceFactory = $this->createMock(\TYPO3\CMS\Core\Resource\ResourceFactory::class);
165 $mockedResourceFactory
166 ->expects($this->once())
167 ->method('getStorageObject')
168 ->will($this->returnValue($mockedNewStorage));
169 GeneralUtility::setSingletonInstance(\TYPO3\CMS\Core\Resource\ResourceFactory::class, $mockedResourceFactory);
170
171 $subject->updateProperties(['storage' => 'different']);
172 $this->assertSame($mockedNewStorage, $subject->getStorage());
173 }
174
175 /**
176 * @test
177 */
178 public function copyToCallsCopyOperationOnTargetFolderStorage(): void
179 {
180 $targetStorage = $this->createMock(\TYPO3\CMS\Core\Resource\ResourceStorage::class);
181 $targetFolder = $this->createMock(\TYPO3\CMS\Core\Resource\Folder::class);
182 $targetFolder->expects($this->any())->method('getStorage')->will($this->returnValue($targetStorage));
183 $fixture = new File([], $this->storageMock);
184 $targetStorage->expects($this->once())->method('copyFile')->with($this->equalTo($fixture), $this->equalTo($targetFolder));
185 $fixture->copyTo($targetFolder);
186 }
187
188 /**
189 * @test
190 */
191 public function moveToCallsMoveOperationOnTargetFolderStorage(): void
192 {
193 $targetStorage = $this->createMock(\TYPO3\CMS\Core\Resource\ResourceStorage::class);
194 $targetFolder = $this->createMock(\TYPO3\CMS\Core\Resource\Folder::class);
195 $targetFolder->expects($this->any())->method('getStorage')->will($this->returnValue($targetStorage));
196 $fixture = new File([], $this->storageMock);
197 $targetStorage->expects($this->once())->method('moveFile')->with($this->equalTo($fixture), $this->equalTo($targetFolder));
198 $fixture->moveTo($targetFolder);
199 }
200
201 public function filenameExtensionDataProvider(): array
202 {
203 return [
204 ['somefile.jpg', 'somefile', 'jpg'],
205 ['SomeFile.PNG', 'SomeFile', 'png'],
206 ['somefile', 'somefile', ''],
207 ['somefile.tar.gz', 'somefile.tar', 'gz'],
208 ['somefile.tar.bz2', 'somefile.tar', 'bz2'],
209 ];
210 }
211
212 /**
213 * @test
214 * @dataProvider filenameExtensionDataProvider
215 */
216 public function getNameWithoutExtensionReturnsCorrectName($originalFilename, $expectedBasename): void
217 {
218 $fixture = new File(
219 [
220 'name' => $originalFilename,
221 'identifier' => '/' . $originalFilename
222 ],
223 $this->storageMock
224 );
225 $this->assertSame($expectedBasename, $fixture->getNameWithoutExtension());
226 }
227
228 /**
229 * @test
230 * @dataProvider filenameExtensionDataProvider
231 */
232 public function getExtensionReturnsCorrectExtension($originalFilename, $expectedBasename, $expectedExtension): void
233 {
234 $fixture = new File([
235 'name' => $originalFilename,
236 'identifier' => '/' . $originalFilename
237 ], $this->storageMock);
238 $this->assertSame($expectedExtension, $fixture->getExtension());
239 }
240
241 /**
242 * @test
243 */
244 public function hasPropertyReturnsTrueFilePropertyExists(): void
245 {
246 $fixture = new File(['testproperty' => 'testvalue'], $this->storageMock);
247 $this->assertTrue($fixture->hasProperty('testproperty'));
248 }
249
250 /**
251 * @test
252 */
253 public function hasPropertyReturnsTrueIfMetadataPropertyExists(): void
254 {
255 $fixture = $this->getMockBuilder(File::class)
256 ->setConstructorArgs([[], $this->storageMock])
257 ->setMethods(['getMetaData'])
258 ->getMock();
259
260 $metaDataAspectMock = $this->getMockBuilder(MetaDataAspect::class)
261 ->setConstructorArgs([$fixture])
262 ->setMethods(['get'])
263 ->getMock();
264
265 $metaDataAspectMock->expects($this->any())->method('get')->willReturn(['testproperty' => 'testvalue']);
266 $fixture->expects($this->any())->method('getMetaData')->willReturn($metaDataAspectMock);
267
268 $this->assertTrue($fixture->hasProperty('testproperty'));
269 $this->assertSame('testvalue', $fixture->getProperty('testproperty'));
270 }
271 }