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