[BUGFIX] hasProperty ignores meta data properties
[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
52 public function tearDown() {
53 \TYPO3\CMS\Core\Utility\GeneralUtility::resetSingletonInstances($this->singletonInstances);
54 }
55
56 /**
57 * @return \TYPO3\CMS\Core\Resource\File
58 */
59 protected function prepareFixture() {
60 $fixture = new \TYPO3\CMS\Core\Resource\File(array('testfile'), $this->storageMock);
61 return $fixture;
62 }
63
64 /**
65 * @test
66 * @todo Old code getAvailableProperties() needs to be replaced by current behaviour
67 */
68 public function propertiesPassedToConstructorAreAvailableViaGenericGetter() {
69 $this->markTestSkipped('TYPO3\\CMS\\Core\\Resource\\File::getAvailableProperties() does not exist');
70 $properties = array(
71 uniqid() => uniqid(),
72 uniqid() => uniqid(),
73 'uid' => 1
74 );
75 $fixture = new \TYPO3\CMS\Core\Resource\File($properties, $this->storageMock);
76 $availablePropertiesBackup = \TYPO3\CMS\Core\Resource\File::getAvailableProperties();
77 \TYPO3\CMS\Core\Resource\File::setAvailableProperties(array_keys($properties));
78 foreach ($properties as $key => $value) {
79 $this->assertTrue($fixture->hasProperty($key));
80 $this->assertEquals($value, $fixture->getProperty($key));
81 }
82 $this->assertFalse($fixture->hasProperty(uniqid()));
83 \TYPO3\CMS\Core\Resource\File::setAvailableProperties($availablePropertiesBackup);
84 $this->setExpectedException('InvalidArgumentException', '', 1314226805);
85 $fixture->getProperty(uniqid());
86 }
87
88 /**
89 * @test
90 */
91 public function commonPropertiesAreAvailableWithOwnGetters() {
92 $properties = array(
93 'name' => uniqid(),
94 'storage' => $this->storageMock,
95 'size' => 1024
96 );
97 $fixture = new \TYPO3\CMS\Core\Resource\File($properties, $this->storageMock);
98 foreach ($properties as $key => $value) {
99 $this->assertEquals($value, call_user_func(array($fixture, 'get' . $key)));
100 }
101 }
102
103 /**
104 * @test
105 */
106 public function fileAsksRepositoryForIndexStatus() {
107 $mockedRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
108 $mockedRepository->expects($this->once())->method('findOneByCombinedIdentifier')->will($this->returnValue(array('uid' => 1)));
109 $mockedRepository->expects($this->exactly(0))->method('add');
110 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository', $mockedRepository);
111
112 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
113 $this->assertTrue($fixture->isIndexed());
114 }
115
116 /**
117 * Tests if a file is seen as indexed if the record has a uid
118 *
119 * @test
120 */
121 public function fileIndexStatusIsTrueIfUidIsSet() {
122 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1), $this->storageMock);
123 $this->assertTrue($fixture->isIndexed());
124 }
125
126 /**
127 * @test
128 */
129 public function updatePropertiesUpdatesFileProperties() {
130 $identifier = '/' . uniqid();
131 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'identifier' => '/test'), $this->storageMock);
132 $fixture->updateProperties(array('identifier' => $identifier));
133 $this->assertEquals($identifier, $fixture->getIdentifier());
134 }
135
136 /**
137 * @test
138 */
139 public function updatePropertiesLeavesPropertiesUntouchedIfNotSetInNewProperties() {
140 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'identifier' => '/test'), $this->storageMock);
141 $fixture->updateProperties(array('foo' => 'foobar'));
142 $this->assertEquals('/test', $fixture->getIdentifier());
143 $this->assertEquals('/test', $fixture->getProperty('identifier'));
144 }
145
146 /**
147 * @test
148 */
149 public function updatePropertiesDiscardsUidIfAlreadySet() {
150 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'identifier' => '/test'), $this->storageMock);
151 $fixture->updateProperties(array('uid' => 3));
152 $this->assertEquals(1, $fixture->getUid());
153 }
154
155 /**
156 * @test
157 */
158 public function updatePropertiesRecordsNamesOfChangedProperties() {
159 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test'), $this->storageMock);
160 $fixture->updateProperties(array('foo' => 'foobar', 'baz' => 'foobaz'));
161 $this->assertEquals(array('foo', 'baz'), $fixture->getUpdatedProperties());
162 }
163
164 /**
165 * @test
166 */
167 public function updatePropertiesDoesNotRecordPropertyNameIfSameValueIsProvided() {
168 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'identifier' => '/test'), $this->storageMock);
169 $fixture->updateProperties(array('foo' => 'asdf'));
170 $this->assertEmpty($fixture->getUpdatedProperties());
171 }
172
173 /**
174 * @test
175 */
176 public function updatePropertiesMarksPropertyAsChangedOnlyOnce() {
177 $fixture = new \TYPO3\CMS\Core\Resource\File(array('uid' => 1, 'foo' => 'asdf', 'baz' => 'fdsw', 'identifier' => '/test'), $this->storageMock);
178 $fixture->updateProperties(array('foo' => 'foobar', 'baz' => 'foobaz'));
179 $fixture->updateProperties(array('foo' => 'fdsw', 'baz' => 'asdf'));
180 $this->assertEquals(array('foo', 'baz'), $fixture->getUpdatedProperties());
181 }
182
183 /**
184 * @test
185 */
186 public function updatePropertiesReloadsStorageObjectIfStorageChanges() {
187 $fileProperties = array(
188 'uid' => 1,
189 'storage' => 'first',
190 );
191 $subject = $this->getMock(
192 'TYPO3\\CMS\\Core\\Resource\\File',
193 array('loadStorage'),
194 array($fileProperties, $this->storageMock)
195 );
196 $mockedNewStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
197 $mockedResourceFactory = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceFactory');
198 $mockedResourceFactory
199 ->expects($this->once())
200 ->method('getStorageObject')
201 ->will($this->returnValue($mockedNewStorage));
202 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\ResourceFactory', $mockedResourceFactory);
203
204 $subject->updateProperties(array('storage' => 'different'));
205 $this->assertSame($mockedNewStorage, $subject->getStorage());
206 }
207
208 /**
209 * @test
210 */
211 public function fetchingIndexedPropertyCausesFileObjectToLoadIndexRecord() {
212 $mockedRepository = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository');
213 $mockedRepository->expects($this->once())->method('findOneByCombinedIdentifier')->will($this->returnValue(array('uid' => 10)));
214 \TYPO3\CMS\Core\Utility\GeneralUtility::setSingletonInstance('TYPO3\\CMS\\Core\\Resource\\Index\\FileIndexRepository', $mockedRepository);
215
216 $fixture = new \TYPO3\CMS\Core\Resource\File(array('identifier' => '/test', 'storage' => 5), $this->storageMock);
217 $this->assertEquals(10, $fixture->getProperty('uid'));
218 }
219
220 /**
221 * @test
222 */
223 public function isIndexedTriggersIndexingIfFileIsNotIndexedAlready() {
224 $subject = $this->getAccessibleMock(
225 'TYPO3\\CMS\\Core\\Resource\\File',
226 array('loadIndexRecord'),
227 array(),
228 '',
229 FALSE
230 );
231 $subject->_set('indexed', NULL);
232 $subject->_set('indexingInProgress', FALSE);
233
234 $subject
235 ->expects($this->once())
236 ->method('loadIndexRecord');
237 $subject->isIndexed();
238 }
239
240 /**
241 * @test
242 */
243 public function fileIsAutomaticallyIndexedOnPropertyAccessIfNotAlreadyIndexed() {
244 $subject = $this->getAccessibleMock(
245 'TYPO3\\CMS\\Core\\Resource\\File',
246 array('loadIndexRecord'),
247 array(),
248 '',
249 FALSE
250 );
251 $subject->_set('metaDataProperties', array());
252 $subject->_set('properties', array());
253
254 $subject->_set('indexed', NULL);
255 $subject
256 ->expects($this->once())
257 ->method('loadIndexRecord');
258 $subject->getProperty('foo');
259 }
260
261 /**
262 * @test
263 */
264 public function copyToCallsCopyOperationOnTargetFolderStorage() {
265 $targetStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
266 $targetFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
267 $targetFolder->expects($this->any())->method('getStorage')->will($this->returnValue($targetStorage));
268 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
269 $targetStorage->expects($this->once())->method('copyFile')->with($this->equalTo($fixture), $this->equalTo($targetFolder));
270 $fixture->copyTo($targetFolder);
271 }
272
273 /**
274 * @test
275 */
276 public function moveToCallsMoveOperationOnTargetFolderStorage() {
277 $targetStorage = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
278 $targetFolder = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Folder', array(), array(), '', FALSE);
279 $targetFolder->expects($this->any())->method('getStorage')->will($this->returnValue($targetStorage));
280 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
281 $targetStorage->expects($this->once())->method('moveFile')->with($this->equalTo($fixture), $this->equalTo($targetFolder));
282 $fixture->moveTo($targetFolder);
283 }
284
285 /**
286 * @test
287 */
288 public function openCorrectlyOpensFileInDriver() {
289 $this->markTestSkipped();
290 $fixture = $this->prepareFixture();
291 $fileMode = 'invalidMode';
292 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
293 $mockDriver->expects($this->atLeastOnce())->method('getFileHandle')->with($this->equalTo($fixture), $this->equalTo($fileMode));
294 $fixture->setStorageDriver($mockDriver);
295 $fixture->open($fileMode);
296 }
297
298 /**
299 * @test
300 */
301 public function isOpenReturnsCorrectValuesForClosedAndOpenFile() {
302 $this->markTestSkipped();
303 $fixture = $this->prepareFixture();
304 $fileMode = 'r';
305 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
306 $mockFileHandle->expects($this->any())->method('isOpen')->will($this->returnValue(TRUE));
307 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
308 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
309 $fixture->setStorageDriver($mockDriver);
310 $this->assertFalse($fixture->isOpen());
311 $fixture->open($fileMode);
312 $this->assertTrue($fixture->isOpen());
313 }
314
315 /**
316 * @test
317 */
318 public function fileIsCorrectlyClosed() {
319 $this->markTestSkipped();
320 $fixture = $this->prepareFixture();
321 $fileMode = 'r';
322 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
323 $mockFileHandle->expects($this->once())->method('close');
324 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
325 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
326 $fixture->setStorageDriver($mockDriver);
327 $fixture->open($fileMode);
328 $fixture->close();
329 $this->assertFalse($fixture->isOpen());
330 }
331
332 /**
333 * @test
334 */
335 public function readReturnsRequestedContentsFromDriver() {
336 $this->markTestSkipped();
337 $fixture = $this->prepareFixture();
338 $fileMode = 'r';
339 $fileContents = 'Some random file contents.';
340 $bytesToRead = 10;
341 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
342 $mockFileHandle->expects($this->any())->method('isOpen')->will($this->returnValue(TRUE));
343 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
344 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
345 $mockDriver->expects($this->once())->method('readFromFile')->with($this->anything(), $this->equalTo($bytesToRead))->will($this->returnValue(substr($fileContents, 0, $bytesToRead)));
346 $fixture->setStorageDriver($mockDriver);
347 $fixture->open($fileMode);
348 $this->assertEquals(substr($fileContents, 0, $bytesToRead), $fixture->read($bytesToRead));
349 }
350
351 /**
352 * @test
353 */
354 public function readFailsIfFileIsClosed() {
355 $this->markTestSkipped();
356 $this->setExpectedException('\\RuntimeException', '', 1299863431);
357 $fixture = $this->prepareFixture();
358 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
359 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
360 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
361 $fixture->setStorageDriver($mockDriver);
362 $fixture->read(1);
363 }
364
365 /**
366 * @test
367 */
368 public function writePassesContentsToDriver() {
369 $this->markTestSkipped();
370 $fixture = $this->prepareFixture();
371 $fileMode = 'r+';
372 $fileContents = 'Some random file contents.';
373 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
374 $mockFileHandle->expects($this->any())->method('isOpen')->will($this->returnValue(TRUE));
375 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
376 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
377 $mockDriver->expects($this->once())->method('writeToFile')->with($this->anything(), $this->equalTo($fileContents))->will($this->returnValue(TRUE));
378 $fixture->setStorageDriver($mockDriver);
379 $fixture->open($fileMode);
380 $this->assertTrue($fixture->write($fileContents));
381 }
382
383 /**
384 * @test
385 */
386 public function writeFailsIfFileIsClosed() {
387 $this->markTestSkipped();
388 $this->setExpectedException('\\RuntimeException', '', 1299863432);
389 $fixture = $this->prepareFixture();
390 $mockFileHandle = $this->getMock('TYPO3\\CMS\\Core\\Resource\\FileHandle', array(), array(), '', FALSE);
391 $mockDriver = $this->getMockForAbstractClass('t3lib_file_driver_Abstract');
392 $mockDriver->expects($this->any())->method('getFileHandle')->will($this->returnValue($mockFileHandle));
393 $fixture->setStorageDriver($mockDriver);
394 $fixture->write('asdf');
395 }
396
397 public function filenameExtensionDataProvider() {
398 return array(
399 array('somefile.jpg', 'somefile', 'jpg'),
400 array('SomeFile.PNG', 'SomeFile', 'png'),
401 array('somefile', 'somefile', ''),
402 array('somefile.tar.gz', 'somefile.tar', 'gz'),
403 array('somefile.tar.bz2', 'somefile.tar', 'bz2'),
404 );
405 }
406
407 /**
408 * @test
409 * @dataProvider filenameExtensionDataProvider
410 */
411 public function getNameWithoutExtensionReturnsCorrectName($originalFilename, $expectedBasename) {
412 $fixture = new \TYPO3\CMS\Core\Resource\File(array(
413 'name' => $originalFilename,
414 'identifier' => '/' . $originalFilename
415 ),
416 $this->storageMock);
417 $this->assertSame($expectedBasename, $fixture->getNameWithoutExtension());
418 }
419
420 /**
421 * @test
422 * @dataProvider filenameExtensionDataProvider
423 */
424 public function getExtensionReturnsCorrectExtension($originalFilename, $expectedBasename, $expectedExtension) {
425 $fixture = new \TYPO3\CMS\Core\Resource\File(array(
426 'name' => $originalFilename,
427 'identifier' => '/' . $originalFilename
428 ), $this->storageMock);
429 $this->assertSame($expectedExtension, $fixture->getExtension());
430 }
431
432 /**
433 * @test
434 */
435 public function indexablePropertyIsByDefaultTrue() {
436 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
437 $this->assertAttributeEquals(TRUE, 'indexable', $fixture);
438 }
439
440 /**
441 * @test
442 */
443 public function indexablePropertyCanBeSetAndGet() {
444 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
445 foreach (array(FALSE, TRUE) as $value) {
446 $fixture->setIndexable($value);
447 $this->assertSame($value, $fixture->isIndexable());
448 }
449 }
450
451 /**
452 * @test
453 */
454 public function callMethodLoadIndexRecordWithPropertyIndexableSetToFalseAndCheckWhetherIsIndexedReturnsNull() {
455 $method = new \ReflectionMethod(
456 'TYPO3\CMS\Core\Resource\File', 'loadIndexRecord'
457 );
458 $method->setAccessible(TRUE);
459
460 $fixture = new \TYPO3\CMS\Core\Resource\File(array(), $this->storageMock);
461 $fixture->setIndexable(FALSE);
462 $method->invoke($fixture);
463 $this->assertNull($fixture->isIndexed());
464 }
465
466 /**
467 * @test
468 */
469 public function hasPropertyReturnsTrueFilePropertyExists() {
470 $fixture = new \TYPO3\CMS\Core\Resource\File(array('testproperty' => 'testvalue'), $this->storageMock);
471 $this->assertTrue($fixture->hasProperty('testproperty'));
472 }
473
474 /**
475 * @test
476 */
477 public function hasPropertyReturnsTrueIfMetadataPropertyExists() {
478 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Resource\\File', array('dummy'), array(array(), $this->storageMock));
479 $fixture->_set('metaDataProperties', array('testproperty' => 'testvalue'));
480 $this->assertTrue($fixture->hasProperty('testproperty'));
481 }
482 }