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

Adds support for http-interop middleware #32

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"require": {
"php": "^5.6 || ^7.0",
"psr/http-message": "^1.0",
"fig/http-message-util": "^1.1"
"fig/http-message-util": "^1.1",
"http-interop/http-middleware": "^0.4.1"
},
"require-dev": {
"phpunit/phpunit": "^4.7 || ^5.6",
Expand Down
17 changes: 13 additions & 4 deletions src/Route.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Zend\Expressive\Router;

use Fig\Http\Message\RequestMethodInterface as RequestMethod;
use Interop\Http\ServerMiddleware\MiddlewareInterface;

/**
* Value object representing a single route.
Expand Down Expand Up @@ -68,7 +69,7 @@ class Route

/**
* @param string $path Path to match.
* @param string|callable $middleware Middleware to use when this route is matched.
* @param string|callable|MiddlewareInterface $middleware Middleware to use when this route is matched.
* @param int|array Allowed HTTP methods; defaults to HTTP_METHOD_ANY.
* @param string|null $name the route name
* @throws Exception\InvalidArgumentException for invalid path type.
Expand All @@ -81,8 +82,16 @@ public function __construct($path, $middleware, $methods = self::HTTP_METHOD_ANY
throw new Exception\InvalidArgumentException('Invalid path; must be a string');
}

if (! is_callable($middleware) && ! is_string($middleware) && ! is_array($middleware)) {
throw new Exception\InvalidArgumentException('Invalid middleware; must be callable or a service name');
if (! is_callable($middleware)
&& ! $middleware instanceof MiddlewareInterface
&& ! is_string($middleware)
&& ! is_array($middleware)
) {
throw new Exception\InvalidArgumentException(sprintf(
'Invalid middleware; must be a callable, a %s instance, a service name, '
. 'or an array of any of these types',
MiddlewareInterface::class
));
}

if ($methods !== self::HTTP_METHOD_ANY && ! is_array($methods)) {
Expand Down Expand Up @@ -136,7 +145,7 @@ public function getName()
}

/**
* @return string|callable|array
* @return string|callable|MiddlewareInterface
*/
public function getMiddleware()
{
Expand Down
49 changes: 44 additions & 5 deletions test/RouteTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace ZendTest\Expressive\Router;

use Fig\Http\Message\RequestMethodInterface as RequestMethod;
use Interop\Http\ServerMiddleware\MiddlewareInterface;
use PHPUnit_Framework_TestCase as TestCase;
use Zend\Expressive\Router\Exception\InvalidArgumentException;
use Zend\Expressive\Router\Route;
Expand Down Expand Up @@ -128,11 +129,7 @@ public function testThrowsExceptionDuringConstructionIfPathIsNotString()

public function testThrowsExceptionDuringConstructionOnInvalidMiddleware()
{
$this->setExpectedException(
InvalidArgumentException::class,
'Invalid middleware; must be callable or a service name'
);

$this->setExpectedException(InvalidArgumentException::class, 'Invalid middleware');
new Route('/foo', 12345);
}

Expand Down Expand Up @@ -208,4 +205,46 @@ public function testPassingWildcardMethodDoesNotMarkAsImplicit()
$this->assertFalse($route->implicitHead());
$this->assertFalse($route->implicitOptions());
}

public function testAllowsHttpInteropMiddleware()
{
$middleware = $this->prophesize(MiddlewareInterface::class)->reveal();
$route = new Route('/test', $middleware, Route::HTTP_METHOD_ANY);
$this->assertSame($middleware, $route->getMiddleware());
}

/**
* This is to allow passing an array of middleware for use in creating a MiddlewarePipe
* instance; Route should simply check if it's a non-callable array, and, if so, store
* the entry as it would a non-callable string.
*/
public function testAllowsNonCallableArraysAsMiddleware()
{
$middleware = ['Non', 'Callable', 'Middleware'];
$route = new Route('/test', $middleware, Route::HTTP_METHOD_ANY);
$this->assertSame($middleware, $route->getMiddleware());
}

public function invalidMiddleware()
{
// Strings are allowed, because they could be service names.
return [
'null' => [null],
'true' => [true],
'false' => [false],
'zero' => [0],
'int' => [1],
'int' => [1],
'non-callable-object' => [(object) ['handler' => 'foo']],
];
}

/**
* @dataProvider invalidMiddleware
*/
public function testConstructorRaisesExceptionForInvalidMiddleware($middleware)
{
$this->setExpectedException(InvalidArgumentException::class, 'Invalid middleware');
new Route('/test', $middleware);
}
}