test(router): verify custom exceptions reach exception callback
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Tests\Unit;
|
||||
|
||||
use Exception;
|
||||
use Libs\Neuron;
|
||||
use Libs\Request;
|
||||
use Libs\Router;
|
||||
use LogicException;
|
||||
use PDOException;
|
||||
@@ -25,10 +26,14 @@ use TypeError;
|
||||
final class RouterTest extends TestCase
|
||||
{
|
||||
private array $serverBackup = [];
|
||||
private array $getBackup = [];
|
||||
private array $postBackup = [];
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->serverBackup = $_SERVER;
|
||||
$this->getBackup = $_GET;
|
||||
$this->postBackup = $_POST;
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
unset($_SERVER['HTTP_ACCEPT']);
|
||||
http_response_code(200);
|
||||
@@ -38,6 +43,8 @@ final class RouterTest extends TestCase
|
||||
protected function tearDown(): void
|
||||
{
|
||||
$_SERVER = $this->serverBackup;
|
||||
$_GET = $this->getBackup;
|
||||
$_POST = $this->postBackup;
|
||||
http_response_code(200);
|
||||
$this->resetRouterState();
|
||||
}
|
||||
@@ -206,4 +213,56 @@ final class RouterTest extends TestCase
|
||||
$this->assertSame('{"status":"ok"}', $output);
|
||||
$this->assertSame(200, http_response_code());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function customOnInvalidExceptionReachesTheExceptionCallbackThroughTheBoundary(): void
|
||||
{
|
||||
$_SERVER['REQUEST_METHOD'] = 'POST';
|
||||
$_SERVER['REQUEST_URI'] = '/signup';
|
||||
$_SERVER['DOCUMENT_ROOT'] = '/nonexistent-docroot';
|
||||
$_POST = ['age' => '5'];
|
||||
|
||||
$caught = [];
|
||||
Router::$exceptionCallback = function (\Throwable $exception) use (&$caught): void {
|
||||
$caught[] = $exception;
|
||||
};
|
||||
|
||||
$finalRan = false;
|
||||
Router::post('/signup', function (StrictSignup $request) use (&$finalRan): void {
|
||||
$finalRan = true;
|
||||
});
|
||||
|
||||
Router::apply('/signup');
|
||||
|
||||
// The Request was built by the container for the final callback and its
|
||||
// custom onInvalid() threw during dependency resolution: the custom type
|
||||
// must arrive intact to the callback, and the final callback must not run.
|
||||
$this->assertCount(1, $caught);
|
||||
$this->assertInstanceOf(RequestRejected::class, $caught[0]);
|
||||
$this->assertSame('The age must be at least 18.', $caught[0]->getMessage());
|
||||
$this->assertSame(400, $caught[0]->getCode(), 'The status channel must survive custom exception types');
|
||||
$this->assertFalse($finalRan, 'A Request that throws during DI resolution must stop the route');
|
||||
}
|
||||
}
|
||||
|
||||
// phpcs:disable PSR1.Classes.ClassDeclaration.MultipleClasses
|
||||
/**
|
||||
* Fixtures locales de la prueba de simetría: un tipo de excepcion propio que
|
||||
* un Request hijo lanza desde su onInvalid() reescrito.
|
||||
*/
|
||||
final class RequestRejected extends Exception
|
||||
{
|
||||
}
|
||||
|
||||
final class StrictSignup extends Request
|
||||
{
|
||||
public function rules(): array
|
||||
{
|
||||
return ['age' => 'required|min:18'];
|
||||
}
|
||||
|
||||
public function onInvalid(string $error): never
|
||||
{
|
||||
throw new RequestRejected($error, 400);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user