]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/InstallerTest.php
2f9ad1646cae7c61bb8116a5e75ae3d05a02c9d1
[friendica.git] / tests / src / Core / InstallerTest.php
1 <?php
2
3 // this is in the same namespace as Install for mocking 'function_exists'
4 namespace Friendica\Core;
5
6 use Friendica\Test\MockedTest;
7 use Friendica\Test\Util\L10nMockTrait;
8 use Friendica\Test\Util\VFSTrait;
9
10 /**
11  * @runTestsInSeparateProcesses
12  * @preserveGlobalState disabled
13  */
14 class InstallerTest extends MockedTest
15 {
16         use VFSTrait;
17         use L10nMockTrait;
18
19         public function setUp()
20         {
21                 parent::setUp();
22
23                 $this->setUpVfsDir();
24         }
25
26         /**
27          * Mocking the L10n::t() calls for the function checks
28          */
29         private function mockFunctionL10TCalls()
30         {
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         }
47
48         private function assertCheckExist($position, $title, $help, $status, $required, $assertionArray)
49         {
50                 $this->assertArraySubset([$position => [
51                         'title' => $title,
52                         'status' => $status,
53                         'required' => $required,
54                         'error_msg' => null,
55                         'help' => $help]
56                 ], $assertionArray);
57         }
58
59         /**
60          * Replaces function_exists results with given mocks
61          *
62          * @param array $functions a list from function names and their result
63          */
64         private function setFunctions($functions)
65         {
66                 global $phpMock;
67                 $phpMock['function_exists'] = function($function) use ($functions) {
68                         foreach ($functions as $name => $value) {
69                                 if ($function == $name) {
70                                         return $value;
71                                 }
72                         }
73                         return '__phpunit_continue__';
74                 };
75         }
76
77         /**
78          * Replaces class_exist results with given mocks
79          *
80          * @param array $classes a list from class names and their results
81          */
82         private function setClasses($classes)
83         {
84                 global $phpMock;
85                 $phpMock['class_exists'] = function($class) use ($classes) {
86                         foreach ($classes as $name => $value) {
87                                 if ($class == $name) {
88                                         return $value;
89                                 }
90                         }
91                         return '__phpunit_continue__';
92                 };
93         }
94
95         /**
96          * @small
97          */
98         public function testCheckKeys()
99         {
100                 $this->setFunctions(['openssl_pkey_new' => false]);
101                 $install = new Installer();
102                 $this->assertFalse($install->checkKeys());
103
104                 $this->setFunctions(['openssl_pkey_new' => true]);
105                 $install = new Installer();
106                 $this->assertTrue($install->checkKeys());
107         }
108
109         /**
110          * @small
111          */
112         public function testCheckFunctions()
113         {
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.',
121                         false,
122                         true,
123                         $install->getChecks());
124
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.',
132                         false,
133                         true,
134                         $install->getChecks());
135
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.',
143                         false,
144                         true,
145                         $install->getChecks());
146
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.',
154                         false,
155                         true,
156                         $install->getChecks());
157
158                 $this->mockFunctionL10TCalls();
159                 $this->setFunctions(['iconv_strlen' => false]);
160                 $install = new Installer();
161                 $this->assertFalse($install->checkFunctions());
162                 $this->assertCheckExist(7,
163                         'iconv PHP module',
164                         'Error: iconv PHP module required but not installed.',
165                         false,
166                         true,
167                         $install->getChecks());
168
169                 $this->mockFunctionL10TCalls();
170                 $this->setFunctions(['posix_kill' => false]);
171                 $install = new Installer();
172                 $this->assertFalse($install->checkFunctions());
173                 $this->assertCheckExist(8,
174                         'POSIX PHP module',
175                         'Error: POSIX PHP module required but not installed.',
176                         false,
177                         true,
178                         $install->getChecks());
179
180                 $this->mockFunctionL10TCalls();
181                 $this->setFunctions(['json_encode' => false]);
182                 $install = new Installer();
183                 $this->assertFalse($install->checkFunctions());
184                 $this->assertCheckExist(9,
185                         'JSON PHP module',
186                         'Error: JSON PHP module required but not installed.',
187                         false,
188                         true,
189                         $install->getChecks());
190
191                 $this->mockFunctionL10TCalls();
192                 $this->setFunctions([
193                         'curl_init' => true,
194                         'imagecreatefromjpeg' => true,
195                         'openssl_public_encrypt' => true,
196                         'mb_strlen' => true,
197                         'iconv_strlen' => true,
198                         'posix_kill' => true,
199                         'json_encode' => true
200                 ]);
201                 $install = new Installer();
202                 $this->assertTrue($install->checkFunctions());
203         }
204
205         /**
206          * @small
207          */
208         public function testCheckLocalIni()
209         {
210                 $this->assertTrue($this->root->hasChild('config/local.config.php'));
211
212                 $install = new Installer();
213                 $this->assertTrue($install->checkLocalIni());
214
215                 $this->delConfigFile('local.config.php');
216
217                 $this->assertFalse($this->root->hasChild('config/local.config.php'));
218
219                 $install = new Installer();
220                 $this->assertTrue($install->checkLocalIni());
221         }
222
223         /**
224          * @small
225          */
226         public function testCheckHtAccessFail()
227         {
228                 // Mocking the CURL Response
229                 $curlResult = \Mockery::mock('Friendica\Network\CurlResult');
230                 $curlResult
231                         ->shouldReceive('getReturnCode')
232                         ->andReturn('404');
233                 $curlResult
234                         ->shouldReceive('getRedirectUrl')
235                         ->andReturn('');
236                 $curlResult
237                         ->shouldReceive('getError')
238                         ->andReturn('test Error');
239
240                 // Mocking the CURL Request
241                 $networkMock = \Mockery::mock('alias:Friendica\Util\Network');
242                 $networkMock
243                         ->shouldReceive('fetchUrlFull')
244                         ->with('https://test/install/testrewrite')
245                         ->andReturn($curlResult);
246                 $networkMock
247                         ->shouldReceive('fetchUrlFull')
248                         ->with('http://test/install/testrewrite')
249                         ->andReturn($curlResult);
250
251                 // Mocking that we can use CURL
252                 $this->setFunctions(['curl_init' => true]);
253
254                 // needed because of "normalise_link"
255                 require_once __DIR__ . '/../../../include/text.php';
256
257                 $install = new Installer();
258
259                 $this->assertFalse($install->checkHtAccess('https://test'));
260                 $this->assertSame('test Error', $install->getChecks()[0]['error_msg']['msg']);
261         }
262
263         /**
264          * @small
265          */
266         public function testCheckHtAccessWork()
267         {
268                 // Mocking the failed CURL Response
269                 $curlResultF = \Mockery::mock('Friendica\Network\CurlResult');
270                 $curlResultF
271                         ->shouldReceive('getReturnCode')
272                         ->andReturn('404');
273
274                 // Mocking the working CURL Response
275                 $curlResultW = \Mockery::mock('Friendica\Network\CurlResult');
276                 $curlResultW
277                         ->shouldReceive('getReturnCode')
278                         ->andReturn('204');
279
280                 // Mocking the CURL Request
281                 $networkMock = \Mockery::mock('alias:Friendica\Util\Network');
282                 $networkMock
283                         ->shouldReceive('fetchUrlFull')
284                         ->with('https://test/install/testrewrite')
285                         ->andReturn($curlResultF);
286                 $networkMock
287                         ->shouldReceive('fetchUrlFull')
288                         ->with('http://test/install/testrewrite')
289                         ->andReturn($curlResultW);
290
291                 // Mocking that we can use CURL
292                 $this->setFunctions(['curl_init' => true]);
293
294                 // needed because of "normalise_link"
295                 require_once __DIR__ . '/../../../include/text.php';
296
297                 $install = new Installer();
298
299                 $this->assertTrue($install->checkHtAccess('https://test'));
300         }
301
302         /**
303          * @small
304          */
305         public function testImagick()
306         {
307                 $imageMock = \Mockery::mock('alias:Friendica\Object\Image');
308                 $imageMock
309                         ->shouldReceive('supportedTypes')
310                         ->andReturn(['image/gif' => 'gif']);
311
312                 $this->setClasses(['Imagick' => true]);
313
314                 $install = new Installer();
315
316                 // even there is no supported type, Imagick should return true (because it is not required)
317                 $this->assertTrue($install->checkImagick());
318
319                 $this->assertCheckExist(1,
320                         L10n::t('ImageMagick supports GIF'),
321                         '',
322                         true,
323                         false,
324                         $install->getChecks());
325         }
326
327         /**
328          * @small
329          */
330         public function testImagickNotFound()
331         {
332                 $imageMock = \Mockery::mock('alias:Friendica\Object\Image');
333                 $imageMock
334                         ->shouldReceive('supportedTypes')
335                         ->andReturn([]);
336
337                 $this->setClasses(['Imagick' => true]);
338
339                 $install = new Installer();
340
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'),
345                         '',
346                         false,
347                         false,
348                         $install->getChecks());
349         }
350
351         public function testImagickNotInstalled()
352         {
353                 $this->setClasses(['Imagick' => false]);
354                 $this->mockL10nT('ImageMagick PHP extension is not installed');
355
356                 $install = new Installer();
357
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',
362                         '',
363                         false,
364                         false,
365                         $install->getChecks());
366         }
367 }
368
369 /**
370  * A workaround to replace the PHP native function_exists with a mocked function
371  *
372  * @param string $function_name the Name of the function
373  *
374  * @return bool true or false
375  */
376 function function_exists($function_name)
377 {
378         global $phpMock;
379         if (isset($phpMock['function_exists'])) {
380                 $result = call_user_func_array($phpMock['function_exists'], func_get_args());
381                 if ($result !== '__phpunit_continue__') {
382                         return $result;
383                 }
384         }
385         return call_user_func_array('\function_exists', func_get_args());
386 }
387
388 function class_exists($class_name)
389 {
390         global $phpMock;
391         if (isset($phpMock['class_exists'])) {
392                 $result = call_user_func_array($phpMock['class_exists'], func_get_args());
393                 if ($result !== '__phpunit_continue__') {
394                         return $result;
395                 }
396         }
397         return call_user_func_array('\class_exists', func_get_args());
398 }