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);
46 $this->mockL10nT('JSON PHP module', 1);
47 $this->mockL10nT('Error: JSON PHP module required but not installed.', 1);
50 private function assertCheckExist($position, $title, $help, $status, $required, $assertionArray)
52 $this->assertArraySubset([$position => [
55 'required' => $required,
62 * Replaces function_exists results with given mocks
64 * @param array $functions a list from function names and their result
66 private function setFunctions($functions)
69 $phpMock['function_exists'] = function($function) use ($functions) {
70 foreach ($functions as $name => $value) {
71 if ($function == $name) {
75 return '__phpunit_continue__';
80 * Replaces class_exist results with given mocks
82 * @param array $classes a list from class names and their results
84 private function setClasses($classes)
87 $phpMock['class_exists'] = function($class) use ($classes) {
88 foreach ($classes as $name => $value) {
89 if ($class == $name) {
93 return '__phpunit_continue__';
100 public function testCheckKeys()
104 $this->setFunctions(['openssl_pkey_new' => false]);
105 $install = new Installer();
106 $this->assertFalse($install->checkKeys());
108 $this->setFunctions(['openssl_pkey_new' => true]);
109 $install = new Installer();
110 $this->assertTrue($install->checkKeys());
116 public function testCheckFunctions()
118 $this->mockFunctionL10TCalls();
119 $this->setFunctions(['curl_init' => false, 'imagecreatefromjpeg' => true]);
120 $install = new Installer();
121 $this->assertFalse($install->checkFunctions());
122 $this->assertCheckExist(3,
123 'libCurl PHP module',
124 'Error: libCURL PHP module required but not installed.',
127 $install->getChecks());
129 $this->mockFunctionL10TCalls();
130 $this->setFunctions(['imagecreatefromjpeg' => false]);
131 $install = new Installer();
132 $this->assertFalse($install->checkFunctions());
133 $this->assertCheckExist(4,
134 'GD graphics PHP module',
135 'Error: GD graphics PHP module with JPEG support required but not installed.',
138 $install->getChecks());
140 $this->mockFunctionL10TCalls();
141 $this->setFunctions(['openssl_public_encrypt' => false]);
142 $install = new Installer();
143 $this->assertFalse($install->checkFunctions());
144 $this->assertCheckExist(5,
145 'OpenSSL PHP module',
146 'Error: openssl PHP module required but not installed.',
149 $install->getChecks());
151 $this->mockFunctionL10TCalls();
152 $this->setFunctions(['mb_strlen' => false]);
153 $install = new Installer();
154 $this->assertFalse($install->checkFunctions());
155 $this->assertCheckExist(6,
156 'mb_string PHP module',
157 'Error: mb_string PHP module required but not installed.',
160 $install->getChecks());
162 $this->mockFunctionL10TCalls();
163 $this->setFunctions(['iconv_strlen' => false]);
164 $install = new Installer();
165 $this->assertFalse($install->checkFunctions());
166 $this->assertCheckExist(7,
168 'Error: iconv PHP module required but not installed.',
171 $install->getChecks());
173 $this->mockFunctionL10TCalls();
174 $this->setFunctions(['posix_kill' => false]);
175 $install = new Installer();
176 $this->assertFalse($install->checkFunctions());
177 $this->assertCheckExist(8,
179 'Error: POSIX PHP module required but not installed.',
182 $install->getChecks());
184 $this->mockFunctionL10TCalls();
185 $this->setFunctions(['json_encode' => false]);
186 $install = new Installer();
187 $this->assertFalse($install->checkFunctions());
188 $this->assertCheckExist(9,
190 'Error: JSON PHP module required but not installed.',
193 $install->getChecks());
195 $this->mockFunctionL10TCalls();
196 $this->setFunctions([
198 'imagecreatefromjpeg' => true,
199 'openssl_public_encrypt' => true,
201 'iconv_strlen' => true,
202 'posix_kill' => true,
203 'json_encode' => true
205 $install = new Installer();
206 $this->assertTrue($install->checkFunctions());
212 public function testCheckLocalIni()
216 $this->assertTrue($this->root->hasChild('config/local.config.php'));
218 $install = new Installer();
219 $this->assertTrue($install->checkLocalIni());
221 $this->delConfigFile('local.config.php');
223 $this->assertFalse($this->root->hasChild('config/local.config.php'));
225 $install = new Installer();
226 $this->assertTrue($install->checkLocalIni());
232 public function testCheckHtAccessFail()
236 // Mocking the CURL Response
237 $curlResult = \Mockery::mock('Friendica\Network\CurlResult');
239 ->shouldReceive('getReturnCode')
242 ->shouldReceive('getRedirectUrl')
245 ->shouldReceive('getError')
246 ->andReturn('test Error');
248 // Mocking the CURL Request
249 $networkMock = \Mockery::mock('alias:Friendica\Util\Network');
251 ->shouldReceive('fetchUrlFull')
252 ->with('https://test/install/testrewrite')
253 ->andReturn($curlResult);
255 ->shouldReceive('fetchUrlFull')
256 ->with('http://test/install/testrewrite')
257 ->andReturn($curlResult);
259 // Mocking that we can use CURL
260 $this->setFunctions(['curl_init' => true]);
262 $install = new Installer();
264 $this->assertFalse($install->checkHtAccess('https://test'));
265 $this->assertSame('test Error', $install->getChecks()[0]['error_msg']['msg']);
271 public function testCheckHtAccessWork()
275 // Mocking the failed CURL Response
276 $curlResultF = \Mockery::mock('Friendica\Network\CurlResult');
278 ->shouldReceive('getReturnCode')
281 // Mocking the working CURL Response
282 $curlResultW = \Mockery::mock('Friendica\Network\CurlResult');
284 ->shouldReceive('getReturnCode')
287 // Mocking the CURL Request
288 $networkMock = \Mockery::mock('alias:Friendica\Util\Network');
290 ->shouldReceive('fetchUrlFull')
291 ->with('https://test/install/testrewrite')
292 ->andReturn($curlResultF);
294 ->shouldReceive('fetchUrlFull')
295 ->with('http://test/install/testrewrite')
296 ->andReturn($curlResultW);
298 // Mocking that we can use CURL
299 $this->setFunctions(['curl_init' => true]);
301 // needed because of "normalise_link"
302 require_once __DIR__ . '/../../../include/text.php';
304 $install = new Installer();
306 $this->assertTrue($install->checkHtAccess('https://test'));
312 public function testImagick()
316 $imageMock = \Mockery::mock('alias:Friendica\Object\Image');
318 ->shouldReceive('supportedTypes')
319 ->andReturn(['image/gif' => 'gif']);
321 $this->setClasses(['Imagick' => true]);
323 $install = new Installer();
325 // even there is no supported type, Imagick should return true (because it is not required)
326 $this->assertTrue($install->checkImagick());
328 $this->assertCheckExist(1,
329 L10n::t('ImageMagick supports GIF'),
333 $install->getChecks());
339 public function testImagickNotFound()
343 $imageMock = \Mockery::mock('alias:Friendica\Object\Image');
345 ->shouldReceive('supportedTypes')
348 $this->setClasses(['Imagick' => true]);
350 $install = new Installer();
352 // even there is no supported type, Imagick should return true (because it is not required)
353 $this->assertTrue($install->checkImagick());
354 $this->assertCheckExist(1,
355 L10n::t('ImageMagick supports GIF'),
359 $install->getChecks());
362 public function testImagickNotInstalled()
364 $this->setClasses(['Imagick' => false]);
365 $this->mockL10nT('ImageMagick PHP extension is not installed');
367 $install = new Installer();
369 // even there is no supported type, Imagick should return true (because it is not required)
370 $this->assertTrue($install->checkImagick());
371 $this->assertCheckExist(0,
372 'ImageMagick PHP extension is not installed',
376 $install->getChecks());
381 * A workaround to replace the PHP native function_exists with a mocked function
383 * @param string $function_name the Name of the function
385 * @return bool true or false
387 function function_exists($function_name)
390 if (isset($phpMock['function_exists'])) {
391 $result = call_user_func_array($phpMock['function_exists'], func_get_args());
392 if ($result !== '__phpunit_continue__') {
396 return call_user_func_array('\function_exists', func_get_args());
399 function class_exists($class_name)
402 if (isset($phpMock['class_exists'])) {
403 $result = call_user_func_array($phpMock['class_exists'], func_get_args());
404 if ($result !== '__phpunit_continue__') {
408 return call_user_func_array('\class_exists', func_get_args());