diff options
author | Arnold Daniels <arnold@jasny.net> | 2016-11-29 16:53:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-29 16:53:49 +0100 |
commit | 8db24c7d9e173bb8a126dfde4889f3316d892d66 (patch) | |
tree | ab215c24bea919013537d67a193ab27f73309c79 | |
parent | 85b270a15e378d2e1862d0e797b9ec44a6925bed (diff) | |
parent | 8f42e1e3a34b1b7eab9892a9d4a40efe524eba42 (diff) | |
download | router-8db24c7d9e173bb8a126dfde4889f3316d892d66.zip router-8db24c7d9e173bb8a126dfde4889f3316d892d66.tar.gz router-8db24c7d9e173bb8a126dfde4889f3316d892d66.tar.bz2 |
Merge pull request #15 from jasny/controller-runner-notfound
Let the controller runner return a not found response
-rw-r--r-- | src/Router/Runner/Controller.php | 25 | ||||
-rw-r--r-- | tests/Router/Runner/ControllerTest.php | 63 | ||||
-rw-r--r-- | tests/support/TestHelpers.php | 19 |
3 files changed, 81 insertions, 26 deletions
diff --git a/src/Router/Runner/Controller.php b/src/Router/Runner/Controller.php index 7985029..3d5e569 100644 --- a/src/Router/Runner/Controller.php +++ b/src/Router/Runner/Controller.php @@ -12,6 +12,25 @@ use Psr\Http\Message\ResponseInterface; class Controller extends Runner { /** + * Return with a 404 not found response + * + * @param ServerRequestInterface $request + * @param ResponseInterface $response + * @return ResponseInterface + */ + protected function notFound(ServerRequestInterface $request, ResponseInterface $response) + { + $finalResponse = $response + ->withProtocolVersion($request->getProtocolVersion()) + ->withStatus(404) + ->withHeader('Content-Type', 'text/plain'); + + $finalResponse->getBody()->write("Not found"); + + return $finalResponse; + } + + /** * Get class name from controller name * * @param string $name @@ -49,11 +68,13 @@ class Controller extends Runner $class = $this->getClass($name); if (!class_exists($class)) { - throw new \RuntimeException("Can not route to controller '$class': class not exists"); + trigger_error("Can't route to controller '$class': class not exists", E_USER_NOTICE); + return $this->notFound($request, $response); } if (!method_exists($class, '__invoke')) { - throw new \RuntimeException("Can not route to controller '$class': class does not have '__invoke' method"); + trigger_error("Can't route to controller '$class': class does not have '__invoke' method", E_USER_NOTICE); + return $this->notFound($request, $response); } $controller = $this->instantiate($class); diff --git a/tests/Router/Runner/ControllerTest.php b/tests/Router/Runner/ControllerTest.php index c1b1801..5bbbeca 100644 --- a/tests/Router/Runner/ControllerTest.php +++ b/tests/Router/Runner/ControllerTest.php @@ -6,6 +6,7 @@ use Jasny\Router\Route; use Jasny\Router\Runner; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\StreamInterface; use Jasny\Router\TestHelpers; @@ -39,44 +40,58 @@ class ControllerTest extends \PHPUnit_Framework_TestCase $this->assertSame($finalResponse, $result); } - /** - * @expectedException RuntimeException - * @expectedExceptionMessage Can not route to controller 'DoesNotExistsController': class not exists - */ - public function testInvalidClass() + public function invalidProvider() { - $request = $this->createMock(ServerRequestInterface::class); - $response = $this->createMock(ResponseInterface::class); + $runnerNotExists = $this->createPartialMock(Runner\Controller::class, ['instantiate']); + $runnerNotExists->expects($this->never())->method('instantiate'); - $route = $this->createMock(Route::class); - $route->controller = 'does-not-exists'; - - $request->expects($this->once())->method('getAttribute')->with('route')->willReturn($route); + $runnerNotCallable = $this->createPartialMock(Runner\Controller::class, ['instantiate', 'getClass']); + $runnerNotCallable->expects($this->once())->method('getClass')->with('foo-bar-zoo')->willReturn('stdClass'); + $runnerNotCallable->expects($this->never())->method('instantiate'); - $runner = $this->getMockBuilder(Runner\Controller::class)->setMethods(['instantiate'])->getMock(); - $runner->expects($this->never())->method('instantiate'); - - $runner($request, $response); + return [ + [ + $runnerNotExists, + "Can't route to controller 'FooBarZooController': class not exists" + ], + [ + $runnerNotCallable, + "Can't route to controller 'stdClass': class does not have '__invoke' method" + ] + ]; } /** - * @expectedException RuntimeException - * @expectedExceptionMessage Can not route to controller 'stdClass': class does not have '__invoke' method + * @dataProvider invalidProvider + * + * @param Runner $runner + * @param string $message */ - public function testInvokeNotCallable() + public function testInvokeInvalid(Runner $runner, $message) { $request = $this->createMock(ServerRequestInterface::class); + $request->method('getProtocolVersion')->willReturn('1.1'); + + $body = $this->createMock(StreamInterface::class); + $body->expects($this->once())->method('write')->with('Not found'); + + $notFound = $this->createMock(ResponseInterface::class); + $notFound->expects($this->once())->method('getBody')->willReturn($body); + $response = $this->createMock(ResponseInterface::class); + $response->expects($this->once())->method('withProtocolVersion')->with('1.1')->willReturnSelf(); + $response->expects($this->once())->method('withStatus')->with(404)->willReturnSelf(); + $response->expects($this->once())->method('withHeader')->with('Content-Type', 'text/plain') + ->willReturn($notFound); $route = $this->createMock(Route::class); - $route->controller = 'foo'; + $route->controller = 'foo-bar-zoo'; $request->expects($this->once())->method('getAttribute')->with('route')->willReturn($route); - $runner = $this->getMockBuilder(Runner\Controller::class)->setMethods(['instantiate', 'getClass'])->getMock(); - $runner->expects($this->once())->method('getClass')->with('foo')->willReturn('stdClass'); - $runner->expects($this->never())->method('instantiate'); - - $runner($request, $response); + $result = @$runner($request, $response); + + $this->assertSame($notFound, $result); + $this->assertLastError(E_USER_NOTICE, $message); } } diff --git a/tests/support/TestHelpers.php b/tests/support/TestHelpers.php index e4fdff7..3781851 100644 --- a/tests/support/TestHelpers.php +++ b/tests/support/TestHelpers.php @@ -27,4 +27,23 @@ trait TestHelpers return $callback; } + + /** + * Assert a non-fatal error + * + * @param int $type + * @param string $message + */ + protected function assertLastError($type, $message) + { + $error = error_get_last(); + + $expect = compact('type', 'message'); + + if (is_array($error)) { + $error = array_intersect_key($error, $expect); + } + + $this->assertEquals($expect, $error); + } } |