]> git.mxchange.org Git - friendica.git/blob - tests/src/Core/Console/AutomaticInstallationConsoleTest.php
Fixing some AutomaticInstallationConsoleTests
[friendica.git] / tests / src / Core / Console / AutomaticInstallationConsoleTest.php
1 <?php
2
3 namespace Friendica\Test\src\Core\Console;
4
5 use Friendica\Core\Config\Cache\ConfigCache;
6 use Friendica\Core\Console\AutomaticInstallation;
7 use Friendica\Core\Logger;
8 use Friendica\Test\Util\DBAMockTrait;
9 use Friendica\Test\Util\DBStructureMockTrait;
10 use Friendica\Test\Util\L10nMockTrait;
11 use Friendica\Test\Util\RendererMockTrait;
12 use Friendica\Util\Logger\VoidLogger;
13 use org\bovigo\vfs\vfsStream;
14 use org\bovigo\vfs\vfsStreamFile;
15
16 /**
17  * @runTestsInSeparateProcesses
18  * @preserveGlobalState disabled
19  * @requires PHP 7.0
20  */
21 class AutomaticInstallationConsoleTest extends ConsoleTest
22 {
23         use L10nMockTrait;
24         use DBAMockTrait;
25         use DBStructureMockTrait;
26         use RendererMockTrait;
27
28         private $db_host;
29         private $db_port;
30         private $db_data;
31         private $db_user;
32         private $db_pass;
33
34         /**
35          * @var vfsStreamFile Assert file without DB credentials
36          */
37         private $assertFile;
38         /**
39          * @var vfsStreamFile Assert file with DB credentials
40          */
41         private $assertFileDb;
42
43         public function setUp()
44         {
45                 parent::setUp();
46
47                 if ($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php')) {
48                         $this->root->getChild('config')
49                                 ->removeChild('local.config.php');
50                 }
51
52                 $this->db_host = getenv('MYSQL_HOST');
53                 $this->db_port = !empty(getenv('MYSQL_PORT')) ? getenv('MYSQL_PORT') : null;
54                 $this->db_data = getenv('MYSQL_DATABASE');
55                 $this->db_user = getenv('MYSQL_USERNAME') . getenv('MYSQL_USER');
56                 $this->db_pass = getenv('MYSQL_PASSWORD');
57
58                 $this->mockL10nT();
59         }
60
61         /**
62          * Creates the arguments which is asserted to be passed to 'replaceMacros()' for creating the local.config.php
63          *
64          * @param ConfigCache $config The config cache of this test
65          *
66          * @return array The arguments to pass to the mock for 'replaceMacros()'
67          */
68         private function createArgumentsForMacro(ConfigCache $config)
69         {
70                 $args = [
71                         '$dbhost' => $config->get('database','hostname'),
72                         '$dbuser' => $config->get('database','username'),
73                         '$dbpass' => $config->get('database','password'),
74                         '$dbdata' => $config->get('database','database'),
75
76                         '$phpath' => $config->get('config','php_path'),
77                         '$adminmail' => $config->get('config','admin_email'),
78                         '$hostname' => $config->get('config','hostname'),
79
80                         '$urlpath' => $config->get('system','urlpath'),
81                         '$baseurl' => $config->get('system','url'),
82                         '$sslpolicy' => $config->get('system','ssl_policy'),
83                         '$timezone' => $config->get('system','default_timezone'),
84                         '$language' => $config->get('system','language'),
85                         '$basepath' => $config->get('system','basepath'),
86                 ];
87
88                 return $args;
89         }
90
91         private function assertFinished($txt, $withconfig = false, $copyfile = false)
92         {
93                 $cfg = '';
94
95                 if ($withconfig) {
96                         $cfg = <<<CFG
97
98
99 Creating config file...
100
101  Complete!
102 CFG;
103                 }
104
105                 if ($copyfile) {
106                         $cfg = <<<CFG
107
108
109 Copying config file...
110
111  Complete!
112 CFG;
113                 }
114
115                 $finished = <<<FIN
116 Initializing setup...
117
118  Complete!
119
120
121 Checking environment...
122
123  NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
124
125  Complete!
126 {$cfg}
127
128
129 Checking database...
130
131  Complete!
132
133
134 Inserting data into database...
135
136  Complete!
137
138
139 Installing theme
140
141  Complete
142
143
144
145 Installation is finished
146
147
148 FIN;
149                 $this->assertEquals($finished, $txt);
150         }
151
152         private function assertStuckDB($txt)
153         {
154                 $finished = <<<FIN
155 Initializing setup...
156
157  Complete!
158
159
160 Checking environment...
161
162  NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
163
164  Complete!
165
166
167 Creating config file...
168
169  Complete!
170
171
172 Checking database...
173
174 [Error] --------
175 Could not connect to database.: 
176
177
178 FIN;
179
180                 $this->assertEquals($finished, $txt);
181         }
182
183         public function dataInstaller()
184         {
185                 return [
186                         'empty' => [
187                                 'data' => [
188                                         'database' => [
189                                                 'hostname'    => '',
190                                                 'username'    => '',
191                                                 'password'    => '',
192                                                 'database'    => '',
193                                         ],
194                                         'config' => [
195                                                 'php_path'    => '',
196                                                 'hostname'    => '',
197                                                 'admin_email' => '',
198                                         ],
199                                         'system' => [
200                                                 'urlpath'     => '',
201                                                 'url'         => '',
202                                                 'basepath'    => '',
203                                                 'ssl_policy'  => '',
204                                                 'default_timezone' => '',
205                                                 'language'    => '',
206                                         ],
207                                 ],
208                         ],
209                         'normal' => [
210                                 'data' => [
211                                         'database' => [
212                                                 'hostname'    => getenv('MYSQL_HOST'),
213                                                 'port'        =>!empty(getenv('MYSQL_PORT')) ? getenv('MYSQL_PORT') : null,
214                                                 'username'    => getenv('MYSQL_USERNAME'),
215                                                 'password'    => getenv('MYSQL_PASSWORD'),
216                                                 'database'    => getenv('MYSQL_DATABASE'),
217                                         ],
218                                         'config' => [
219                                                 'php_path'    => '',
220                                                 'hostname'    => 'friendica.local',
221                                                 'admin_email' => 'admin@philipp.info',
222                                         ],
223                                         'system' => [
224                                                 'urlpath'     => 'test/it',
225                                                 'url'         => 'friendica.local/test/it',
226                                                 'basepath'    => '',
227                                                 'ssl_policy'  => '2',
228                                                 'default_timezone' => 'en',
229                                                 'language'    => 'Europe/Berlin',
230                                         ],
231                                 ],
232                         ],
233                 ];
234         }
235
236         /**
237          * Test the automatic installation without any parameter
238          * @dataProvider dataInstaller
239          */
240         public function testEmpty(array $data)
241         {
242                 $configCache = new ConfigCache();
243                 $configCache->load($data);
244                 $configCache->set('system', 'basepath', $this->root->url());
245                 $configCache->set('config', 'php_path', trim(shell_exec('which php')));
246
247                 $this->mockApp($this->root, null, true);
248
249                 $this->configMock->shouldReceive('set');
250                 $this->configMock->shouldReceive('has')->andReturn(true);
251                 $this->configMock->shouldReceive('get')->andReturnUsing(function ($cat, $key) use ($configCache) {
252                         return $configCache->get($cat, $key);
253                 });
254
255                 $this->mockConnect(true, 1);
256                 $this->mockConnected(true, 1);
257                 $this->mockExistsTable('user', false, 1);
258                 $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
259
260                 $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
261                 $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro($configCache), '', 1);
262
263                 $console = new AutomaticInstallation($this->consoleArgv);
264
265                 $txt = $this->dumpExecute($console);
266
267                 $this->assertFinished($txt, true, false);
268                 $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
269         }
270
271         /**
272          * @medium
273          * @dataProvider dataInstaller
274          */
275         public function testWithConfig(array $data)
276         {
277                 $configCache = new ConfigCache();
278                 $configCache->load($data);
279                 $configCache->set('system', 'basepath', $this->root->url());
280                 $configCache->set('config', 'php_path', trim(shell_exec('which php')));
281
282                 $this->mockApp($this->root, $configCache, true);
283                 $this->mode->shouldReceive('isInstall')->andReturn(false);
284                 Logger::init(new VoidLogger());
285
286                 $this->mockConnect(true, 1);
287                 $this->mockConnected(true, 1);
288                 $this->mockExistsTable('user', false, 1);
289                 $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
290
291                 $conf = function ($cat, $key) use ($configCache) {
292                         return $configCache->get($cat, $key);
293                 };
294
295                 $config = <<<CONF
296 <?php
297
298 // Local configuration
299
300 // If you're unsure about what any of the config keys below do, please check the config/defaults.config.php for detailed
301 // documentation of their data type and behavior.
302
303 return [
304         'database' => [
305                 'hostname' => '{$conf('database','hostname')}',
306                 'username' => '{$conf('database', 'username')}',
307                 'password' => '{$conf('database', 'password')}',
308                 'database' => '{$conf('database', 'database')}',
309                 'charset' => 'utf8mb4',
310         ],
311
312         // ****************************************************************
313         // The configuration below will be overruled by the admin panel.
314         // Changes made below will only have an effect if the database does
315         // not contain any configuration for the friendica system.
316         // ****************************************************************
317
318         'config' => [
319                 'admin_email' => '{$conf('config', 'admin_email')}',
320                 'hostname' => '{$conf('config', 'hostname')}',
321                 'sitename' => 'Friendica Social Network',
322                 'register_policy' => \Friendica\Module\Register::OPEN,
323                 'register_text' => '',
324         ],
325         'system' => [
326                 'basepath => '{$conf('system', 'basepath')}',
327                 'urlpath => '{$conf('system', 'urlpath')}',
328                 'url' => '{$conf('system', 'url')}',
329                 'default_timezone' => '{$conf('system', 'default_timezone')}',
330                 'language' => '{$conf('system', 'language')}',
331         ],
332 ];
333 CONF;
334
335                 vfsStream::newFile('prepared.config.php')
336                         ->at($this->root)
337                         ->setContent($config);
338
339                 $console = new AutomaticInstallation($this->consoleArgv);
340                 $console->setOption('f', 'prepared.config.php');
341
342                 $txt = $this->dumpExecute($console);
343
344                 $this->assertFinished($txt, false, true);
345
346                 $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.config.php'));
347                 $this->assertEquals($config, file_get_contents($this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.config.php')->url()));
348         }
349
350         /**
351          * @medium
352          * @dataProvider dataInstaller
353          */
354         public function testWithEnvironmentAndSave(array $data)
355         {
356                 $configCache = new ConfigCache();
357                 $configCache->set('system', 'basepath', $this->root->url());
358                 $configCache->set('config', 'php_path', trim(shell_exec('which php')));
359
360                 $this->mockApp($this->root, $configCache);
361
362                 $this->mockConnect(true, 1);
363                 $this->mockConnected(true, 1);
364                 $this->mockExistsTable('user', false, 1);
365                 $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
366
367                 $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
368                 $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro($configCache), '', 1);
369
370                 $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
371                 $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
372                 $this->assertTrue(putenv('FRIENDICA_LANG=de'));
373                 $this->assertTrue(putenv('FRIENDICA_URL_PATH=/friendica'));
374
375                 $console = new AutomaticInstallation($this->consoleArgv);
376                 $console->setOption('savedb', true);
377
378                 $txt = $this->dumpExecute($console);
379
380                 print_r($configCache);
381
382                 $this->assertFinished($txt, true);
383         }
384
385         /**
386          * @medium
387          */
388         public function testWithEnvironmentWithoutSave()
389         {
390                 $this->mockConnect(true, 1);
391                 $this->mockConnected(true, 1);
392                 $this->mockExistsTable('user', false, 1);
393                 $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
394
395                 $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
396                 $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro(false), '', 1);
397
398                 $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
399                 $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
400                 $this->assertTrue(putenv('FRIENDICA_LANG=de'));
401                 $this->assertTrue(putenv('FRIENDICA_URL_PATH=/friendica'));
402
403                 $console = new AutomaticInstallation($this->consoleArgv);
404
405                 $txt = $this->dumpExecute($console);
406
407                 $this->assertFinished($txt, true);
408         }
409
410         /**
411          * @medium
412          */
413         public function testWithArguments()
414         {
415                 $this->mockConnect(true, 1);
416                 $this->mockConnected(true, 1);
417                 $this->mockExistsTable('user', false, 1);
418                 $this->mockUpdate([$this->root->url(), false, true, true], null, 1);
419
420                 $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
421                 $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro(true), '', 1);
422
423                 $console = new AutomaticInstallation($this->consoleArgv);
424
425                 $console->setOption('dbhost', $this->db_host);
426                 $console->setOption('dbuser', $this->db_user);
427                 if (!empty($this->db_pass)) {
428                         $console->setOption('dbpass', $this->db_pass);
429                 }
430                 if (!empty($this->db_port)) {
431                         $console->setOption('dbport', $this->db_port);
432                 }
433                 $console->setOption('dbdata', $this->db_data);
434
435                 $console->setOption('admin', 'admin@friendica.local');
436                 $console->setOption('tz', 'Europe/Berlin');
437                 $console->setOption('lang', 'de');
438
439                 $console->setOption('urlpath', '/friendica');
440
441                 $txt = $this->dumpExecute($console);
442
443                 $this->assertFinished($txt, true);
444         }
445
446         /**
447          * @runTestsInSeparateProcesses
448          * @preserveGlobalState disabled
449          */
450         public function testNoDatabaseConnection()
451         {
452                 $this->mockConnect(false, 1);
453
454                 $this->mockGetMarkupTemplate('local.config.tpl', 'testTemplate', 1);
455                 $this->mockReplaceMacros('testTemplate', $this->createArgumentsForMacro(false), '', 1);
456
457                 $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
458                 $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
459                 $this->assertTrue(putenv('FRIENDICA_LANG=de'));
460                 $this->assertTrue(putenv('FRIENDICA_URL_PATH=/friendica'));
461
462                 $console = new AutomaticInstallation($this->consoleArgv);
463
464                 $txt = $this->dumpExecute($console);
465
466                 $this->assertStuckDB($txt);
467         }
468
469         public function testGetHelp()
470         {
471                 // Usable to purposely fail if new commands are added without taking tests into account
472                 $theHelp = <<<HELP
473 Installation - Install Friendica automatically
474 Synopsis
475         bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
476
477 Description
478     Installs Friendica with data based on the local.config.php file or environment variables
479
480 Notes
481     Not checking .htaccess/URL-Rewrite during CLI installation.
482
483 Options
484     -h|--help|-?            Show help information
485     -v                      Show more debug information.
486     -a                      All setup checks are required (except .htaccess)
487     -f|--file <config>      prepared config file (e.g. "config/local.config.php" itself) which will override every other config option - except the environment variables)
488     -s|--savedb             Save the DB credentials to the file (if environment variables is used)
489     -H|--dbhost <host>      The host of the mysql/mariadb database (env MYSQL_HOST)
490     -p|--dbport <port>      The port of the mysql/mariadb database (env MYSQL_PORT)
491     -d|--dbdata <database>  The name of the mysql/mariadb database (env MYSQL_DATABASE)
492     -U|--dbuser <username>  The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
493     -P|--dbpass <password>  The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
494     -u|--urlpath <url_path> The URL path of Friendica - f.e. '/friendica' (env FRIENDICA_URL_PATH) 
495     -b|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH) 
496     -A|--admin <mail>       The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL)
497     -T|--tz <timezone>      The timezone of Friendica (env FRIENDICA_TZ)
498     -L|--lang <language>    The language of Friendica (env FRIENDICA_LANG)
499  
500 Environment variables
501    MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
502    MYSQL_PORT                  The port of the mysql/mariadb database
503    MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
504    MYSQL_PASSWORD              The password of the mysql/mariadb database login
505    MYSQL_DATABASE              The name of the mysql/mariadb database
506    FRIENDICA_URL_PATH          The URL path of Friendica (f.e. '/friendica')
507    FRIENDICA_PHP_PATH          The path of the PHP binary
508    FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
509    FRIENDICA_TZ                The timezone of Friendica
510    FRIENDICA_LANG              The langauge of Friendica
511    
512 Examples
513         bin/console autoinstall -f 'input.config.php
514                 Installs Friendica with the prepared 'input.config.php' file
515
516         bin/console autoinstall --savedb
517                 Installs Friendica with environment variables and saves them to the 'config/local.config.php' file
518
519         bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
520                 Installs Friendica with a local mysql database with credentials
521
522 HELP;
523
524                 $console = new AutomaticInstallation($this->consoleArgv);
525                 $console->setOption('help', true);
526
527                 $txt = $this->dumpExecute($console);
528
529                 $this->assertEquals($txt, $theHelp);
530         }
531 }