[BUGFIX] Follow-up: Split sys_file table to extract metadata
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Resource / FileTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Resource;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2011-2013 Andreas Wolf <andreas.wolf@ikt-werk.de>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26 use TYPO3\CMS\Core\Resource\ResourceStorage;
27
28 /**
29 * Testcase for the file class of the TYPO3 FAL
30 *
31 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
32 * @todo Many, many, many tests are skipped in this test case...
33 */
34 class FileTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
35
36 /**
37 * @var array A backup of registered singleton instances
38 */
39 protected $singletonInstances = array();
40
41 /**
42 * @var ResourceStorage
43 */
44 protected $storageMock;
45
46 public function setUp() {
47 $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
48 $this->storageMock = $this->getMock('TYPO3\CMS\Core\Resource\ResourceStorage', array(), array(), '', FALSE);
49 $this->storageMock->expects($this->any())->method('getUid')->will($this->returnValue(5));
50
51 \TYPO3\CMS\Core\Utility\GeneralUtility::purgeInstances();
52 }
53
54 public function tearDown() {
55 \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
56 }
57
58 /**
59 * @return \TYPO3\CMS\Core\Resource\File
60 */
61 protected function prepareFixture() {
62 $fixture = new \TYPO3\CMS\Core\Resource\File(array('testfile'), $this->storageMock);
63 return $fixture;
64 }
65
66 /**
67 * @test
68 * @todo Old code getAvailableProperties() needs to be replaced by current behaviour
69 */
70 public function propertiesPassedToConstructorAreAvailableViaGenericGetter() {
71 $this->markTestSkipped('TYPO3\\CMS\\Core\\Resource\\File::getAvailableProperties() does not exist');
72 $properties = array(
73 uniqid() => uniqid(),
74 uniqid() => uniqid(),
75 'uid' => 1
76 );
77 $fixture = new \TYPO3\CMS\Core\Resource\File($properties, $this->storageMock);
78 $availablePropertiesBackup = \TYPO3\CMS\Core\Resource\File::getAvailableProperties();
79 \TYPO3\CMS\Core\Resource\File::setAvailableProperties(array_keys($properties));
80 foreach ($properties as $key => $value) {
81 $this->assertTrue($fixture->hasProperty($key));
82 $this->assertEquals($value, $fixture->getProperty($key));
83 }
84 $this->assertFalse($fixture->hasProperty(uniqid()));
85 \TYPO3\CMS\Core\Resource\File::setAvailableProperties($availablePropertiesBackup);
86 $this->setExpectedException('InvalidArgumentException', '', 1314226805);
87 $fixture->getProperty(uniqid());
88 }
89
90 /**
91 * @test
92 */
93 public function commonPropertiesAreAvailableWithOwnGetters() {
94 $properties = array(
95 'name' => uniqid(),
96 'storage' => $this->storageMock,
97 'size' => 1024
98 );
99 $fixture = new \TYPO3\CMS\Core\Resource\File($properties, $this->storageMock);
100 foreach ($properties as $key => $value) {
101 $this->assertEquals($value, call_user_func(array($fixture, 'get' . $key)));
102 }
103 }
104
105 /**
106 * @test
107 */
108 public function fileAsksRepositoryForIndexStatus() {
109 $mockedRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
110 $mockedRepository->expects($this->once())->method('findOneByCombinedIdentifier')->will($this->returnValue(array('uid' => 1)));
111 $mockedRepository->expects($this->exactly(0))->method('add');
112 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository', $mockedRepository);
113
114 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
115 $this->assertTrue($fixture->isIndexed());
116 }
117
118 /**
119 * Tests if a file is seen as indexed if the record has a uid
120 *
121 * @test
122 */
123 public function fileIndexStatusIsTrueIfUidIsSet() {
124 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1), $this->storageMock);
125 $this->assertTrue($fixture->isIndexed());
126 }
127
128 /**
129 * @test
130 */
131 public function updatePropertiesUpdatesFileProperties() {
132 $identifier = '/' . uniqid();
133 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'identifier' => '/test'), $this->storageMock);
134 $fixture->updateProperties(array('identifier' => $identifier));
135 $this->assertEquals($identifier, $fixture->getIdentifier());
136 }
137
138 /**
139 * @test
140 */
141 public function updatePropertiesLeavesPropertiesUntouchedIfNotSetInNewProperties() {
142 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'identifier' => '/test'), $this->storageMock);
143 $fixture->updateProperties(array('foo' => 'foobar'));
144 $this->assertEquals('/test', $fixture->getIdentifier());
145 $this->assertEquals('/test', $fixture->getProperty('identifier'));
146 }
147
148 /**
149 * @test
150 */
151 public function updatePropertiesDiscardsUidIfAlreadySet() {
152 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'identifier' => '/test'), $this->storageMock);
153 $fixture->updateProperties(array('uid' => 3));
154 $this->assertEquals(1, $fixture->getUid());
155 }
156
157 /**
158 * @test
159 */
160 public function updatePropertiesRecordsNamesOfChangedProperties() {
161 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test'), $this->storageMock);
162 $fixture->updateProperties(array('foo' => 'foobar', 'baz' => 'foobaz'));
163 $this->assertEquals(array('foo', 'baz'), $fixture->getUpdatedProperties());
164 }
165
166 /**
167 * @test
168 */
169 public function updatePropertiesDoesNotRecordPropertyNameIfSameValueIsProvided() {
170 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'identifier' => '/test'), $this->storageMock);
171 $fixture->updateProperties(array('foo' => 'asdf'));
172 $this->assertEmpty($fixture->getUpdatedProperties());
173 }
174
175 /**
176 * @test
177 */
178 public function updatePropertiesMarksPropertyAsChangedOnlyOnce() {
179 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test'), $this->storageMock);
180 $fixture->updateProperties(array('foo' => 'foobar', 'baz' => 'foobaz'));
181 $fixture->updateProperties(array('foo' => 'fdsw', 'baz' => 'asdf'));
182 $this->assertEquals(array('foo', 'baz'), $fixture->getUpdatedProperties());
183 }
184
185 /**
186 * @test
187 */
188 public function updatePropertiesReloadsStorageObjectIfStorageChanges() {
189 $mockedNewStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
190 $mockedOldStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
191 $mockedOldStorage->expects($this->any())->method('getUid')->will($this->returnValue(1));
192 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test', 'storage' => 1), $mockedOldStorage);
193 $mockedResourceFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
194 $mockedResourceFactory->expects($this->once())->method('getStorageObject')->with(2)->will($this->returnValue($mockedNewStorage));
195 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', $mockedResourceFactory);
196 $fixture->updateProperties(array('storage' => 2));
197 $this->assertSame($mockedNewStorage, $fixture->getStorage());
198 }
199
200 /**
201 * @test
202 */
203 public function fetchingIndexedPropertyCausesFileObjectToLoadIndexRecord() {
204 $mockedRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
205 $mockedRepository->expects($this->once())->method('findOneByCombinedIdentifier')->will($this->returnValue(array('uid' => 10)));
206 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository', $mockedRepository);
207
208 $fixture = new \TYPO3\CMS\Core\Resource\File(array('identifier' => '/test', 'storage' => 5), $this->storageMock);
209 $this->assertEquals(10, $fixture->getProperty('uid'));
210 }
211
212 /**
213 * @test
214 */
215 public function isIndexedTriggersIndexingIfFileIsNotIndexedAlready() {
216 $sut = $this->getAccessibleMock(
217 'TYPO3\\CMS\\Core\\Resource\\File',
218 array('loadIndexRecord'),
219 array(),
220 '',
221 FALSE
222 );
223 $sut->_set('indexed', NULL);
224 $sut->_set('indexingInProgress', FALSE);
225
226 $sut
227 ->expects($this->once())
228 ->method('loadIndexRecord');
229 $sut->isIndexed();
230 }
231
232 /**
233 * @test
234 */
235 public function fileIsAutomaticallyIndexedOnPropertyAccessIfNotAlreadyIndexed() {
236 $sut = $this->getAccessibleMock(
237 'TYPO3\\CMS\\Core\\Resource\\File',
238 array('loadIndexRecord'),
239 array(),
240 '',
241 FALSE
242 );
243 $sut->_set('metaDataProperties', array());
244 $sut->_set('properties', array());
245
246 $sut->_set('indexed', NULL);
247 $sut
248 ->expects($this->once())
249 ->method('loadIndexRecord');
250 $sut->getProperty('foo');
251 }
252
253 /**
254 * @test
255 */
256 public function copyToCallsCopyOperationOnTargetFolderStorage() {
257 $targetStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
258 $targetFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
259 $targetFolder->expects($this->any())->method('getStorage')->will($this->returnValue($targetStorage));
260 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
261 $targetStorage->expects($this->once())->method('copyFile')->with($this->equalTo($fixture), $this->equalTo($targetFolder));
262 $fixture->copyTo($targetFolder);
263 }
264
265 /**
266 * @test
267 */
268 public function moveToCallsMoveOperationOnTargetFolderStorage() {
269 $targetStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
270 $targetFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
271 $targetFolder->expects($this->any())->method('getStorage')->will($this->returnValue($targetStorage));
272 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
273 $targetStorage->expects($this->once())->method('moveFile')->with($this->equalTo($fixture), $this->equalTo($targetFolder));
274 $fixture->moveTo($targetFolder);
275 }
276
277 /**
278 * @test
279 */
280 public function openCorrectlyOpensFileInDriver() {
281 $this->markTestSkipped();
282 $fixture = $this->prepareFixture();
283 $fileMode = 'invalidMode';
284 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
285 $mockDriver->expects($this->atLeastOnce())->method('getFileHandle')->with($this->equalTo($fixture), $this->equalTo($fileMode));
286 $fixture->setStorageDriver($mockDriver);
287 $fixture->open($fileMode);
288 }
289
290 /**
291 * @test
292 */
293 public function isOpenReturnsCorrectValuesForClosedAndOpenFile() {
294 $this->markTestSkipped();
295 $fixture = $this->prepareFixture();
296 $fileMode = 'r';
297 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
298 $mockFileHandle->expects($this->any())->method('isOpen')->will($this->returnValue(TRUE));
299 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
300 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
301 $fixture->setStorageDriver($mockDriver);
302 $this->assertFalse($fixture->isOpen());
303 $fixture->open($fileMode);
304 $this->assertTrue($fixture->isOpen());
305 }
306
307 /**
308 * @test
309 */
310 public function fileIsCorrectlyClosed() {
311 $this->markTestSkipped();
312 $fixture = $this->prepareFixture();
313 $fileMode = 'r';
314 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
315 $mockFileHandle->expects($this->once())->method('close');
316 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
317 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
318 $fixture->setStorageDriver($mockDriver);
319 $fixture->open($fileMode);
320 $fixture->close();
321 $this->assertFalse($fixture->isOpen());
322 }
323
324 /**
325 * @test
326 */
327 public function readReturnsRequestedContentsFromDriver() {
328 $this->markTestSkipped();
329 $fixture = $this->prepareFixture();
330 $fileMode = 'r';
331 $fileContents = 'Some random file contents.';
332 $bytesToRead = 10;
333 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
334 $mockFileHandle->expects($this->any())->method('isOpen')->will($this->returnValue(TRUE));
335 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
336 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
337 $mockDriver->expects($this->once())->method('readFromFile')->with($this->anything(), $this->equalTo($bytesToRead))->will($this->returnValue(substr($fileContents, 0, $bytesToRead)));
338 $fixture->setStorageDriver($mockDriver);
339 $fixture->open($fileMode);
340 $this->assertEquals(substr($fileContents, 0, $bytesToRead), $fixture->read($bytesToRead));
341 }
342
343 /**
344 * @test
345 */
346 public function readFailsIfFileIsClosed() {
347 $this->markTestSkipped();
348 $this->setExpectedException('\\RuntimeException', '', 1299863431);
349 $fixture = $this->prepareFixture();
350 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
351 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
352 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
353 $fixture->setStorageDriver($mockDriver);
354 $fixture->read(1);
355 }
356
357 /**
358 * @test
359 */
360 public function writePassesContentsToDriver() {
361 $this->markTestSkipped();
362 $fixture = $this->prepareFixture();
363 $fileMode = 'r+';
364 $fileContents = 'Some random file contents.';
365 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
366 $mockFileHandle->expects($this->any())->method('isOpen')->will($this->returnValue(TRUE));
367 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
368 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
369 $mockDriver->expects($this->once())->method('writeToFile')->with($this->anything(), $this->equalTo($fileContents))->will($this->returnValue(TRUE));
370 $fixture->setStorageDriver($mockDriver);
371 $fixture->open($fileMode);
372 $this->assertTrue($fixture->write($fileContents));
373 }
374
375 /**
376 * @test
377 */
378 public function writeFailsIfFileIsClosed() {
379 $this->markTestSkipped();
380 $this->setExpectedException('\\RuntimeException', '', 1299863432);
381 $fixture = $this->prepareFixture();
382 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
383 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
384 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
385 $fixture->setStorageDriver($mockDriver);
386 $fixture->write('asdf');
387 }
388
389 public function filenameExtensionDataProvider() {
390 return array(
391 array('somefile.jpg', 'somefile', 'jpg'),
392 array('SomeFile.PNG', 'SomeFile', 'png'),
393 array('somefile', 'somefile', ''),
394 array('somefile.tar.gz', 'somefile.tar', 'gz'),
395 array('somefile.tar.bz2', 'somefile.tar', 'bz2'),
396 );
397 }
398
399 /**
400 * @test
401 * @dataProvider filenameExtensionDataProvider
402 */
403 public function getNameWithoutExtensionReturnsCorrectName($originalFilename, $expectedBasename) {
404 $fixture = new \TYPO3\CMS\Core\Resource\File(array(
405 'name' => $originalFilename,
406 'identifier' => '/' . $originalFilename
407 ),
408 $this->storageMock);
409 $this->assertSame($expectedBasename, $fixture->getNameWithoutExtension());
410 }
411
412 /**
413 * @test
414 * @dataProvider filenameExtensionDataProvider
415 */
416 public function getExtensionReturnsCorrectExtension($originalFilename, $expectedBasename, $expectedExtension) {
417 $fixture = new \TYPO3\CMS\Core\Resource\File(array(
418 'name' => $originalFilename,
419 'identifier' => '/' . $originalFilename
420 ), $this->storageMock);
421 $this->assertSame($expectedExtension, $fixture->getExtension());
422 }
423
424 /**
425 * @test
426 */
427 public function indexablePropertyIsByDefaultTrue() {
428 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
429 $this->assertAttributeEquals(TRUE, 'indexable', $fixture);
430 }
431
432 /**
433 * @test
434 */
435 public function indexablePropertyCanBeSetAndGet() {
436 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
437 foreach (array(FALSE, TRUE) as $value) {
438 $fixture->setIndexable($value);
439 $this->assertSame($value, $fixture->isIndexable());
440 }
441 }
442
443 /**
444 * @test
445 */
446 public function callMethodLoadIndexRecordWithPropertyIndexableSetToFalseAndCheckWhetherIsIndexedReturnsNull() {
447 $method = new \ReflectionMethod(
448 'TYPO3\CMS\Core\Resource\File', 'loadIndexRecord'
449 );
450 $method->setAccessible(TRUE);
451
452 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
453 $fixture->setIndexable(FALSE);
454 $method->invoke($fixture);
455 $this->assertNull($fixture->isIndexed());
456 }
457 }