3 * @copyright Copyright (C) 2010-2023, the Friendica project
5 * @license GNU AGPL version 3 or any later version
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.
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.
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/>.
22 namespace Friendica\Test\src\Util;
24 use Friendica\App\BaseURL;
25 use Friendica\Core\Config\Capability\IManageConfigValues;
26 use Friendica\Test\MockedTest;
28 class BaseURLTest extends MockedTest
30 public function dataDefault()
44 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
49 'WithSubDirectory' => [
51 'SERVER_NAME' => 'friendica.local',
52 'REDIRECT_URI' => 'test/module/more',
53 'QUERY_STRING' => 'module/more',
62 'hostname' => 'friendica.local',
64 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
65 'url' => 'http://friendica.local/test',
72 'hostname' => 'friendica.local',
74 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
75 'url' => 'http://friendica.local/test',
78 'hostname' => 'friendica.local',
80 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
81 'url' => 'http://friendica.local/test',
85 'WithHttpsScheme' => [
87 'SERVER_NAME' => 'friendica.local',
88 'REDIRECT_URI' => 'test/module/more',
89 'QUERY_STRING' => 'module/more',
99 'hostname' => 'friendica.local',
101 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
102 'url' => 'https://friendica.local/test',
106 'WithoutQueryString' => [
108 'SERVER_NAME' => 'friendica.local',
109 'REDIRECT_URI' => 'test/more',
119 'hostname' => 'friendica.local',
120 'urlPath' => 'test/more',
121 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
122 'url' => 'https://friendica.local/test/more',
128 'SERVER_NAME' => 'friendica.local',
129 'SERVER_PORT' => '1234',
130 'REDIRECT_URI' => 'test/more',
140 'hostname' => 'friendica.local:1234',
141 'urlPath' => 'test/more',
142 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
143 'url' => 'https://friendica.local:1234/test/more',
149 'SERVER_NAME' => 'friendica.local',
150 'SERVER_PORT' => '443',
151 'REDIRECT_URI' => 'test/more',
160 'hostname' => 'friendica.local',
161 'urlPath' => 'test/more',
162 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
163 'url' => 'https://friendica.local/test/more',
169 'SERVER_NAME' => 'friendica.local',
170 'SERVER_PORT' => '80',
171 'REDIRECT_URI' => 'test/more',
180 'hostname' => 'friendica.local',
181 'urlPath' => 'test/more',
182 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
183 'url' => 'http://friendica.local/test/more',
191 * Test the default config determination
192 * @dataProvider dataDefault
194 public function testCheck($server, $input, $assert)
196 $configMock = \Mockery::mock(IManageConfigValues::class);
197 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
198 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
199 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
200 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
204 // If we don't have an urlPath as an input, we assert it, we will save it to the DB for the next time
205 if (!isset($input['urlPath']) && isset($assert['urlPath'])) {
206 $configMock->shouldReceive('set')->with('system', 'urlpath', $assert['urlPath'], false)->once();
210 // If we don't have the ssl_policy as an input, we assert it, we will save it to the DB for the next time
211 if (!isset($input['sslPolicy']) && isset($assert['sslPolicy'])) {
212 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $assert['sslPolicy'], false)->once();
216 // If we don't have the hostname as an input, we assert it, we will save it to the DB for the next time
217 if (empty($input['hostname']) && !empty($assert['hostname'])) {
218 $configMock->shouldReceive('set')->with('config', 'hostname', $assert['hostname'], false)->once();
222 // If we don't have an URL at first, but we assert it, we will save it to the DB for the next time
223 if (empty($input['url']) && !empty($assert['url'])) {
224 $configMock->shouldReceive('set')->with('system', 'url', $assert['url'], false)->once();
229 $configMock->shouldReceive('save')->once();
232 $baseUrl = new BaseURL($configMock, $server);
234 self::assertEquals($assert['hostname'], $baseUrl->getHostname());
235 self::assertEquals($assert['urlPath'], $baseUrl->getUrlPath());
236 self::assertEquals($assert['sslPolicy'], $baseUrl->getSSLPolicy());
237 self::assertEquals($assert['scheme'], $baseUrl->getScheme());
238 self::assertEquals($assert['url'], $baseUrl->get());
241 public function dataSave()
246 'hostname' => 'friendica.old',
247 'urlPath' => 'is/old/path',
248 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
249 'url' => 'http://friendica.old/is/old/path',
253 'hostname' => 'friendica.local',
254 'urlPath' => 'new/path',
255 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
257 'url' => 'https://friendica.local/new/path',
261 'hostname' => 'friendica.old',
262 'urlPath' => 'is/old/path',
263 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
264 'url' => 'http://friendica.old/is/old/path',
272 'url' => 'http://friendica.old/is/old/path',
274 'changeHostname' => [
276 'hostname' => 'friendica.old',
277 'urlPath' => 'is/old/path',
278 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
279 'url' => 'http://friendica.old/is/old/path',
283 'hostname' => 'friendica.local',
287 'url' => 'http://friendica.local/is/old/path',
291 'hostname' => 'friendica.old',
292 'urlPath' => 'is/old/path',
293 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
294 'url' => 'http://friendica.old/is/old/path',
299 'urlPath' => 'new/path',
302 'url' => 'http://friendica.old/new/path',
304 'changeSSLPolicy' => [
306 'hostname' => 'friendica.old',
307 'urlPath' => 'is/old/path',
308 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
309 'url' => 'http://friendica.old/is/old/path',
315 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
317 'url' => 'https://friendica.old/is/old/path',
323 * Test the save() method
324 * @dataProvider dataSave
326 public function testSave($input, $save, $url)
328 $configMock = \Mockery::mock(IManageConfigValues::class);
329 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
330 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
331 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
332 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
333 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($input['force_ssl']);
335 $baseUrl = new BaseURL($configMock, []);
337 if (isset($save['hostname'])) {
338 $configMock->shouldReceive('set')->with('config', 'hostname', $save['hostname'], false)->andReturn(true)->once();
341 if (isset($save['urlPath'])) {
342 $configMock->shouldReceive('set')->with('system', 'urlpath', $save['urlPath'], false)->andReturn(true)->once();
345 if (isset($save['sslPolicy'])) {
346 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $save['sslPolicy'], false)->andReturn(true)->once();
349 $configMock->shouldReceive('set')->with('system', 'url', $url, false)->andReturn(true)->once();
351 $configMock->shouldReceive('save')->once();
353 $baseUrl->save($save['hostname'], $save['sslPolicy'], $save['urlPath']);
355 self::assertEquals($url, $baseUrl->get());
359 * Test the saveByUrl() method
360 * @dataProvider dataSave
366 public function testSaveByUrl($input, $save, $url)
368 $configMock = \Mockery::mock(IManageConfigValues::class);
369 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
370 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
371 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
372 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
373 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($input['force_ssl']);
375 $baseUrl = new BaseURL($configMock, []);
377 if (isset($save['hostname'])) {
378 $configMock->shouldReceive('set')->with('config', 'hostname', $save['hostname'], false)->andReturn(true)->once();
381 if (isset($save['urlPath'])) {
382 $configMock->shouldReceive('set')->with('system', 'urlpath', $save['urlPath'], false)->andReturn(true)->once();
385 if (isset($save['sslPolicy'])) {
386 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $save['sslPolicy'], false)->andReturn(true)->once();
389 $configMock->shouldReceive('set')->with('system', 'url', $url, false)->andReturn(true)->once();
391 $configMock->shouldReceive('save')->once();
393 $baseUrl->saveByURL($url);
395 self::assertEquals($url, $baseUrl->get());
398 public function dataGetBaseUrl()
402 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
404 'url' => 'http://friendica.local/new/test',
405 'assert' => 'http://friendica.local/new/test',
407 'DefaultWithSSL' => [
408 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
410 'url' => 'http://friendica.local/new/test',
411 'assert' => 'https://friendica.local/new/test',
413 'SSLFullWithSSL' => [
414 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
416 'url' => 'http://friendica.local/new/test',
417 'assert' => 'http://friendica.local/new/test',
419 'SSLFullWithoutSSL' => [
420 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
422 'url' => 'https://friendica.local/new/test',
423 'assert' => 'https://friendica.local/new/test',
426 'sslPolicy' => BaseURL::SSL_POLICY_NONE,
428 'url' => 'http://friendica.local/new/test',
429 'assert' => 'http://friendica.local/new/test',
431 'NoSSLWithoutSSL' => [
432 'sslPolicy' => BaseURL::SSL_POLICY_NONE,
434 'url' => 'http://friendica.local/new/test',
435 'assert' => 'http://friendica.local/new/test',
441 * Test the get() method
442 * @dataProvider dataGetBaseUrl
444 public function testGetURL($sslPolicy, $ssl, $url, $assert)
446 $configMock = \Mockery::mock(IManageConfigValues::class);
447 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
448 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
449 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
450 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($url);
452 $baseUrl = new BaseURL($configMock, []);
454 self::assertEquals($assert, $baseUrl->get($ssl));
457 public function dataCheckRedirectHTTPS()
462 'REQUEST_METHOD' => 'GET',
466 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
467 'url' => 'https://friendica.local',
472 'REQUEST_METHOD' => 'GET',
475 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
476 'url' => 'https://friendica.local',
479 'forceSSLWithSSLPolicy' => [
482 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
483 'url' => 'https://friendica.local',
486 'forceSSLWithSSLPolicyAndGet' => [
488 'REQUEST_METHOD' => 'GET',
491 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
492 'url' => 'https://friendica.local',
499 * Test the checkRedirectHTTPS() method
500 * @dataProvider dataCheckRedirectHTTPS
502 public function testCheckRedirectHTTPS($server, $forceSSL, $sslPolicy, $url, $redirect)
504 $configMock = \Mockery::mock(IManageConfigValues::class);
505 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
506 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
507 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
508 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($url);
509 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($forceSSL);
511 $baseUrl = new BaseURL($configMock, $server);
513 self::assertEquals($redirect, $baseUrl->checkRedirectHttps());
516 public function dataWrongSave()
520 'fail' => 'hostname',
522 'wrongSSLPolicy' => [
523 'fail' => 'sslPolicy',
535 * Test the save() method with wrong parameters
536 * @dataProvider dataWrongSave
538 public function testWrongSave($fail)
540 $configMock = \Mockery::mock(IManageConfigValues::class);
541 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
542 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
543 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn(BaseURL::DEFAULT_SSL_SCHEME);
544 $configMock->shouldReceive('get')->with('system', 'url')->andReturn('http://friendica.local/new/test');
548 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any(), false)->andReturn(false)->once();
551 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any(), false)->andReturn(true)->twice();
552 $configMock->shouldReceive('set')->with('system', 'ssl_policy', \Mockery::any(), false)->andReturn(false)->once();
553 $configMock->shouldReceive('save')->once();
556 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any(), false)->andReturn(true)->twice();
557 $configMock->shouldReceive('set')->with('system', 'ssl_policy', \Mockery::any(), false)->andReturn(true)->twice();
558 $configMock->shouldReceive('set')->with('system', 'urlpath', \Mockery::any(), false)->andReturn(false)->once();
559 $configMock->shouldReceive('save')->once();
562 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any(), false)->andReturn(true)->twice();
563 $configMock->shouldReceive('set')->with('system', 'ssl_policy', \Mockery::any(), false)->andReturn(true)->twice();
564 $configMock->shouldReceive('set')->with('system', 'urlpath', \Mockery::any(), false)->andReturn(true)->twice();
565 $configMock->shouldReceive('set')->with('system', 'url', \Mockery::any(), false)->andReturn(false)->once();
566 $configMock->shouldReceive('save')->once();
570 $baseUrl = new BaseURL($configMock, []);
571 self::assertFalse($baseUrl->save('test', 10, 'nope'));
573 // nothing should have changed because we never successfully saved anything
574 self::assertEquals('friendica.local', $baseUrl->getHostname());
575 self::assertEquals('new/test', $baseUrl->getUrlPath());
576 self::assertEquals(BaseURL::DEFAULT_SSL_SCHEME, $baseUrl->getSSLPolicy());
577 self::assertEquals('http://friendica.local/new/test', $baseUrl->get());