3 // this is in the same namespace as Install for mocking 'function_exists'
4 namespace Friendica\Core;
6 use Friendica\Test\MockedTest;
7 use Friendica\Test\Util\L10nMockTrait;
8 use Friendica\Test\Util\VFSTrait;
11 * @runTestsInSeparateProcesses
12 * @preserveGlobalState disabled
14 class InstallerTest extends MockedTest
19 public function setUp()
27 * Mocking the L10n::t() calls for the function checks
29 private function mockFunctionL10TCalls()
31 $this->mockL10nT('Apache mod_rewrite module', 1);
32 $this->mockL10nT('PDO or MySQLi PHP module', 1);
33 $this->mockL10nT('libCurl PHP module', 1);
34 $this->mockL10nT('Error: libCURL PHP module required but not installed.', 1);
35 $this->mockL10nT('XML PHP module', 1);
36 $this->mockL10nT('GD graphics PHP module', 1);
37 $this->mockL10nT('Error: GD graphics PHP module with JPEG support required but not installed.', 1);
38 $this->mockL10nT('OpenSSL PHP module', 1);
39 $this->mockL10nT('Error: openssl PHP module required but not installed.', 1);
40 $this->mockL10nT('mb_string PHP module', 1);
41 $this->mockL10nT('Error: mb_string PHP module required but not installed.', 1);
42 $this->mockL10nT('iconv PHP module', 1);
43 $this->mockL10nT('Error: iconv PHP module required but not installed.', 1);
44 $this->mockL10nT('POSIX PHP module', 1);
45 $this->mockL10nT('Error: POSIX PHP module required but not installed.', 1);
48 private function assertCheckExist($position, $title, $help, $status, $required, $assertionArray)
50 $this->assertArraySubset([$position => [
53 'required' => $required,
60 * Replaces function_exists results with given mocks
62 * @param array $functions a list from function names and their result
64 private function setFunctions($functions)
67 $phpMock['function_exists'] = function($function) use ($functions) {
68 foreach ($functions as $name => $value) {
69 if ($function == $name) {
73 return '__phpunit_continue__';
78 * Replaces class_exist results with given mocks
80 * @param array $classes a list from class names and their results
82 private function setClasses($classes)
85 $phpMock['class_exists'] = function($class) use ($classes) {
86 foreach ($classes as $name => $value) {
87 if ($class == $name) {
91 return '__phpunit_continue__';
98 public function testCheckKeys()
100 $this->setFunctions(['openssl_pkey_new' => false]);
101 $install = new Installer();
102 $this->assertFalse($install->checkKeys());
104 $this->setFunctions(['openssl_pkey_new' => true]);
105 $install = new Installer();
106 $this->assertTrue($install->checkKeys());
112 public function testCheckFunctions()
114 $this->mockFunctionL10TCalls();
115 $this->setFunctions(['curl_init' => false, 'imagecreatefromjpeg' => true]);
116 $install = new Installer();
117 $this->assertFalse($install->checkFunctions());
118 $this->assertCheckExist(3,
119 'libCurl PHP module',
120 'Error: libCURL PHP module required but not installed.',
123 $install->getChecks());
125 $this->mockFunctionL10TCalls();
126 $this->setFunctions(['imagecreatefromjpeg' => false]);
127 $install = new Installer();
128 $this->assertFalse($install->checkFunctions());
129 $this->assertCheckExist(4,
130 'GD graphics PHP module',
131 'Error: GD graphics PHP module with JPEG support required but not installed.',
134 $install->getChecks());
136 $this->mockFunctionL10TCalls();
137 $this->setFunctions(['openssl_public_encrypt' => false]);
138 $install = new Installer();
139 $this->assertFalse($install->checkFunctions());
140 $this->assertCheckExist(5,
141 'OpenSSL PHP module',
142 'Error: openssl PHP module required but not installed.',
145 $install->getChecks());
147 $this->mockFunctionL10TCalls();
148 $this->setFunctions(['mb_strlen' => false]);
149 $install = new Installer();
150 $this->assertFalse($install->checkFunctions());
151 $this->assertCheckExist(6,
152 'mb_string PHP module',
153 'Error: mb_string PHP module required but not installed.',
156 $install->getChecks());
158 $this->mockFunctionL10TCalls();
159 $this->setFunctions(['iconv_strlen' => false]);
160 $install = new Installer();
161 $this->assertFalse($install->checkFunctions());
162 $this->assertCheckExist(7,
164 'Error: iconv PHP module required but not installed.',
167 $install->getChecks());
169 $this->mockFunctionL10TCalls();
170 $this->setFunctions(['posix_kill' => false]);
171 $install = new Installer();
172 $this->assertFalse($install->checkFunctions());
173 $this->assertCheckExist(8,
175 'Error: POSIX PHP module required but not installed.',
178 $install->getChecks());
180 $this->mockFunctionL10TCalls();
181 $this->setFunctions(['json_encode' => false]);
182 $install = new Installer();
183 $this->assertFalse($install->checkFunctions());
184 $this->assertCheckExist(9,
186 'Error: JSON PHP module required but not installed.',
189 $install->getChecks());
191 $this->mockFunctionL10TCalls();
192 $this->setFunctions([
194 'imagecreatefromjpeg' => true,
195 'openssl_public_encrypt' => true,
197 'iconv_strlen' => true,
198 'posix_kill' => true,
199 'json_encode' => true
201 $install = new Installer();
202 $this->assertTrue($install->checkFunctions());
208 public function testCheckLocalIni()
210 $this->assertTrue($this->root->hasChild('config/local.config.php'));
212 $install = new Installer();
213 $this->assertTrue($install->checkLocalIni());
215 $this->delConfigFile('local.config.php');
217 $this->assertFalse($this->root->hasChild('config/local.config.php'));
219 $install = new Installer();
220 $this->assertTrue($install->checkLocalIni());
226 public function testCheckHtAccessFail()
228 // Mocking the CURL Response
229 $curlResult = \Mockery::mock('Friendica\Network\CurlResult');
231 ->shouldReceive('getReturnCode')
234 ->shouldReceive('getRedirectUrl')
237 ->shouldReceive('getError')
238 ->andReturn('test Error');
240 // Mocking the CURL Request
241 $networkMock = \Mockery::mock('alias:Friendica\Util\Network');
243 ->shouldReceive('fetchUrlFull')
244 ->with('https://test/install/testrewrite')
245 ->andReturn($curlResult);
247 ->shouldReceive('fetchUrlFull')
248 ->with('http://test/install/testrewrite')
249 ->andReturn($curlResult);
251 // Mocking that we can use CURL
252 $this->setFunctions(['curl_init' => true]);
254 // needed because of "normalise_link"
255 require_once __DIR__ . '/../../../include/text.php';
257 $install = new Installer();
259 $this->assertFalse($install->checkHtAccess('https://test'));
260 $this->assertSame('test Error', $install->getChecks()[0]['error_msg']['msg']);
266 public function testCheckHtAccessWork()
268 // Mocking the failed CURL Response
269 $curlResultF = \Mockery::mock('Friendica\Network\CurlResult');
271 ->shouldReceive('getReturnCode')
274 // Mocking the working CURL Response
275 $curlResultW = \Mockery::mock('Friendica\Network\CurlResult');
277 ->shouldReceive('getReturnCode')
280 // Mocking the CURL Request
281 $networkMock = \Mockery::mock('alias:Friendica\Util\Network');
283 ->shouldReceive('fetchUrlFull')
284 ->with('https://test/install/testrewrite')
285 ->andReturn($curlResultF);
287 ->shouldReceive('fetchUrlFull')
288 ->with('http://test/install/testrewrite')
289 ->andReturn($curlResultW);
291 // Mocking that we can use CURL
292 $this->setFunctions(['curl_init' => true]);
294 // needed because of "normalise_link"
295 require_once __DIR__ . '/../../../include/text.php';
297 $install = new Installer();
299 $this->assertTrue($install->checkHtAccess('https://test'));
305 public function testImagick()
307 $imageMock = \Mockery::mock('alias:Friendica\Object\Image');
309 ->shouldReceive('supportedTypes')
310 ->andReturn(['image/gif' => 'gif']);
312 $this->setClasses(['Imagick' => true]);
314 $install = new Installer();
316 // even there is no supported type, Imagick should return true (because it is not required)
317 $this->assertTrue($install->checkImagick());
319 $this->assertCheckExist(1,
320 L10n::t('ImageMagick supports GIF'),
324 $install->getChecks());
330 public function testImagickNotFound()
332 $imageMock = \Mockery::mock('alias:Friendica\Object\Image');
334 ->shouldReceive('supportedTypes')
337 $this->setClasses(['Imagick' => true]);
339 $install = new Installer();
341 // even there is no supported type, Imagick should return true (because it is not required)
342 $this->assertTrue($install->checkImagick());
343 $this->assertCheckExist(1,
344 L10n::t('ImageMagick supports GIF'),
348 $install->getChecks());
351 public function testImagickNotInstalled()
353 $this->setClasses(['Imagick' => false]);
354 $this->mockL10nT('ImageMagick PHP extension is not installed');
356 $install = new Installer();
358 // even there is no supported type, Imagick should return true (because it is not required)
359 $this->assertTrue($install->checkImagick());
360 $this->assertCheckExist(0,
361 'ImageMagick PHP extension is not installed',
365 $install->getChecks());
370 * A workaround to replace the PHP native function_exists with a mocked function
372 * @param string $function_name the Name of the function
374 * @return bool true or false
376 function function_exists($function_name)
379 if (isset($phpMock['function_exists'])) {
380 $result = call_user_func_array($phpMock['function_exists'], func_get_args());
381 if ($result !== '__phpunit_continue__') {
385 return call_user_func_array('\function_exists', func_get_args());
388 function class_exists($class_name)
391 if (isset($phpMock['class_exists'])) {
392 $result = call_user_func_array($phpMock['class_exists'], func_get_args());
393 if ($result !== '__phpunit_continue__') {
397 return call_user_func_array('\class_exists', func_get_args());