summaryrefslogtreecommitdiffstats
path: root/tests/Router/Routes/RouteBindingTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Router/Routes/RouteBindingTest.php')
-rw-r--r--tests/Router/Routes/RouteBindingTest.php263
1 files changed, 263 insertions, 0 deletions
diff --git a/tests/Router/Routes/RouteBindingTest.php b/tests/Router/Routes/RouteBindingTest.php
new file mode 100644
index 0000000..96536ac
--- /dev/null
+++ b/tests/Router/Routes/RouteBindingTest.php
@@ -0,0 +1,263 @@
+<?php
+
+namespace Jasny\Router\Routes;
+
+use Jasny\Router\Routes\Glob;
+use Jasny\Router\Route;
+use Psr\Http\Message\ServerRequestInterface;
+
+use InvalidArgumentException;
+
+/**
+ * @covers Jasny\Router\Routes\RouteBinding
+ */
+class RouteBindingTest extends \PHPUnit_Framework_TestCase
+{
+ /**
+ * Test binding simple string when getting route
+ */
+ public function testBindVarString()
+ {
+ $uri = '/foo/bar';
+ $values = [$uri => ['controller' => 'value1', 'check' => 'value1']];
+
+ $glob = new Glob($values);
+ $request = $this->getServerRequest($uri);
+ $route = $glob->getRoute($request);
+
+ $this->assertEquals($values[$uri]['check'], $route->check);
+ }
+
+ /**
+ * Provide uri's and corresponding patterns for testBindVarSingleUrlPart()
+ */
+ public function bindVarSingleUrlPartProvider()
+ {
+ return [
+ ['/*', '/test', ['check' => '$1'], 'test'],
+ ['/', '/', ['check' => '$1|test'], 'test'],
+ ['/foo/*/bar', '/foo/test/bar', ['check' => '$2'], 'test'],
+ ['/foo/bar/*', '/foo/bar/test', ['check' => '$3'], 'test'],
+ ['/foo/bar/*/zet/*', '/foo/bar/test1/zet/test2', ['check' => '$3', 'checkB' => '$5'], 'test1', 'test2'],
+ ['/foo/bar/*/zet/*', '/foo/bar/test1/zet/test2', ['check' => '~$3~/~$5~'], 'test1/test2'],
+ ['/', '/', ['check' => '$foo'], null],
+ ['/', '/', ['check' => 'test', 'checkB' => null], 'test', null]
+ ];
+ }
+
+ /**
+ * Test binding single url part to route option
+ * @dataProvider bindVarSingleUrlPartProvider
+ *
+ * @param string $pattern
+ * @param string $uri
+ * @param array $options Route options
+ * @param string $check Expected value for `check`
+ * @param string $checkB Expected value for `checkB`
+ */
+ public function testBindVarSingleUrlPart($pattern, $uri, $options, $check, $checkB = null)
+ {
+ $values = [$pattern => $options];
+
+ $glob = new Glob($values);
+ $request = $this->getServerRequest($uri);
+ $route = $glob->getRoute($request);
+
+ $this->assertNotNull($route, "Route not found");
+ $this->assertInstanceOf(Route::class, $route);
+
+ $this->assertEquals($check, $route->check);
+
+ if (isset($checkB)) {
+ $this->assertEquals($checkB, $route->checkB);
+ } else {
+ $this->assertObjectNotHasAttribute('checkB', $route);
+ }
+ }
+
+ public function testBindVarWithObject()
+ {
+ $object = new \Exception(); // Could be anything, just not stdClass
+ $glob = new Glob(['/' => ['object' => $object]]);
+
+ $request = $this->getServerRequest('/');
+ $route = $glob->getRoute($request);
+
+ $this->assertNotNull($route, "Route not found");
+ $this->assertInstanceOf(Route::class, $route);
+
+ $this->assertSame($object, $route->object);
+ }
+
+ public function bindVarWithSubProvider()
+ {
+ return [
+ [['group' => ['check' => '$1']], 'array'],
+ [['group' => (object)['check' => '$1']], 'object'],
+ [['group' => ['sub' => (object)['check' => '$1']]], 'array', 'object'],
+ [['group' => (object)['sub' => ['check' => '$1']]], 'object', 'array']
+ ];
+ }
+
+ /**
+ * @dataProvider bindVarWithSubProvider
+ *
+ * @param array $options
+ * @param string $type
+ * @param string $subtype
+ */
+ public function testBindVarWithSub(array $options, $type, $subtype = null)
+ {
+ $glob = new Glob(['/*' => $options]);
+
+ $request = $this->getServerRequest('/test');
+ $route = $glob->getRoute($request);
+
+ $this->assertNotNull($route, "Route not found");
+ $this->assertInstanceOf(Route::class, $route);
+
+ $this->assertInternalType($type, $route->group);
+
+ $group = (array)$route->group;
+
+ if (isset($subtype)) {
+ $this->assertArrayHasKey('sub', $group);
+ $this->assertInternalType($subtype, $group['sub']);
+
+ $group = (array)$group['sub'];
+ }
+
+ $this->assertEquals($group, ['check' => 'test']);
+ }
+
+
+ /**
+ * Provide uri's and corresponding patterns for testBindVarMultipleUrlParts()
+ */
+ public function bindVarMultipleUrlPartsProvider()
+ {
+ return [
+ ['/foo', ['check' => '$1...'], false, InvalidArgumentException::class],
+ ['/', ['check' => ['$1...']], false],
+ ['/foo', ['check' => ['$1...']], true],
+ ['/foo/bar', ['check' => ['$1...'], 'checkB' => ['$2...']],
+ InvalidArgumentException::class]
+ ];
+ }
+
+ /**
+ * Test binding multyple url parts to route option
+ * @dataProvider bindVarMultipleUrlPartsProvider
+ *
+ * @param string $uri
+ * @param array $options Route options
+ * @param boolean $positive
+ * @param string $exception
+ */
+ public function testBindVarMultipleUrlParts($uri, $options, $positive, $exception = false)
+ {
+ if ($exception) {
+ $this->expectException($exception);
+ }
+
+ $glob = new Glob([$uri => $options]);
+ $request = $this->getServerRequest($uri);
+ $route = $glob->getRoute($request);
+
+ if ($exception) return;
+
+ $this->assertNotNull($route, "Route not found");
+ $this->assertInstanceOf(Route::class, $route);
+
+ $values = explode('/', trim($uri, '/'));
+
+ $positive ?
+ $this->assertArraysEqual($values, $route->check, "Multyple url parts are not picked correctly") :
+ $this->assertEmpty($route->check, "Multyple parts element should be empty");
+
+ if (!empty($options->checkB)) {
+ array_shift($values);
+ $this->assertArraysEqual($values, $route->checkB, "Secondary multyple url parts are not picked correctly");
+ }
+ }
+
+ /**
+ * Provide uri's and corresponding patterns for testBindVarMultipleUrlParts()
+ */
+ public function bindVarSuperGlobalProvider()
+ {
+ return [
+ ['/foo', ['check' => '$_GET[check]'], 'get'],
+ ['/foo', ['check' => '$_POST[check]'], 'post'],
+ ['/foo', ['check' => '$_COOKIE[check]'], 'cookie']
+ ];
+ }
+
+ /**
+ * Test binding element of superglobal array to route option
+ * @dataProvider bindVarSuperGlobalProvider
+ *
+ * @param string $uri
+ * @param array $options
+ * @param string $type ('get', 'post', 'cookie')
+ */
+ public function testBindVarSuperGlobal($uri, $options, $type)
+ {
+ $test = ['check' => 'test'];
+ $glob = new Glob([$uri => $options]);
+ $request = $this->getServerRequest($uri, 'GET', [$type => $test]);
+ $route = $glob->getRoute($request);
+
+ $this->assertEquals($test['check'], $route->check, "Did not obtaine value for superglobal '$type'");
+ }
+
+ /**
+ * Test binding element of superglobal array to route option
+ */
+ public function testBindVarRequestHeader()
+ {
+ $uri = '/foo/bar';
+ $test = 'test_header_value';
+
+ $glob = new Glob([$uri => ['check' => '$HTTP_REFERER']]);
+ $request = $this->getServerRequest($uri, 'GET', [], $test);
+
+ $route = $glob->getRoute($request);
+ $this->assertNotNull($route, "Route not found");
+
+ $this->assertEquals($test, $route->check);
+ }
+
+ /**
+ * Get ServerRequestInterface object
+ *
+ * @param string $uri
+ * @param string $method Http query method
+ * @return ServerRequestInterface
+ */
+ public function getServerRequest($uri, $method = 'GET', $globals = [], $header = '')
+ {
+ $request = $this->createMock(ServerRequestInterface::class);
+ $request->method('getUri')->willReturn($uri);
+ $request->method('getMethod')->willReturn($method);
+ $request->method('getQueryParams')->willReturn(isset($globals['get']) ? $globals['get'] : []);
+ $request->method('getParsedBody')->willReturn(isset($globals['post']) ? $globals['post'] : []);
+ $request->method('getCookieParams')->willReturn(isset($globals['cookie']) ? $globals['cookie'] : []);
+ $request->method('getHeaderLine')->willReturn($header);
+
+ return $request;
+ }
+
+ /**
+ * Assert that two 1-dimensional arrays are equal.
+ * Use if array elements are scalar values, or objects with __toString() method
+ *
+ * @param array $array1
+ * @param array $array2
+ */
+ public function assertArraysEqual(array $array1, array $array2)
+ {
+ $this->assertEmpty(array_diff($array2, $array1), 'Missing items');
+ $this->assertEmpty(array_diff($array1, $array2), 'Additional items');
+ }
+}