mirror of
https://github.com/friendica/friendica
synced 2025-04-27 23:10:12 +00:00
Add Arguments & Modules class
This commit is contained in:
parent
f068d00645
commit
0af9747c6c
12 changed files with 1083 additions and 358 deletions
242
tests/src/App/ArgumentsTest.php
Normal file
242
tests/src/App/ArgumentsTest.php
Normal file
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\src\App;
|
||||
|
||||
use Friendica\App;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ArgumentsTest extends TestCase
|
||||
{
|
||||
private function assertArguments(array $assert, App\Arguments $arguments)
|
||||
{
|
||||
$this->assertEquals($assert['queryString'], $arguments->getQueryString());
|
||||
$this->assertEquals($assert['command'], $arguments->getCommand());
|
||||
$this->assertEquals($assert['argv'], $arguments->getArgv());
|
||||
$this->assertEquals($assert['argc'], $arguments->getArgc());
|
||||
$this->assertCount($assert['argc'], $arguments->getArgv());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the default argument without any determinations
|
||||
*/
|
||||
public function testDefault()
|
||||
{
|
||||
$arguments = new App\Arguments();
|
||||
|
||||
$this->assertArguments([
|
||||
'queryString' => '',
|
||||
'command' => '',
|
||||
'argv' => ['home'],
|
||||
'argc' => 1,
|
||||
],
|
||||
$arguments);
|
||||
}
|
||||
|
||||
public function dataArguments()
|
||||
{
|
||||
return [
|
||||
'withPagename' => [
|
||||
'assert' => [
|
||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'pagename=profile/test/it?arg1=value1&arg2=value2',
|
||||
],
|
||||
'get' => [
|
||||
'pagename' => 'profile/test/it',
|
||||
],
|
||||
],
|
||||
'withQ' => [
|
||||
'assert' => [
|
||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'q=profile/test/it?arg1=value1&arg2=value2',
|
||||
],
|
||||
'get' => [
|
||||
'q' => 'profile/test/it',
|
||||
],
|
||||
],
|
||||
'withWrongDelimiter' => [
|
||||
'assert' => [
|
||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'pagename=profile/test/it&arg1=value1&arg2=value2',
|
||||
],
|
||||
'get' => [
|
||||
'pagename' => 'profile/test/it',
|
||||
],
|
||||
],
|
||||
'withUnixHomeDir' => [
|
||||
'assert' => [
|
||||
'queryString' => '~test/it?arg1=value1&arg2=value2',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'pagename=~test/it?arg1=value1&arg2=value2',
|
||||
],
|
||||
'get' => [
|
||||
'pagename' => '~test/it',
|
||||
],
|
||||
],
|
||||
'withDiasporaHomeDir' => [
|
||||
'assert' => [
|
||||
'queryString' => 'u/test/it?arg1=value1&arg2=value2',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'pagename=u/test/it?arg1=value1&arg2=value2',
|
||||
],
|
||||
'get' => [
|
||||
'pagename' => 'u/test/it',
|
||||
],
|
||||
],
|
||||
'withTrailingSlash' => [
|
||||
'assert' => [
|
||||
'queryString' => 'profile/test/it?arg1=value1&arg2=value2/',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'pagename=profile/test/it?arg1=value1&arg2=value2/',
|
||||
],
|
||||
'get' => [
|
||||
'pagename' => 'profile/test/it',
|
||||
],
|
||||
],
|
||||
'withWrongQueryString' => [
|
||||
'assert' => [
|
||||
// empty query string?!
|
||||
'queryString' => '',
|
||||
'command' => 'profile/test/it',
|
||||
'argv' => ['profile', 'test', 'it'],
|
||||
'argc' => 3,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'wrong=profile/test/it?arg1=value1&arg2=value2/',
|
||||
],
|
||||
'get' => [
|
||||
'pagename' => 'profile/test/it',
|
||||
],
|
||||
],
|
||||
'withMissingPageName' => [
|
||||
'assert' => [
|
||||
'queryString' => 'notvalid/it?arg1=value1&arg2=value2/',
|
||||
'command' => App\Module::DEFAULT,
|
||||
'argv' => [App\Module::DEFAULT],
|
||||
'argc' => 1,
|
||||
],
|
||||
'server' => [
|
||||
'QUERY_STRING' => 'pagename=notvalid/it?arg1=value1&arg2=value2/',
|
||||
],
|
||||
'get' => [
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test all variants of argument determination
|
||||
*
|
||||
* @dataProvider dataArguments
|
||||
*/
|
||||
public function testDetermine(array $assert, array $server, array $get)
|
||||
{
|
||||
$arguments = (new App\Arguments())
|
||||
->determine($server, $get);
|
||||
|
||||
$this->assertArguments($assert, $arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the get/has methods are working for the determined arguments
|
||||
*
|
||||
* @dataProvider dataArguments
|
||||
*/
|
||||
public function testGetHas(array $assert, array $server, array $get)
|
||||
{
|
||||
$arguments = (new App\Arguments())
|
||||
->determine($server, $get);
|
||||
|
||||
for ($i = 0; $i < $arguments->getArgc(); $i++) {
|
||||
$this->assertTrue($arguments->has($i));
|
||||
$this->assertEquals($assert['argv'][$i], $arguments->get($i));
|
||||
}
|
||||
|
||||
$this->assertFalse($arguments->has($arguments->getArgc()));
|
||||
$this->assertEmpty($arguments->get($arguments->getArgc()));
|
||||
$this->assertEquals('default', $arguments->get($arguments->getArgc(), 'default'));
|
||||
}
|
||||
|
||||
public function dataStripped()
|
||||
{
|
||||
return [
|
||||
'strippedZRLFirst' => [
|
||||
'assert' => '?arg1=value1',
|
||||
'input' => '?zrl=nope&arg1=value1',
|
||||
],
|
||||
'strippedZRLLast' => [
|
||||
'assert' => '?arg1=value1',
|
||||
'input' => '?arg1=value1&zrl=nope',
|
||||
],
|
||||
'strippedZTLMiddle' => [
|
||||
'assert' => '?arg1=value1&arg2=value2',
|
||||
'input' => '?arg1=value1&zrl=nope&arg2=value2',
|
||||
],
|
||||
'strippedOWTFirst' => [
|
||||
'assert' => '?arg1=value1',
|
||||
'input' => '?owt=test&arg1=value1',
|
||||
],
|
||||
'strippedOWTLast' => [
|
||||
'assert' => '?arg1=value1',
|
||||
'input' => '?arg1=value1&owt=test',
|
||||
],
|
||||
'strippedOWTMiddle' => [
|
||||
'assert' => '?arg1=value1&arg2=value2',
|
||||
'input' => '?arg1=value1&owt=test&arg2=value2',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the ZRL and OWT stripping
|
||||
*
|
||||
* @dataProvider dataStripped
|
||||
*/
|
||||
public function testStrippedQueries(string $assert, string $input)
|
||||
{
|
||||
$command = 'test/it';
|
||||
|
||||
$arguments = (new App\Arguments())
|
||||
->determine(['QUERY_STRING' => 'q=' . $command . $input,], ['pagename' => $command]);
|
||||
|
||||
$this->assertEquals($command . $assert, $arguments->getQueryString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that arguments are immutable
|
||||
*/
|
||||
public function testImmutable()
|
||||
{
|
||||
$argument = new App\Arguments();
|
||||
|
||||
$argNew = $argument->determine([], []);
|
||||
|
||||
$this->assertNotSame($argument, $argNew);
|
||||
}
|
||||
}
|
|
@ -38,22 +38,20 @@ class ModeTest extends MockedTest
|
|||
$this->setUpVfsDir();
|
||||
|
||||
$this->basePathMock = \Mockery::mock(BasePath::class);
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->databaseMock = \Mockery::mock(Database::class);
|
||||
$this->configCacheMock = \Mockery::mock(Config\Cache\ConfigCache::class);
|
||||
}
|
||||
|
||||
public function testItEmpty()
|
||||
{
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$mode = new Mode();
|
||||
$this->assertTrue($mode->isInstall());
|
||||
$this->assertFalse($mode->isNormal());
|
||||
}
|
||||
|
||||
public function testWithoutConfig()
|
||||
{
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->assertTrue($this->root->hasChild('config/local.config.php'));
|
||||
|
||||
|
@ -61,7 +59,7 @@ class ModeTest extends MockedTest
|
|||
|
||||
$this->assertFalse($this->root->hasChild('config/local.config.php'));
|
||||
|
||||
$mode->determine();
|
||||
$mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertTrue($mode->isInstall());
|
||||
$this->assertFalse($mode->isNormal());
|
||||
|
@ -71,10 +69,11 @@ class ModeTest extends MockedTest
|
|||
|
||||
public function testWithoutDatabase()
|
||||
{
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->databaseMock->shouldReceive('connected')->andReturn(false)->once();
|
||||
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$mode->determine();
|
||||
$mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertFalse($mode->isNormal());
|
||||
$this->assertTrue($mode->isInstall());
|
||||
|
@ -85,12 +84,13 @@ class ModeTest extends MockedTest
|
|||
|
||||
public function testWithoutDatabaseSetup()
|
||||
{
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
|
||||
$this->databaseMock->shouldReceive('fetchFirst')
|
||||
->with('SHOW TABLES LIKE \'config\'')->andReturn(false)->once();
|
||||
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$mode->determine();
|
||||
$mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertFalse($mode->isNormal());
|
||||
$this->assertTrue($mode->isInstall());
|
||||
|
@ -100,14 +100,15 @@ class ModeTest extends MockedTest
|
|||
|
||||
public function testWithMaintenanceMode()
|
||||
{
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
|
||||
$this->databaseMock->shouldReceive('fetchFirst')
|
||||
->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once();
|
||||
$this->configCacheMock->shouldReceive('get')->with('system', 'maintenance')
|
||||
->andReturn(true)->once();
|
||||
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$mode->determine();
|
||||
$mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertFalse($mode->isNormal());
|
||||
$this->assertFalse($mode->isInstall());
|
||||
|
@ -118,6 +119,8 @@ class ModeTest extends MockedTest
|
|||
|
||||
public function testNormalMode()
|
||||
{
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
|
||||
$this->databaseMock->shouldReceive('fetchFirst')
|
||||
->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once();
|
||||
|
@ -127,8 +130,7 @@ class ModeTest extends MockedTest
|
|||
->with('config', ['v'], ['cat' => 'system', 'k' => 'maintenance'])
|
||||
->andReturn(['v' => null])->once();
|
||||
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$mode->determine();
|
||||
$mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertTrue($mode->isNormal());
|
||||
$this->assertFalse($mode->isInstall());
|
||||
|
@ -142,6 +144,8 @@ class ModeTest extends MockedTest
|
|||
*/
|
||||
public function testDisabledMaintenance()
|
||||
{
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn($this->root->url())->once();
|
||||
|
||||
$this->databaseMock->shouldReceive('connected')->andReturn(true)->once();
|
||||
$this->databaseMock->shouldReceive('fetchFirst')
|
||||
->with('SHOW TABLES LIKE \'config\'')->andReturn(true)->once();
|
||||
|
@ -151,8 +155,7 @@ class ModeTest extends MockedTest
|
|||
->with('config', ['v'], ['cat' => 'system', 'k' => 'maintenance'])
|
||||
->andReturn(['v' => '0'])->once();
|
||||
|
||||
$mode = new Mode($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
$mode->determine();
|
||||
$mode = (new Mode())->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertTrue($mode->isNormal());
|
||||
$this->assertFalse($mode->isInstall());
|
||||
|
@ -160,4 +163,18 @@ class ModeTest extends MockedTest
|
|||
$this->assertTrue($mode->has(Mode::DBCONFIGAVAILABLE));
|
||||
$this->assertTrue($mode->has(Mode::MAINTENANCEDISABLED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that modes are immutable
|
||||
*/
|
||||
public function testImmutable()
|
||||
{
|
||||
$this->basePathMock->shouldReceive('getPath')->andReturn(null)->once();
|
||||
|
||||
$mode = new Mode();
|
||||
|
||||
$modeNew = $mode->determine($this->basePathMock, $this->databaseMock, $this->configCacheMock);
|
||||
|
||||
$this->assertNotSame($modeNew, $mode);
|
||||
}
|
||||
}
|
||||
|
|
189
tests/src/App/ModuleTest.php
Normal file
189
tests/src/App/ModuleTest.php
Normal file
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
|
||||
namespace Friendica\Test\src\App;
|
||||
|
||||
use Friendica\App;
|
||||
use Friendica\Core\Config\Configuration;
|
||||
use Friendica\LegacyModule;
|
||||
use Friendica\Module\PageNotFound;
|
||||
use Friendica\Module\WellKnown\HostMeta;
|
||||
use Friendica\Test\DatabaseTest;
|
||||
|
||||
class ModuleTest extends DatabaseTest
|
||||
{
|
||||
private function assertModule(array $assert, App\Module $module)
|
||||
{
|
||||
$this->assertEquals($assert['isBackend'], $module->isBackend());
|
||||
$this->assertEquals($assert['name'], $module->getName());
|
||||
$this->assertEquals($assert['class'], $module->getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the default module mode
|
||||
*/
|
||||
public function testDefault()
|
||||
{
|
||||
$module = new App\Module();
|
||||
|
||||
$this->assertModule([
|
||||
'isBackend' => false,
|
||||
'name' => App\Module::DEFAULT,
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
], $module);
|
||||
}
|
||||
|
||||
public function dataModuleName()
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
'assert' => [
|
||||
'isBackend' => false,
|
||||
'name' => 'network',
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments('network/data/in',
|
||||
'network/data/in',
|
||||
['network', 'data', 'in'],
|
||||
3),
|
||||
'server' => [],
|
||||
],
|
||||
'withStrikeAndPoint' => [
|
||||
'assert' => [
|
||||
'isBackend' => false,
|
||||
'name' => 'with_strike_and_point',
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments('with-strike.and-point/data/in',
|
||||
'with-strike.and-point/data/in',
|
||||
['with-strike.and-point', 'data', 'in'],
|
||||
3),
|
||||
'server' => [],
|
||||
],
|
||||
'withNothing' => [
|
||||
'assert' => [
|
||||
'isBackend' => false,
|
||||
'name' => App\Module::DEFAULT,
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments(),
|
||||
'server' => []
|
||||
],
|
||||
'withIndex' => [
|
||||
'assert' => [
|
||||
'isBackend' => false,
|
||||
'name' => App\Module::DEFAULT,
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments(),
|
||||
'server' => ['PHP_SELF' => 'index.php']
|
||||
],
|
||||
'withIndexButBackendMod' => [
|
||||
'assert' => [
|
||||
'isBackend' => false,
|
||||
'name' => App\Module::BACKEND_MODULES[0],
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments(App\Module::BACKEND_MODULES[0] . '/data/in',
|
||||
App\Module::BACKEND_MODULES[0] . '/data/in',
|
||||
[App\Module::BACKEND_MODULES[0], 'data', 'in'],
|
||||
3),
|
||||
'server' => ['PHP_SELF' => 'index.php']
|
||||
],
|
||||
'withNotIndexAndBackendMod' => [
|
||||
'assert' => [
|
||||
'isBackend' => true,
|
||||
'name' => App\Module::BACKEND_MODULES[0],
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments(App\Module::BACKEND_MODULES[0] . '/data/in',
|
||||
App\Module::BACKEND_MODULES[0] . '/data/in',
|
||||
[App\Module::BACKEND_MODULES[0], 'data', 'in'],
|
||||
3),
|
||||
'server' => ['PHP_SELF' => 'daemon.php']
|
||||
],
|
||||
'withFirefoxApp' => [
|
||||
'assert' => [
|
||||
'isBackend' => false,
|
||||
'name' => 'login',
|
||||
'class' => App\Module::DEFAULT_CLASS,
|
||||
],
|
||||
'args' => new App\Arguments('users/sign_in',
|
||||
'users/sign_in',
|
||||
['users', 'sign_in'],
|
||||
3),
|
||||
'server' => ['PHP_SELF' => 'index.php'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the module name and backend determination
|
||||
*
|
||||
* @dataProvider dataModuleName
|
||||
*/
|
||||
public function testModuleName(array $assert, App\Arguments $args, array $server)
|
||||
{
|
||||
$module = (new App\Module())->determineModule($args, $server);
|
||||
|
||||
$this->assertModule($assert, $module);
|
||||
}
|
||||
|
||||
public function dataModuleClass()
|
||||
{
|
||||
return [
|
||||
'default' => [
|
||||
'assert' => App\Module::DEFAULT_CLASS,
|
||||
'name' => App\Module::DEFAULT,
|
||||
'command' => App\Module::DEFAULT,
|
||||
'privAdd' => false,
|
||||
],
|
||||
'legacy' => [
|
||||
'assert' => LegacyModule::class,
|
||||
// API is one of the last modules to switch from legacy to new BaseModule
|
||||
// so this should be a stable test case until we completely switch ;-)
|
||||
'name' => 'api',
|
||||
'command' => 'api/test/it',
|
||||
'privAdd' => false,
|
||||
],
|
||||
'new' => [
|
||||
'assert' => HostMeta::class,
|
||||
'not_required',
|
||||
'command' => '.well-known/host-meta',
|
||||
'privAdd' => false,
|
||||
],
|
||||
'404' => [
|
||||
'assert' => PageNotFound::class,
|
||||
'name' => 'invalid',
|
||||
'command' => 'invalid',
|
||||
'privAdd' => false,
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the determination of the module class
|
||||
*
|
||||
* @dataProvider dataModuleClass
|
||||
*/
|
||||
public function testModuleClass($assert, string $name, string $command, bool $privAdd)
|
||||
{
|
||||
$config = \Mockery::mock(Configuration::class);
|
||||
$config->shouldReceive('get')->with('config', 'private_addons', false)->andReturn($privAdd)->atMost()->once();
|
||||
|
||||
$module = (new App\Module($name))->determineClass(new App\Arguments('', $command), new App\Router(), $config);
|
||||
|
||||
$this->assertEquals($assert, $module->getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that modules are immutable
|
||||
*/
|
||||
public function testImmutable()
|
||||
{
|
||||
$module = new App\Module();
|
||||
|
||||
$moduleNew = $module->determineModule(new App\Arguments(), []);
|
||||
|
||||
$this->assertNotSame($moduleNew, $module);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue