4e1f269dcd28f8f05f1cad17b68ea81f49ec51f7
[friendica.git/.git] / tests / src / Core / Console / AutomaticInstallationConsoleTest.php
1 <?php
2
3 namespace Friendica\Test\src\Core\Console;
4
5 use org\bovigo\vfs\vfsStream;
6
7 /**
8  * @runTestsInSeparateProcesses
9  * @preserveGlobalState disabled
10  * @requires PHP 7.0
11  */
12 class AutomaticInstallationConsoleTest extends ConsoleTest
13 {
14         private $db_host;
15         private $db_port;
16         private $db_data;
17         private $db_user;
18         private $db_pass;
19
20         public function setUp()
21         {
22                 parent::setUp();
23
24                 if ($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')) {
25                         $this->root->getChild('config')
26                                 ->removeChild('local.ini.php');
27                 }
28
29                 $this->db_host = getenv('MYSQL_HOST');
30                 $this->db_port = (!empty(getenv('MYSQL_PORT'))) ? getenv('MYSQL_PORT') : null;
31                 $this->db_data = getenv('MYSQL_DATABASE');
32                 $this->db_user = getenv('MYSQL_USERNAME') . getenv('MYSQL_USER');
33                 $this->db_pass = getenv('MYSQL_PASSWORD');
34
35                 // Mocking 'DBStructure::existsTable()' because with CI, we cannot create an empty database
36                 // therefore we temporary override the existing database
37                 /// @todo Mocking the DB-Calls of ConsoleTest so we don't need this specific mock anymore
38                 $existsMock = \Mockery::mock('alias:Friendica\Database\DBStructure');
39                 $existsMock->shouldReceive('existsTable')
40                         ->with('user')
41                         ->andReturn(false);
42         }
43
44         private function assertConfig($family, $key, $value)
45         {
46                 $config = $this->execute(['config', $family, $key]);
47                 $this->assertEquals($family . "." . $key . " => " . $value . "\n", $config);
48         }
49
50         private function assertFinished($txt, $withconfig = false, $copyfile = false)
51         {
52                 $cfg = '';
53
54                 if ($withconfig) {
55                         $cfg = <<<CFG
56
57
58 Creating config file...
59
60  Complete!
61 CFG;
62                 }
63
64                 if ($copyfile) {
65                         $cfg = <<<CFG
66
67
68 Copying config file...
69
70  Complete!
71 CFG;
72                 }
73
74                 $finished = <<<FIN
75 Initializing setup...
76
77  Complete!
78
79
80 Checking environment...
81
82  NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
83
84  Complete!
85 {$cfg}
86
87
88 Checking database...
89
90  Complete!
91
92
93 Inserting data into database...
94
95  Complete!
96
97
98 Installing theme
99
100  Complete
101
102
103
104 Installation is finished
105
106
107 FIN;
108                 $this->assertEquals($finished, $txt);
109         }
110
111         private function assertStuckDB($txt)
112         {
113                 $finished = <<<FIN
114 Initializing setup...
115
116 Creating config file...
117
118  Complete!
119
120
121 Checking basic setup...
122
123  NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
124
125  Complete!
126
127
128 Checking database...
129
130 [Error] --------
131 MySQL Connection: Failed, please check your MySQL settings and credentials.
132
133
134 FIN;
135
136                 $this->assertEquals($finished, $txt);
137         }
138
139         /**
140          * @medium
141          */
142         public function testWithConfig()
143         {
144                 $config = <<<CONF
145 <?php return <<<INI
146
147 [database]
148 hostname = 
149 username = 
150 password = 
151 database = 
152 charset = utf8mb4
153
154
155 ; ****************************************************************
156 ; The configuration below will be overruled by the admin panel.
157 ; Changes made below will only have an effect if the database does
158 ; not contain any configuration for the friendica system.
159 ; ****************************************************************
160
161 [config]
162 admin_email =
163
164 sitename = Friendica Social Network
165
166 register_policy = REGISTER_OPEN
167 register_text =
168
169 [system]
170 default_timezone = UTC
171
172 language = en
173 INI;
174 // Keep this line
175
176 CONF;
177
178                 vfsStream::newFile('prepared.ini.php')
179                         ->at($this->root)
180                         ->setContent($config);
181
182                 $txt = $this->execute(['autoinstall', '-f', 'prepared.ini.php']);
183
184                 $this->assertFinished($txt, false, true);
185
186                 $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
187         }
188
189         /**
190          * @medium
191          */
192         public function testWithEnvironmentAndSave()
193         {
194                 $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
195                 $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
196                 $this->assertTrue(putenv('FRIENDICA_LANG=de'));
197
198                 $txt = $this->execute(['autoinstall', '--savedb']);
199
200                 $this->assertFinished($txt, true);
201
202                 $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
203
204                 $this->assertConfig('database', 'hostname', $this->db_host . (!empty($this->db_port) ? ':' . $this->db_port : ''));
205                 $this->assertConfig('database', 'username', $this->db_user);
206                 $this->assertConfig('database', 'database', $this->db_data);
207                 $this->assertConfig('config', 'admin_email', 'admin@friendica.local');
208                 $this->assertConfig('system', 'default_timezone', 'Europe/Berlin');
209                 // TODO language changes back to en
210                 //$this->assertConfig('system', 'language', 'de');
211         }
212
213         /**
214          * @medium
215          */
216         public function testWithEnvironmentWithoutSave()
217         {
218                 $this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
219                 $this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
220                 $this->assertTrue(putenv('FRIENDICA_LANG=de'));
221                 $this->assertTrue(putenv('FRIENDICA_URL_PATH=/friendica'));
222
223                 $txt = $this->execute(['autoinstall']);
224
225                 $this->assertFinished($txt, true);
226
227                 $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
228
229                 $this->assertConfig('database', 'hostname', '');
230                 $this->assertConfig('database', 'username', '');
231                 $this->assertConfig('database', 'database', '');
232                 $this->assertConfig('config', 'admin_email', 'admin@friendica.local');
233                 $this->assertConfig('system', 'default_timezone', 'Europe/Berlin');
234                 $this->assertConfig('system', 'urlpath', '/friendica');
235                 // TODO language changes back to en
236                 //$this->assertConfig('system', 'language', 'de');
237         }
238
239         /**
240          * @medium
241          */
242         public function testWithArguments()
243         {
244                 $args = ['autoinstall'];
245                 array_push($args, '--dbhost');
246                 array_push($args, $this->db_host);
247                 array_push($args, '--dbuser');
248                 array_push($args, $this->db_user);
249                 if (!empty($this->db_pass)) {
250                         array_push($args, '--dbpass');
251                         array_push($args, $this->db_pass);
252                 }
253                 if (!empty($this->db_port)) {
254                         array_push($args, '--dbport');
255                         array_push($args, $this->db_port);
256                 }
257                 array_push($args, '--dbdata');
258                 array_push($args, $this->db_data);
259
260                 array_push($args, '--admin');
261                 array_push($args, 'admin@friendica.local');
262                 array_push($args, '--tz');
263                 array_push($args, 'Europe/Berlin');
264                 array_push($args, '--lang');
265                 array_push($args, 'de');
266
267                 array_push($args, '--urlpath');
268                 array_push($args, '/friendica');
269
270                 $txt = $this->execute($args);
271
272                 $this->assertFinished($txt, true);
273
274                 $this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
275
276                 $this->assertConfig('database', 'hostname', $this->db_host . (!empty($this->db_port) ? ':' . $this->db_port : ''));
277                 $this->assertConfig('database', 'username', $this->db_user);
278                 $this->assertConfig('database', 'database', $this->db_data);
279                 $this->assertConfig('config', 'admin_email', 'admin@friendica.local');
280                 $this->assertConfig('system', 'default_timezone', 'Europe/Berlin');
281                 $this->assertConfig('system', 'urlpath', '/friendica');
282                 // TODO language changes back to en
283                 //$this->assertConfig('system', 'language', 'de');
284         }
285
286         /**
287          * @runTestsInSeparateProcesses
288          * @preserveGlobalState disabled
289          */
290         public function testNoDatabaseConnection()
291         {
292                 // TODO DBA mocking for whole console tests make this test work again
293                 $this->markTestSkipped('DBA is already loaded, we have to mock the whole App to make it work');
294
295                 $dbaMock = \Mockery::mock('alias:Friendica\Database\DBA');
296                 $dbaMock
297                         ->shouldReceive('connected')
298                         ->andReturn(false);
299
300                 $txt = $this->execute(['autoinstall']);
301
302                 $this->assertStuckDB($txt);
303         }
304
305         public function testGetHelp()
306         {
307                 // Usable to purposely fail if new commands are added without taking tests into account
308                 $theHelp = <<<HELP
309 Installation - Install Friendica automatically
310 Synopsis
311         bin/console autoinstall [-h|--help|-?] [-v] [-a] [-f]
312
313 Description
314     Installs Friendica with data based on the local.ini.php file or environment variables
315
316 Notes
317     Not checking .htaccess/URL-Rewrite during CLI installation.
318
319 Options
320     -h|--help|-?            Show help information
321     -v                      Show more debug information.
322     -a                      All setup checks are required (except .htaccess)
323     -f|--file <config>      prepared config file (e.g. "config/local.ini.php" itself) which will override every other config option - except the environment variables)
324     -s|--savedb             Save the DB credentials to the file (if environment variables is used)
325     -H|--dbhost <host>      The host of the mysql/mariadb database (env MYSQL_HOST)
326     -p|--dbport <port>      The port of the mysql/mariadb database (env MYSQL_PORT)
327     -d|--dbdata <database>  The name of the mysql/mariadb database (env MYSQL_DATABASE)
328     -U|--dbuser <username>  The username of the mysql/mariadb database login (env MYSQL_USER or MYSQL_USERNAME)
329     -P|--dbpass <password>  The password of the mysql/mariadb database login (env MYSQL_PASSWORD)
330     -u|--urlpath <url_path> The URL path of Friendica - f.e. '/friendica' (env FRIENDICA_URL_PATH) 
331     -b|--phppath <php_path> The path of the PHP binary (env FRIENDICA_PHP_PATH) 
332     -A|--admin <mail>       The admin email address of Friendica (env FRIENDICA_ADMIN_MAIL)
333     -T|--tz <timezone>      The timezone of Friendica (env FRIENDICA_TZ)
334     -L|--lang <language>    The language of Friendica (env FRIENDICA_LANG)
335  
336 Environment variables
337    MYSQL_HOST                  The host of the mysql/mariadb database (mandatory if mysql and environment is used)
338    MYSQL_PORT                  The port of the mysql/mariadb database
339    MYSQL_USERNAME|MYSQL_USER   The username of the mysql/mariadb database login (MYSQL_USERNAME is for mysql, MYSQL_USER for mariadb)
340    MYSQL_PASSWORD              The password of the mysql/mariadb database login
341    MYSQL_DATABASE              The name of the mysql/mariadb database
342    FRIENDICA_URL_PATH          The URL path of Friendica (f.e. '/friendica')
343    FRIENDICA_PHP_PATH          The path of the PHP binary
344    FRIENDICA_ADMIN_MAIL        The admin email address of Friendica (this email will be used for admin access)
345    FRIENDICA_TZ                The timezone of Friendica
346    FRIENDICA_LANG              The langauge of Friendica
347    
348 Examples
349         bin/console autoinstall -f 'input.ini.php
350                 Installs Friendica with the prepared 'input.ini.php' file
351
352         bin/console autoinstall --savedb
353                 Installs Friendica with environment variables and saves them to the 'config/local.ini.php' file
354
355         bin/console autoinstall -h localhost -p 3365 -U user -P passwort1234 -d friendica
356                 Installs Friendica with a local mysql database with credentials
357
358 HELP;
359
360                 $txt = $this->execute(['autoinstall', '-h']);
361
362                 $this->assertEquals($txt, $theHelp);
363         }
364 }