3 namespace Friendica\Test\src\App;
5 use Detection\MobileDetect;
6 use Friendica\App\Mode;
7 use Friendica\App\Module;
8 use Friendica\Core\Config;
9 use Friendica\Database\Database;
10 use Friendica\Test\MockedTest;
11 use Friendica\Test\Util\DBAMockTrait;
12 use Friendica\Test\Util\VFSTrait;
13 use Friendica\Util\BasePath;
14 use Mockery\MockInterface;
16 class ModeTest extends MockedTest
22 * @var BasePath|MockInterface
24 private $basePathMock;
27 * @var Database|MockInterface
29 private $databaseMock;
32 * @var Config\Cache\ConfigCache|MockInterface
34 private $configCacheMock;
36 public function setUp()
42 $this->basePathMock = \Mockery::mock(BasePath::class);
43 $this->databaseMock = \Mockery::mock(Database::class);
44 $this->configCacheMock = \Mockery::mock(Config\Cache\ConfigCache::class);
47 public function testItEmpty()
50 $this->assertTrue($mode->isInstall());
51 $this->assertFalse($mode->isNormal());
54 public function testWithoutConfig()
56 $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
58 $this->assertTrue($this->root->hasChild('config/local.config.php'));
60 $this->delConfigFile('local.config.php');
62 $this->assertFalse($this->root->hasChild('config/local.config.php'));
64 $mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
66 $this->assertTrue($mode->isInstall());
67 $this->assertFalse($mode->isNormal());
69 $this->assertFalse($mode->has(Mode::LOCALCONFIGPRESENT));
72 public function testWithoutDatabase()
74 $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
76 $this->databaseMock->shouldReceive('connected')->andReturn(false)->once();
78 $mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
80 $this->assertFalse($mode->isNormal());
81 $this->assertTrue($mode->isInstall());
83 $this->assertTrue($mode->has(Mode::LOCALCONFIGPRESENT));
84 $this->assertFalse($mode->has(Mode::DBAVAILABLE));
87 public function testWithoutDatabaseSetup()
89 $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
91 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
92 $this->databaseMock->shouldReceive('fetchFirst')
93 ->with('SHOW TABLES LIKE \'config\'')->andReturn(false)->once();
95 $mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
97 $this->assertFalse($mode->isNormal());
98 $this->assertTrue($mode->isInstall());
100 $this->assertTrue($mode->has(Mode::LOCALCONFIGPRESENT));
103 public function testWithMaintenanceMode()
105 $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
107 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
108 $this->databaseMock->shouldReceive('fetchFirst')
109 ->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once();
110 $this->configCacheMock->shouldReceive('get')->with('system', 'maintenance')
111 ->andReturn(true)->once();
113 $mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
115 $this->assertFalse($mode->isNormal());
116 $this->assertFalse($mode->isInstall());
118 $this->assertTrue($mode->has(Mode::DBCONFIGAVAILABLE));
119 $this->assertFalse($mode->has(Mode::MAINTENANCEDISABLED));
122 public function testNormalMode()
124 $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
126 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
127 $this->databaseMock->shouldReceive('fetchFirst')
128 ->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once();
129 $this->configCacheMock->shouldReceive('get')->with('system', 'maintenance')
130 ->andReturn(false)->once();
131 $this->databaseMock->shouldReceive('selectFirst')
132 ->with('config', ['v'], ['cat' => 'system', 'k' => 'maintenance'])
133 ->andReturn(['v' => null])->once();
135 $mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
137 $this->assertTrue($mode->isNormal());
138 $this->assertFalse($mode->isInstall());
140 $this->assertTrue($mode->has(Mode::DBCONFIGAVAILABLE));
141 $this->assertTrue($mode->has(Mode::MAINTENANCEDISABLED));
145 * Test explicit disabled maintenance (in case you manually disable it)
147 public function testDisabledMaintenance()
149 $this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
151 $this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
152 $this->databaseMock->shouldReceive('fetchFirst')
153 ->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once();
154 $this->configCacheMock->shouldReceive('get')->with('system', 'maintenance')
155 ->andReturn(false)->once();
156 $this->databaseMock->shouldReceive('selectFirst')
157 ->with('config', ['v'], ['cat' => 'system', 'k' => 'maintenance'])
158 ->andReturn(['v' => '0'])->once();
160 $mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
162 $this->assertTrue($mode->isNormal());
163 $this->assertFalse($mode->isInstall());
165 $this->assertTrue($mode->has(Mode::DBCONFIGAVAILABLE));
166 $this->assertTrue($mode->has(Mode::MAINTENANCEDISABLED));
170 * Test that modes are immutable
172 public function testImmutable()
174 $this->basePathMock->shouldReceive('getPath')->andReturn(null)->once();
178 $modeNew = $mode->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
180 $this->assertNotSame($modeNew, $mode);
184 * Test if not called by index is backend
186 public function testIsBackendNotIsBackend()
189 $module = new Module();
190 $mobileDetect = new MobileDetect();
192 $mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
194 $this->assertTrue($mode->isBackend());
198 * Test is called by index but module is backend
200 public function testIsBackendButIndex()
203 $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], true);
204 $mobileDetect = new MobileDetect();
206 $mode = (new Mode())->determineRunMode(false, $module, $server, $mobileDetect);
208 $this->assertTrue($mode->isBackend());
212 * Test is called by index and module is not backend
214 public function testIsNotBackend()
217 $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
218 $mobileDetect = new MobileDetect();
220 $mode = (new Mode())->determineRunMode(false, $module, $server, $mobileDetect);
222 $this->assertFalse($mode->isBackend());
226 * Test if the call is an ajax call
228 public function testIsAjax()
230 // This is the server environment variable to determine ajax calls
232 'HTTP_X_REQUESTED_WITH' => 'xmlhttprequest',
235 $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
236 $mobileDetect = new MobileDetect();
238 $mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
240 $this->assertTrue($mode->isAjax());
244 * Test if the call is not nan ajax call
246 public function testIsNotAjax()
249 $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
250 $mobileDetect = new MobileDetect();
252 $mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
254 $this->assertFalse($mode->isAjax());
258 * Test if the call is a mobile and is a tablet call
260 public function testIsMobileIsTablet()
263 $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
264 $mobileDetect = \Mockery::mock(MobileDetect::class);
265 $mobileDetect->shouldReceive('isMobile')->andReturn(true);
266 $mobileDetect->shouldReceive('isTablet')->andReturn(true);
268 $mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
270 $this->assertTrue($mode->isMobile());
271 $this->assertTrue($mode->isTablet());
276 * Test if the call is not a mobile and is not a tablet call
278 public function testIsNotMobileIsNotTablet()
281 $module = new Module(Module::DEFAULT, Module::DEFAULT_CLASS, [], false);
282 $mobileDetect = \Mockery::mock(MobileDetect::class);
283 $mobileDetect->shouldReceive('isMobile')->andReturn(false);
284 $mobileDetect->shouldReceive('isTablet')->andReturn(false);
286 $mode = (new Mode())->determineRunMode(true, $module, $server, $mobileDetect);
288 $this->assertFalse($mode->isMobile());
289 $this->assertFalse($mode->isTablet());