3427acfb7736fd9a7abc6f13f039164125f7961d
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Configuration / ConfigurationManagerTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Configuration;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2012-2013 Christian Kuhn <lolli@schwarzbu.ch>
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
27 /**
28 * Test case
29 *
30 * @author Christian Kuhn <lolli@schwarzbu.ch>
31 */
32 class ConfigurationManagerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
33
34 /**
35 * Absolute path to files that must be removed
36 * after a test - handled in tearDown
37 */
38 protected $testFilesToDelete = array();
39
40 /**
41 * @var \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject
42 */
43 protected $fixture;
44
45 public function setUp() {
46 $this->createFixtureWithMockedMethods(
47 array(
48 'getDefaultConfigurationFileLocation',
49 'getLocalConfigurationFileLocation',
50 )
51 );
52 }
53
54 /**
55 * Tear down test case
56 */
57 public function tearDown() {
58 foreach ($this->testFilesToDelete as $absoluteFileName) {
59 \TYPO3\CMS\Core\Utility\GeneralUtility::unlink_tempfile($absoluteFileName);
60 }
61 }
62
63 /**
64 * @param array $methods
65 */
66 protected function createFixtureWithMockedMethods(array $methods) {
67 $this->fixture = $this->getMock(
68 'TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager',
69 $methods
70 );
71 }
72
73 /**
74 * @test
75 * @expectedException \RuntimeException
76 */
77 public function getDefaultConfigurationExecutesDefinedDefaultConfigurationFile() {
78 $defaultConfigurationFile = PATH_site . 'typo3temp/' . uniqid('defaultConfiguration');
79 file_put_contents(
80 $defaultConfigurationFile,
81 '<?php throw new \RuntimeException(\'foo\', 1310203814); ?>'
82 );
83 $this->testFilesToDelete[] = $defaultConfigurationFile;
84
85 $this->fixture
86 ->expects($this->once())
87 ->method('getDefaultConfigurationFileLocation')
88 ->will($this->returnValue($defaultConfigurationFile));
89 $this->fixture->getDefaultConfiguration();
90 }
91
92 /**
93 * @test
94 * @expectedException \RuntimeException
95 */
96 public function getLocalConfigurationExecutesDefinedConfigurationFile() {
97 $configurationFile = PATH_site . 'typo3temp/' . uniqid('localConfiguration');
98 file_put_contents(
99 $configurationFile,
100 '<?php throw new \RuntimeException(\'foo\', 1310203815); ?>'
101 );
102 $this->testFilesToDelete[] = $configurationFile;
103
104 $this->fixture
105 ->expects($this->once())
106 ->method('getLocalConfigurationFileLocation')
107 ->will($this->returnValue($configurationFile));
108 $this->fixture->getLocalConfiguration();
109 }
110
111 /**
112 * @test
113 */
114 public function updateLocalConfigurationWritesNewMergedLocalConfigurationArray() {
115 $currentLocalConfiguration = array(
116 'notChanged' => 23,
117 'changed' => 'unChanged',
118 );
119 $overrideConfiguration = array(
120 'changed' => 'changed',
121 'new' => 'new'
122 );
123 $expectedConfiguration = array(
124 'notChanged' => 23,
125 'changed' => 'changed',
126 'new' => 'new',
127 );
128
129 $this->createFixtureWithMockedMethods(
130 array(
131 'getLocalConfiguration',
132 'writeLocalConfiguration',
133 )
134 );
135 $this->fixture->expects($this->once())
136 ->method('getLocalConfiguration')
137 ->will($this->returnValue($currentLocalConfiguration));
138 $this->fixture->expects($this->once())
139 ->method('writeLocalConfiguration')
140 ->with($expectedConfiguration);
141
142 $this->fixture->updateLocalConfiguration($overrideConfiguration);
143 }
144
145 /**
146 * @test
147 */
148 public function getDefaultConfigurationValueByPathReturnsCorrectValue() {
149 $this->createFixtureWithMockedMethods(
150 array(
151 'getDefaultConfiguration',
152 )
153 );
154 $this->fixture->expects($this->once())
155 ->method('getDefaultConfiguration')
156 ->will($this->returnValue(array(
157 'path' => 'value',
158 )
159 ));
160
161 $this->assertSame('value', $this->fixture->getDefaultConfigurationValueByPath('path'));
162 }
163
164 /**
165 * @test
166 */
167 public function getLocalConfigurationValueByPathReturnsCorrectValue() {
168 $this->createFixtureWithMockedMethods(
169 array(
170 'getLocalConfiguration',
171 )
172 );
173 $this->fixture->expects($this->once())
174 ->method('getLocalConfiguration')
175 ->will($this->returnValue(array(
176 'path' => 'value',
177 )
178 ));
179
180 $this->assertSame('value', $this->fixture->getLocalConfigurationValueByPath('path'));
181 }
182
183 /**
184 * @test
185 */
186 public function getConfigurationValueByPathReturnsCorrectValue() {
187 $this->createFixtureWithMockedMethods(
188 array(
189 'getDefaultConfiguration',
190 'getLocalConfiguration',
191 )
192 );
193 $this->fixture->expects($this->once())
194 ->method('getDefaultConfiguration')
195 ->will($this->returnValue(array(
196 'path' => 'value',
197 )
198 ));
199 $this->fixture->expects($this->once())
200 ->method('getLocalConfiguration')
201 ->will($this->returnValue(array(
202 'path' => 'valueOverride',
203 )
204 ));
205
206 $this->assertSame('valueOverride', $this->fixture->getConfigurationValueByPath('path'));
207 }
208
209 /**
210 * @test
211 */
212 public function setLocalConfigurationValueByPathReturnFalseIfPathIsNotValid() {
213 $this->createFixtureWithMockedMethods(array(
214 'isValidLocalConfigurationPath',
215 ));
216 $this->fixture->expects($this->once())
217 ->method('isValidLocalConfigurationPath')
218 ->will($this->returnValue(FALSE));
219
220 $this->assertFalse($this->fixture->setLocalConfigurationValueByPath('path', 'value'));
221 }
222
223 /**
224 * @test
225 */
226 public function setLocalConfigurationValueByPathUpdatesValueDefinedByPath() {
227 $currentLocalConfiguration = array(
228 'notChanged' => 23,
229 'toUpdate' => 'notUpdated',
230 );
231 $expectedConfiguration = array(
232 'notChanged' => 23,
233 'toUpdate' => 'updated',
234 );
235
236 $this->createFixtureWithMockedMethods(
237 array(
238 'isValidLocalConfigurationPath',
239 'getLocalConfiguration',
240 'writeLocalConfiguration',
241 )
242 );
243 $this->fixture->expects($this->once())
244 ->method('isValidLocalConfigurationPath')
245 ->will($this->returnValue(TRUE));
246 $this->fixture->expects($this->once())
247 ->method('getLocalConfiguration')
248 ->will($this->returnValue($currentLocalConfiguration));
249 $this->fixture->expects($this->once())
250 ->method('writeLocalConfiguration')
251 ->with($expectedConfiguration);
252
253 $this->fixture->setLocalConfigurationValueByPath('toUpdate', 'updated');
254 }
255
256 /**
257 * @test
258 */
259 public function setLocalConfigurationValuesByPathValuePairsSetsPathValuePairs() {
260 $currentLocalConfiguration = array(
261 'notChanged' => 23,
262 'toUpdate' => 'notUpdated',
263 );
264 $expectedConfiguration = array(
265 'notChanged' => 23,
266 'toUpdate' => 'updated',
267 'new' => 'new',
268 );
269
270 $this->createFixtureWithMockedMethods(
271 array(
272 'isValidLocalConfigurationPath',
273 'getLocalConfiguration',
274 'writeLocalConfiguration',
275 )
276 );
277 $this->fixture->expects($this->any())
278 ->method('isValidLocalConfigurationPath')
279 ->will($this->returnValue(TRUE));
280 $this->fixture->expects($this->once())
281 ->method('getLocalConfiguration')
282 ->will($this->returnValue($currentLocalConfiguration));
283 $this->fixture->expects($this->once())
284 ->method('writeLocalConfiguration')
285 ->with($expectedConfiguration);
286
287 $pairs = array(
288 'toUpdate' => 'updated',
289 'new' => 'new'
290 );
291 $this->fixture->setLocalConfigurationValuesByPathValuePairs($pairs);
292 }
293
294 /**
295 * @test
296 */
297 public function canWriteConfigurationReturnsFalseIfDirectoryIsNotWritable() {
298 if (TYPO3_OS == 'WIN') {
299 $this->markTestSkipped('Not available on Windows');
300 }
301 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
302 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
303
304 $directory = 'typo3temp/' . uniqid('test_');
305 $absoluteDirectory = PATH_site . $directory;
306 mkdir($absoluteDirectory);
307 chmod($absoluteDirectory, 0544);
308 clearstatcache();
309
310 $fixture->_set('pathTypo3Conf', $directory);
311
312 $result = $fixture->canWriteConfiguration();
313
314 chmod($absoluteDirectory, 0755);
315 rmdir($absoluteDirectory);
316
317 $this->assertFalse($result);
318 }
319
320 /**
321 * @test
322 */
323 public function canWriteConfigurationReturnsFalseIfLocalConfigurationFileIsNotWritable() {
324 if (TYPO3_OS == 'WIN') {
325 $this->markTestSkipped('Not available on Windows');
326 }
327 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
328 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
329
330 $file = 'typo3temp/' . uniqid('test_');
331 $absoluteFile = PATH_site . $file;
332 touch($absoluteFile);
333 $this->testFilesToDelete[] = $absoluteFile;
334 chmod($absoluteFile, 0444);
335 clearstatcache();
336
337 $fixture->_set('localConfigurationFile', $file);
338
339 $result = $fixture->canWriteConfiguration();
340
341 chmod($absoluteFile, 0644);
342
343 $this->assertFalse($result);
344 }
345
346 /**
347 * @test
348 */
349 public function canWriteConfigurationReturnsFalseIfLocalconfFileIsNotWritable() {
350 if (TYPO3_OS == 'WIN') {
351 $this->markTestSkipped('Not available on Windows');
352 }
353 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
354 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
355
356 $file = 'typo3temp/' . uniqid('test_');
357 $absoluteFile = PATH_site . $file;
358 touch($absoluteFile);
359 $this->testFilesToDelete[] = $absoluteFile;
360 chmod($absoluteFile, 0444);
361 clearstatcache();
362
363 $fixture->_set('localconfFile', $file);
364
365 $result = $fixture->canWriteConfiguration();
366
367 chmod($absoluteFile, 0644);
368
369 $this->assertFalse($result);
370 }
371
372 /**
373 * @test
374 */
375 public function canWriteConfigurationReturnsTrueIfDirectoryAndFilesAreWritable() {
376 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
377 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
378
379 $directory = 'typo3temp/' . uniqid('test_');
380 $absoluteDirectory = PATH_site . $directory;
381 mkdir($absoluteDirectory);
382 $fixture->_set('pathTypo3Conf', $directory);
383
384 $file1 = 'typo3temp/' . uniqid('test_');
385 $absoluteFile1 = PATH_site . $file1;
386 touch($absoluteFile1);
387 $this->testFilesToDelete[] = $absoluteFile1;
388 $fixture->_set('localConfigurationFile', $file1);
389
390 $file2 = 'typo3temp/' . uniqid('test_');
391 $absoluteFile2 = PATH_site . $file2;
392 touch($absoluteFile2);
393 $this->testFilesToDelete[] = $absoluteFile2;
394 $fixture->_set('localconfFile', $file2);
395
396 clearstatcache();
397
398 $result = $fixture->canWriteConfiguration();
399
400 $this->assertTrue($result);
401 }
402
403 /**
404 * @test
405 */
406 public function writeLocalConfigurationWritesSortedContentToConfigurationFile() {
407 $configurationFile = PATH_site . 'typo3temp/' . uniqid('localConfiguration');
408 if (!is_file($configurationFile)) {
409 if (!$fh = fopen($configurationFile, 'wb')) {
410 $this->markTestSkipped('Can not create file ' . $configurationFile . '. Please check your write permissions.');
411 }
412 fclose($fh);
413 }
414
415 if (!@is_file($configurationFile)) {
416 throw new \RuntimeException('File ' . $configurationFile . ' could not be found. Please check your write permissions', 1346364362);
417 }
418 $this->testFilesToDelete[] = $configurationFile;
419
420 $this->fixture
421 ->expects($this->any())
422 ->method('getLocalConfigurationFileLocation')
423 ->will($this->returnValue($configurationFile));
424
425 $pairs = array(
426 'foo' => 42,
427 'bar' => 23
428 );
429 $expectedContent =
430 '<?php' . LF .
431 'return array(' . LF .
432 TAB . '\'bar\' => 23,' . LF .
433 TAB . '\'foo\' => 42,' . LF .
434 ');' . LF .
435 '?>';
436
437 $this->fixture->writeLocalConfiguration($pairs);
438 $this->assertSame($expectedContent, file_get_contents($configurationFile));
439 }
440
441 /**
442 * @test
443 * @expectedException \RuntimeException
444 */
445 public function createLocalConfigurationFromFactoryConfigurationThrowsExceptionIfFileExists() {
446 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
447 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
448
449 $file = 'typo3temp/' . uniqid('test_');
450 $absoluteFile = PATH_site . $file;
451 touch($absoluteFile);
452 $this->testFilesToDelete[] = $absoluteFile;
453 $fixture->_set('localConfigurationFile', $file);
454
455 $fixture->createLocalConfigurationFromFactoryConfiguration();
456 }
457
458 /**
459 * @test
460 */
461 public function createLocalConfigurationFromFactoryConfigurationWritesContentFromFactoryFile() {
462 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
463 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('writeLocalConfiguration'));
464 $fixture->_set('localConfigurationFile', 'typo3temp/' . uniqid('dummy_'));
465
466 $factoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
467 $factoryConfigurationAbsoluteFile = PATH_site . $factoryConfigurationFile;
468 $uniqueContentString = uniqid('string_');
469 $validFactoryConfigurationFileContent =
470 '<?php' . LF .
471 'return array(' . LF .
472 $uniqueContentString . ' => foo,' . LF .
473 ');' . LF .
474 '?>';
475 file_put_contents(
476 $factoryConfigurationAbsoluteFile,
477 $validFactoryConfigurationFileContent
478 );
479 $this->testFilesToDelete[] = $factoryConfigurationAbsoluteFile;
480
481 $fixture->_set('factoryConfigurationFile', $factoryConfigurationFile);
482
483 $fixture
484 ->expects($this->once())
485 ->method('writeLocalConfiguration')
486 ->with($this->arrayHasKey($uniqueContentString));
487 $fixture->createLocalConfigurationFromFactoryConfiguration();
488 }
489
490 /**
491 * @test
492 */
493 public function createLocalConfigurationFromFactoryConfigurationMergesConfigurationWithAdditionalFactoryFile() {
494 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
495 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('writeLocalConfiguration'));
496 $fixture->_set('localConfigurationFile', 'typo3temp/' . uniqid('dummy_'));
497
498 $factoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
499 $factoryConfigurationAbsoluteFile = PATH_site . $factoryConfigurationFile;
500 $validFactoryConfigurationFileContent =
501 '<?php' . LF .
502 'return array();' . LF .
503 '?>';
504 file_put_contents(
505 $factoryConfigurationAbsoluteFile,
506 $validFactoryConfigurationFileContent
507 );
508 $this->testFilesToDelete[] = $factoryConfigurationAbsoluteFile;
509 $fixture->_set('factoryConfigurationFile', $factoryConfigurationFile);
510
511 $additionalFactoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
512 $additionalFactoryConfigurationAbsoluteFile = PATH_site . $additionalFactoryConfigurationFile;
513 $uniqueContentString = uniqid('string_');
514 $validAdditionalFactoryConfigurationFileContent =
515 '<?php' . LF .
516 'return array(' . LF .
517 $uniqueContentString . ' => foo,' . LF .
518 ');' . LF .
519 '?>';
520 file_put_contents(
521 $additionalFactoryConfigurationAbsoluteFile,
522 $validAdditionalFactoryConfigurationFileContent
523 );
524 $this->testFilesToDelete[] = $additionalFactoryConfigurationAbsoluteFile;
525 $fixture->_set('additionalFactoryConfigurationFile', $additionalFactoryConfigurationFile);
526
527 $fixture
528 ->expects($this->once())
529 ->method('writeLocalConfiguration')
530 ->with($this->arrayHasKey($uniqueContentString));
531 $fixture->createLocalConfigurationFromFactoryConfiguration();
532 }
533
534 /**
535 * @test
536 */
537 public function isValidLocalConfigurationPathAcceptsWhitelistedPath() {
538 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
539 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
540 $fixture->_set('whiteListedLocalConfigurationPaths', array('foo/bar'));
541 $this->assertTrue($fixture->_call('isValidLocalConfigurationPath', 'foo/bar/baz'));
542 }
543
544 /**
545 * @test
546 */
547 public function isValidLocalConfigurationPathDeniesNotWhitelistedPath() {
548 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
549 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
550 $fixture->_set('whiteListedLocalConfigurationPaths', array('foo/bar'));
551 $this->assertFalse($fixture->_call('isValidLocalConfigurationPath', 'bar/baz'));
552 }
553 }
554 ?>