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']);
202 // If we don't have an urlPath as an input, we assert it, we will save it to the DB for the next time
203 if (!isset($input['urlPath']) && isset($assert['urlPath'])) {
204 $configMock->shouldReceive('set')->with('system', 'urlpath', $assert['urlPath'])->once();
207 // 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
208 if (!isset($input['sslPolicy']) && isset($assert['sslPolicy'])) {
209 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $assert['sslPolicy'])->once();
212 // If we don't have the hostname as an input, we assert it, we will save it to the DB for the next time
213 if (empty($input['hostname']) && !empty($assert['hostname'])) {
214 $configMock->shouldReceive('set')->with('config', 'hostname', $assert['hostname'])->once();
217 // If we don't have an URL at first, but we assert it, we will save it to the DB for the next time
218 if (empty($input['url']) && !empty($assert['url'])) {
219 $configMock->shouldReceive('set')->with('system', 'url', $assert['url'])->once();
222 $baseUrl = new BaseURL($configMock, $server);
224 self::assertEquals($assert['hostname'], $baseUrl->getHostname());
225 self::assertEquals($assert['urlPath'], $baseUrl->getUrlPath());
226 self::assertEquals($assert['sslPolicy'], $baseUrl->getSSLPolicy());
227 self::assertEquals($assert['scheme'], $baseUrl->getScheme());
228 self::assertEquals($assert['url'], $baseUrl->get());
231 public function dataSave()
236 'hostname' => 'friendica.local',
238 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
239 'url' => 'https://friendica.local/path',
243 'hostname' => 'friendica.local',
245 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
247 'url' => 'https://friendica.local/path',
251 'hostname' => 'friendica.old',
252 'urlPath' => 'is/old/path',
253 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
254 'url' => 'http://friendica.old/is/old/path',
258 'hostname' => 'friendica.local',
259 'urlPath' => 'new/path',
260 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
262 'url' => 'https://friendica.local/new/path',
266 'hostname' => 'friendica.old',
267 'urlPath' => 'is/old/path',
268 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
269 'url' => 'http://friendica.old/is/old/path',
277 'url' => 'http://friendica.old/is/old/path',
279 'changeHostname' => [
281 'hostname' => 'friendica.old',
282 'urlPath' => 'is/old/path',
283 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
284 'url' => 'http://friendica.old/is/old/path',
288 'hostname' => 'friendica.local',
292 'url' => 'http://friendica.local/is/old/path',
296 'hostname' => 'friendica.old',
297 'urlPath' => 'is/old/path',
298 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
299 'url' => 'http://friendica.old/is/old/path',
304 'urlPath' => 'new/path',
307 'url' => 'http://friendica.old/new/path',
309 'changeSSLPolicy' => [
311 'hostname' => 'friendica.old',
312 'urlPath' => 'is/old/path',
313 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
314 'url' => 'http://friendica.old/is/old/path',
320 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
322 'url' => 'https://friendica.old/is/old/path',
328 * Test the save() method
329 * @dataProvider dataSave
331 public function testSave($input, $save, $url)
333 $configMock = \Mockery::mock(IManageConfigValues::class);
334 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
335 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
336 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
337 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
338 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($input['force_ssl']);
340 $baseUrl = new BaseURL($configMock, []);
342 if (isset($save['hostname']) && ($save['hostname'] !== $input['hostname'])) {
343 $configMock->shouldReceive('set')->with('config', 'hostname', $save['hostname'])->andReturn(true)->once();
346 if (isset($save['urlPath']) && ($save['urlPath'] !== $input['urlPath'])) {
347 $configMock->shouldReceive('set')->with('system', 'urlpath', $save['urlPath'])->andReturn(true)->once();
350 if (isset($save['sslPolicy']) && ($save['sslPolicy'] !== $input['sslPolicy'])) {
351 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $save['sslPolicy'])->andReturn(true)->once();
354 if ($input['url'] !== $url) {
355 $configMock->shouldReceive('set')->with('system', 'url', $url)->andReturn(true)->once();
358 $baseUrl->save($save['hostname'], $save['sslPolicy'], $save['urlPath']);
360 self::assertEquals($url, $baseUrl->get());
364 * Test the saveByUrl() method
365 * @dataProvider dataSave
371 public function testSaveByUrl($input, $save, $url)
373 $configMock = \Mockery::mock(IManageConfigValues::class);
374 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
375 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
376 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
377 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
378 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($input['force_ssl']);
380 $baseUrl = new BaseURL($configMock, []);
382 if (isset($save['hostname']) && ($save['hostname'] !== $input['hostname'])) {
383 $configMock->shouldReceive('set')->with('config', 'hostname', $save['hostname'])->andReturn(true)->once();
386 if (isset($save['urlPath']) && ($save['urlPath'] !== $input['urlPath'])) {
387 $configMock->shouldReceive('set')->with('system', 'urlpath', $save['urlPath'])->andReturn(true)->once();
390 if (isset($save['sslPolicy']) && ($save['sslPolicy'] !== $input['sslPolicy'])) {
391 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $save['sslPolicy'])->andReturn(true)->once();
394 if ($input['url'] !== $url) {
395 $configMock->shouldReceive('set')->with('system', 'url', $url)->andReturn(true)->once();
398 $baseUrl->saveByURL($url);
400 self::assertEquals($url, $baseUrl->get());
403 public function dataGetBaseUrl()
407 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
409 'url' => 'http://friendica.local/new/test',
410 'assert' => 'http://friendica.local/new/test',
412 'DefaultWithSSL' => [
413 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
415 'url' => 'http://friendica.local/new/test',
416 'assert' => 'https://friendica.local/new/test',
418 'SSLFullWithSSL' => [
419 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
421 'url' => 'http://friendica.local/new/test',
422 'assert' => 'http://friendica.local/new/test',
424 'SSLFullWithoutSSL' => [
425 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
427 'url' => 'https://friendica.local/new/test',
428 'assert' => 'https://friendica.local/new/test',
431 'sslPolicy' => BaseURL::SSL_POLICY_NONE,
433 'url' => 'http://friendica.local/new/test',
434 'assert' => 'http://friendica.local/new/test',
436 'NoSSLWithoutSSL' => [
437 'sslPolicy' => BaseURL::SSL_POLICY_NONE,
439 'url' => 'http://friendica.local/new/test',
440 'assert' => 'http://friendica.local/new/test',
446 * Test the get() method
447 * @dataProvider dataGetBaseUrl
449 public function testGetURL($sslPolicy, $ssl, $url, $assert)
451 $configMock = \Mockery::mock(IManageConfigValues::class);
452 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
453 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
454 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
455 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($url);
457 $baseUrl = new BaseURL($configMock, []);
459 self::assertEquals($assert, $baseUrl->get($ssl));
462 public function dataCheckRedirectHTTPS()
467 'REQUEST_METHOD' => 'GET',
471 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
472 'url' => 'https://friendica.local',
477 'REQUEST_METHOD' => 'GET',
480 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
481 'url' => 'https://friendica.local',
484 'forceSSLWithSSLPolicy' => [
487 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
488 'url' => 'https://friendica.local',
491 'forceSSLWithSSLPolicyAndGet' => [
493 'REQUEST_METHOD' => 'GET',
496 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
497 'url' => 'https://friendica.local',
504 * Test the checkRedirectHTTPS() method
505 * @dataProvider dataCheckRedirectHTTPS
507 public function testCheckRedirectHTTPS($server, $forceSSL, $sslPolicy, $url, $redirect)
509 $configMock = \Mockery::mock(IManageConfigValues::class);
510 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
511 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
512 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
513 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($url);
514 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($forceSSL);
516 $baseUrl = new BaseURL($configMock, $server);
518 self::assertEquals($redirect, $baseUrl->checkRedirectHttps());
521 public function dataWrongSave()
525 'fail' => 'hostname',
527 'wrongSSLPolicy' => [
528 'fail' => 'sslPolicy',
540 * Test the save() method with wrong parameters
541 * @dataProvider dataWrongSave
543 public function testWrongSave($fail)
545 $configMock = \Mockery::mock(IManageConfigValues::class);
546 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
547 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
548 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn(BaseURL::DEFAULT_SSL_SCHEME);
549 $configMock->shouldReceive('get')->with('system', 'url')->andReturn('http://friendica.local/new/test');
553 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any())->andReturn(false)->once();
556 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any())->andReturn(true)->twice();
557 $configMock->shouldReceive('set')->with('system', 'ssl_policy', \Mockery::any())->andReturn(false)->once();
560 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any())->andReturn(true)->twice();
561 $configMock->shouldReceive('set')->with('system', 'ssl_policy', \Mockery::any())->andReturn(true)->twice();
562 $configMock->shouldReceive('set')->with('system', 'urlpath', \Mockery::any())->andReturn(false)->once();
565 $configMock->shouldReceive('set')->with('config', 'hostname', \Mockery::any())->andReturn(true)->twice();
566 $configMock->shouldReceive('set')->with('system', 'ssl_policy', \Mockery::any())->andReturn(true)->twice();
567 $configMock->shouldReceive('set')->with('system', 'urlpath', \Mockery::any())->andReturn(true)->twice();
568 $configMock->shouldReceive('set')->with('system', 'url', \Mockery::any())->andReturn(false)->once();
572 $baseUrl = new BaseURL($configMock, []);
573 self::assertFalse($baseUrl->save('test', 10, 'nope'));
575 // nothing should have changed because we never successfully saved anything
576 self::assertEquals('friendica.local', $baseUrl->getHostname());
577 self::assertEquals('new/test', $baseUrl->getUrlPath());
578 self::assertEquals(BaseURL::DEFAULT_SSL_SCHEME, $baseUrl->getSSLPolicy());
579 self::assertEquals('http://friendica.local/new/test', $baseUrl->get());