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