Added Route layer proof of concept

This commit is contained in:
Marcin Kurczewski 2014-11-19 22:00:50 +01:00
parent 9e894bc41c
commit 2a7ca79b2d
7 changed files with 107 additions and 7 deletions

View file

@ -24,6 +24,7 @@ final class Dispatcher
HttpHelper $httpHelper,
AuthService $authService,
TokenService $tokenService,
RouteRepository $routeRepository,
ControllerRepository $controllerRepository)
{
$this->router = $router;
@ -38,6 +39,8 @@ final class Dispatcher
foreach ($controllerRepository->getControllers() as $controller)
$controller->registerRoutes($router);
$routeRepository->injectRoutes($router);
}
public function run($requestMethod, $requestUri)

29
src/RouteRepository.php Normal file
View 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']);
}
}
}
}

View file

@ -0,0 +1,11 @@
<?php
namespace Szurubooru\Routes;
abstract class AbstractRoute
{
public abstract function getMethods();
public abstract function getUrl();
public abstract function work();
}

View file

@ -1,5 +1,5 @@
<?php
namespace Szurubooru\Controllers;
namespace Szurubooru\Routes;
use Szurubooru\Controllers\ViewProxies\TokenViewProxy;
use Szurubooru\Controllers\ViewProxies\UserViewProxy;
use Szurubooru\FormData\LoginFormData;
@ -10,7 +10,7 @@ use Szurubooru\Services\PrivilegeService;
use Szurubooru\Services\TokenService;
use Szurubooru\Services\UserService;
final class AuthController extends AbstractController
class Login extends AbstractRoute
{
private $authService;
private $userService;
@ -38,13 +38,17 @@ final class AuthController extends AbstractController
$this->tokenViewProxy = $tokenViewProxy;
}
public function registerRoutes(Router $router)
public function getMethods()
{
$router->post('/api/login', [$this, 'login']);
$router->put('/api/login', [$this, 'login']);
return ['POST', 'PUT'];
}
public function login()
public function getUrl()
{
return '/api/login';
}
public function work()
{
if (isset($this->inputReader->userNameOrEmail) && isset($this->inputReader->password))
{

View file

@ -11,6 +11,7 @@ $publicDataDirectory = __DIR__
return [
\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\Upgrades\UpgradeRepository::class => DI\object()->constructor(DI\link('upgrades')),
@ -56,7 +57,6 @@ return [
'controllers' => DI\factory(function (DI\container $container) {
return [
$container->get(\Szurubooru\Controllers\AuthController::class),
$container->get(\Szurubooru\Controllers\UserController::class),
$container->get(\Szurubooru\Controllers\UserAvatarController::class),
$container->get(\Szurubooru\Controllers\PostController::class),
@ -70,4 +70,10 @@ return [
$container->get(\Szurubooru\Controllers\TagController::class),
];
}),
'routes' => DI\factory(function (DI\container $container) {
return [
$container->get(\Szurubooru\Routes\Login::class),
];
}),
];

View file

@ -3,6 +3,7 @@ namespace Szurubooru\Tests;
use Szurubooru\ControllerRepository;
use Szurubooru\Dispatcher;
use Szurubooru\Helpers\HttpHelper;
use Szurubooru\RouteRepository;
use Szurubooru\Router;
use Szurubooru\Services\AuthService;
use Szurubooru\Services\TokenService;
@ -16,6 +17,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
private $authServiceMock;
private $tokenServiceMock;
private $controllerRepositoryMock;
private $routeRepositoryMock;
public function setUp()
{
@ -26,6 +28,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
$this->authServiceMock = $this->mock(AuthService::class);
$this->tokenServiceMock = $this->mock(TokenService::class);
$this->controllerRepositoryMock = $this->mock(ControllerRepository::class);
$this->routeRepositoryMock = $this->mock(RouteRepository::class);
$this->configMock->set('misc/dumpSqlIntoQueries', 0);
}
@ -39,6 +42,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
->withConsecutive([$this->equalTo(500)], [$this->equalTo(200)]);
$this->routerMock->expects($this->once())->method('handle')->willReturn($expected);
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
$this->routeRepositoryMock->expects($this->once())->method('injectRoutes');
$dispatcher = $this->getDispatcher();
$actual = $dispatcher->run('GET', '/');
@ -55,6 +59,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
$this->routerMock->expects($this->once())->method('handle')->willReturn($classData);
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
$this->routeRepositoryMock->expects($this->once())->method('injectRoutes');
$dispatcher = $this->getDispatcher();
$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->tokenServiceMock->expects($this->once())->method('getByName');
$this->controllerRepositoryMock->method('getControllers')->willReturn([]);
$this->routeRepositoryMock->expects($this->once())->method('injectRoutes');
$dispatcher = $this->getDispatcher();
$dispatcher->run('GET', '/');
@ -82,6 +88,7 @@ final class DispatcherTest extends AbstractDatabaseTestCase
$this->httpHelperMock,
$this->authServiceMock,
$this->tokenServiceMock,
$this->routeRepositoryMock,
$this->controllerRepositoryMock);
}
}

View 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');
}
}