Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge branch 'hotfix/#95-ensure-middlewares-called-as-callables-when-…
Browse files Browse the repository at this point in the history
…error-present'

Close #95
  • Loading branch information
Ocramius committed Jan 5, 2017
2 parents b12bae3 + eefbe51 commit d09cf24
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Dispatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ public function __invoke(
$this->setResponsePrototype($response);
}

// Handle middleware pipes as callables if an $err is present
if ($route->handler instanceof MiddlewarePipe && null !== $err) {
return $this->dispatchCallableMiddleware($route->handler, $next, $request, $response, $err);
}

if ($route->handler instanceof ServerMiddlewareInterface) {
return $this->dispatchInteropMiddleware($route->handler, $next, $request);
}
Expand Down
98 changes: 98 additions & 0 deletions test/DispatchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,104 @@ public function testInvokingWithInteropMiddlewareDispatchesIt()
);
}

public function errorProvider()
{
yield 'exception' => [new \Exception('expected')];
yield 'derivative-exception' => [new RuntimeException('expected')];
if (version_compare(\PHP_VERSION, '7.0', 'gte')) {
yield 'throwable' => [new \Error('expected')];
}
}

/**
* @dataProvider errorProvider
*/
public function testInvokingWithMiddlewarePipeAndErrorDispatchesNextErrorMiddleware($error)
{
$request = $this->prophesize(ServerRequestInterface::class)->reveal();
$response = $this->prophesize(ResponseInterface::class)->reveal();
$expected = $this->prophesize(ResponseInterface::class)->reveal();

$next = $this->prophesize(Next::class);
$next->willImplement(DelegateInterface::class);
$next
->__invoke(
$request,
$this->response->reveal(),
$error
)
->willReturn($expected);

$middleware = $this->prophesize(MiddlewarePipe::class);
$middleware
->__invoke(
Argument::type(ServerRequestInterface::class),
Argument::type(ResponseInterface::class),
Argument::type('callable')
)
->shouldNotBeCalled();
$middleware
->process(
Argument::type(ServerRequestInterface::class),
Argument::type(DelegateInterface::class)
)
->shouldNotBeCalled();

$route = new Route('/foo', $middleware->reveal());

$dispatch = new Dispatch();

$this->assertSame(
$expected,
$dispatch($route, $error, $request, $this->response->reveal(), $next->reveal())
);
}

public function testInvokingWithMiddlewarePipeAndNoErrorDispatchesAsInteropMiddleware()
{
$request = $this->prophesize(ServerRequestInterface::class)->reveal();
$response = $this->prophesize(ResponseInterface::class)->reveal();

$next = $this->prophesize(Next::class);
$next->willImplement(DelegateInterface::class);
$next
->__invoke(
Argument::type(ServerRequestInterface::class),
Argument::type(ResponseInterface::class)
)
->shouldNotBeCalled();
$next
->process(Argument::type(ServerRequestInterface::class))
->shouldNotBeCalled();

$middleware = $this->prophesize(MiddlewarePipe::class);
$middleware
->__invoke(
Argument::type(ServerRequestInterface::class),
Argument::type(ResponseInterface::class),
Argument::type('callable')
)
->shouldNotBeCalled();
$middleware
->hasResponsePrototype()
->willReturn(true);
$middleware
->process(
Argument::type(ServerRequestInterface::class),
Argument::type(DelegateInterface::class)
)
->willReturn($response);

$route = new Route('/foo', $middleware->reveal());

$dispatch = new Dispatch();

$this->assertSame(
$response,
$dispatch($route, null, $request, $this->response->reveal(), $next->reveal())
);
}

/**
* @group http-interop
*/
Expand Down

0 comments on commit d09cf24

Please sign in to comment.