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