Added Route layer proof of concept
This commit is contained in:
parent
9e894bc41c
commit
2a7ca79b2d
7 changed files with 107 additions and 7 deletions
|
@ -24,6 +24,7 @@ final class Dispatcher
|
||||||
HttpHelper $httpHelper,
|
HttpHelper $httpHelper,
|
||||||
AuthService $authService,
|
AuthService $authService,
|
||||||
TokenService $tokenService,
|
TokenService $tokenService,
|
||||||
|
RouteRepository $routeRepository,
|
||||||
ControllerRepository $controllerRepository)
|
ControllerRepository $controllerRepository)
|
||||||
{
|
{
|
||||||
$this->router = $router;
|
$this->router = $router;
|
||||||
|
@ -38,6 +39,8 @@ final class Dispatcher
|
||||||
|
|
||||||
foreach ($controllerRepository->getControllers() as $controller)
|
foreach ($controllerRepository->getControllers() as $controller)
|
||||||
$controller->registerRoutes($router);
|
$controller->registerRoutes($router);
|
||||||
|
|
||||||
|
$routeRepository->injectRoutes($router);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function run($requestMethod, $requestUri)
|
public function run($requestMethod, $requestUri)
|
||||||
|
|
29
src/RouteRepository.php
Normal file
29
src/RouteRepository.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru;
|
||||||
|
|
||||||
|
class RouteRepository
|
||||||
|
{
|
||||||
|
private $routes = [];
|
||||||
|
|
||||||
|
public function __construct(array $routes)
|
||||||
|
{
|
||||||
|
$this->routes = $routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRoutes()
|
||||||
|
{
|
||||||
|
return $this->routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function injectRoutes(Router $router)
|
||||||
|
{
|
||||||
|
foreach ($this->routes as $route)
|
||||||
|
{
|
||||||
|
foreach ($route->getMethods() as $method)
|
||||||
|
{
|
||||||
|
$method = strtolower($method);
|
||||||
|
$router->$method($route->getUrl(), [$route, 'work']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
src/Routes/AbstractRoute.php
Normal file
11
src/Routes/AbstractRoute.php
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\Routes;
|
||||||
|
|
||||||
|
abstract class AbstractRoute
|
||||||
|
{
|
||||||
|
public abstract function getMethods();
|
||||||
|
|
||||||
|
public abstract function getUrl();
|
||||||
|
|
||||||
|
public abstract function work();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Szurubooru\Controllers;
|
namespace Szurubooru\Routes;
|
||||||
use Szurubooru\Controllers\ViewProxies\TokenViewProxy;
|
use Szurubooru\Controllers\ViewProxies\TokenViewProxy;
|
||||||
use Szurubooru\Controllers\ViewProxies\UserViewProxy;
|
use Szurubooru\Controllers\ViewProxies\UserViewProxy;
|
||||||
use Szurubooru\FormData\LoginFormData;
|
use Szurubooru\FormData\LoginFormData;
|
||||||
|
@ -10,7 +10,7 @@ use Szurubooru\Services\PrivilegeService;
|
||||||
use Szurubooru\Services\TokenService;
|
use Szurubooru\Services\TokenService;
|
||||||
use Szurubooru\Services\UserService;
|
use Szurubooru\Services\UserService;
|
||||||
|
|
||||||
final class AuthController extends AbstractController
|
class Login extends AbstractRoute
|
||||||
{
|
{
|
||||||
private $authService;
|
private $authService;
|
||||||
private $userService;
|
private $userService;
|
||||||
|
@ -38,13 +38,17 @@ final class AuthController extends AbstractController
|
||||||
$this->tokenViewProxy = $tokenViewProxy;
|
$this->tokenViewProxy = $tokenViewProxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function registerRoutes(Router $router)
|
public function getMethods()
|
||||||
{
|
{
|
||||||
$router->post('/api/login', [$this, 'login']);
|
return ['POST', 'PUT'];
|
||||||
$router->put('/api/login', [$this, 'login']);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function login()
|
public function getUrl()
|
||||||
|
{
|
||||||
|
return '/api/login';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function work()
|
||||||
{
|
{
|
||||||
if (isset($this->inputReader->userNameOrEmail) && isset($this->inputReader->password))
|
if (isset($this->inputReader->userNameOrEmail) && isset($this->inputReader->password))
|
||||||
{
|
{
|
|
@ -11,6 +11,7 @@ $publicDataDirectory = __DIR__
|
||||||
return [
|
return [
|
||||||
\Szurubooru\Config::class => DI\object()->constructor($dataDirectory, $publicDataDirectory),
|
\Szurubooru\Config::class => DI\object()->constructor($dataDirectory, $publicDataDirectory),
|
||||||
|
|
||||||
|
\Szurubooru\RouteRepository::class => DI\object()->constructor(DI\link('routes')),
|
||||||
\Szurubooru\ControllerRepository::class => DI\object()->constructor(DI\link('controllers')),
|
\Szurubooru\ControllerRepository::class => DI\object()->constructor(DI\link('controllers')),
|
||||||
\Szurubooru\Upgrades\UpgradeRepository::class => DI\object()->constructor(DI\link('upgrades')),
|
\Szurubooru\Upgrades\UpgradeRepository::class => DI\object()->constructor(DI\link('upgrades')),
|
||||||
|
|
||||||
|
@ -56,7 +57,6 @@ return [
|
||||||
|
|
||||||
'controllers' => DI\factory(function (DI\container $container) {
|
'controllers' => DI\factory(function (DI\container $container) {
|
||||||
return [
|
return [
|
||||||
$container->get(\Szurubooru\Controllers\AuthController::class),
|
|
||||||
$container->get(\Szurubooru\Controllers\UserController::class),
|
$container->get(\Szurubooru\Controllers\UserController::class),
|
||||||
$container->get(\Szurubooru\Controllers\UserAvatarController::class),
|
$container->get(\Szurubooru\Controllers\UserAvatarController::class),
|
||||||
$container->get(\Szurubooru\Controllers\PostController::class),
|
$container->get(\Szurubooru\Controllers\PostController::class),
|
||||||
|
@ -70,4 +70,10 @@ return [
|
||||||
$container->get(\Szurubooru\Controllers\TagController::class),
|
$container->get(\Szurubooru\Controllers\TagController::class),
|
||||||
];
|
];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
'routes' => DI\factory(function (DI\container $container) {
|
||||||
|
return [
|
||||||
|
$container->get(\Szurubooru\Routes\Login::class),
|
||||||
|
];
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
|
|
@ -3,6 +3,7 @@ namespace Szurubooru\Tests;
|
||||||
use Szurubooru\ControllerRepository;
|
use Szurubooru\ControllerRepository;
|
||||||
use Szurubooru\Dispatcher;
|
use Szurubooru\Dispatcher;
|
||||||
use Szurubooru\Helpers\HttpHelper;
|
use Szurubooru\Helpers\HttpHelper;
|
||||||
|
use Szurubooru\RouteRepository;
|
||||||
use Szurubooru\Router;
|
use Szurubooru\Router;
|
||||||
use Szurubooru\Services\AuthService;
|
use Szurubooru\Services\AuthService;
|
||||||
use Szurubooru\Services\TokenService;
|
use Szurubooru\Services\TokenService;
|
||||||
|
@ -16,6 +17,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
|
||||||
private $authServiceMock;
|
private $authServiceMock;
|
||||||
private $tokenServiceMock;
|
private $tokenServiceMock;
|
||||||
private $controllerRepositoryMock;
|
private $controllerRepositoryMock;
|
||||||
|
private $routeRepositoryMock;
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
|
@ -26,6 +28,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
|
||||||
$this->authServiceMock = $this->mock(AuthService::class);
|
$this->authServiceMock = $this->mock(AuthService::class);
|
||||||
$this->tokenServiceMock = $this->mock(TokenService::class);
|
$this->tokenServiceMock = $this->mock(TokenService::class);
|
||||||
$this->controllerRepositoryMock = $this->mock(ControllerRepository::class);
|
$this->controllerRepositoryMock = $this->mock(ControllerRepository::class);
|
||||||
|
$this->routeRepositoryMock = $this->mock(RouteRepository::class);
|
||||||
$this->configMock->set('misc/dumpSqlIntoQueries', 0);
|
$this->configMock->set('misc/dumpSqlIntoQueries', 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +42,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
|
||||||
->withConsecutive([$this->equalTo(500)], [$this->equalTo(200)]);
|
->withConsecutive([$this->equalTo(500)], [$this->equalTo(200)]);
|
||||||
$this->routerMock->expects($this->once())->method('handle')->willReturn($expected);
|
$this->routerMock->expects($this->once())->method('handle')->willReturn($expected);
|
||||||
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
|
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
|
||||||
|
$this->routeRepositoryMock->expects($this->once())->method('injectRoutes');
|
||||||
|
|
||||||
$dispatcher = $this->getDispatcher();
|
$dispatcher = $this->getDispatcher();
|
||||||
$actual = $dispatcher->run('GET', '/');
|
$actual = $dispatcher->run('GET', '/');
|
||||||
|
@ -55,6 +59,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
|
||||||
|
|
||||||
$this->routerMock->expects($this->once())->method('handle')->willReturn($classData);
|
$this->routerMock->expects($this->once())->method('handle')->willReturn($classData);
|
||||||
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
|
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
|
||||||
|
$this->routeRepositoryMock->expects($this->once())->method('injectRoutes');
|
||||||
|
|
||||||
$dispatcher = $this->getDispatcher();
|
$dispatcher = $this->getDispatcher();
|
||||||
$actual = $dispatcher->run('GET', '/');
|
$actual = $dispatcher->run('GET', '/');
|
||||||
|
@ -68,6 +73,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
|
||||||
$this->httpHelperMock->expects($this->once())->method('getRequestHeader')->with($this->equalTo('X-Authorization-Token'))->willReturn('test');
|
$this->httpHelperMock->expects($this->once())->method('getRequestHeader')->with($this->equalTo('X-Authorization-Token'))->willReturn('test');
|
||||||
$this->tokenServiceMock->expects($this->once())->method('getByName');
|
$this->tokenServiceMock->expects($this->once())->method('getByName');
|
||||||
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
|
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
|
||||||
|
$this->routeRepositoryMock->expects($this->once())->method('injectRoutes');
|
||||||
|
|
||||||
$dispatcher = $this->getDispatcher();
|
$dispatcher = $this->getDispatcher();
|
||||||
$dispatcher->run('GET', '/');
|
$dispatcher->run('GET', '/');
|
||||||
|
@ -82,6 +88,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
|
||||||
$this->httpHelperMock,
|
$this->httpHelperMock,
|
||||||
$this->authServiceMock,
|
$this->authServiceMock,
|
||||||
$this->tokenServiceMock,
|
$this->tokenServiceMock,
|
||||||
|
$this->routeRepositoryMock,
|
||||||
$this->controllerRepositoryMock);
|
$this->controllerRepositoryMock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
tests/RouteRepositoryTest.php
Normal file
40
tests/RouteRepositoryTest.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
namespace Szurubooru\Tests;
|
||||||
|
use Szurubooru\Injector;
|
||||||
|
use Szurubooru\RouteRepository;
|
||||||
|
use Szurubooru\Router;
|
||||||
|
use Szurubooru\Routes\AbstractRoute;
|
||||||
|
use Szurubooru\Tests\AbstractTestCase;
|
||||||
|
|
||||||
|
final class RouteRepositoryTest extends AbstractTestCase
|
||||||
|
{
|
||||||
|
public function testFactory()
|
||||||
|
{
|
||||||
|
$routeRepository = Injector::get(RouteRepository::class);
|
||||||
|
$this->assertNotEmpty($routeRepository->getRoutes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRouteInjection()
|
||||||
|
{
|
||||||
|
$routerMock = $this->mock(Router::class);
|
||||||
|
$routeMock = $this->mock(AbstractRoute::class);
|
||||||
|
$routeMock->expects($this->once())->method('getMethods')->willReturn(['POST', 'GET']);
|
||||||
|
$routeMock->expects($this->atLeast(1))->method('getUrl')->willReturn('/test');
|
||||||
|
$routerMock->expects($this->once())->method('post')->with('/test', $this->anything());
|
||||||
|
$routerMock->expects($this->once())->method('get')->with('/test', $this->anything());
|
||||||
|
$routeRepository = new RouteRepository([$routeMock]);
|
||||||
|
$routeRepository->injectRoutes($routerMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRouteCallbackInjection()
|
||||||
|
{
|
||||||
|
$router = new Router();
|
||||||
|
$routeMock = $this->mock(AbstractRoute::class);
|
||||||
|
$routeMock->expects($this->once())->method('getMethods')->willReturn(['POST', 'GET']);
|
||||||
|
$routeMock->expects($this->atLeast(1))->method('getUrl')->willReturn('/test');
|
||||||
|
$routeMock->expects($this->atLeast(1))->method('work');
|
||||||
|
$routeRepository = new RouteRepository([$routeMock]);
|
||||||
|
$routeRepository->injectRoutes($router);
|
||||||
|
$router->handle('GET', '/test');
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue