e2ce1558519e8f4ce603965d39fd8fee1846c356
[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 (function_exists('posix_getegid') && posix_getegid() === 0) {
299 $this->markTestSkipped('Test skipped if run on linux as root');
300 } elseif (TYPO3_OS == 'WIN') {
301 $this->markTestSkipped('Not available on Windows');
302 }
303 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
304 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
305
306 $directory = 'typo3temp/' . uniqid('test_');
307 $absoluteDirectory = PATH_site . $directory;
308 mkdir($absoluteDirectory);
309 chmod($absoluteDirectory, 0544);
310 clearstatcache();
311
312 $fixture->_set('pathTypo3Conf', $directory);
313
314 $result = $fixture->canWriteConfiguration();
315
316 chmod($absoluteDirectory, 0755);
317 rmdir($absoluteDirectory);
318
319 $this->assertFalse($result);
320 }
321
322 /**
323 * @test
324 */
325 public function canWriteConfigurationReturnsFalseIfLocalConfigurationFileIsNotWritable() {
326 if (function_exists('posix_getegid') && posix_getegid() === 0) {
327 $this->markTestSkipped('Test skipped if run on linux as root');
328 } elseif (TYPO3_OS == 'WIN') {
329 $this->markTestSkipped('Not available on Windows');
330 }
331 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
332 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
333
334 $file = 'typo3temp/' . uniqid('test_');
335 $absoluteFile = PATH_site . $file;
336 touch($absoluteFile);
337 $this->testFilesToDelete[] = $absoluteFile;
338 chmod($absoluteFile, 0444);
339 clearstatcache();
340
341 $fixture->_set('localConfigurationFile', $file);
342
343 $result = $fixture->canWriteConfiguration();
344
345 chmod($absoluteFile, 0644);
346
347 $this->assertFalse($result);
348 }
349
350 /**
351 * @test
352 */
353 public function canWriteConfigurationReturnsFalseIfLocalconfFileIsNotWritable() {
354 if (function_exists('posix_getegid') && posix_getegid() === 0) {
355 $this->markTestSkipped('Test skipped if run on linux as root');
356 } elseif (TYPO3_OS == 'WIN') {
357 $this->markTestSkipped('Not available on Windows');
358 }
359 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
360 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
361
362 $file = 'typo3temp/' . uniqid('test_');
363 $absoluteFile = PATH_site . $file;
364 touch($absoluteFile);
365 $this->testFilesToDelete[] = $absoluteFile;
366 chmod($absoluteFile, 0444);
367 clearstatcache();
368
369 $fixture->_set('localconfFile', $file);
370
371 $result = $fixture->canWriteConfiguration();
372
373 chmod($absoluteFile, 0644);
374
375 $this->assertFalse($result);
376 }
377
378 /**
379 * @test
380 */
381 public function canWriteConfigurationReturnsTrueIfDirectoryAndFilesAreWritable() {
382 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
383 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
384
385 $directory = 'typo3temp/' . uniqid('test_');
386 $absoluteDirectory = PATH_site . $directory;
387 mkdir($absoluteDirectory);
388 $fixture->_set('pathTypo3Conf', $directory);
389
390 $file1 = 'typo3temp/' . uniqid('test_');
391 $absoluteFile1 = PATH_site . $file1;
392 touch($absoluteFile1);
393 $this->testFilesToDelete[] = $absoluteFile1;
394 $fixture->_set('localConfigurationFile', $file1);
395
396 $file2 = 'typo3temp/' . uniqid('test_');
397 $absoluteFile2 = PATH_site . $file2;
398 touch($absoluteFile2);
399 $this->testFilesToDelete[] = $absoluteFile2;
400 $fixture->_set('localconfFile', $file2);
401
402 clearstatcache();
403
404 $result = $fixture->canWriteConfiguration();
405
406 $this->assertTrue($result);
407 }
408
409 /**
410 * @test
411 */
412 public function writeLocalConfigurationWritesSortedContentToConfigurationFile() {
413 $configurationFile = PATH_site . 'typo3temp/' . uniqid('localConfiguration');
414 if (!is_file($configurationFile)) {
415 if (!$fh = fopen($configurationFile, 'wb')) {
416 $this->markTestSkipped('Can not create file ' . $configurationFile . '. Please check your write permissions.');
417 }
418 fclose($fh);
419 }
420
421 if (!@is_file($configurationFile)) {
422 throw new \RuntimeException('File ' . $configurationFile . ' could not be found. Please check your write permissions', 1346364362);
423 }
424 $this->testFilesToDelete[] = $configurationFile;
425
426 $this->fixture
427 ->expects($this->any())
428 ->method('getLocalConfigurationFileLocation')
429 ->will($this->returnValue($configurationFile));
430
431 $pairs = array(
432 'foo' => 42,
433 'bar' => 23
434 );
435 $expectedContent =
436 '<?php' . LF .
437 'return array(' . LF .
438 TAB . '\'bar\' => 23,' . LF .
439 TAB . '\'foo\' => 42,' . LF .
440 ');' . LF .
441 '?>';
442
443 $this->fixture->writeLocalConfiguration($pairs);
444 $this->assertSame($expectedContent, file_get_contents($configurationFile));
445 }
446
447 /**
448 * @test
449 * @expectedException \RuntimeException
450 */
451 public function createLocalConfigurationFromFactoryConfigurationThrowsExceptionIfFileExists() {
452 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
453 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
454
455 $file = 'typo3temp/' . uniqid('test_');
456 $absoluteFile = PATH_site . $file;
457 touch($absoluteFile);
458 $this->testFilesToDelete[] = $absoluteFile;
459 $fixture->_set('localConfigurationFile', $file);
460
461 $fixture->createLocalConfigurationFromFactoryConfiguration();
462 }
463
464 /**
465 * @test
466 */
467 public function createLocalConfigurationFromFactoryConfigurationWritesContentFromFactoryFile() {
468 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
469 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('writeLocalConfiguration'));
470 $fixture->_set('localConfigurationFile', 'typo3temp/' . uniqid('dummy_'));
471
472 $factoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
473 $factoryConfigurationAbsoluteFile = PATH_site . $factoryConfigurationFile;
474 $uniqueContentString = uniqid('string_');
475 $validFactoryConfigurationFileContent =
476 '<?php' . LF .
477 'return array(' . LF .
478 $uniqueContentString . ' => foo,' . LF .
479 ');' . LF .
480 '?>';
481 file_put_contents(
482 $factoryConfigurationAbsoluteFile,
483 $validFactoryConfigurationFileContent
484 );
485 $this->testFilesToDelete[] = $factoryConfigurationAbsoluteFile;
486
487 $fixture->_set('factoryConfigurationFile', $factoryConfigurationFile);
488
489 $fixture
490 ->expects($this->once())
491 ->method('writeLocalConfiguration')
492 ->with($this->arrayHasKey($uniqueContentString));
493 $fixture->createLocalConfigurationFromFactoryConfiguration();
494 }
495
496 /**
497 * @test
498 */
499 public function createLocalConfigurationFromFactoryConfigurationMergesConfigurationWithAdditionalFactoryFile() {
500 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
501 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('writeLocalConfiguration'));
502 $fixture->_set('localConfigurationFile', 'typo3temp/' . uniqid('dummy_'));
503
504 $factoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
505 $factoryConfigurationAbsoluteFile = PATH_site . $factoryConfigurationFile;
506 $validFactoryConfigurationFileContent =
507 '<?php' . LF .
508 'return array();' . LF .
509 '?>';
510 file_put_contents(
511 $factoryConfigurationAbsoluteFile,
512 $validFactoryConfigurationFileContent
513 );
514 $this->testFilesToDelete[] = $factoryConfigurationAbsoluteFile;
515 $fixture->_set('factoryConfigurationFile', $factoryConfigurationFile);
516
517 $additionalFactoryConfigurationFile = 'typo3temp/' . uniqid('test_') . '.php';
518 $additionalFactoryConfigurationAbsoluteFile = PATH_site . $additionalFactoryConfigurationFile;
519 $uniqueContentString = uniqid('string_');
520 $validAdditionalFactoryConfigurationFileContent =
521 '<?php' . LF .
522 'return array(' . LF .
523 $uniqueContentString . ' => foo,' . LF .
524 ');' . LF .
525 '?>';
526 file_put_contents(
527 $additionalFactoryConfigurationAbsoluteFile,
528 $validAdditionalFactoryConfigurationFileContent
529 );
530 $this->testFilesToDelete[] = $additionalFactoryConfigurationAbsoluteFile;
531 $fixture->_set('additionalFactoryConfigurationFile', $additionalFactoryConfigurationFile);
532
533 $fixture
534 ->expects($this->once())
535 ->method('writeLocalConfiguration')
536 ->with($this->arrayHasKey($uniqueContentString));
537 $fixture->createLocalConfigurationFromFactoryConfiguration();
538 }
539
540 /**
541 * @test
542 */
543 public function isValidLocalConfigurationPathAcceptsWhitelistedPath() {
544 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
545 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
546 $fixture->_set('whiteListedLocalConfigurationPaths', array('foo/bar'));
547 $this->assertTrue($fixture->_call('isValidLocalConfigurationPath', 'foo/bar/baz'));
548 }
549
550 /**
551 * @test
552 */
553 public function isValidLocalConfigurationPathDeniesNotWhitelistedPath() {
554 /** @var $fixture \TYPO3\CMS\Core\Configuration\ConfigurationManager|\PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface */
555 $fixture = $this->getAccessibleMock('TYPO3\\CMS\\Core\\Configuration\\ConfigurationManager', array('dummy'));
556 $fixture->_set('whiteListedLocalConfigurationPaths', array('foo/bar'));
557 $this->assertFalse($fixture->_call('isValidLocalConfigurationPath', 'bar/baz'));
558 }
559 }
560 ?>