Merge branch 'develop' of https://github.com/friendica/friendica into develop
[friendica.git/.git] / tests / src / App / ModeTest.php
1 <?php
2 /**
3  * @copyright Copyright (C) 2010-2024, the Friendica project
4  *
5  * @license GNU AGPL version 3 or any later version
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Affero General Public License as
9  * published by the Free Software Foundation, either version 3 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Affero General Public License for more details.
16  *
17  * You should have received a copy of the GNU Affero General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  */
21
22 namespace Friendica\Test\src\App;
23
24 use Detection\MobileDetect;
25 use Friendica\App\Arguments;
26 use Friendica\App\Mode;
27 use Friendica\Core\Config\Capability\IManageConfigValues;
28 use Friendica\Database\Database;
29 use Friendica\Test\MockedTest;
30 use Friendica\Test\Util\VFSTrait;
31 use Friendica\Util\BasePath;
32 use Mockery;
33 use Mockery\MockInterface;
34
35 class ModeTest extends MockedTest
36 {
37         use VFSTrait;
38
39         /**
40          * @var BasePath|MockInterface
41          */
42         private $basePathMock;
43
44         /**
45          * @var Database|MockInterface
46          */
47         private $databaseMock;
48
49         /**
50          * @var IManageConfigValues|MockInterface
51          */
52         private $configMock;
53
54         protected function setUp(): void
55         {
56                 parent::setUp();
57
58                 $this->setUpVfsDir();
59
60                 $this->databaseMock = Mockery::mock(Database::class);
61                 $this->configMock   = Mockery::mock(IManageConfigValues::class);
62         }
63
64         public function testItEmpty()
65         {
66                 $mode = new Mode();
67                 self::assertTrue($mode->isInstall());
68                 self::assertFalse($mode->isNormal());
69         }
70
71         public function testWithoutConfig()
72         {
73                 self::assertTrue($this->root->hasChild('config/local.config.php'));
74
75                 $this->delConfigFile('local.config.php');
76
77                 self::assertFalse($this->root->hasChild('config/local.config.php'));
78
79                 $mode = (new Mode())->determine($this->root->url(), $this->databaseMock, $this->configMock);
80
81                 self::assertTrue($mode->isInstall());
82                 self::assertFalse($mode->isNormal());
83
84                 self::assertFalse($mode->has(Mode::LOCALCONFIGPRESENT));
85         }
86
87         public function testWithoutDatabase()
88         {
89                 $this->databaseMock->shouldReceive('connected')->andReturn(false)->once();
90
91                 $mode = (new Mode())->determine($this->root->url(), $this->databaseMock, $this->configMock);
92
93                 self::assertFalse($mode->isNormal());
94                 self::assertTrue($mode->isInstall());
95
96                 self::assertTrue($mode->has(Mode::LOCALCONFIGPRESENT));
97                 self::assertFalse($mode->has(Mode::DBAVAILABLE));
98         }
99
100         public function testWithMaintenanceMode()
101         {
102                 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
103                 $this->configMock->shouldReceive('get')->with('system', 'maintenance')
104                                                           ->andReturn(true)->once();
105
106                 $mode = (new Mode())->determine($this->root->url(), $this->databaseMock, $this->configMock);
107
108                 self::assertFalse($mode->isNormal());
109                 self::assertFalse($mode->isInstall());
110
111                 self::assertFalse($mode->has(Mode::MAINTENANCEDISABLED));
112         }
113
114         public function testNormalMode()
115         {
116                 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
117                 $this->configMock->shouldReceive('get')->with('system', 'maintenance')
118                                                           ->andReturn(false)->once();
119
120                 $mode = (new Mode())->determine($this->root->url(), $this->databaseMock, $this->configMock);
121
122                 self::assertTrue($mode->isNormal());
123                 self::assertFalse($mode->isInstall());
124
125                 self::assertTrue($mode->has(Mode::MAINTENANCEDISABLED));
126         }
127
128         /**
129          * Test explicit disabled maintenance (in case you manually disable it)
130          */
131         public function testDisabledMaintenance()
132         {
133                 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
134                 $this->configMock->shouldReceive('get')->with('system', 'maintenance')
135                                                           ->andReturn(false)->once();
136
137                 $mode = (new Mode())->determine($this->root->url(), $this->databaseMock, $this->configMock);
138
139                 self::assertTrue($mode->isNormal());
140                 self::assertFalse($mode->isInstall());
141
142                 self::assertTrue($mode->has(Mode::MAINTENANCEDISABLED));
143         }
144
145         /**
146          * Test that modes are immutable
147          */
148         public function testImmutable()
149         {
150                 $mode = new Mode();
151
152                 $modeNew = $mode->determine('', $this->databaseMock, $this->configMock);
153
154                 self::assertNotSame($modeNew, $mode);
155         }
156
157         /**
158          * Test if not called by index is backend
159          */
160         public function testIsBackendNotIsBackend()
161         {
162                 $server       = [];
163                 $args         = new Arguments();
164                 $mobileDetect = new MobileDetect();
165
166                 $mode = (new Mode())->determineRunMode(true, $server, $args, $mobileDetect);
167
168                 self::assertTrue($mode->isBackend());
169         }
170
171         /**
172          * Test is called by index but module is backend
173          */
174         public function testIsBackendButIndex()
175         {
176                 $server       = [];
177                 $args         = new Arguments('', '', Mode::BACKEND_MODULES[0]);
178                 $mobileDetect = new MobileDetect();
179
180                 $mode = (new Mode())->determineRunMode(false, $server, $args, $mobileDetect);
181
182                 self::assertTrue($mode->isBackend());
183         }
184
185         /**
186          * Test is called by index and module is not backend
187          */
188         public function testIsNotBackend()
189         {
190                 $server       = [];
191                 $args         = new Arguments('', '', Arguments::DEFAULT_MODULE);
192                 $mobileDetect = new MobileDetect();
193
194                 $mode = (new Mode())->determineRunMode(false, $server, $args, $mobileDetect);
195
196                 self::assertFalse($mode->isBackend());
197         }
198
199         /**
200          * Test if the call is an ajax call
201          */
202         public function testIsAjax()
203         {
204                 // This is the server environment variable to determine ajax calls
205                 $server = [
206                         'HTTP_X_REQUESTED_WITH' => 'xmlhttprequest',
207                 ];
208
209                 $args         = new Arguments('', '', Arguments::DEFAULT_MODULE);
210                 $mobileDetect = new MobileDetect();
211
212                 $mode = (new Mode())->determineRunMode(true, $server, $args, $mobileDetect);
213
214                 self::assertTrue($mode->isAjax());
215         }
216
217         /**
218          * Test if the call is not nan ajax call
219          */
220         public function testIsNotAjax()
221         {
222                 $server       = [];
223                 $args         = new Arguments('', '', Arguments::DEFAULT_MODULE);
224                 $mobileDetect = new MobileDetect();
225
226                 $mode = (new Mode())->determineRunMode(true, $server, $args, $mobileDetect);
227
228                 self::assertFalse($mode->isAjax());
229         }
230
231         /**
232          * Test if the call is a mobile and is a tablet call
233          */
234         public function testIsMobileIsTablet()
235         {
236                 $server       = [];
237                 $args         = new Arguments('', '', Arguments::DEFAULT_MODULE);
238                 $mobileDetect = Mockery::mock(MobileDetect::class);
239                 $mobileDetect->shouldReceive('isMobile')->andReturn(true);
240                 $mobileDetect->shouldReceive('isTablet')->andReturn(true);
241
242                 $mode = (new Mode())->determineRunMode(true, $server, $args, $mobileDetect);
243
244                 self::assertTrue($mode->isMobile());
245                 self::assertTrue($mode->isTablet());
246         }
247
248
249         /**
250          * Test if the call is not a mobile and is not a tablet call
251          */
252         public function testIsNotMobileIsNotTablet()
253         {
254                 $server       = [];
255                 $args         = new Arguments('', '', Arguments::DEFAULT_MODULE);
256                 $mobileDetect = Mockery::mock(MobileDetect::class);
257                 $mobileDetect->shouldReceive('isMobile')->andReturn(false);
258                 $mobileDetect->shouldReceive('isTablet')->andReturn(false);
259
260                 $mode = (new Mode())->determineRunMode(true, $server, $args, $mobileDetect);
261
262                 self::assertFalse($mode->isMobile());
263                 self::assertFalse($mode->isTablet());
264         }
265 }