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\Core\Config\Model\Config;
27 use Friendica\Core\Config\Util\ConfigFileManager;
28 use Friendica\Core\Config\ValueObject\Cache;
29 use Friendica\Test\MockedTest;
30 use Friendica\Test\Util\VFSTrait;
32 class BaseURLTest extends MockedTest
36 protected function setUp(): void
43 public function dataDefault()
57 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
62 'WithSubDirectory' => [
64 'SERVER_NAME' => 'friendica.local',
65 'REDIRECT_URI' => 'test/module/more',
66 'QUERY_STRING' => 'module/more',
75 'hostname' => 'friendica.local',
77 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
78 'url' => 'http://friendica.local/test',
85 'hostname' => 'friendica.local',
87 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
88 'url' => 'http://friendica.local/test',
91 'hostname' => 'friendica.local',
93 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
94 'url' => 'http://friendica.local/test',
98 'WithHttpsScheme' => [
100 'SERVER_NAME' => 'friendica.local',
101 'REDIRECT_URI' => 'test/module/more',
102 'QUERY_STRING' => 'module/more',
112 'hostname' => 'friendica.local',
114 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
115 'url' => 'https://friendica.local/test',
119 'WithoutQueryString' => [
121 'SERVER_NAME' => 'friendica.local',
122 'REDIRECT_URI' => 'test/more',
132 'hostname' => 'friendica.local',
133 'urlPath' => 'test/more',
134 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
135 'url' => 'https://friendica.local/test/more',
141 'SERVER_NAME' => 'friendica.local',
142 'SERVER_PORT' => '1234',
143 'REDIRECT_URI' => 'test/more',
153 'hostname' => 'friendica.local:1234',
154 'urlPath' => 'test/more',
155 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
156 'url' => 'https://friendica.local:1234/test/more',
162 'SERVER_NAME' => 'friendica.local',
163 'SERVER_PORT' => '443',
164 'REDIRECT_URI' => 'test/more',
173 'hostname' => 'friendica.local',
174 'urlPath' => 'test/more',
175 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
176 'url' => 'https://friendica.local/test/more',
182 'SERVER_NAME' => 'friendica.local',
183 'SERVER_PORT' => '80',
184 'REDIRECT_URI' => 'test/more',
193 'hostname' => 'friendica.local',
194 'urlPath' => 'test/more',
195 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
196 'url' => 'http://friendica.local/test/more',
204 * Test the default config determination
205 * @dataProvider dataDefault
207 public function testCheck($server, $input, $assert)
209 $configMock = \Mockery::mock(IManageConfigValues::class);
210 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn($input['hostname']);
211 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn($input['urlPath']);
212 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($input['sslPolicy']);
213 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($input['url']);
215 // If we don't have an urlPath as an input, we assert it, we will save it to the DB for the next time
216 if (!isset($input['urlPath']) && isset($assert['urlPath'])) {
217 $configMock->shouldReceive('set')->with('system', 'urlpath', $assert['urlPath'])->once();
220 // 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
221 if (!isset($input['sslPolicy']) && isset($assert['sslPolicy'])) {
222 $configMock->shouldReceive('set')->with('system', 'ssl_policy', $assert['sslPolicy'])->once();
225 // If we don't have the hostname as an input, we assert it, we will save it to the DB for the next time
226 if (empty($input['hostname']) && !empty($assert['hostname'])) {
227 $configMock->shouldReceive('set')->with('config', 'hostname', $assert['hostname'])->once();
230 // If we don't have an URL at first, but we assert it, we will save it to the DB for the next time
231 if (empty($input['url']) && !empty($assert['url'])) {
232 $configMock->shouldReceive('set')->with('system', 'url', $assert['url'])->once();
235 $baseUrl = new BaseURL($configMock, $server);
237 self::assertEquals($assert['hostname'], $baseUrl->getHostname());
238 self::assertEquals($assert['urlPath'], $baseUrl->getUrlPath());
239 self::assertEquals($assert['sslPolicy'], $baseUrl->getSSLPolicy());
240 self::assertEquals($assert['scheme'], $baseUrl->getScheme());
241 self::assertEquals($assert['url'], $baseUrl->get());
244 public function dataSave()
249 'hostname' => 'friendica.local',
251 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
252 'url' => 'https://friendica.local/path',
256 'hostname' => 'friendica.local',
258 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
260 'url' => 'https://friendica.local/path',
264 'hostname' => 'friendica.old',
265 'urlPath' => 'is/old/path',
266 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
267 'url' => 'http://friendica.old/is/old/path',
271 'hostname' => 'friendica.local',
272 'urlPath' => 'new/path',
273 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
275 'url' => 'https://friendica.local/new/path',
279 'hostname' => 'friendica.old',
280 'urlPath' => 'is/old/path',
281 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
282 'url' => 'http://friendica.old/is/old/path',
290 'url' => 'http://friendica.old/is/old/path',
292 'changeHostname' => [
294 'hostname' => 'friendica.old',
295 'urlPath' => 'is/old/path',
296 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
297 'url' => 'http://friendica.old/is/old/path',
301 'hostname' => 'friendica.local',
305 'url' => 'http://friendica.local/is/old/path',
309 'hostname' => 'friendica.old',
310 'urlPath' => 'is/old/path',
311 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
312 'url' => 'http://friendica.old/is/old/path',
317 'urlPath' => 'new/path',
320 'url' => 'http://friendica.old/new/path',
322 'changeSSLPolicy' => [
324 'hostname' => 'friendica.old',
325 'urlPath' => 'is/old/path',
326 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
327 'url' => 'http://friendica.old/is/old/path',
333 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
335 'url' => 'https://friendica.old/is/old/path',
341 * Test the save() method
342 * @dataProvider dataSave
344 public function testSave($input, $save, $url)
346 $configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/');
347 $config = new Config($configFileManager, new Cache([
349 'hostname' => $input['hostname'] ?? null,
352 'urlpath' => $input['urlPath'] ?? null,
353 'ssl_policy' => $input['sslPolicy'] ?? null,
354 'url' => $input['url'] ?? null,
355 'force_ssl' => $input['force_ssl'] ?? null,
359 $baseUrl = new BaseURL($config, []);
361 $baseUrl->save($save['hostname'], $save['sslPolicy'], $save['urlPath']);
363 self::assertEquals($url, $baseUrl->get());
367 * Test the saveByUrl() method
368 * @dataProvider dataSave
374 public function testSaveByUrl($input, $save, $url)
376 $configFileManager = new ConfigFileManager($this->root->url(), $this->root->url() . '/config/', $this->root->url() . '/static/');
377 $config = new Config($configFileManager, new Cache([
379 'hostname' => $input['hostname'] ?? null,
382 'urlpath' => $input['urlPath'] ?? null,
383 'ssl_policy' => $input['sslPolicy'] ?? null,
384 'url' => $input['url'] ?? null,
385 'force_ssl' => $input['force_ssl'] ?? null,
389 $baseUrl = new BaseURL($config, []);
391 $baseUrl->saveByURL($url);
393 self::assertEquals($url, $baseUrl->get());
396 public function dataGetBaseUrl()
400 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
402 'url' => 'http://friendica.local/new/test',
403 'assert' => 'http://friendica.local/new/test',
405 'DefaultWithSSL' => [
406 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
408 'url' => 'http://friendica.local/new/test',
409 'assert' => 'https://friendica.local/new/test',
411 'SSLFullWithSSL' => [
412 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
414 'url' => 'http://friendica.local/new/test',
415 'assert' => 'http://friendica.local/new/test',
417 'SSLFullWithoutSSL' => [
418 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
420 'url' => 'https://friendica.local/new/test',
421 'assert' => 'https://friendica.local/new/test',
424 'sslPolicy' => BaseURL::SSL_POLICY_NONE,
426 'url' => 'http://friendica.local/new/test',
427 'assert' => 'http://friendica.local/new/test',
429 'NoSSLWithoutSSL' => [
430 'sslPolicy' => BaseURL::SSL_POLICY_NONE,
432 'url' => 'http://friendica.local/new/test',
433 'assert' => 'http://friendica.local/new/test',
439 * Test the get() method
440 * @dataProvider dataGetBaseUrl
442 public function testGetURL($sslPolicy, $ssl, $url, $assert)
444 $configMock = \Mockery::mock(IManageConfigValues::class);
445 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
446 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
447 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
448 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($url);
450 $baseUrl = new BaseURL($configMock, []);
452 self::assertEquals($assert, $baseUrl->get($ssl));
455 public function dataCheckRedirectHTTPS()
460 'REQUEST_METHOD' => 'GET',
464 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
465 'url' => 'https://friendica.local',
470 'REQUEST_METHOD' => 'GET',
473 'sslPolicy' => BaseURL::DEFAULT_SSL_SCHEME,
474 'url' => 'https://friendica.local',
477 'forceSSLWithSSLPolicy' => [
480 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
481 'url' => 'https://friendica.local',
484 'forceSSLWithSSLPolicyAndGet' => [
486 'REQUEST_METHOD' => 'GET',
489 'sslPolicy' => BaseURL::SSL_POLICY_FULL,
490 'url' => 'https://friendica.local',
497 * Test the checkRedirectHTTPS() method
498 * @dataProvider dataCheckRedirectHTTPS
500 public function testCheckRedirectHTTPS($server, $forceSSL, $sslPolicy, $url, $redirect)
502 $configMock = \Mockery::mock(IManageConfigValues::class);
503 $configMock->shouldReceive('get')->with('config', 'hostname')->andReturn('friendica.local');
504 $configMock->shouldReceive('get')->with('system', 'urlpath')->andReturn('new/test');
505 $configMock->shouldReceive('get')->with('system', 'ssl_policy')->andReturn($sslPolicy);
506 $configMock->shouldReceive('get')->with('system', 'url')->andReturn($url);
507 $configMock->shouldReceive('get')->with('system', 'force_ssl')->andReturn($forceSSL);
509 $baseUrl = new BaseURL($configMock, $server);
511 self::assertEquals($redirect, $baseUrl->checkRedirectHttps());