_parseExtension($url); } } /** * Test case for Route */ class RouteTest extends TestCase { /** * setUp method * * @return void */ public function setUp() { parent::setUp(); Configure::write('Routing', ['admin' => null, 'prefixes' => []]); } /** * Test the construction of a Route * * @return void */ public function testConstruction() { $route = new Route('/:controller/:action/:id', [], ['id' => '[0-9]+']); $this->assertEquals('/:controller/:action/:id', $route->template); $this->assertEquals([], $route->defaults); $this->assertEquals(['id' => '[0-9]+', '_ext' => []], $route->options); $this->assertFalse($route->compiled()); } /** * Test set middleware in the constructor * * @return void */ public function testConstructorSetMiddleware() { $route = new Route('/:controller/:action/*', [], ['_middleware' => ['auth', 'cookie']]); $this->assertSame(['auth', 'cookie'], $route->getMiddleware()); } /** * Test Route compiling. * * @return void */ public function testBasicRouteCompiling() { $route = new Route('/', ['controller' => 'pages', 'action' => 'display', 'home']); $result = $route->compile(); $expected = '#^/*$#'; $this->assertEquals($expected, $result); $this->assertEquals([], $route->keys); $route = new Route('/:controller/:action', ['controller' => 'posts']); $result = $route->compile(); $this->assertRegExp($result, '/posts/edit'); $this->assertRegExp($result, '/posts/super_delete'); $this->assertNotRegExp($result, '/posts'); $this->assertNotRegExp($result, '/posts/super_delete/1'); $this->assertSame($result, $route->compile()); $route = new Route('/posts/foo:id', ['controller' => 'posts', 'action' => 'view']); $result = $route->compile(); $this->assertRegExp($result, '/posts/foo:1'); $this->assertRegExp($result, '/posts/foo:param'); $this->assertNotRegExp($result, '/posts'); $this->assertNotRegExp($result, '/posts/'); $this->assertEquals(['id'], $route->keys); $route = new Route('/:plugin/:controller/:action/*', ['plugin' => 'test_plugin', 'action' => 'index']); $result = $route->compile(); $this->assertRegExp($result, '/test_plugin/posts/index'); $this->assertRegExp($result, '/test_plugin/posts/edit/5'); $this->assertRegExp($result, '/test_plugin/posts/edit/5/name:value/nick:name'); } /** * Test that single letter placeholders work. * * @return void */ public function testRouteCompileSmallPlaceholders() { $route = new Route( '/fighters/:id/move/:x/:y', ['controller' => 'Fighters', 'action' => 'move'], ['id' => '\d+', 'x' => '\d+', 'y' => '\d+', 'pass' => ['id', 'x', 'y']] ); $pattern = $route->compile(); $this->assertRegExp($pattern, '/fighters/123/move/8/42'); $result = $route->match([ 'controller' => 'Fighters', 'action' => 'move', 'id' => 123, 'x' => 8, 'y' => 42, ]); $this->assertEquals('/fighters/123/move/8/42', $result); } /** * Test route compile with brace format. * * @return void */ public function testRouteCompileBraces() { $route = new Route( '/fighters/{id}/move/{x}/{y}', ['controller' => 'Fighters', 'action' => 'move'], ['id' => '\d+', 'x' => '\d+', 'y' => '\d+', 'pass' => ['id', 'x', 'y']] ); $this->assertRegExp($route->compile(), '/fighters/123/move/8/42'); $result = $route->match([ 'controller' => 'Fighters', 'action' => 'move', 'id' => 123, 'x' => 8, 'y' => 42, ]); $this->assertEquals('/fighters/123/move/8/42', $result); $route = new Route( '/images/{id}/{x}x{y}', ['controller' => 'Images', 'action' => 'view'] ); $this->assertRegExp($route->compile(), '/images/123/640x480'); $result = $route->match([ 'controller' => 'Images', 'action' => 'view', 'id' => 123, 'x' => 8, 'y' => 42, ]); $this->assertEquals('/images/123/8x42', $result); } /** * Test route compile with brace format. * * @return void */ public function testRouteCompileBracesVariableName() { $route = new Route( '/fighters/{0id}', ['controller' => 'Fighters', 'action' => 'move'] ); $pattern = $route->compile(); $this->assertNotRegExp($route->compile(), '/fighters/123', 'Placeholders must start with letter'); $route = new Route('/fighters/{Id}', ['controller' => 'Fighters', 'action' => 'move']); $this->assertRegExp($route->compile(), '/fighters/123'); $route = new Route('/fighters/{i_d}', ['controller' => 'Fighters', 'action' => 'move']); $this->assertRegExp($route->compile(), '/fighters/123'); $route = new Route('/fighters/{id99}', ['controller' => 'Fighters', 'action' => 'move']); $this->assertRegExp($route->compile(), '/fighters/123'); } /** * Test route compile with brace format. * * @return void */ public function testRouteCompileBracesInvalid() { $route = new Route( '/fighters/{ id }', ['controller' => 'Fighters', 'action' => 'move'] ); $this->assertNotRegExp($route->compile(), '/fighters/123', 'no spaces in placeholder'); $route = new Route( '/fighters/{i d}', ['controller' => 'Fighters', 'action' => 'move'] ); $this->assertNotRegExp($route->compile(), '/fighters/123', 'no spaces in placeholder'); } /** * Test route compile with mixed placeholder types brace format. * * @return void */ public function testRouteCompileMixedPlaceholders() { $route = new Route( '/images/{open/:id', ['controller' => 'Images', 'action' => 'open'] ); $pattern = $route->compile(); $this->assertRegExp($pattern, '/images/{open/9', 'Need both {} to enable brace mode'); $result = $route->match([ 'controller' => 'Images', 'action' => 'open', 'id' => 123, ]); $this->assertEquals('/images/{open/123', $result); $route = new Route( '/fighters/{id}/move/{x}/:y', ['controller' => 'Fighters', 'action' => 'move'], ['id' => '\d+', 'x' => '\d+', 'pass' => ['id', 'x']] ); $pattern = $route->compile(); $this->assertRegExp($pattern, '/fighters/123/move/8/:y'); $result = $route->match([ 'controller' => 'Fighters', 'action' => 'move', 'id' => 123, 'x' => 8, 'y' => 9, ]); $this->assertEquals('/fighters/123/move/8/:y?y=9', $result); } /** * Test parsing routes with extensions. * * @return void */ public function testRouteParsingWithExtensions() { $route = new Route( '/:controller/:action/*', [], ['_ext' => ['json', 'xml']] ); $result = $route->parse('/posts/index', 'GET'); $this->assertArrayNotHasKey('_ext', $result); $result = $route->parse('/posts/index.pdf', 'GET'); $this->assertArrayNotHasKey('_ext', $result); $result = $route->setExtensions(['pdf', 'json', 'xml', 'xml.gz'])->parse('/posts/index.pdf', 'GET'); $this->assertEquals('pdf', $result['_ext']); $result = $route->parse('/posts/index.json', 'GET'); $this->assertEquals('json', $result['_ext']); $result = $route->parse('/posts/index.xml', 'GET'); $this->assertEquals('xml', $result['_ext']); $result = $route->parse('/posts/index.xml.gz', 'GET'); $this->assertEquals('xml.gz', $result['_ext']); } /** * @return array */ public function provideMatchParseExtension() { return [ ['/foo/bar.xml', ['/foo/bar', 'xml'], ['xml', 'json', 'xml.gz']], ['/foo/bar.json', ['/foo/bar', 'json'], ['xml', 'json', 'xml.gz']], ['/foo/bar.xml.gz', ['/foo/bar', 'xml.gz'], ['xml', 'json', 'xml.gz']], ['/foo/with.dots.json.xml.zip', ['/foo/with.dots.json.xml', 'zip'], ['zip']], ['/foo/confusing.extensions.dots.json.xml.zip', ['/foo/confusing.extensions.dots.json.xml', 'zip'], ['json', 'xml', 'zip']], ['/foo/confusing.extensions.dots.json.xml', ['/foo/confusing.extensions.dots.json', 'xml'], ['json', 'xml', 'zip']], ['/foo/confusing.extensions.dots.json', ['/foo/confusing.extensions.dots', 'json'], ['json', 'xml', 'zip']], ]; } /** * Expects _parseExtension to match extensions in URLs * * @param string $url * @param array $expected * @param array $ext * @return void * @dataProvider provideMatchParseExtension */ public function testMatchParseExtension($url, array $expected, array $ext) { $route = new RouteProtected('/:controller/:action/*', [], ['_ext' => $ext]); $result = $route->parseExtension($url); $this->assertEquals($expected, $result); } /** * @return array */ public function provideNoMatchParseExtension() { return [ ['/foo/bar', ['xml']], ['/foo/bar.zip', ['xml']], ['/foo/bar.xml.zip', ['xml']], ['/foo/bar.', ['xml']], ['/foo/bar.xml', []], ['/foo/bar...xml...zip...', ['xml']], ]; } /** * Expects _parseExtension to not match extensions in URLs * * @param string $url * @param array $ext * @return void * @dataProvider provideNoMatchParseExtension */ public function testNoMatchParseExtension($url, array $ext) { $route = new RouteProtected('/:controller/:action/*', [], ['_ext' => $ext]); list($outUrl, $outExt) = $route->parseExtension($url); $this->assertEquals($url, $outUrl); $this->assertNull($outExt); } /** * Expects extensions to be set * * @group deprecated * @return void */ public function testExtensions() { $this->deprecated(function () { $route = new RouteProtected('/:controller/:action/*', []); $this->assertEquals([], $route->extensions()); $route->extensions(['xml']); $this->assertEquals(['xml'], $route->extensions()); }); } /** * Expects extensions to be set * * @return void */ public function testSetExtensions() { $route = new RouteProtected('/:controller/:action/*', []); $this->assertEquals([], $route->getExtensions()); $route->setExtensions(['xml']); $this->assertEquals(['xml'], $route->getExtensions()); $route->setExtensions(['xml', 'json', 'zip']); $this->assertEquals(['xml', 'json', 'zip'], $route->getExtensions()); $route->setExtensions([]); $this->assertEquals([], $route->getExtensions()); $route = new RouteProtected('/:controller/:action/*', [], ['_ext' => ['one', 'two']]); $this->assertEquals(['one', 'two'], $route->getExtensions()); } /** * Expects extensions to be return. * * @return void */ public function testGetExtensions() { $route = new RouteProtected('/:controller/:action/*', []); $this->assertEquals([], $route->getExtensions()); $route = new RouteProtected('/:controller/:action/*', [], ['_ext' => ['one', 'two']]); $this->assertEquals(['one', 'two'], $route->getExtensions()); $route = new RouteProtected('/:controller/:action/*', []); $this->assertEquals([], $route->getExtensions()); $route->setExtensions(['xml', 'json', 'zip']); $this->assertEquals(['xml', 'json', 'zip'], $route->getExtensions()); } /** * Test that route parameters that overlap don't cause errors. * * @return void */ public function testRouteParameterOverlap() { $route = new Route('/invoices/add/:idd/:id', ['controller' => 'invoices', 'action' => 'add']); $result = $route->compile(); $this->assertRegExp($result, '/invoices/add/1/3'); $route = new Route('/invoices/add/:id/:idd', ['controller' => 'invoices', 'action' => 'add']); $result = $route->compile(); $this->assertRegExp($result, '/invoices/add/1/3'); } /** * Test compiling routes with keys that have patterns * * @return void */ public function testRouteCompilingWithParamPatterns() { $route = new Route( '/:controller/:action/:id', [], ['id' => Router::ID] ); $result = $route->compile(); $this->assertRegExp($result, '/posts/edit/1'); $this->assertRegExp($result, '/posts/view/518098'); $this->assertNotRegExp($result, '/posts/edit/name-of-post'); $this->assertNotRegExp($result, '/posts/edit/4/other:param'); $this->assertEquals(['id', 'controller', 'action'], $route->keys); $route = new Route( '/:lang/:controller/:action/:id', ['controller' => 'testing4'], ['id' => Router::ID, 'lang' => '[a-z]{3}'] ); $result = $route->compile(); $this->assertRegExp($result, '/eng/posts/edit/1'); $this->assertRegExp($result, '/cze/articles/view/1'); $this->assertNotRegExp($result, '/language/articles/view/2'); $this->assertNotRegExp($result, '/eng/articles/view/name-of-article'); $this->assertEquals(['lang', 'id', 'controller', 'action'], $route->keys); foreach ([':', '@', ';', '$', '-'] as $delim) { $route = new Route('/posts/:id' . $delim . ':title'); $result = $route->compile(); $this->assertRegExp($result, '/posts/1' . $delim . 'name-of-article'); $this->assertRegExp($result, '/posts/13244' . $delim . 'name-of_Article[]'); $this->assertNotRegExp($result, '/posts/11!nameofarticle'); $this->assertNotRegExp($result, '/posts/11'); $this->assertEquals(['title', 'id'], $route->keys); } $route = new Route( '/posts/:id::title/:year', ['controller' => 'posts', 'action' => 'view'], ['id' => Router::ID, 'year' => Router::YEAR, 'title' => '[a-z-_]+'] ); $result = $route->compile(); $this->assertRegExp($result, '/posts/1:name-of-article/2009/'); $this->assertRegExp($result, '/posts/13244:name-of-article/1999'); $this->assertNotRegExp($result, '/posts/hey_now:nameofarticle'); $this->assertNotRegExp($result, '/posts/:nameofarticle/2009'); $this->assertNotRegExp($result, '/posts/:nameofarticle/01'); $this->assertEquals(['year', 'title', 'id'], $route->keys); $route = new Route( '/posts/:url_title-(uuid::id)', ['controller' => 'posts', 'action' => 'view'], ['pass' => ['id', 'url_title'], 'id' => Router::ID] ); $result = $route->compile(); $this->assertRegExp($result, '/posts/some_title_for_article-(uuid:12534)/'); $this->assertRegExp($result, '/posts/some_title_for_article-(uuid:12534)'); $this->assertNotRegExp($result, '/posts/'); $this->assertNotRegExp($result, '/posts/nameofarticle'); $this->assertNotRegExp($result, '/posts/nameofarticle-12347'); $this->assertEquals(['url_title', 'id'], $route->keys); } /** * Test route with unicode * * @return void */ public function testCompileWithUnicodePatterns() { $route = new Route( '/test/:slug', ['controller' => 'Pages', 'action' => 'display'], ['pass' => ['slug'], 'multibytePattern' => false, 'slug' => '[A-zА-я\-\ ]+'] ); $result = $route->compile(); $this->assertNotRegExp($result, '/test/bla-blan-тест'); $route = new Route( '/test/:slug', ['controller' => 'Pages', 'action' => 'display'], ['pass' => ['slug'], 'multibytePattern' => true, 'slug' => '[A-zА-я\-\ ]+'] ); $result = $route->compile(); $this->assertRegExp($result, '/test/bla-blan-тест'); } /** * Test more complex route compiling & parsing with mid route greedy stars * and optional routing parameters * * @return void */ public function testComplexRouteCompilingAndParsing() { $route = new Route( '/posts/:month/:day/:year/*', ['controller' => 'posts', 'action' => 'view'], ['year' => Router::YEAR, 'month' => Router::MONTH, 'day' => Router::DAY] ); $result = $route->compile(); $this->assertRegExp($result, '/posts/08/01/2007/title-of-post'); $result = $route->parse('/posts/08/01/2007/title-of-post', 'GET'); $this->assertCount(7, $result); $this->assertEquals($result['controller'], 'posts'); $this->assertEquals($result['action'], 'view'); $this->assertEquals($result['year'], '2007'); $this->assertEquals($result['month'], '08'); $this->assertEquals($result['day'], '01'); $this->assertEquals($result['pass'][0], 'title-of-post'); $this->assertEquals($result['_matchedRoute'], '/posts/:month/:day/:year/*'); $route = new Route( '/:extra/page/:slug/*', ['controller' => 'pages', 'action' => 'view', 'extra' => null], ['extra' => '[a-z1-9_]*', 'slug' => '[a-z1-9_]+', 'action' => 'view'] ); $result = $route->compile(); $this->assertRegExp($result, '/some_extra/page/this_is_the_slug'); $this->assertRegExp($result, '/page/this_is_the_slug'); $this->assertEquals(['slug', 'extra'], $route->keys); $this->assertEquals(['extra' => '[a-z1-9_]*', 'slug' => '[a-z1-9_]+', 'action' => 'view', '_ext' => []], $route->options); $expected = [ 'controller' => 'pages', 'action' => 'view', ]; $this->assertEquals($expected, $route->defaults); $route = new Route( '/:controller/:action/*', ['project' => false], [ 'controller' => 'source|wiki|commits|tickets|comments|view', 'action' => 'branches|history|branch|logs|view|start|add|edit|modify', ] ); $this->assertFalse($route->parse('/chaw_test/wiki', 'GET')); $result = $route->compile(); $this->assertNotRegExp($result, '/some_project/source'); $this->assertRegExp($result, '/source/view'); $this->assertRegExp($result, '/source/view/other/params'); $this->assertNotRegExp($result, '/chaw_test/wiki'); $this->assertNotRegExp($result, '/source/weird_action'); } /** * Test that routes match their pattern. * * @return void */ public function testMatchBasic() { $route = new Route('/:controller/:action/:id', ['plugin' => null]); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'plugin' => null]); $this->assertFalse($result); $result = $route->match(['plugin' => null, 'controller' => 'posts', 'action' => 'view', 0]); $this->assertFalse($result); $result = $route->match(['plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 1]); $this->assertEquals('/posts/view/1', $result); $route = new Route('/', ['controller' => 'pages', 'action' => 'display', 'home']); $result = $route->match(['controller' => 'pages', 'action' => 'display', 'home']); $this->assertEquals('/', $result); $result = $route->match(['controller' => 'pages', 'action' => 'display', 'about']); $this->assertFalse($result); $route = new Route('/pages/*', ['controller' => 'pages', 'action' => 'display']); $result = $route->match(['controller' => 'pages', 'action' => 'display', 'home']); $this->assertEquals('/pages/home', $result); $result = $route->match(['controller' => 'pages', 'action' => 'display', 'about']); $this->assertEquals('/pages/about', $result); $route = new Route('/blog/:action', ['controller' => 'posts']); $result = $route->match(['controller' => 'posts', 'action' => 'view']); $this->assertEquals('/blog/view', $result); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'id' => 2]); $this->assertEquals('/blog/view?id=2', $result); $result = $route->match(['controller' => 'nodes', 'action' => 'view']); $this->assertFalse($result); $result = $route->match(['controller' => 'posts', 'action' => 'view', 1]); $this->assertFalse($result); $route = new Route('/foo/:controller/:action', ['action' => 'index']); $result = $route->match(['controller' => 'posts', 'action' => 'view']); $this->assertEquals('/foo/posts/view', $result); $route = new Route('/:plugin/:id/*', ['controller' => 'posts', 'action' => 'view']); $result = $route->match(['plugin' => 'test', 'controller' => 'posts', 'action' => 'view', 'id' => '1']); $this->assertEquals('/test/1/', $result); $result = $route->match(['plugin' => 'fo', 'controller' => 'posts', 'action' => 'view', 'id' => '1', '0']); $this->assertEquals('/fo/1/0', $result); $result = $route->match(['plugin' => 'fo', 'controller' => 'nodes', 'action' => 'view', 'id' => 1]); $this->assertFalse($result); $result = $route->match(['plugin' => 'fo', 'controller' => 'posts', 'action' => 'edit', 'id' => 1]); $this->assertFalse($result); $route = new Route('/admin/subscriptions/:action/*', [ 'controller' => 'subscribe', 'prefix' => 'admin', ]); $url = ['controller' => 'subscribe', 'prefix' => 'admin', 'action' => 'edit', 1]; $result = $route->match($url); $expected = '/admin/subscriptions/edit/1'; $this->assertEquals($expected, $result); $url = [ 'controller' => 'subscribe', 'prefix' => 'admin', 'action' => 'edit_admin_e', 1, ]; $result = $route->match($url); $expected = '/admin/subscriptions/edit_admin_e/1'; $this->assertEquals($expected, $result); } /** * Test match() with persist option * * @return void */ public function testMatchWithPersistOption() { $context = [ 'params' => ['lang' => 'en'], ]; $route = new Route('/:lang/:controller/:action', [], ['persist' => ['lang']]); $result = $route->match( ['controller' => 'tasks', 'action' => 'add'], $context ); $this->assertEquals('/en/tasks/add', $result); } /** * Test match() with _host and other keys. * * @return void */ public function testMatchWithHostKeys() { $context = [ '_host' => 'foo.com', '_scheme' => 'http', '_port' => 80, '_base' => '', ]; $route = new Route('/:controller/:action'); $result = $route->match( ['controller' => 'posts', 'action' => 'index', '_host' => 'example.com'], $context ); // Http has port 80 as default, do not include it in the url $this->assertEquals('http://example.com/posts/index', $result); $result = $route->match( ['controller' => 'posts', 'action' => 'index', '_scheme' => 'webcal'], $context ); // Webcal is not on port 80 by default, include it in url $this->assertEquals('webcal://foo.com:80/posts/index', $result); $result = $route->match( ['controller' => 'posts', 'action' => 'index', '_port' => '8080'], $context ); $this->assertEquals('http://foo.com:8080/posts/index', $result); $result = $route->match( ['controller' => 'posts', 'action' => 'index', '_base' => '/dir'], $context ); $this->assertEquals('/dir/posts/index', $result); $result = $route->match( [ 'controller' => 'posts', 'action' => 'index', '_port' => '8080', '_host' => 'example.com', '_scheme' => 'https', '_base' => '/dir', ], $context ); $this->assertEquals('https://example.com:8080/dir/posts/index', $result); $context = [ '_host' => 'foo.com', '_scheme' => 'http', '_port' => 8080, '_base' => '', ]; $result = $route->match( [ 'controller' => 'posts', 'action' => 'index', '_port' => '8080', '_host' => 'example.com', '_scheme' => 'https', '_base' => '/dir', ], $context ); // Https scheme is not on port 8080 by default, include the port $this->assertEquals('https://example.com:8080/dir/posts/index', $result); } /** * Test that the _host option sets the default host. * * @return void */ public function testMatchWithHostOption() { $route = new Route( '/fallback', ['controller' => 'Articles', 'action' => 'index'], ['_host' => 'www.example.com'] ); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', ]); $this->assertSame('http://www.example.com/fallback', $result); } /** * Test wildcard host options * * @return void */ public function testMatchWithHostWildcardOption() { $route = new Route( '/fallback', ['controller' => 'Articles', 'action' => 'index'], ['_host' => '*.example.com'] ); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', ]); $this->assertFalse($result, 'No request context means no match'); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', ], ['_host' => 'wrong.com']); $this->assertFalse($result, 'Request context has bad host'); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', '_host' => 'wrong.com', ]); $this->assertFalse($result, 'Url param is wrong'); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', '_host' => 'foo.example.com', ]); $this->assertSame('http://foo.example.com/fallback', $result); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', ], [ '_host' => 'foo.example.com', ]); $this->assertSame('http://foo.example.com/fallback', $result); $result = $route->match([ 'controller' => 'Articles', 'action' => 'index', ], [ '_scheme' => 'https', '_host' => 'foo.example.com', '_port' => 8080, ]); // When the port and scheme in the context are not present in the original url, they should be added $this->assertSame('https://foo.example.com:8080/fallback', $result); } /** * Test that non-greedy routes fail with extra passed args * * @return void */ public function testMatchGreedyRouteFailurePassedArg() { $route = new Route('/:controller/:action', ['plugin' => null]); $result = $route->match(['controller' => 'posts', 'action' => 'view', '0']); $this->assertFalse($result); $route = new Route('/:controller/:action', ['plugin' => null]); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'test']); $this->assertFalse($result); } /** * Test that falsey values do not interrupt a match. * * @return void */ public function testMatchWithFalseyValues() { $route = new Route('/:controller/:action/*', ['plugin' => null]); $result = $route->match([ 'controller' => 'posts', 'action' => 'index', 'plugin' => null, 'admin' => false, ]); $this->assertEquals('/posts/index/', $result); } /** * Test match() with greedy routes, and passed args. * * @return void */ public function testMatchWithPassedArgs() { $route = new Route('/:controller/:action/*', ['plugin' => null]); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'plugin' => null, 5]); $this->assertEquals('/posts/view/5', $result); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'plugin' => null, 0]); $this->assertEquals('/posts/view/0', $result); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'plugin' => null, '0']); $this->assertEquals('/posts/view/0', $result); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'plugin' => null, 'word space']); $this->assertEquals('/posts/view/word%20space', $result); $route = new Route('/test2/*', ['controller' => 'pages', 'action' => 'display', 2]); $result = $route->match(['controller' => 'pages', 'action' => 'display', 1]); $this->assertFalse($result); $result = $route->match(['controller' => 'pages', 'action' => 'display', 2, 'something']); $this->assertEquals('/test2/something', $result); $result = $route->match(['controller' => 'pages', 'action' => 'display', 5, 'something']); $this->assertFalse($result); } /** * Test that the pass option lets you use positional arguments for the * route elements that were named. * * @return void */ public function testMatchWithPassOption() { $route = new Route( '/blog/:id-:slug', ['controller' => 'Blog', 'action' => 'view'], ['pass' => ['id', 'slug']] ); $result = $route->match([ 'controller' => 'Blog', 'action' => 'view', 'id' => 1, 'slug' => 'second', ]); $this->assertEquals('/blog/1-second', $result); $result = $route->match([ 'controller' => 'Blog', 'action' => 'view', 1, 'second', ]); $this->assertEquals('/blog/1-second', $result); $result = $route->match([ 'controller' => 'Blog', 'action' => 'view', 1, 'second', 'query' => 'string', ]); $this->assertEquals('/blog/1-second?query=string', $result); $result = $route->match([ 'controller' => 'Blog', 'action' => 'view', 1 => 2, 2 => 'second', ]); $this->assertFalse($result, 'Positional args must match exactly.'); } /** * Test that match() with pass and greedy routes. * * @return void */ public function testMatchWithPassOptionGreedy() { $route = new Route( '/blog/:id-:slug/*', ['controller' => 'Blog', 'action' => 'view'], ['pass' => ['id', 'slug']] ); $result = $route->match([ 'controller' => 'Blog', 'action' => 'view', 'id' => 1, 'slug' => 'second', 'third', 'fourth', 'query' => 'string', ]); $this->assertEquals('/blog/1-second/third/fourth?query=string', $result); $result = $route->match([ 'controller' => 'Blog', 'action' => 'view', 1, 'second', 'third', 'fourth', 'query' => 'string', ]); $this->assertEquals('/blog/1-second/third/fourth?query=string', $result); } /** * Test that extensions work. * * @return void */ public function testMatchWithExtension() { $route = new Route('/:controller/:action'); $result = $route->match([ 'controller' => 'posts', 'action' => 'index', '_ext' => 'json', ]); $this->assertEquals('/posts/index.json', $result); $route = new Route('/:controller/:action/*'); $result = $route->match([ 'controller' => 'posts', 'action' => 'index', '_ext' => 'json', ]); $this->assertEquals('/posts/index.json', $result); $result = $route->match([ 'controller' => 'posts', 'action' => 'view', 1, '_ext' => 'json', ]); $this->assertEquals('/posts/view/1.json', $result); $result = $route->match([ 'controller' => 'posts', 'action' => 'view', 1, '_ext' => 'json', 'id' => 'b', 'c' => 'd', ]); $this->assertEquals('/posts/view/1.json?id=b&c=d', $result); $result = $route->match([ 'controller' => 'posts', 'action' => 'index', '_ext' => 'json.gz', ]); $this->assertEquals('/posts/index.json.gz', $result); } /** * Test that match with patterns works. * * @return void */ public function testMatchWithPatterns() { $route = new Route('/:controller/:action/:id', ['plugin' => null], ['id' => '[0-9]+']); $result = $route->match(['controller' => 'posts', 'action' => 'view', 'id' => 'foo']); $this->assertFalse($result); $result = $route->match(['plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 9]); $this->assertSame('/posts/view/9', $result); $result = $route->match(['plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '9']); $this->assertEquals('/posts/view/9', $result); $result = $route->match(['plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => '922']); $this->assertEquals('/posts/view/922', $result); $result = $route->match(['plugin' => null, 'controller' => 'posts', 'action' => 'view', 'id' => 'a99']); $this->assertFalse($result); } /** * Test that match() with multibyte pattern * * @return void */ public function testMatchWithMultibytePattern() { $route = new Route( '/articles/:action/:id', ['controller' => 'Articles'], ['multibytePattern' => true, 'id' => '\pL+'] ); $result = $route->match([ 'controller' => 'Articles', 'action' => 'view', 'id' => "\xC4\x81", ]); $this->assertEquals("/articles/view/\xC4\x81", $result); } /** * Test that match() matches explicit GET routes * * @return void */ public function testMatchWithExplicitGet() { $route = new Route( '/anything', ['controller' => 'Articles', 'action' => 'foo', '_method' => 'GET'] ); $result = $route->match([ 'controller' => 'Articles', 'action' => 'foo', ]); $this->assertEquals("/anything", $result); } /** * Test separartor. * * @return void */ public function testQueryStringGeneration() { $route = new Route('/:controller/:action/*'); $restore = ini_get('arg_separator.output'); ini_set('arg_separator.output', '&'); $result = $route->match([ 'controller' => 'posts', 'action' => 'index', 0, 'test' => 'var', 'var2' => 'test2', 'more' => 'test data', ]); $expected = '/posts/index/0?test=var&var2=test2&more=test+data'; $this->assertEquals($expected, $result); ini_set('arg_separator.output', $restore); } /** * Ensure that parseRequest() calls parse() as that is required * for backwards compat * * @return void */ public function testParseRequestDelegates() { $route = $this->getMockBuilder('Cake\Routing\Route\Route') ->setMethods(['parse']) ->setConstructorArgs(['/forward', ['controller' => 'Articles', 'action' => 'index']]) ->getMock(); $route->expects($this->once()) ->method('parse') ->with('/forward', 'GET') ->will($this->returnValue('works!')); $request = new ServerRequest([ 'environment' => [ 'REQUEST_METHOD' => 'GET', 'PATH_INFO' => '/forward', ], ]); $result = $route->parseRequest($request); } /** * Test that parseRequest() applies host conditions * * @return void */ public function testParseRequestHostConditions() { $route = new Route( '/fallback', ['controller' => 'Articles', 'action' => 'index'], ['_host' => '*.example.com'] ); $request = new ServerRequest([ 'environment' => [ 'HTTP_HOST' => 'a.example.com', 'PATH_INFO' => '/fallback', ], ]); $result = $route->parseRequest($request); $expected = [ 'controller' => 'Articles', 'action' => 'index', 'pass' => [], '_matchedRoute' => '/fallback', ]; $this->assertEquals($expected, $result, 'Should match, domain is correct'); $request = new ServerRequest([ 'environment' => [ 'HTTP_HOST' => 'foo.bar.example.com', 'PATH_INFO' => '/fallback', ], ]); $result = $route->parseRequest($request); $this->assertEquals($expected, $result, 'Should match, domain is a matching subdomain'); $request = new ServerRequest([ 'environment' => [ 'HTTP_HOST' => 'example.test.com', 'PATH_INFO' => '/fallback', ], ]); $this->assertFalse($route->parseRequest($request)); } /** * test the parse method of Route. * * @return void */ public function testParse() { $route = new Route( '/:controller/:action/:id', ['controller' => 'testing4', 'id' => null], ['id' => Router::ID] ); $route->compile(); $result = $route->parse('/posts/view/1', 'GET'); $this->assertEquals('posts', $result['controller']); $this->assertEquals('view', $result['action']); $this->assertEquals('1', $result['id']); $route = new Route( '/admin/:controller', ['prefix' => 'admin', 'admin' => 1, 'action' => 'index'] ); $route->compile(); $result = $route->parse('/admin/', 'GET'); $this->assertFalse($result); $result = $route->parse('/admin/posts', 'GET'); $this->assertEquals('posts', $result['controller']); $this->assertEquals('index', $result['action']); $route = new Route( '/media/search/*', ['controller' => 'Media', 'action' => 'search'] ); $result = $route->parse('/media/search', 'GET'); $this->assertEquals('Media', $result['controller']); $this->assertEquals('search', $result['action']); $this->assertEquals([], $result['pass']); $result = $route->parse('/media/search/tv/shows', 'GET'); $this->assertEquals('Media', $result['controller']); $this->assertEquals('search', $result['action']); $this->assertEquals(['tv', 'shows'], $result['pass']); } /** * Test that :key elements are urldecoded * * @return void */ public function testParseUrlDecodeElements() { $route = new Route( '/:controller/:slug', ['action' => 'view'] ); $route->compile(); $result = $route->parse('/posts/%E2%88%82%E2%88%82', 'GET'); $this->assertEquals('posts', $result['controller']); $this->assertEquals('view', $result['action']); $this->assertEquals('∂∂', $result['slug']); $result = $route->parse('/posts/∂∂', 'GET'); $this->assertEquals('posts', $result['controller']); $this->assertEquals('view', $result['action']); $this->assertEquals('∂∂', $result['slug']); } /** * Test numerically indexed defaults, get appended to pass * * @return void */ public function testParseWithPassDefaults() { $route = new Route('/:controller', ['action' => 'display', 'home']); $result = $route->parse('/posts', 'GET'); $expected = [ 'controller' => 'posts', 'action' => 'display', 'pass' => ['home'], '_matchedRoute' => '/:controller', ]; $this->assertEquals($expected, $result); } /** * Test that middleware is returned from parse() * * @return void */ public function testParseWithMiddleware() { $route = new Route('/:controller', ['action' => 'display', 'home']); $route->setMiddleware(['auth', 'cookie']); $result = $route->parse('/posts', 'GET'); $expected = [ 'controller' => 'posts', 'action' => 'display', 'pass' => ['home'], '_matchedRoute' => '/:controller', '_middleware' => ['auth', 'cookie'], ]; $this->assertEquals($expected, $result); } /** * Test that http header conditions can cause route failures. * * @return void */ public function testParseWithHttpHeaderConditions() { $route = new Route('/sample', ['controller' => 'posts', 'action' => 'index', '_method' => 'POST']); $this->assertFalse($route->parse('/sample', 'GET')); $expected = [ 'controller' => 'posts', 'action' => 'index', 'pass' => [], '_method' => 'POST', '_matchedRoute' => '/sample', ]; $this->assertEquals($expected, $route->parse('/sample', 'POST')); } /** * Test that http header conditions can cause route failures. * * @return void */ public function testParseWithMultipleHttpMethodConditions() { $route = new Route('/sample', [ 'controller' => 'posts', 'action' => 'index', '_method' => ['PUT', 'POST'], ]); $this->assertFalse($route->parse('/sample', 'GET')); $expected = [ 'controller' => 'posts', 'action' => 'index', 'pass' => [], '_method' => ['PUT', 'POST'], '_matchedRoute' => '/sample', ]; $this->assertEquals($expected, $route->parse('/sample', 'POST')); } /** * Test deprecated globals reading for method matching * * @group deprecated * @return void */ public function testParseWithMultipleHttpMethodDeprecated() { $this->deprecated(function () { $_SERVER['REQUEST_METHOD'] = 'GET'; $route = new Route('/sample', [ 'controller' => 'posts', 'action' => 'index', '_method' => ['PUT', 'POST'], ]); $this->assertFalse($route->parse('/sample')); $_SERVER['REQUEST_METHOD'] = 'POST'; $expected = [ 'controller' => 'posts', 'action' => 'index', 'pass' => [], '_method' => ['PUT', 'POST'], '_matchedRoute' => '/sample', ]; $this->assertEquals($expected, $route->parse('/sample')); }); } /** * Test that http header conditions can work with URL generation * * @return void */ public function testMatchWithMultipleHttpMethodConditions() { $route = new Route('/sample', [ 'controller' => 'posts', 'action' => 'index', '_method' => ['PUT', 'POST'], ]); $url = [ 'controller' => 'posts', 'action' => 'index', ]; $this->assertFalse($route->match($url)); $url = [ 'controller' => 'posts', 'action' => 'index', '_method' => 'GET', ]; $this->assertFalse($route->match($url)); $url = [ 'controller' => 'posts', 'action' => 'index', '_method' => 'PUT', ]; $this->assertEquals('/sample', $route->match($url)); $url = [ 'controller' => 'posts', 'action' => 'index', '_method' => 'POST', ]; $this->assertEquals('/sample', $route->match($url)); $url = [ 'controller' => 'posts', 'action' => 'index', '_method' => ['PUT', 'POST'], ]; $this->assertEquals('/sample', $route->match($url)); } /** * Check [method] compatibility. * * @group deprecated * @return void */ public function testMethodCompatibility() { $this->deprecated(function () { $_SERVER['REQUEST_METHOD'] = 'POST'; $route = new Route('/sample', [ 'controller' => 'Articles', 'action' => 'index', '[method]' => 'POST', ]); $url = [ 'controller' => 'Articles', 'action' => 'index', '_method' => 'POST', ]; $this->assertEquals('/sample', $route->match($url)); $url = [ 'controller' => 'Articles', 'action' => 'index', '[method]' => 'POST', ]; $this->assertEquals('/sample', $route->match($url)); }); } /** * Test that patterns work for :action * * @return void */ public function testPatternOnAction() { $route = new Route( '/blog/:action/*', ['controller' => 'blog_posts'], ['action' => 'other|actions'] ); $result = $route->match(['controller' => 'blog_posts', 'action' => 'foo']); $this->assertFalse($result); $result = $route->match(['controller' => 'blog_posts', 'action' => 'actions']); $this->assertNotEmpty($result); $result = $route->parse('/blog/other', 'GET'); $expected = [ 'controller' => 'blog_posts', 'action' => 'other', 'pass' => [], '_matchedRoute' => '/blog/:action/*', ]; $this->assertEquals($expected, $result); $result = $route->parse('/blog/foobar', 'GET'); $this->assertFalse($result); } /** * Test the parseArgs method * * @return void */ public function testParsePassedArgument() { $route = new Route('/:controller/:action/*'); $result = $route->parse('/posts/edit/1/2/0', 'GET'); $expected = [ 'controller' => 'posts', 'action' => 'edit', 'pass' => ['1', '2', '0'], '_matchedRoute' => '/:controller/:action/*', ]; $this->assertEquals($expected, $result); } /** * Test matching of parameters where one parameter name starts with another parameter name * * @return void */ public function testMatchSimilarParameters() { $route = new Route('/:thisParam/:thisParamIsLonger'); $url = [ 'thisParamIsLonger' => 'bar', 'thisParam' => 'foo', ]; $result = $route->match($url); $expected = '/foo/bar'; $this->assertEquals($expected, $result); } /** * Test match() with trailing ** style routes. * * @return void */ public function testMatchTrailing() { $route = new Route('/pages/**', ['controller' => 'pages', 'action' => 'display']); $id = 'test/ spaces/漢字/la†în'; $result = $route->match([ 'controller' => 'pages', 'action' => 'display', $id, ]); $expected = '/pages/test/%20spaces/%E6%BC%A2%E5%AD%97/la%E2%80%A0%C3%AEn'; $this->assertEquals($expected, $result); } /** * Test match handles optional keys * * @return void */ public function testMatchNullValueOptionalKey() { $route = new Route('/path/:optional/fixed'); $this->assertSame('/path/fixed', $route->match(['optional' => null])); $route = new Route('/path/{optional}/fixed'); $this->assertSame('/path/fixed', $route->match(['optional' => null])); } /** * Test matching fails on required keys (controller/action) * * @return void */ public function testMatchControllerRequiredKeys() { $route = new Route('/:controller/:action', ['action' => 'test']); $this->assertFalse($route->match(['controller' => null])); $route = new Route('/test/:action', ['controller' => 'thing']); $this->assertFalse($route->match(['action' => null])); } /** * Test restructuring args with pass key * * @return void */ public function testPassArgRestructure() { $route = new Route('/:controller/:action/:slug', [], [ 'pass' => ['slug'], ]); $result = $route->parse('/posts/view/my-title', 'GET'); $expected = [ 'controller' => 'posts', 'action' => 'view', 'slug' => 'my-title', 'pass' => ['my-title'], '_matchedRoute' => '/:controller/:action/:slug', ]; $this->assertEquals($expected, $result, 'Slug should have moved'); } /** * Test the /** special type on parsing. * * @return void */ public function testParseTrailing() { $route = new Route('/:controller/:action/**'); $result = $route->parse('/posts/index/1/2/3/foo:bar', 'GET'); $expected = [ 'controller' => 'posts', 'action' => 'index', 'pass' => ['1/2/3/foo:bar'], '_matchedRoute' => '/:controller/:action/**', ]; $this->assertEquals($expected, $result); $result = $route->parse('/posts/index/http://example.com', 'GET'); $expected = [ 'controller' => 'posts', 'action' => 'index', 'pass' => ['http://example.com'], '_matchedRoute' => '/:controller/:action/**', ]; $this->assertEquals($expected, $result); } /** * Test the /** special type on parsing - UTF8. * * @return void */ public function testParseTrailingUTF8() { $route = new Route('/category/**', ['controller' => 'categories', 'action' => 'index']); $result = $route->parse('/category/%D9%85%D9%88%D8%A8%D8%A7%DB%8C%D9%84', 'GET'); $expected = [ 'controller' => 'categories', 'action' => 'index', 'pass' => ['موبایل'], '_matchedRoute' => '/category/**', ]; $this->assertEquals($expected, $result); } /** * Test getName(); * * @return void */ public function testGetName() { $route = new Route('/foo/bar', [], ['_name' => 'testing']); $this->assertEquals('', $route->getName()); $route = new Route('/:controller/:action'); $this->assertEquals('_controller:_action', $route->getName()); $route = new Route('/{controller}/{action}'); $this->assertSame('_controller:_action', $route->getName()); $route = new Route('/articles/:action', ['controller' => 'posts']); $this->assertEquals('posts:_action', $route->getName()); $route = new Route('/articles/list', ['controller' => 'posts', 'action' => 'index']); $this->assertEquals('posts:index', $route->getName()); $route = new Route('/:controller/:action', ['action' => 'index']); $this->assertEquals('_controller:_action', $route->getName()); } /** * Test getName() with plugins. * * @return void */ public function testGetNamePlugins() { $route = new Route( '/a/:controller/:action', ['plugin' => 'asset'] ); $this->assertEquals('asset._controller:_action', $route->getName()); $route = new Route( '/a/assets/:action', ['plugin' => 'asset', 'controller' => 'assets'] ); $this->assertEquals('asset.assets:_action', $route->getName()); $route = new Route( '/assets/get', ['plugin' => 'asset', 'controller' => 'assets', 'action' => 'get'] ); $this->assertEquals('asset.assets:get', $route->getName()); } /** * Test getName() with prefixes. * * @return void */ public function testGetNamePrefix() { $route = new Route( '/admin/:controller/:action', ['prefix' => 'admin'] ); $this->assertEquals('admin:_controller:_action', $route->getName()); $route = new Route( '/:prefix/assets/:action', ['controller' => 'assets'] ); $this->assertEquals('_prefix:assets:_action', $route->getName()); $route = new Route( '/admin/assets/get', ['prefix' => 'admin', 'plugin' => 'asset', 'controller' => 'assets', 'action' => 'get'] ); $this->assertEquals('admin:asset.assets:get', $route->getName()); $route = new Route( '/:prefix/:plugin/:controller/:action/*', [] ); $this->assertEquals('_prefix:_plugin._controller:_action', $route->getName()); } /** * Test that utf-8 patterns work for :section * * @return void */ public function testUTF8PatternOnSection() { $route = new Route( '/:section', ['plugin' => 'blogs', 'controller' => 'posts', 'action' => 'index'], [ 'persist' => ['section'], 'section' => 'آموزش|weblog', ] ); $result = $route->parse('/%D8%A2%D9%85%D9%88%D8%B2%D8%B4', 'GET'); $expected = [ 'section' => 'آموزش', 'plugin' => 'blogs', 'controller' => 'posts', 'action' => 'index', 'pass' => [], '_matchedRoute' => '/:section', ]; $this->assertEquals($expected, $result); $result = $route->parse('/weblog', 'GET'); $expected = [ 'section' => 'weblog', 'plugin' => 'blogs', 'controller' => 'posts', 'action' => 'index', 'pass' => [], '_matchedRoute' => '/:section', ]; $this->assertEquals($expected, $result); } /** * Test getting the static path for a route. * * @return void */ public function testStaticPath() { $route = new Route('/*', ['controller' => 'Pages', 'action' => 'display']); $this->assertEquals('/', $route->staticPath()); $route = new Route('/pages/*', ['controller' => 'Pages', 'action' => 'display']); $this->assertEquals('/pages', $route->staticPath()); $route = new Route('/pages/:id/*', ['controller' => 'Pages', 'action' => 'display']); $this->assertEquals('/pages/', $route->staticPath()); $route = new Route('/:controller/:action/*'); $this->assertEquals('/', $route->staticPath()); $route = new Route('/api/{/:action/*'); $this->assertEquals('/api/{/', $route->staticPath()); $route = new Route('/books/reviews', ['controller' => 'Reviews', 'action' => 'index']); $this->assertEquals('/books/reviews', $route->staticPath()); } /** * Test getting the static path for a route. * * @return void */ public function testStaticPathBrace() { $route = new Route('/pages/{id}/*', ['controller' => 'Pages', 'action' => 'display']); $this->assertEquals('/pages/', $route->staticPath()); $route = new Route('/{controller}/{action}/*'); $this->assertEquals('/', $route->staticPath()); $route = new Route('/books/reviews', ['controller' => 'Reviews', 'action' => 'index']); $this->assertEquals('/books/reviews', $route->staticPath()); } /** * Test for __set_state magic method on CakeRoute * * @return void */ public function testSetState() { $route = Route::__set_state([ 'keys' => [], 'options' => [], 'defaults' => [ 'controller' => 'pages', 'action' => 'display', 'home', ], 'template' => '/', '_greedy' => false, '_compiledRoute' => null, ]); $this->assertInstanceOf('Cake\Routing\Route\Route', $route); $this->assertSame('/', $route->match(['controller' => 'pages', 'action' => 'display', 'home'])); $this->assertFalse($route->match(['controller' => 'pages', 'action' => 'display', 'about'])); $expected = [ 'controller' => 'pages', 'action' => 'display', 'pass' => ['home'], '_matchedRoute' => '/', ]; $this->assertEquals($expected, $route->parse('/', 'GET')); } /** * Test setting the method on a route. * * @return void */ public function testSetMethods() { $route = new Route('/books/reviews', ['controller' => 'Reviews', 'action' => 'index']); $result = $route->setMethods(['put']); $this->assertSame($result, $route, 'Should return this'); $this->assertSame(['PUT'], $route->defaults['_method'], 'method is wrong'); $route->setMethods(['post', 'get', 'patch']); $this->assertSame(['POST', 'GET', 'PATCH'], $route->defaults['_method']); } /** * Test setting the method on a route to an invalid method * * @return void */ public function testSetMethodsInvalid() { $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Invalid HTTP method received. NOPE is invalid'); $route = new Route('/books/reviews', ['controller' => 'Reviews', 'action' => 'index']); $route->setMethods(['nope']); } /** * Test setting patterns through the method * * @return void */ public function testSetPatterns() { $route = new Route('/reviews/:date/:id', ['controller' => 'Reviews', 'action' => 'view']); $result = $route->setPatterns([ 'date' => '\d+\-\d+\-\d+', 'id' => '[a-z]+', ]); $this->assertSame($result, $route, 'Should return this'); $this->assertArrayHasKey('id', $route->options); $this->assertArrayHasKey('date', $route->options); $this->assertSame('[a-z]+', $route->options['id']); $this->assertArrayNotHasKey('multibytePattern', $route->options); $this->assertFalse($route->parse('/reviews/a-b-c/xyz')); $this->assertNotEmpty($route->parse('/reviews/2016-05-12/xyz')); } /** * Test setting patterns enables multibyte mode * * @return void */ public function testSetPatternsMultibyte() { $route = new Route('/reviews/:accountid/:slug', ['controller' => 'Reviews', 'action' => 'view']); $result = $route->setPatterns([ 'date' => '[A-zА-я\-\ ]+', 'accountid' => '[a-z]+', ]); $this->assertArrayHasKey('multibytePattern', $route->options); $this->assertNotEmpty($route->parse('/reviews/abcs/bla-blan-тест')); } /** * Test setting host requirements * * @return void */ public function testSetHost() { $route = new Route('/reviews', ['controller' => 'Reviews', 'action' => 'index']); $result = $route->setHost('blog.example.com'); $this->assertSame($result, $route, 'Should return this'); $request = new ServerRequest([ 'environment' => [ 'HTTP_HOST' => 'a.example.com', 'PATH_INFO' => '/reviews', ], ]); $this->assertFalse($route->parseRequest($request)); $uri = $request->getUri(); $request = $request->withUri($uri->withHost('blog.example.com')); $this->assertNotEmpty($route->parseRequest($request)); } /** * Test setting pass parameters * * @return void */ public function testSetPass() { $route = new Route('/reviews/:date/:id', ['controller' => 'Reviews', 'action' => 'view']); $result = $route->setPass(['date', 'id']); $this->assertSame($result, $route, 'Should return this'); $this->assertEquals(['date', 'id'], $route->options['pass']); } /** * Test setting persisted parameters * * @return void */ public function testSetPersist() { $route = new Route('/reviews/:date/:id', ['controller' => 'Reviews', 'action' => 'view']); $result = $route->setPersist(['date']); $this->assertSame($result, $route, 'Should return this'); $this->assertEquals(['date'], $route->options['persist']); } /** * Test setting/getting middleware. * * @return void */ public function testSetMiddleware() { $route = new Route('/reviews/:date/:id', ['controller' => 'Reviews', 'action' => 'view']); $result = $route->setMiddleware(['auth', 'cookie']); $this->assertSame($result, $route); $this->assertSame(['auth', 'cookie'], $route->getMiddleware()); } }