Simple Route
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
require_once 'Dummy/Managers/TestBootManager.php';
|
||||
require_once 'Dummy/Managers/FindUrlBootManager.php';
|
||||
|
||||
class BootManagerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testBootManagerRoutes()
|
||||
{
|
||||
$result = false;
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
TestRouter::get('/about', 'DummyController@method2');
|
||||
TestRouter::get('/contact', 'DummyController@method3');
|
||||
|
||||
// Add boot-manager
|
||||
TestRouter::addBootManager(new TestBootManager([
|
||||
'/con' => '/about',
|
||||
'/contact' => '/',
|
||||
]));
|
||||
|
||||
TestRouter::debug('/contact');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testFindUrlFromBootManager()
|
||||
{
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
TestRouter::get('/about', 'DummyController@method2')->name('about');
|
||||
TestRouter::get('/contact', 'DummyController@method3')->name('contact');
|
||||
|
||||
$result = false;
|
||||
|
||||
// Add boot-manager
|
||||
TestRouter::addBootManager(new FindUrlBootManager($result));
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/ClassLoader/CustomClassLoader.php';
|
||||
|
||||
class ClassLoaderTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testCustomClassLoader()
|
||||
{
|
||||
$result = false;
|
||||
|
||||
TestRouter::setCustomClassLoader(new CustomClassLoader());
|
||||
|
||||
TestRouter::get('/', 'NonExistingClass@method3');
|
||||
TestRouter::get('/test-closure', function($status) use(&$result) {
|
||||
$result = $status;
|
||||
});
|
||||
|
||||
$classLoaderClass = TestRouter::debugOutput('/', 'get', false);
|
||||
TestRouter::debugOutput('/test-closure');
|
||||
|
||||
$this->assertEquals('method3', $classLoaderClass);
|
||||
$this->assertTrue($result);
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
require_once 'Dummy/CsrfVerifier/DummyCsrfVerifier.php';
|
||||
require_once 'Dummy/Security/SilentTokenProvider.php';
|
||||
|
||||
class CsrfVerifierTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testTokenPass()
|
||||
{
|
||||
global $_POST;
|
||||
|
||||
$tokenProvider = new SilentTokenProvider();
|
||||
|
||||
$_POST[DummyCsrfVerifier::POST_KEY] = $tokenProvider->getToken();
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->getRequest()->setMethod(\Pecee\Http\Request::REQUEST_TYPE_POST);
|
||||
$router->getRequest()->setUrl(new \Pecee\Http\Url('/page'));
|
||||
$csrf = new DummyCsrfVerifier();
|
||||
$csrf->setTokenProvider($tokenProvider);
|
||||
|
||||
$csrf->handle($router->getRequest());
|
||||
|
||||
// If handle doesn't throw exception, the test has passed
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testTokenFail()
|
||||
{
|
||||
$this->expectException(\Pecee\Http\Middleware\Exceptions\TokenMismatchException::class);
|
||||
|
||||
global $_POST;
|
||||
|
||||
$tokenProvider = new SilentTokenProvider();
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->getRequest()->setMethod(\Pecee\Http\Request::REQUEST_TYPE_POST);
|
||||
$router->getRequest()->setUrl(new \Pecee\Http\Url('/page'));
|
||||
$csrf = new DummyCsrfVerifier();
|
||||
$csrf->setTokenProvider($tokenProvider);
|
||||
|
||||
$csrf->handle($router->getRequest());
|
||||
}
|
||||
|
||||
public function testExcludeInclude()
|
||||
{
|
||||
$router = TestRouter::router();
|
||||
$csrf = new DummyCsrfVerifier();
|
||||
$request = $router->getRequest();
|
||||
|
||||
$request->setUrl(new \Pecee\Http\Url('/exclude-page'));
|
||||
$this->assertTrue($csrf->testSkip($router->getRequest()));
|
||||
|
||||
$request->setUrl(new \Pecee\Http\Url('/exclude-all/page'));
|
||||
$this->assertTrue($csrf->testSkip($router->getRequest()));
|
||||
|
||||
$request->setUrl(new \Pecee\Http\Url('/exclude-all/include-page'));
|
||||
$this->assertFalse($csrf->testSkip($router->getRequest()));
|
||||
|
||||
$request->setUrl(new \Pecee\Http\Url('/include-page'));
|
||||
$this->assertFalse($csrf->testSkip($router->getRequest()));
|
||||
}
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Middleware/IpRestrictMiddleware.php';
|
||||
|
||||
class CustomMiddlewareTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testIpBlock() {
|
||||
|
||||
$this->expectException(\Pecee\SimpleRouter\Exceptions\HttpException::class);
|
||||
|
||||
global $_SERVER;
|
||||
|
||||
// Test exact ip
|
||||
|
||||
$_SERVER['remote-addr'] = '5.5.5.5';
|
||||
|
||||
TestRouter::group(['middleware' => IpRestrictMiddleware::class], function() {
|
||||
TestRouter::get('/fail', 'DummyController@method1');
|
||||
});
|
||||
|
||||
TestRouter::debug('/fail');
|
||||
|
||||
// Test ip-range
|
||||
|
||||
$_SERVER['remote-addr'] = '8.8.4.4';
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
TestRouter::group(['middleware' => IpRestrictMiddleware::class], function() {
|
||||
TestRouter::get('/fail', 'DummyController@method1');
|
||||
});
|
||||
|
||||
TestRouter::debug('/fail');
|
||||
|
||||
}
|
||||
|
||||
public function testIpSuccess() {
|
||||
|
||||
global $_SERVER;
|
||||
|
||||
// Test ip that is not blocked
|
||||
|
||||
$_SERVER['remote-addr'] = '6.6.6.6';
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
TestRouter::group(['middleware' => IpRestrictMiddleware::class], function() {
|
||||
TestRouter::get('/success', 'DummyController@method1');
|
||||
});
|
||||
|
||||
TestRouter::debug('/success');
|
||||
|
||||
// Test ip in whitelist
|
||||
|
||||
$_SERVER['remote-addr'] = '8.8.2.2';
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
TestRouter::group(['middleware' => IpRestrictMiddleware::class], function() {
|
||||
TestRouter::get('/success', 'DummyController@method1');
|
||||
});
|
||||
|
||||
TestRouter::debug('/success');
|
||||
|
||||
$this->assertTrue(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class CustomClassLoader implements \Pecee\SimpleRouter\ClassLoader\IClassLoader
|
||||
{
|
||||
public function loadClass(string $class)
|
||||
{
|
||||
return new DummyController();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when loading class method
|
||||
* @param object $class
|
||||
* @param string $method
|
||||
* @param array $parameters
|
||||
* @return object
|
||||
*/
|
||||
public function loadClassMethod($class, string $method, array $parameters)
|
||||
{
|
||||
return call_user_func_array([$class, $method], [true]);
|
||||
}
|
||||
|
||||
public function loadClosure(callable $closure, array $parameters)
|
||||
{
|
||||
return call_user_func_array($closure, [true]);
|
||||
}
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
class DummyCsrfVerifier extends \Pecee\Http\Middleware\BaseCsrfVerifier {
|
||||
|
||||
protected array $except = [
|
||||
'/exclude-page',
|
||||
'/exclude-all/*',
|
||||
];
|
||||
|
||||
protected array $include = [
|
||||
'/exclude-all/include-page',
|
||||
];
|
||||
|
||||
public function testSkip(\Pecee\Http\Request $request) {
|
||||
return $this->skip($request);
|
||||
}
|
||||
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
class DummyController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function method1()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function method2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function method3()
|
||||
{
|
||||
return 'method3';
|
||||
}
|
||||
|
||||
public function param($params = null)
|
||||
{
|
||||
echo join(', ', func_get_args());
|
||||
}
|
||||
|
||||
public function getTest()
|
||||
{
|
||||
echo 'getTest';
|
||||
}
|
||||
|
||||
public function postTest()
|
||||
{
|
||||
echo 'postTest';
|
||||
}
|
||||
|
||||
public function putTest()
|
||||
{
|
||||
echo 'putTest';
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
require_once 'Exception/MiddlewareLoadedException.php';
|
||||
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class DummyMiddleware implements \Pecee\Http\Middleware\IMiddleware
|
||||
{
|
||||
public function handle(Request $request) : void
|
||||
{
|
||||
throw new MiddlewareLoadedException('Middleware loaded!');
|
||||
}
|
||||
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
|
||||
class ExceptionHandlerException extends \Exception
|
||||
{
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
class MiddlewareLoadedException extends \Exception
|
||||
{
|
||||
}
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
class ResponseException extends \Exception
|
||||
{
|
||||
protected $response;
|
||||
|
||||
public function __construct($response)
|
||||
{
|
||||
$this->response = $response;
|
||||
parent::__construct('', 0);
|
||||
}
|
||||
|
||||
public function getResponse()
|
||||
{
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
class ExceptionHandler implements \Pecee\SimpleRouter\Handlers\IExceptionHandler
|
||||
{
|
||||
public function handleError(\Pecee\Http\Request $request, \Exception $error) : void
|
||||
{
|
||||
echo $error->getMessage();
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class ExceptionHandlerFirst implements \Pecee\SimpleRouter\Handlers\IExceptionHandler
|
||||
{
|
||||
public function handleError(\Pecee\Http\Request $request, \Exception $error) : void
|
||||
{
|
||||
global $stack;
|
||||
$stack[] = static::class;
|
||||
|
||||
$request->setUrl(new \Pecee\Http\Url('/'));
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class ExceptionHandlerSecond implements \Pecee\SimpleRouter\Handlers\IExceptionHandler
|
||||
{
|
||||
public function handleError(\Pecee\Http\Request $request, \Exception $error) : void
|
||||
{
|
||||
global $stack;
|
||||
$stack[] = static::class;
|
||||
|
||||
$request->setUrl(new \Pecee\Http\Url('/'));
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
class ExceptionHandlerThird implements \Pecee\SimpleRouter\Handlers\IExceptionHandler
|
||||
{
|
||||
public function handleError(\Pecee\Http\Request $request, \Exception $error) : void
|
||||
{
|
||||
global $stack;
|
||||
$stack[] = static::class;
|
||||
|
||||
throw new ResponseException('ExceptionHandler loaded');
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class FindUrlBootManager implements \Pecee\SimpleRouter\IRouterBootManager
|
||||
{
|
||||
protected $result;
|
||||
|
||||
public function __construct(&$result)
|
||||
{
|
||||
$this->result = &$result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when router loads it's routes
|
||||
*
|
||||
* @param \Pecee\SimpleRouter\Router $router
|
||||
* @param \Pecee\Http\Request $request
|
||||
*/
|
||||
public function boot(\Pecee\SimpleRouter\Router $router, \Pecee\Http\Request $request): void
|
||||
{
|
||||
$contact = $router->findRoute('contact');
|
||||
|
||||
if($contact !== null) {
|
||||
$this->result = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
class TestBootManager implements \Pecee\SimpleRouter\IRouterBootManager
|
||||
{
|
||||
|
||||
protected $rewrite;
|
||||
|
||||
public function __construct(array $rewrite)
|
||||
{
|
||||
$this->rewrite = $rewrite;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when router loads it's routes
|
||||
*
|
||||
* @param \Pecee\SimpleRouter\Router $router
|
||||
* @param \Pecee\Http\Request $request
|
||||
*/
|
||||
public function boot(\Pecee\SimpleRouter\Router $router, \Pecee\Http\Request $request): void
|
||||
{
|
||||
foreach ($this->rewrite as $url => $rewrite) {
|
||||
// If the current url matches the rewrite url, we use our custom route
|
||||
|
||||
if ($request->getUrl()->contains($url) === true) {
|
||||
$request->setRewriteUrl($rewrite);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class IpRestrictMiddleware extends \Pecee\Http\Middleware\IpRestrictAccess {
|
||||
|
||||
protected array $ipBlacklist = [
|
||||
'5.5.5.5',
|
||||
'8.8.*',
|
||||
];
|
||||
|
||||
protected array $ipWhitelist = [
|
||||
'8.8.2.2',
|
||||
];
|
||||
|
||||
}
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Middleware\IMiddleware;
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class RewriteMiddleware implements IMiddleware {
|
||||
|
||||
public function handle(Request $request) : void {
|
||||
|
||||
$request->setRewriteCallback(function() {
|
||||
return 'ok';
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
namespace MyNamespace;
|
||||
|
||||
class NSController {
|
||||
|
||||
public function method()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
class ResourceController implements \Pecee\Controllers\IResourceController
|
||||
{
|
||||
|
||||
public function index() : ?string
|
||||
{
|
||||
return 'index';
|
||||
}
|
||||
|
||||
public function show($id) : ?string
|
||||
{
|
||||
return 'show ' . $id;
|
||||
}
|
||||
|
||||
public function store() : ?string
|
||||
{
|
||||
return 'store';
|
||||
}
|
||||
|
||||
public function create() : ?string
|
||||
{
|
||||
return 'create';
|
||||
}
|
||||
|
||||
public function edit($id) : ?string
|
||||
{
|
||||
return 'edit ' . $id;
|
||||
}
|
||||
|
||||
public function update($id) : ?string
|
||||
{
|
||||
return 'update ' . $id;
|
||||
}
|
||||
|
||||
public function destroy($id) : ?string
|
||||
{
|
||||
return 'destroy ' . $id;
|
||||
}
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Request;
|
||||
|
||||
class DummyLoadableRoute extends Pecee\SimpleRouter\Route\LoadableRoute {
|
||||
|
||||
public function matchRoute(string $url, Request $request): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Vendored
+41
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
class SilentTokenProvider implements \Pecee\Http\Security\ITokenProvider {
|
||||
|
||||
protected $token;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh existing token
|
||||
*/
|
||||
public function refresh(): void
|
||||
{
|
||||
$this->token = uniqid('', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate valid CSRF token
|
||||
*
|
||||
* @param string $token
|
||||
* @return bool
|
||||
*/
|
||||
public function validate(string $token): bool
|
||||
{
|
||||
return ($token === $this->token);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get token token
|
||||
*
|
||||
* @param string|null $defaultValue
|
||||
* @return string|null
|
||||
*/
|
||||
public function getToken(?string $defaultValue = null): ?string
|
||||
{
|
||||
return $this->token ?? $defaultValue;
|
||||
}
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
require_once 'Dummy/Security/SilentTokenProvider.php';
|
||||
require_once 'Dummy/Managers/TestBootManager.php';
|
||||
|
||||
use Pecee\SimpleRouter\Event\EventArgument;
|
||||
use Pecee\SimpleRouter\Handlers\EventHandler;
|
||||
|
||||
class EventHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testAllEventTriggered()
|
||||
{
|
||||
$events = EventHandler::$events;
|
||||
|
||||
// Remove the all event
|
||||
unset($events[\array_search(EventHandler::EVENT_ALL, $events, true)]);
|
||||
|
||||
$eventHandler = new EventHandler();
|
||||
$eventHandler->register(EventHandler::EVENT_ALL, function (EventArgument $arg) use (&$events) {
|
||||
$key = \array_search($arg->getEventName(), $events, true);
|
||||
unset($events[$key]);
|
||||
});
|
||||
|
||||
TestRouter::addEventHandler($eventHandler);
|
||||
|
||||
// Add rewrite
|
||||
TestRouter::error(function (\Pecee\Http\Request $request, \Exception $error) {
|
||||
|
||||
// Trigger rewrite
|
||||
$request->setRewriteUrl('/');
|
||||
|
||||
});
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1')->name('home');
|
||||
|
||||
// Trigger findRoute
|
||||
TestRouter::router()->findRoute('home');
|
||||
|
||||
// Trigger getUrl
|
||||
TestRouter::router()->getUrl('home');
|
||||
|
||||
// Add csrf-verifier
|
||||
$csrfVerifier = new \Pecee\Http\Middleware\BaseCsrfVerifier();
|
||||
$csrfVerifier->setTokenProvider(new SilentTokenProvider());
|
||||
TestRouter::csrfVerifier($csrfVerifier);
|
||||
|
||||
// Add boot-manager
|
||||
TestRouter::addBootManager(new TestBootManager([
|
||||
'/test' => '/',
|
||||
]));
|
||||
|
||||
// Start router
|
||||
TestRouter::debug('/non-existing');
|
||||
|
||||
$this->assertEquals($events, []);
|
||||
}
|
||||
|
||||
public function testAllEvent()
|
||||
{
|
||||
$status = false;
|
||||
|
||||
$eventHandler = new EventHandler();
|
||||
$eventHandler->register(EventHandler::EVENT_ALL, function (EventArgument $arg) use (&$status) {
|
||||
$status = true;
|
||||
});
|
||||
|
||||
TestRouter::addEventHandler($eventHandler);
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
TestRouter::debug('/');
|
||||
|
||||
// All event should fire for each other event
|
||||
$this->assertEquals(true, $status);
|
||||
}
|
||||
|
||||
public function testPrefixEvent()
|
||||
{
|
||||
|
||||
$eventHandler = new EventHandler();
|
||||
$eventHandler->register(EventHandler::EVENT_ADD_ROUTE, function (EventArgument $arg) use (&$status) {
|
||||
|
||||
if ($arg->route instanceof \Pecee\SimpleRouter\Route\LoadableRoute) {
|
||||
$arg->route->prependUrl('/local-path');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
TestRouter::addEventHandler($eventHandler);
|
||||
|
||||
$status = false;
|
||||
|
||||
TestRouter::get('/', function () use (&$status) {
|
||||
$status = true;
|
||||
});
|
||||
|
||||
TestRouter::debug('/local-path');
|
||||
|
||||
$this->assertTrue($status);
|
||||
|
||||
}
|
||||
|
||||
public function testCustomBasePath() {
|
||||
|
||||
$basePath = '/basepath/';
|
||||
|
||||
$eventHandler = new EventHandler();
|
||||
$eventHandler->register(EventHandler::EVENT_ADD_ROUTE, function(EventArgument $data) use($basePath) {
|
||||
|
||||
// Skip routes added by group
|
||||
if($data->isSubRoute === false) {
|
||||
|
||||
switch (true) {
|
||||
case $data->route instanceof \Pecee\SimpleRouter\Route\ILoadableRoute:
|
||||
$data->route->prependUrl($basePath);
|
||||
break;
|
||||
case $data->route instanceof \Pecee\SimpleRouter\Route\IGroupRoute:
|
||||
$data->route->prependPrefix($basePath);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$results = [];
|
||||
|
||||
TestRouter::addEventHandler($eventHandler);
|
||||
|
||||
TestRouter::get('/about', function() use(&$results) {
|
||||
$results[] = 'about';
|
||||
});
|
||||
|
||||
TestRouter::group(['prefix' => '/admin'], function() use(&$results) {
|
||||
TestRouter::get('/', function() use(&$results) {
|
||||
$results[] = 'admin';
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::router()->setRenderMultipleRoutes(false);
|
||||
TestRouter::debugNoReset('/basepath/about');
|
||||
TestRouter::debugNoReset('/basepath/admin');
|
||||
|
||||
$this->assertEquals(['about', 'admin'], $results);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Input\InputFile;
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class InputHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
protected $names = [
|
||||
'Lester',
|
||||
'Michael',
|
||||
'Franklin',
|
||||
'Trevor',
|
||||
];
|
||||
|
||||
protected $brands = [
|
||||
'Samsung',
|
||||
'Apple',
|
||||
'HP',
|
||||
'Canon',
|
||||
];
|
||||
|
||||
protected $sodas = [
|
||||
0 => 'Pepsi',
|
||||
1 => 'Coca Cola',
|
||||
2 => 'Harboe',
|
||||
3 => 'Mountain Dew',
|
||||
];
|
||||
|
||||
protected $day = 'monday';
|
||||
|
||||
public function testPost()
|
||||
{
|
||||
global $_POST;
|
||||
|
||||
$_POST = [
|
||||
'names' => $this->names,
|
||||
'day' => $this->day,
|
||||
'sodas' => $this->sodas,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
|
||||
$handler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$this->assertEquals($this->names, $handler->value('names'));
|
||||
$this->assertEquals($this->names, $handler->all(['names'])['names']);
|
||||
$this->assertEquals($this->day, $handler->value('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->post('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day', 'post'));
|
||||
|
||||
// Check non-existing and wrong request-type
|
||||
$this->assertCount(1, $handler->all(['non-existing']));
|
||||
$this->assertEmpty($handler->all(['non-existing'])['non-existing']);
|
||||
$this->assertNull($handler->value('non-existing'));
|
||||
$this->assertNull($handler->find('non-existing'));
|
||||
$this->assertNull($handler->value('names', null, 'get'));
|
||||
$this->assertNull($handler->find('names', 'get'));
|
||||
$this->assertEquals($this->sodas, $handler->value('sodas'));
|
||||
|
||||
$objects = $handler->find('names');
|
||||
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $objects);
|
||||
$this->assertCount(4, $objects);
|
||||
|
||||
/* @var $object \Pecee\Http\Input\InputItem */
|
||||
foreach($objects as $i => $object) {
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $object);
|
||||
$this->assertEquals($this->names[$i], $object->getValue());
|
||||
}
|
||||
|
||||
// Reset
|
||||
$_POST = [];
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
global $_GET;
|
||||
|
||||
$_GET = [
|
||||
'names' => $this->names,
|
||||
'day' => $this->day,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('get');
|
||||
|
||||
$handler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$this->assertEquals($this->names, $handler->value('names'));
|
||||
$this->assertEquals($this->names, $handler->all(['names'])['names']);
|
||||
$this->assertEquals($this->day, $handler->value('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->find('day'));
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $handler->get('day'));
|
||||
|
||||
// Check non-existing and wrong request-type
|
||||
$this->assertCount(1, $handler->all(['non-existing']));
|
||||
$this->assertEmpty($handler->all(['non-existing'])['non-existing']);
|
||||
$this->assertNull($handler->value('non-existing'));
|
||||
$this->assertNull($handler->find('non-existing'));
|
||||
$this->assertNull($handler->value('names', null, 'post'));
|
||||
$this->assertNull($handler->find('names', 'post'));
|
||||
|
||||
$objects = $handler->find('names');
|
||||
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $objects);
|
||||
$this->assertCount(4, $objects);
|
||||
|
||||
/* @var $object \Pecee\Http\Input\InputItem */
|
||||
foreach($objects as $i => $object) {
|
||||
$this->assertInstanceOf(\Pecee\Http\Input\InputItem::class, $object);
|
||||
$this->assertEquals($this->names[$i], $object->getValue());
|
||||
}
|
||||
|
||||
// Reset
|
||||
$_GET = [];
|
||||
}
|
||||
|
||||
public function testFindInput() {
|
||||
|
||||
global $_POST;
|
||||
$_POST['hello'] = 'motto';
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
$inputHandler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$value = $inputHandler->value('hello', null, \Pecee\Http\Request::$requestTypesPost);
|
||||
|
||||
$this->assertEquals($_POST['hello'], $value);
|
||||
}
|
||||
|
||||
public function testFile()
|
||||
{
|
||||
global $_FILES;
|
||||
|
||||
$testFile = $this->generateFile();
|
||||
|
||||
$_FILES = [
|
||||
'test_input' => $testFile,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
$inputHandler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$testFileContent = md5(uniqid('test', false));
|
||||
|
||||
$file = $inputHandler->file('test_input');
|
||||
|
||||
$this->assertInstanceOf(InputFile::class, $file);
|
||||
$this->assertEquals($testFile['name'], $file->getFilename());
|
||||
$this->assertEquals($testFile['type'], $file->getType());
|
||||
$this->assertEquals($testFile['tmp_name'], $file->getTmpName());
|
||||
$this->assertEquals($testFile['error'], $file->getError());
|
||||
$this->assertEquals($testFile['size'], $file->getSize());
|
||||
$this->assertEquals(pathinfo($testFile['name'], PATHINFO_EXTENSION), $file->getExtension());
|
||||
|
||||
file_put_contents($testFile['tmp_name'], $testFileContent);
|
||||
$this->assertEquals($testFileContent, $file->getContents());
|
||||
|
||||
// Cleanup
|
||||
unlink($testFile['tmp_name']);
|
||||
}
|
||||
|
||||
public function testFilesArray()
|
||||
{
|
||||
global $_FILES;
|
||||
|
||||
$testFiles = [
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
$file = $this->generateFile(),
|
||||
];
|
||||
|
||||
$_FILES = [
|
||||
'my_files' => $testFiles,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
$inputHandler = TestRouter::request()->getInputHandler();
|
||||
|
||||
$files = $inputHandler->file('my_files');
|
||||
$this->assertCount(5, $files);
|
||||
|
||||
/* @var $file InputFile */
|
||||
foreach ($files as $key => $file) {
|
||||
|
||||
$testFileContent = md5(uniqid('test', false));
|
||||
|
||||
$this->assertInstanceOf(InputFile::class, $file);
|
||||
$this->assertEquals($testFiles[$key]['name'], $file->getFilename());
|
||||
$this->assertEquals($testFiles[$key]['type'], $file->getType());
|
||||
$this->assertEquals($testFiles[$key]['tmp_name'], $file->getTmpName());
|
||||
$this->assertEquals($testFiles[$key]['error'], $file->getError());
|
||||
$this->assertEquals($testFiles[$key]['size'], $file->getSize());
|
||||
$this->assertEquals(pathinfo($testFiles[$key]['name'], PATHINFO_EXTENSION), $file->getExtension());
|
||||
|
||||
file_put_contents($testFiles[$key]['tmp_name'], $testFileContent);
|
||||
|
||||
$this->assertEquals($testFileContent, $file->getContents());
|
||||
|
||||
// Cleanup
|
||||
unlink($testFiles[$key]['tmp_name']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function testAll()
|
||||
{
|
||||
global $_POST;
|
||||
global $_GET;
|
||||
|
||||
$_POST = [
|
||||
'names' => $this->names,
|
||||
'is_sad' => true,
|
||||
];
|
||||
|
||||
$_GET = [
|
||||
'brands' => $this->brands,
|
||||
'is_happy' => true,
|
||||
];
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
$router->getRequest()->setMethod('post');
|
||||
|
||||
$handler = TestRouter::request()->getInputHandler();
|
||||
|
||||
// GET
|
||||
$brandsFound = $handler->all(['brands', 'nothing']);
|
||||
|
||||
$this->assertArrayHasKey('brands', $brandsFound);
|
||||
$this->assertArrayHasKey('nothing', $brandsFound);
|
||||
$this->assertEquals($this->brands, $brandsFound['brands']);
|
||||
$this->assertNull($brandsFound['nothing']);
|
||||
|
||||
// POST
|
||||
$namesFound = $handler->all(['names', 'nothing']);
|
||||
|
||||
$this->assertArrayHasKey('names', $namesFound);
|
||||
$this->assertArrayHasKey('nothing', $namesFound);
|
||||
$this->assertEquals($this->names, $namesFound['names']);
|
||||
$this->assertNull($namesFound['nothing']);
|
||||
|
||||
// DEFAULT VALUE
|
||||
$nonExisting = $handler->all([
|
||||
'non-existing'
|
||||
]);
|
||||
|
||||
$this->assertArrayHasKey('non-existing', $nonExisting);
|
||||
$this->assertNull($nonExisting['non-existing']);
|
||||
|
||||
// Reset
|
||||
$_GET = [];
|
||||
$_POST = [];
|
||||
}
|
||||
|
||||
protected function generateFile()
|
||||
{
|
||||
return [
|
||||
'name' => uniqid('', false) . '.txt',
|
||||
'type' => 'text/plain',
|
||||
'tmp_name' => sys_get_temp_dir() . '/phpYfWUiw',
|
||||
'error' => 0,
|
||||
'size' => rand(3, 40),
|
||||
];
|
||||
}
|
||||
|
||||
protected function generateFileContent()
|
||||
{
|
||||
return md5(uniqid('', false));
|
||||
}
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/Route/DummyLoadableRoute.php';
|
||||
|
||||
class LoadableRouteTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testSetUrlUpdatesParameters()
|
||||
{
|
||||
$route = new DummyLoadableRoute();
|
||||
$this->assertEmpty($route->getParameters());
|
||||
|
||||
$route->setUrl('/');
|
||||
$this->assertEmpty($route->getParameters());
|
||||
|
||||
$expected = ['param' => null, 'optionalParam' => null];
|
||||
$route->setUrl('/{param}/{optionalParam?}');
|
||||
$this->assertEquals($expected, $route->getParameters());
|
||||
|
||||
$expected = ['otherParam' => null];
|
||||
$route->setUrl('/{otherParam}');
|
||||
$this->assertEquals($expected, $route->getParameters());
|
||||
|
||||
$expected = [];
|
||||
$route->setUrl('/');
|
||||
$this->assertEquals($expected, $route->getParameters());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class MiddlewareTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
public function testMiddlewareFound()
|
||||
{
|
||||
$this->expectException(MiddlewareLoadedException::class);
|
||||
|
||||
TestRouter::group(['exceptionHandler' => 'ExceptionHandler'], function () {
|
||||
TestRouter::get('/my/test/url', 'DummyController@method1', ['middleware' => 'DummyMiddleware']);
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/test/url', 'get');
|
||||
|
||||
}
|
||||
|
||||
public function testNestedMiddlewareDontLoad()
|
||||
{
|
||||
|
||||
TestRouter::group(['exceptionHandler' => 'ExceptionHandler', 'middleware' => 'DummyMiddleware'], function () {
|
||||
TestRouter::get('/middleware', 'DummyController@method1');
|
||||
});
|
||||
|
||||
TestRouter::get('/my/test/url', 'DummyController@method1');
|
||||
|
||||
TestRouter::debug('/my/test/url', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
use Pecee\Http\Input\InputFile;
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class RequestTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
protected function processHeader($name, $value, callable $callback)
|
||||
{
|
||||
global $_SERVER;
|
||||
|
||||
$_SERVER[$name] = $value;
|
||||
|
||||
$router = TestRouter::router();
|
||||
$router->reset();
|
||||
|
||||
$request = $router->getRequest();
|
||||
|
||||
$callback($request);
|
||||
|
||||
// Reset everything
|
||||
$_SERVER[$name] = null;
|
||||
$router->reset();
|
||||
}
|
||||
|
||||
public function testContentTypeParse()
|
||||
{
|
||||
global $_SERVER;
|
||||
|
||||
// Test normal content-type
|
||||
|
||||
$contentType = 'application/x-www-form-urlencoded';
|
||||
|
||||
$this->processHeader('content_type', $contentType, function(\Pecee\Http\Request $request) use($contentType) {
|
||||
$this->assertEquals($contentType, $request->getContentType());
|
||||
});
|
||||
|
||||
// Test special content-type with encoding
|
||||
|
||||
$contentTypeWithEncoding = 'application/x-www-form-urlencoded; charset=UTF-8';
|
||||
|
||||
$this->processHeader('content_type', $contentTypeWithEncoding, function(\Pecee\Http\Request $request) use($contentType) {
|
||||
$this->assertEquals($contentType, $request->getContentType());
|
||||
});
|
||||
}
|
||||
|
||||
public function testGetIp()
|
||||
{
|
||||
$ip = '1.1.1.1';
|
||||
$this->processHeader('remote_addr', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
$ip = '2.2.2.2';
|
||||
$this->processHeader('http-cf-connecting-ip', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
$ip = '3.3.3.3';
|
||||
$this->processHeader('http-client-ip', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
$ip = '4.4.4.4';
|
||||
$this->processHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) use($ip) {
|
||||
$this->assertEquals($ip, $request->getIp());
|
||||
});
|
||||
|
||||
// Test safe
|
||||
|
||||
$ip = '5.5.5.5';
|
||||
$this->processHeader('http-x-forwarded-for', $ip, function(\Pecee\Http\Request $request) {
|
||||
$this->assertEquals(null, $request->getIp(true));
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// TODO: implement more test-cases
|
||||
|
||||
}
|
||||
Vendored
+47
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Exception/ExceptionHandlerException.php';
|
||||
|
||||
class RouterCallbackExceptionHandlerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testCallbackExceptionHandler()
|
||||
{
|
||||
$this->expectException(ExceptionHandlerException::class);
|
||||
|
||||
// Match normal route on alias
|
||||
TestRouter::get('/my-new-url', 'DummyController@method2');
|
||||
TestRouter::get('/my-url', 'DummyController@method1');
|
||||
|
||||
TestRouter::error(function (\Pecee\Http\Request $request, \Exception $exception) {
|
||||
throw new ExceptionHandlerException();
|
||||
});
|
||||
|
||||
TestRouter::debug('/404-url');
|
||||
}
|
||||
|
||||
public function testExceptionHandlerCallback() {
|
||||
|
||||
TestRouter::group(['prefix' => null], function() {
|
||||
TestRouter::get('/', function() {
|
||||
return 'Hello world';
|
||||
});
|
||||
|
||||
TestRouter::get('/not-found', 'DummyController@method1');
|
||||
TestRouter::error(function(\Pecee\Http\Request $request, \Exception $exception) {
|
||||
|
||||
if($exception instanceof \Pecee\SimpleRouter\Exceptions\NotFoundHttpException && $exception->getCode() === 404) {
|
||||
return $request->setRewriteCallback(static function() {
|
||||
return 'success';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$result = TestRouter::debugOutput('/thisdoes-not/existssss', 'get');
|
||||
$this->assertEquals('success', $result);
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyController.php';
|
||||
|
||||
class RouterControllerTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
// Match normal route on alias
|
||||
TestRouter::controller('/url', 'DummyController');
|
||||
|
||||
$response = TestRouter::debugOutput('/url/test', 'get');
|
||||
|
||||
$this->assertEquals('getTest', $response);
|
||||
|
||||
}
|
||||
|
||||
public function testPost()
|
||||
{
|
||||
// Match normal route on alias
|
||||
TestRouter::controller('/url', 'DummyController');
|
||||
|
||||
$response = TestRouter::debugOutput('/url/test', 'post');
|
||||
|
||||
$this->assertEquals('postTest', $response);
|
||||
|
||||
}
|
||||
|
||||
public function testPut()
|
||||
{
|
||||
// Match normal route on alias
|
||||
TestRouter::controller('/url', 'DummyController');
|
||||
|
||||
$response = TestRouter::debugOutput('/url/test', 'put');
|
||||
|
||||
$this->assertEquals('putTest', $response);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
|
||||
class RouterGroupTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testGroupLoad()
|
||||
{
|
||||
$result = false;
|
||||
|
||||
TestRouter::group(['prefix' => '/group'], function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/', 'get');
|
||||
} catch (\Exception $e) {
|
||||
|
||||
}
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testNestedGroup()
|
||||
{
|
||||
|
||||
TestRouter::group(['prefix' => '/api'], function () {
|
||||
|
||||
TestRouter::group(['prefix' => '/v1'], function () {
|
||||
TestRouter::get('/test', 'DummyController@method1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
TestRouter::debug('/api/v1/test', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testMultipleRoutes()
|
||||
{
|
||||
|
||||
TestRouter::group(['prefix' => '/api'], function () {
|
||||
|
||||
TestRouter::group(['prefix' => '/v1'], function () {
|
||||
TestRouter::get('/test', 'DummyController@method1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
TestRouter::get('/my/match', 'DummyController@method1');
|
||||
|
||||
TestRouter::group(['prefix' => '/service'], function () {
|
||||
|
||||
TestRouter::group(['prefix' => '/v1'], function () {
|
||||
TestRouter::get('/no-match', 'DummyController@method1');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/match', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testUrls()
|
||||
{
|
||||
// Test array name
|
||||
TestRouter::get('/my/fancy/url/1', 'DummyController@method1', ['as' => 'fancy1']);
|
||||
|
||||
// Test method name
|
||||
TestRouter::get('/my/fancy/url/2', 'DummyController@method1')->setName('fancy2');
|
||||
|
||||
TestRouter::debugNoReset('/my/fancy/url/1');
|
||||
|
||||
$this->assertEquals('/my/fancy/url/1/', TestRouter::getUrl('fancy1'));
|
||||
$this->assertEquals('/my/fancy/url/2/', TestRouter::getUrl('fancy2'));
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
}
|
||||
|
||||
public function testNamespaceExtend()
|
||||
{
|
||||
TestRouter::group(['namespace' => '\My\Namespace'], function () use (&$result) {
|
||||
|
||||
TestRouter::group(['namespace' => 'Service'], function () use (&$result) {
|
||||
|
||||
TestRouter::get('/test', function () use (&$result) {
|
||||
return \Pecee\SimpleRouter\SimpleRouter::router()->getRequest()->getLoadedRoute()->getNamespace();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$namespace = TestRouter::debugOutput('/test');
|
||||
$this->assertEquals('\My\Namespace\Service', $namespace);
|
||||
}
|
||||
|
||||
public function testNamespaceOverwrite()
|
||||
{
|
||||
TestRouter::group(['namespace' => '\My\Namespace'], function () use (&$result) {
|
||||
|
||||
TestRouter::group(['namespace' => '\Service'], function () use (&$result) {
|
||||
|
||||
TestRouter::get('/test', function () use (&$result) {
|
||||
return \Pecee\SimpleRouter\SimpleRouter::router()->getRequest()->getLoadedRoute()->getNamespace();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$namespace = TestRouter::debugOutput('/test');
|
||||
$this->assertEquals('\Service', $namespace);
|
||||
}
|
||||
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class RouterPartialGroupTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testParameters()
|
||||
{
|
||||
$result1 = null;
|
||||
$result2 = null;
|
||||
|
||||
TestRouter::partialGroup('{param1}/{param2}', function ($param1 = null, $param2 = null) use (&$result1, &$result2) {
|
||||
$result1 = $param1;
|
||||
$result2 = $param2;
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
});
|
||||
|
||||
TestRouter::debug('/param1/param2', 'get');
|
||||
|
||||
$this->assertEquals('param1', $result1);
|
||||
$this->assertEquals('param2', $result2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixed issue with partial routes not loading child groups.
|
||||
* Reported in issue: #456
|
||||
*/
|
||||
public function testPartialGroupWithGroup() {
|
||||
|
||||
$lang = null;
|
||||
|
||||
$route1 = '/lang/da/test/';
|
||||
$route2 = '/lang/da/auth';
|
||||
$route3 = '/lang/da/auth/test';
|
||||
|
||||
TestRouter::partialGroup(
|
||||
'/lang/{test}/',
|
||||
function ($lang = 'en') use($route1, $route2, $route3) {
|
||||
|
||||
TestRouter::get('/test/', function () use($route1) {
|
||||
return $route1;
|
||||
});
|
||||
|
||||
TestRouter::group(['prefix' => '/auth/'], function () use($route2, $route3) {
|
||||
|
||||
TestRouter::get('/', function() use($route2) {
|
||||
return $route2;
|
||||
});
|
||||
|
||||
TestRouter::get('/test', function () use($route3){
|
||||
return $route3;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
$test1 = TestRouter::debugOutput('/lang/da/test', 'get', false);
|
||||
$test2 = TestRouter::debugOutput('/lang/da/auth', 'get', false);
|
||||
$test3 = TestRouter::debugOutput('/lang/da/auth/test', 'get', false);
|
||||
|
||||
$this->assertEquals($test1, $route1);
|
||||
$this->assertEquals($test2, $route2);
|
||||
$this->assertEquals($test3, $route3);
|
||||
|
||||
}
|
||||
|
||||
public function testPhp8CallUserFunc() {
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
$result = false;
|
||||
$lang = 'de';
|
||||
|
||||
TestRouter::group(['prefix' => '/lang'], function() use(&$result) {
|
||||
TestRouter::get('/{lang}', function ($lang) use(&$result) {
|
||||
$result = $lang;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug("/lang/$lang");
|
||||
|
||||
$this->assertEquals($lang, $result);
|
||||
|
||||
// Test partial group
|
||||
|
||||
$lang = 'de';
|
||||
$userId = 22;
|
||||
|
||||
$result1 = false;
|
||||
$result2 = false;
|
||||
|
||||
TestRouter::partialGroup(
|
||||
'/lang/{lang}/',
|
||||
function ($lang) use(&$result1, &$result2) {
|
||||
|
||||
$result1 = $lang;
|
||||
|
||||
TestRouter::get('/user/{userId}', function ($userId) use(&$result2) {
|
||||
$result2 = $userId;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug("/lang/$lang/user/$userId");
|
||||
|
||||
$this->assertEquals($lang, $result1);
|
||||
$this->assertEquals($userId, $result2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/ResourceController.php';
|
||||
|
||||
class RouterResourceTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testResourceStore()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource', 'post');
|
||||
|
||||
$this->assertEquals('store', $response);
|
||||
}
|
||||
|
||||
public function testResourceCreate()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource/create', 'get');
|
||||
|
||||
$this->assertEquals('create', $response);
|
||||
|
||||
}
|
||||
|
||||
public function testResourceIndex()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource', 'get');
|
||||
|
||||
$this->assertEquals('index', $response);
|
||||
}
|
||||
|
||||
public function testResourceDestroy()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource/38', 'delete');
|
||||
|
||||
$this->assertEquals('destroy 38', $response);
|
||||
}
|
||||
|
||||
|
||||
public function testResourceEdit()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource/38/edit', 'get');
|
||||
|
||||
$this->assertEquals('edit 38', $response);
|
||||
|
||||
}
|
||||
|
||||
public function testResourceUpdate()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource/38', 'put');
|
||||
|
||||
$this->assertEquals('update 38', $response);
|
||||
|
||||
}
|
||||
|
||||
public function testResourceGet()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController');
|
||||
$response = TestRouter::debugOutput('/resource/38', 'get');
|
||||
|
||||
$this->assertEquals('show 38', $response);
|
||||
}
|
||||
|
||||
public function testResourceUrls()
|
||||
{
|
||||
TestRouter::resource('/resource', 'ResourceController')->name('resource');
|
||||
|
||||
TestRouter::debugNoReset('/resource');
|
||||
|
||||
$this->assertEquals('/resource/3/create/', TestRouter::router()->getUrl('resource.create', ['id' => 3]));
|
||||
$this->assertEquals('/resource/5/edit/', TestRouter::router()->getUrl('resource.edit', ['id' => 5]));
|
||||
$this->assertEquals('/resource/6/', TestRouter::router()->getUrl('resource.update', ['id' => 6]));
|
||||
$this->assertEquals('/resource/9/', TestRouter::router()->getUrl('resource.destroy', ['id' => 9]));
|
||||
$this->assertEquals('/resource/12/', TestRouter::router()->getUrl('resource.delete', ['id' => 12]));
|
||||
$this->assertEquals('/resource/', TestRouter::router()->getUrl('resource'));
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
}
|
||||
+203
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Exception/ResponseException.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandlerFirst.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandlerSecond.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandlerThird.php';
|
||||
require_once 'Dummy/Middleware/RewriteMiddleware.php';
|
||||
|
||||
class RouterRewriteTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Redirects to another route through 3 exception handlers.
|
||||
*
|
||||
* You will see "ExceptionHandler 1 loaded" 2 times. This happen because
|
||||
* the exceptionhandler is asking the router to reload.
|
||||
*
|
||||
* That means that the exceptionhandler is loaded again, but this time
|
||||
* the router ignores the same rewrite-route to avoid loop - loads
|
||||
* the second which have same behavior and is also ignored before
|
||||
* throwing the final Exception in ExceptionHandler 3.
|
||||
*
|
||||
* So this tests:
|
||||
* 1. If ExceptionHandlers loads
|
||||
* 2. If ExceptionHandlers load in the correct order
|
||||
* 3. If ExceptionHandlers can rewrite the page on error
|
||||
* 4. If the router can avoid redirect-loop due to developer has started loop.
|
||||
* 5. And finally if we reaches the last exception-handler and that the correct
|
||||
* exception-type is being thrown.
|
||||
*/
|
||||
public function testExceptionHandlerRewrite()
|
||||
{
|
||||
global $stack;
|
||||
$stack = [];
|
||||
|
||||
TestRouter::group(['exceptionHandler' => [ExceptionHandlerFirst::class, ExceptionHandlerSecond::class]], function () {
|
||||
|
||||
TestRouter::group(['prefix' => '/test', 'exceptionHandler' => ExceptionHandlerThird::class], function () {
|
||||
|
||||
TestRouter::get('/my-path', 'DummyController@method1');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/test/non-existing', 'get');
|
||||
} catch (\ResponseException $e) {
|
||||
|
||||
}
|
||||
|
||||
$expectedStack = [
|
||||
ExceptionHandlerThird::class,
|
||||
ExceptionHandlerSecond::class,
|
||||
ExceptionHandlerFirst::class,
|
||||
];
|
||||
|
||||
$this->assertEquals($expectedStack, $stack);
|
||||
|
||||
}
|
||||
|
||||
public function testStopMergeExceptionHandlers()
|
||||
{
|
||||
global $stack;
|
||||
$stack = [];
|
||||
|
||||
TestRouter::group(['prefix' => '/', 'exceptionHandler' => ExceptionHandlerFirst::class], function () {
|
||||
|
||||
TestRouter::group(['prefix' => '/admin', 'exceptionHandler' => ExceptionHandlerSecond::class, 'mergeExceptionHandlers' => false], function () {
|
||||
|
||||
TestRouter::get('/my-path', 'DummyController@method1');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/admin/my-path-test', 'get');
|
||||
} catch (\Pecee\SimpleRouter\Exceptions\NotFoundHttpException $e) {
|
||||
|
||||
}
|
||||
|
||||
$expectedStack = [
|
||||
ExceptionHandlerSecond::class,
|
||||
];
|
||||
|
||||
$this->assertEquals($expectedStack, $stack);
|
||||
}
|
||||
|
||||
public function testRewriteExceptionMessage()
|
||||
{
|
||||
$this->expectException(\Pecee\SimpleRouter\Exceptions\NotFoundHttpException::class);
|
||||
|
||||
TestRouter::error(function (\Pecee\Http\Request $request, \Exception $error) {
|
||||
|
||||
if (strtolower($request->getUrl()->getPath()) === '/my/test/') {
|
||||
$request->setRewriteUrl('/another-non-existing');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/test', 'get');
|
||||
}
|
||||
|
||||
public function testRewriteUrlFromRoute()
|
||||
{
|
||||
|
||||
TestRouter::get('/old', function () {
|
||||
TestRouter::request()->setRewriteUrl('/new');
|
||||
});
|
||||
|
||||
TestRouter::get('/new', function () {
|
||||
echo 'ok';
|
||||
});
|
||||
|
||||
TestRouter::get('/new1', function () {
|
||||
echo 'ok';
|
||||
});
|
||||
|
||||
TestRouter::get('/new2', function () {
|
||||
echo 'ok';
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/old');
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
public function testRewriteCallbackFromRoute()
|
||||
{
|
||||
|
||||
TestRouter::get('/old', function () {
|
||||
TestRouter::request()->setRewriteUrl('/new');
|
||||
});
|
||||
|
||||
TestRouter::get('/new', function () {
|
||||
return 'ok';
|
||||
});
|
||||
|
||||
TestRouter::get('/new1', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('/new/2', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/old');
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
public function testRewriteRouteFromRoute()
|
||||
{
|
||||
|
||||
TestRouter::get('/match', function () {
|
||||
TestRouter::request()->setRewriteRoute(new \Pecee\SimpleRouter\Route\RouteUrl('/match', function () {
|
||||
return 'ok';
|
||||
}));
|
||||
});
|
||||
|
||||
TestRouter::get('/old1', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('/old/2', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('/new2', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/match');
|
||||
|
||||
TestRouter::router()->reset();
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
public function testMiddlewareRewrite()
|
||||
{
|
||||
|
||||
TestRouter::group(['middleware' => 'RewriteMiddleware'], function () {
|
||||
TestRouter::get('/', function () {
|
||||
return 'fail';
|
||||
});
|
||||
|
||||
TestRouter::get('no/match', function () {
|
||||
return 'fail';
|
||||
});
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/');
|
||||
|
||||
$this->assertEquals('ok', $output);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+335
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/NSController.php';
|
||||
require_once 'Dummy/Exception/ExceptionHandlerException.php';
|
||||
|
||||
class RouterRouteTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Issue #421: Incorrectly optional character in route
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function testOptionalCharacterRoute()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::get('/api/v1/users/{userid}/projects/{id}/pages/{pageid?}', function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
|
||||
TestRouter::debug('/api/v1/users/1/projects/8399421535/pages/43/', 'get');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testMultiParam()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::get('/test-{param1}-{param2}', function ($param1, $param2) use (&$result) {
|
||||
|
||||
if ($param1 === 'param1' && $param2 === 'param2') {
|
||||
$result = true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
TestRouter::debug('/test-param1-param2', 'get');
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
}
|
||||
|
||||
public function testNotFound()
|
||||
{
|
||||
$this->expectException('\Pecee\SimpleRouter\Exceptions\NotFoundHttpException');
|
||||
TestRouter::get('/non-existing-path', 'DummyController@method1');
|
||||
TestRouter::debug('/test-param1-param2', 'post');
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
TestRouter::get('/my/test/url', 'DummyController@method1');
|
||||
TestRouter::debug('/my/test/url', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testPost()
|
||||
{
|
||||
TestRouter::post('/my/test/url', 'DummyController@method1');
|
||||
TestRouter::debug('/my/test/url', 'post');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testPut()
|
||||
{
|
||||
TestRouter::put('/my/test/url', 'DummyController@method1');
|
||||
TestRouter::debug('/my/test/url', 'put');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
TestRouter::delete('/my/test/url', 'DummyController@method1');
|
||||
TestRouter::debug('/my/test/url', 'delete');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testMethodNotAllowed()
|
||||
{
|
||||
TestRouter::get('/my/test/url', 'DummyController@method1');
|
||||
|
||||
try {
|
||||
TestRouter::debug('/my/test/url', 'post');
|
||||
} catch (\Exception $e) {
|
||||
$this->assertEquals(403, $e->getCode());
|
||||
}
|
||||
}
|
||||
|
||||
public function testSimpleParam()
|
||||
{
|
||||
TestRouter::get('/test-{param1}', 'DummyController@param');
|
||||
$response = TestRouter::debugOutput('/test-param1', 'get');
|
||||
|
||||
$this->assertEquals('param1', $response);
|
||||
}
|
||||
|
||||
public function testPathParamRegex()
|
||||
{
|
||||
TestRouter::get('/{lang}/productscategories/{name}', 'DummyController@param', ['where' => ['lang' => '[a-z]+', 'name' => '[A-Za-z0-9-]+']]);
|
||||
$response = TestRouter::debugOutput('/it/productscategories/system', 'get');
|
||||
|
||||
$this->assertEquals('it, system', $response);
|
||||
}
|
||||
|
||||
public function testFixedDomain()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::request()->setHost('admin.world.com');
|
||||
|
||||
TestRouter::group(['domain' => 'admin.world.com'], function () use (&$result) {
|
||||
TestRouter::get('/test', function ($subdomain = null) use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug('/test', 'get');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testFixedNotAllowedDomain()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::request()->setHost('other.world.com');
|
||||
|
||||
TestRouter::group(['domain' => 'admin.world.com'], function () use (&$result) {
|
||||
TestRouter::get('/', function ($subdomain = null) use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/', 'get');
|
||||
} catch(\Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
$this->assertFalse($result);
|
||||
}
|
||||
|
||||
public function testDomainAllowedRoute()
|
||||
{
|
||||
$result = false;
|
||||
TestRouter::request()->setHost('hello.world.com');
|
||||
|
||||
TestRouter::group(['domain' => '{subdomain}.world.com'], function () use (&$result) {
|
||||
TestRouter::get('/test', function ($subdomain = null) use (&$result) {
|
||||
$result = ($subdomain === 'hello');
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug('/test', 'get');
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
}
|
||||
|
||||
public function testDomainNotAllowedRoute()
|
||||
{
|
||||
TestRouter::request()->setHost('other.world.com');
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::group(['domain' => '{subdomain}.world.com'], function () use (&$result) {
|
||||
TestRouter::get('/test', function ($subdomain = null) use (&$result) {
|
||||
$result = ($subdomain === 'hello');
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug('/test', 'get');
|
||||
|
||||
$this->assertFalse($result);
|
||||
|
||||
}
|
||||
|
||||
public function testFixedSubdomainDynamicDomain()
|
||||
{
|
||||
TestRouter::request()->setHost('other.world.com');
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::group(['domain' => 'other.{domain}'], function () use (&$result) {
|
||||
TestRouter::get('/test', function ($domain = null) use (&$result) {
|
||||
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug('/test', 'get');
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
}
|
||||
|
||||
public function testFixedSubdomainDynamicDomainParameter()
|
||||
{
|
||||
TestRouter::request()->setHost('other.world.com');
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::group(['domain' => 'other.{domain}'], function () use (&$result) {
|
||||
TestRouter::get('/test', 'DummyController@param');
|
||||
TestRouter::get('/test/{key}', 'DummyController@param');
|
||||
});
|
||||
|
||||
$response = TestRouter::debugOutputNoReset('/test', 'get');
|
||||
|
||||
$this->assertEquals('world.com', $response);
|
||||
|
||||
$response = TestRouter::debugOutput('/test/unittest', 'get');
|
||||
|
||||
$this->assertEquals('unittest, world.com', $response);
|
||||
|
||||
}
|
||||
|
||||
public function testWrongFixedSubdomainDynamicDomain()
|
||||
{
|
||||
TestRouter::request()->setHost('wrong.world.com');
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::group(['domain' => 'other.{domain}'], function () use (&$result) {
|
||||
TestRouter::get('/test', function ($domain = null) use (&$result) {
|
||||
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
TestRouter::debug('/test', 'get');
|
||||
} catch(\Exception $e) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
$this->assertFalse($result);
|
||||
|
||||
}
|
||||
|
||||
public function testRegEx()
|
||||
{
|
||||
TestRouter::get('/my/{path}', 'DummyController@method1')->where(['path' => '[a-zA-Z-]+']);
|
||||
TestRouter::debug('/my/custom-path', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testParametersWithDashes()
|
||||
{
|
||||
|
||||
$defaultVariable = null;
|
||||
|
||||
TestRouter::get('/my/{path}', function ($path = 'working') use (&$defaultVariable) {
|
||||
$defaultVariable = $path;
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/hello-motto-man');
|
||||
|
||||
$this->assertEquals('hello-motto-man', $defaultVariable);
|
||||
|
||||
}
|
||||
|
||||
public function testParameterDefaultValue()
|
||||
{
|
||||
|
||||
$defaultVariable = null;
|
||||
|
||||
TestRouter::get('/my/{path?}', function ($path = 'working') use (&$defaultVariable) {
|
||||
$defaultVariable = $path;
|
||||
});
|
||||
|
||||
TestRouter::debug('/my/');
|
||||
|
||||
$this->assertEquals('working', $defaultVariable);
|
||||
|
||||
}
|
||||
|
||||
public function testDefaultParameterRegex()
|
||||
{
|
||||
TestRouter::get('/my/{path}', 'DummyController@param', ['defaultParameterRegex' => '[\w-]+']);
|
||||
$output = TestRouter::debugOutput('/my/custom-regex', 'get');
|
||||
|
||||
$this->assertEquals('custom-regex', $output);
|
||||
}
|
||||
|
||||
public function testDefaultParameterRegexGroup()
|
||||
{
|
||||
TestRouter::group(['defaultParameterRegex' => '[\w-]+'], function () {
|
||||
TestRouter::get('/my/{path}', 'DummyController@param');
|
||||
});
|
||||
|
||||
$output = TestRouter::debugOutput('/my/custom-regex', 'get');
|
||||
|
||||
$this->assertEquals('custom-regex', $output);
|
||||
}
|
||||
|
||||
public function testClassHint()
|
||||
{
|
||||
TestRouter::get('/my/test/url', ['DummyController', 'method1']);
|
||||
TestRouter::all('/my/test/url', ['DummyController', 'method1']);
|
||||
TestRouter::match(['put', 'get', 'post'], '/my/test/url', ['DummyController', 'method1']);
|
||||
|
||||
TestRouter::debug('/my/test/url', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
public function testDefaultNameSpaceOverload()
|
||||
{
|
||||
TestRouter::setDefaultNamespace('DefaultNamespace\\Controllers');
|
||||
TestRouter::get('/test', [\MyNamespace\NSController::class, 'method']);
|
||||
|
||||
$result = TestRouter::debugOutput('/test');
|
||||
|
||||
$this->assertTrue( (bool)$result);
|
||||
}
|
||||
|
||||
public function testSameRoutes()
|
||||
{
|
||||
TestRouter::get('/recipe', 'DummyController@method1')->name('add');
|
||||
TestRouter::post('/recipe', 'DummyController@method2')->name('edit');
|
||||
|
||||
TestRouter::debugNoReset('/recipe', 'post');
|
||||
TestRouter::debug('/recipe', 'get');
|
||||
|
||||
$this->assertTrue(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
<?php
|
||||
|
||||
require_once 'Dummy/DummyMiddleware.php';
|
||||
require_once 'Dummy/DummyController.php';
|
||||
require_once 'Dummy/Handler/ExceptionHandler.php';
|
||||
|
||||
class RouterUrlTest extends \PHPUnit\Framework\TestCase
|
||||
{
|
||||
|
||||
public function testIssue253()
|
||||
{
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
TestRouter::get('/page/{id?}', 'DummyController@method1');
|
||||
TestRouter::get('/test-output', function () {
|
||||
return 'return value';
|
||||
});
|
||||
|
||||
TestRouter::debugNoReset('/page/22', 'get');
|
||||
$this->assertEquals('/page/{id?}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::debugNoReset('/', 'get');
|
||||
$this->assertEquals('/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
$output = TestRouter::debugOutput('/test-output', 'get');
|
||||
$this->assertEquals('return value', $output);
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testLastParameterSlash()
|
||||
{
|
||||
TestRouter::get('/test/{param}', function ($param) {
|
||||
return $param;
|
||||
})->setSettings(['includeSlash' => true]);
|
||||
|
||||
// Test with ending /
|
||||
$output = TestRouter::debugOutputNoReset('/test/param/');
|
||||
$this->assertEquals($output, 'param/');
|
||||
|
||||
// Test without ending /
|
||||
$output = TestRouter::debugOutputNoReset('/test/param');
|
||||
$this->assertEquals($output, 'param');
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testUnicodeCharacters()
|
||||
{
|
||||
// Test spanish characters
|
||||
TestRouter::get('/cursos/listado/{listado?}/{category?}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s\-]+']);
|
||||
TestRouter::get('/test/{param}', 'DummyController@method1', ['defaultParameterRegex' => '[\w\p{L}\s\-\í]+']);
|
||||
TestRouter::debugNoReset('/cursos/listado/especialidad/cirugía local', 'get');
|
||||
|
||||
$this->assertEquals('/cursos/listado/{listado?}/{category?}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::debugNoReset('/test/Dermatología');
|
||||
$parameters = TestRouter::request()->getLoadedRoute()->getParameters();
|
||||
|
||||
$this->assertEquals('Dermatología', $parameters['param']);
|
||||
|
||||
// Test danish characters
|
||||
TestRouter::get('/kategori/økse', 'DummyController@method1', ['defaultParameterRegex' => '[\w\ø]+']);
|
||||
TestRouter::debugNoReset('/kategori/økse', 'get');
|
||||
|
||||
$this->assertEquals('/kategori/økse/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testOptionalParameters()
|
||||
{
|
||||
TestRouter::get('/aviso/legal', 'DummyController@method1');
|
||||
TestRouter::get('/aviso/{aviso}', 'DummyController@method1');
|
||||
TestRouter::get('/pagina/{pagina}', 'DummyController@method1');
|
||||
TestRouter::get('/{pagina?}', 'DummyController@method1');
|
||||
|
||||
TestRouter::debugNoReset('/aviso/optional', 'get');
|
||||
$this->assertEquals('/aviso/{aviso}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::debugNoReset('/pagina/optional', 'get');
|
||||
$this->assertEquals('/pagina/{pagina}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::debugNoReset('/optional', 'get');
|
||||
$this->assertEquals('/{pagina?}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::debugNoReset('/avisolegal', 'get');
|
||||
$this->assertNotEquals('/aviso/{aviso}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::debugNoReset('/avisolegal', 'get');
|
||||
$this->assertEquals('/{pagina?}/', TestRouter::router()->getRequest()->getLoadedRoute()->getUrl());
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testSimilarUrls()
|
||||
{
|
||||
TestRouter::reset();
|
||||
// Match normal route on alias
|
||||
TestRouter::get('/url11', 'DummyController@method1');
|
||||
TestRouter::get('/url22', 'DummyController@method2');
|
||||
TestRouter::get('/url33', 'DummyController@method2')->name('match');
|
||||
|
||||
|
||||
TestRouter::debugNoReset('/url33', 'get');
|
||||
|
||||
$this->assertEquals(TestRouter::getUrl('match'), TestRouter::getUrl());
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testUrls()
|
||||
{
|
||||
// Match normal route on alias
|
||||
TestRouter::get('/', 'DummyController@method1', ['as' => 'home']);
|
||||
|
||||
TestRouter::get('/about', 'DummyController@about');
|
||||
|
||||
TestRouter::group(['prefix' => '/admin', 'as' => 'admin'], function () {
|
||||
|
||||
// Match route with prefix on alias
|
||||
TestRouter::get('/{id?}', 'DummyController@method2', ['as' => 'home']);
|
||||
|
||||
// Match controller with prefix and alias
|
||||
TestRouter::controller('/users', 'DummyController', ['as' => 'users']);
|
||||
|
||||
// Match controller with prefix and NO alias
|
||||
TestRouter::controller('/pages', 'DummyController');
|
||||
|
||||
});
|
||||
|
||||
TestRouter::group(['prefix' => 'api', 'as' => 'api'], function () {
|
||||
|
||||
// Match resource controller
|
||||
TestRouter::resource('phones', 'DummyController');
|
||||
|
||||
});
|
||||
|
||||
TestRouter::controller('gadgets', 'DummyController', ['names' => ['getIphoneInfo' => 'iphone']]);
|
||||
|
||||
// Match controller with no prefix and no alias
|
||||
TestRouter::controller('/cats', 'CatsController');
|
||||
|
||||
// Pretend to load page
|
||||
TestRouter::debugNoReset('/', 'get');
|
||||
|
||||
$this->assertEquals('/gadgets/iphoneinfo/', TestRouter::getUrl('gadgets.iphone'));
|
||||
|
||||
$this->assertEquals('/api/phones/create/', TestRouter::getUrl('api.phones.create'));
|
||||
|
||||
// Should match /
|
||||
$this->assertEquals('/', TestRouter::getUrl('home'));
|
||||
|
||||
// Should match /about/
|
||||
$this->assertEquals('/about/', TestRouter::getUrl('DummyController@about'));
|
||||
|
||||
// Should match /admin/
|
||||
$this->assertEquals('/admin/', TestRouter::getUrl('DummyController@method2'));
|
||||
|
||||
// Should match /admin/
|
||||
$this->assertEquals('/admin/', TestRouter::getUrl('admin.home'));
|
||||
|
||||
// Should match /admin/2/
|
||||
$this->assertEquals('/admin/2/', TestRouter::getUrl('admin.home', ['id' => 2]));
|
||||
|
||||
// Should match /admin/users/
|
||||
$this->assertEquals('/admin/users/', TestRouter::getUrl('admin.users'));
|
||||
|
||||
// Should match /admin/users/home/
|
||||
$this->assertEquals('/admin/users/home/', TestRouter::getUrl('admin.users@home'));
|
||||
|
||||
// Should match /cats/
|
||||
$this->assertEquals('/cats/', TestRouter::getUrl('CatsController'));
|
||||
|
||||
// Should match /cats/view/
|
||||
$this->assertEquals('/cats/view/', TestRouter::getUrl('CatsController', 'view'));
|
||||
|
||||
// Should match /cats/view/
|
||||
//$this->assertEquals('/cats/view/', TestRouter::getUrl('CatsController', ['view']));
|
||||
|
||||
// Should match /cats/view/666
|
||||
$this->assertEquals('/cats/view/666/', TestRouter::getUrl('CatsController@getView', ['666']));
|
||||
|
||||
// Should match /funny/man/
|
||||
$this->assertEquals('/funny/man/', TestRouter::getUrl('/funny/man'));
|
||||
|
||||
// Should match /?jackdaniels=true&cola=yeah
|
||||
$this->assertEquals('/?jackdaniels=true&cola=yeah', TestRouter::getUrl('home', null, ['jackdaniels' => 'true', 'cola' => 'yeah']));
|
||||
|
||||
TestRouter::reset();
|
||||
|
||||
}
|
||||
|
||||
public function testCustomRegex()
|
||||
{
|
||||
TestRouter::request()->setHost('google.com');
|
||||
|
||||
TestRouter::get('/admin/', function () {
|
||||
return 'match';
|
||||
})->setMatch('/^\/admin\/?(.*)/i');
|
||||
|
||||
$output = TestRouter::debugOutput('/admin/asd/bec/123', 'get');
|
||||
$this->assertEquals('match', $output);
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testCustomRegexWithParameter()
|
||||
{
|
||||
TestRouter::request()->setHost('google.com');
|
||||
|
||||
$results = '';
|
||||
|
||||
TestRouter::get('/tester/{param}', function ($param = null) use ($results) {
|
||||
return $results = $param;
|
||||
})->setMatch('/(.*)/i');
|
||||
|
||||
$output = TestRouter::debugOutput('/tester/abepik/ko');
|
||||
$this->assertEquals('/tester/abepik/ko/', $output);
|
||||
}
|
||||
|
||||
public function testRenderMultipleRoutesDisabled()
|
||||
{
|
||||
TestRouter::router()->setRenderMultipleRoutes(false);
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result = false;
|
||||
});
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testRenderMultipleRoutesEnabled()
|
||||
{
|
||||
TestRouter::router()->setRenderMultipleRoutes(true);
|
||||
|
||||
$result = [];
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result[] = 'route1';
|
||||
});
|
||||
|
||||
TestRouter::get('/', function () use (&$result) {
|
||||
$result[] = 'route2';
|
||||
});
|
||||
|
||||
TestRouter::debug('/');
|
||||
|
||||
$this->assertCount(2, $result);
|
||||
}
|
||||
|
||||
public function testDefaultNamespace()
|
||||
{
|
||||
TestRouter::setDefaultNamespace('\\Default\\Namespace');
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1', ['as' => 'home']);
|
||||
|
||||
TestRouter::group([
|
||||
'namespace' => 'Appended\Namespace',
|
||||
'prefix' => '/horses',
|
||||
], function () {
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
|
||||
TestRouter::group([
|
||||
'namespace' => '\\New\\Namespace',
|
||||
'prefix' => '/race',
|
||||
], function () {
|
||||
|
||||
TestRouter::get('/', 'DummyController@method1');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
// Test appended namespace
|
||||
|
||||
$class = null;
|
||||
|
||||
try {
|
||||
TestRouter::debugNoReset('/horses/');
|
||||
} catch (\Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException $e) {
|
||||
$class = $e->getClass();
|
||||
}
|
||||
|
||||
$this->assertEquals('\\Default\\Namespace\\Appended\Namespace\\DummyController', $class);
|
||||
|
||||
// Test overwritten namespace
|
||||
|
||||
$class = null;
|
||||
|
||||
try {
|
||||
TestRouter::debugNoReset('/horses/race');
|
||||
} catch (\Pecee\SimpleRouter\Exceptions\ClassNotFoundHttpException $e) {
|
||||
$class = $e->getClass();
|
||||
}
|
||||
|
||||
$this->assertEquals('\\New\\Namespace\\DummyController', $class);
|
||||
|
||||
TestRouter::router()->reset();
|
||||
}
|
||||
|
||||
public function testGroupPrefix()
|
||||
{
|
||||
|
||||
$result = false;
|
||||
|
||||
TestRouter::group(['prefix' => '/lang/{lang}'], function () use (&$result) {
|
||||
|
||||
TestRouter::get('/test', function () use (&$result) {
|
||||
$result = true;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug('/lang/da/test');
|
||||
|
||||
$this->assertTrue($result);
|
||||
|
||||
// Test group prefix sub-route
|
||||
|
||||
$result = null;
|
||||
$expectedResult = 28;
|
||||
|
||||
TestRouter::group(['prefix' => '/lang/{lang}'], function () use (&$result) {
|
||||
|
||||
TestRouter::get('/horse/{horseType}', function ($horseType) use (&$result) {
|
||||
$result = false;
|
||||
});
|
||||
|
||||
TestRouter::get('/user/{userId}', function ($userId) use (&$result) {
|
||||
$result = $userId;
|
||||
});
|
||||
});
|
||||
|
||||
TestRouter::debug("/lang/da/user/$expectedResult");
|
||||
|
||||
$this->assertEquals($expectedResult, $result);
|
||||
|
||||
}
|
||||
|
||||
public function testPassParameter()
|
||||
{
|
||||
|
||||
$result = false;
|
||||
$expectedLanguage = 'da';
|
||||
|
||||
TestRouter::group(['prefix' => '/lang/{lang}'], function ($language) use (&$result) {
|
||||
|
||||
TestRouter::get('/test', function ($language) use (&$result) {
|
||||
$result = $language;
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
TestRouter::debug("/lang/$expectedLanguage/test");
|
||||
|
||||
$this->assertEquals($expectedLanguage, $result);
|
||||
|
||||
}
|
||||
|
||||
public function testPassParameterDeep()
|
||||
{
|
||||
|
||||
$result = false;
|
||||
$expectedLanguage = 'da';
|
||||
|
||||
TestRouter::group(['prefix' => '/lang/{lang}'], function ($language) use (&$result) {
|
||||
|
||||
TestRouter::group(['prefix' => '/admin'], function ($language) use (&$result) {
|
||||
TestRouter::get('/test', function ($language) use (&$result) {
|
||||
$result = $language;
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
TestRouter::debug("/lang/$expectedLanguage/admin/test");
|
||||
|
||||
$this->assertEquals($expectedLanguage, $result);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
class TestRouter extends \Pecee\SimpleRouter\SimpleRouter
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
static::request()->setHost('testhost.com');
|
||||
}
|
||||
|
||||
public static function reset(): void
|
||||
{
|
||||
static::$router = null;
|
||||
}
|
||||
|
||||
public static function debugNoReset(string $testUrl, string $testMethod = 'get'): void
|
||||
{
|
||||
$request = static::request();
|
||||
|
||||
$request->setUrl((new \Pecee\Http\Url($testUrl)));
|
||||
$request->setMethod($testMethod);
|
||||
|
||||
static::start();
|
||||
}
|
||||
|
||||
public static function debug(string $testUrl, string $testMethod = 'get', bool $reset = true): void
|
||||
{
|
||||
try {
|
||||
static::debugNoReset($testUrl, $testMethod);
|
||||
} catch (\Exception $e) {
|
||||
static::$defaultNamespace = null;
|
||||
static::router()->reset();
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if ($reset === true) {
|
||||
static::$defaultNamespace = null;
|
||||
static::router()->reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static function debugOutput(string $testUrl, string $testMethod = 'get', bool $reset = true): string
|
||||
{
|
||||
$response = null;
|
||||
|
||||
// Route request
|
||||
ob_start();
|
||||
static::debug($testUrl, $testMethod, $reset);
|
||||
$response = ob_get_clean();
|
||||
|
||||
// Return response
|
||||
return $response;
|
||||
}
|
||||
|
||||
public static function debugOutputNoReset(string $testUrl, string $testMethod = 'get', bool $reset = true): string
|
||||
{
|
||||
$response = null;
|
||||
|
||||
// Route request
|
||||
ob_start();
|
||||
static::debugNoReset($testUrl, $testMethod, $reset);
|
||||
$response = ob_get_clean();
|
||||
|
||||
// Return response
|
||||
return $response;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<?php
|
||||
|
||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||
require_once 'TestRouter.php';
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
require_once dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
use \Pecee\SimpleRouter\SimpleRouter;
|
||||
|
||||
SimpleRouter::get('/user/{name}', 'UserController@show')->where(['name' => '[\w]+']);
|
||||
$debugInfo = SimpleRouter::startDebug();
|
||||
echo sprintf('<pre>%s</pre>', var_export($debugInfo, true));
|
||||
exit;
|
||||
Reference in New Issue
Block a user