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