diff --git a/tests/unit/suites/libraries/cms/router/JRouterAdministratorTest.php b/tests/unit/suites/libraries/cms/router/JRouterAdministratorTest.php index 1e712c38b7527..43c3b35a30ce8 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterAdministratorTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterAdministratorTest.php @@ -12,6 +12,7 @@ * * @package Joomla.UnitTest * @subpackage Router + * @group Router * @since 3.0 */ class JRouterAdministratorTest extends TestCase @@ -46,7 +47,7 @@ protected function setUp() $this->server = $_SERVER; - $_SERVER['HTTP_HOST'] = 'example.com'; + $_SERVER['HTTP_HOST'] = 'example.com'; $_SERVER['SCRIPT_NAME'] = ''; JUri::reset(); @@ -73,41 +74,30 @@ protected function tearDown() * Tests the parse method * * @return void - * + * @testdox JRouterAdministrator::parse() returns an array * @since 3.0 */ public function testParse() { $uri = JUri::getInstance('http://localhost'); - $this->assertThat( - $this->object->parse($uri), - $this->isType('array'), - 'JRouterAdministrator::parse() returns an empty array.' - ); + $vars = $this->object->parse($uri); + $this->assertTrue(is_array($vars)); } /** * Tests the build method * * @return void - * + * @testdox JRouterAdministrator::build() returns an instance of JUri * @since 3.1 */ public function testBuild() { $uri = JUri::getInstance('http://localhost/joomla-cms/intro/to/joomla'); - $this->assertInstanceOf( - 'JUri', - $this->object->build($uri), - 'JRouterAdministrator::build() returns an instance of JUri.' - ); + $this->assertInstanceOf('JUri', $this->object->build($uri)); - $this->assertEquals( - $uri->getPath(), - '/joomla-cms/intro/to/joomla', - 'JRouterAdministrator::build() returns the path as provided.' - ); + $this->assertEquals('/joomla-cms/intro/to/joomla', $uri->getPath()); } } diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index abbd53eee2a28..1101225625fcf 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -7,32 +7,26 @@ * @license GNU General Public License version 2 or later; see LICENSE */ -require_once __DIR__ . '/stubs/JRouterSiteInspector.php'; +require_once __DIR__ . '/data/TestRouter.php'; +jimport('cms.router.router'); /** * Test class for JRouterSite. * * @package Joomla.UnitTest * @subpackage Router + * @group Router * @since 3.0 */ class JRouterSiteTest extends TestCase { - /** - * Object under test - * - * @var JRouter - * @since 3.4 - */ - protected $object; - /** * Backup of the $_SERVER variable * * @var array * @since 3.4 */ - protected $server; + private $server; /** * Sets up the fixture, for example, opens a network connection. @@ -46,19 +40,11 @@ protected function setUp() { parent::setUp(); - $this->server = $_SERVER; - - $_SERVER['HTTP_HOST'] = 'mydomain.com'; - $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0'; - $_SERVER['REQUEST_URI'] = '/index.php'; - $_SERVER['SCRIPT_NAME'] = '/index.php'; - JUri::reset(); - $options = array(); - $app = $this->getMockCmsApp(); - $menu = TestMockMenu::create($this); - $this->object = new JRouterSiteInspector($options, $app, $menu); + $this->server = $_SERVER; + + $_SERVER['HTTP_HOST'] = 'mydomain.com'; } /** @@ -80,21 +66,18 @@ protected function tearDown() * Tests the __construct() method * * @return void - * + * @testdox JRouterSite is a JRouter * @since 3.4 */ - public function testConstruct() + public function testJRouterSiteIsAJRouter() { - $options = array(); - $app = $this->getMockCmsApp(); - $menu = TestMockMenu::create($this); - $object = new JRouterSiteInspector($options, $app, $menu); - $this->assertInstanceOf('JRouterSite', $object); - - $options = array(); - $app = $this->getMockCmsApp(); - $object = new JRouterSiteInspector($options, $app); - $this->assertInstanceOf('JRouterSite', $object); + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + + $this->assertInstanceOf('JRouter', $object); } /** @@ -121,78 +104,162 @@ public function casesParse() ); $server3 = array( - 'HTTP_HOST' => '', - 'SCRIPT_NAME' => '', + 'HTTP_HOST' => '', + 'SCRIPT_NAME' => '', 'SCRIPT_FILENAME' => JPATH_SITE . '/cli/deletefiles.php', - 'PHP_SELF' => '', - 'REQUEST_URI' => '' + 'PHP_SELF' => '', + 'REQUEST_URI' => '' ); - $cases = array(); - $cases[] = array('', JROUTER_MODE_RAW, array(), $server1, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), ''); - - $cases[] = array('/index.php?var1=value1', JROUTER_MODE_RAW, array(), $server1, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'index.php?var1=value1'); - $cases[] = array('index.php?var1=value1', JROUTER_MODE_RAW, array(), $server1, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'index.php?var1=value1'); - - $cases[] = array('/joomla/blog/test.json', JROUTER_MODE_SEF, array(array('sef_suffix', null, '1')), $server1, array('format' => 'json', 'option' => 'com_test3', 'Itemid' => '45'), 'joomla/blog/test.json'); - $cases[] = array('/joomla/blog/test.json/', JROUTER_MODE_SEF, array(array('sef_suffix', null, '1')), $server1, array('option' => 'com_test3', 'Itemid' => '45'), 'joomla/blog/test.json'); - - $cases[] = array('/joomla/blog/test%202', JROUTER_MODE_RAW, array(), $server1, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'joomla/blog/test 2'); - $cases[] = array('/joomla/blog/test', JROUTER_MODE_RAW, array(), $server2, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'blog/test'); - $cases[] = array('/joomla/blog/te%20st', JROUTER_MODE_RAW, array(), $server2, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'blog/te st'); - $cases[] = array('/otherfolder/blog/test', JROUTER_MODE_RAW, array(), $server2, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), 'older/blog/test'); - - $cases[] = array('/cli/deletefiles.php?var1=value1', JROUTER_MODE_RAW, array(), $server3, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), '?var1=value1'); - - return $cases; + return array( + array( + 'url' => '', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server1, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => '' + ), + array( + 'url' => '/index.php?var1=value1', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server1, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => 'index.php?var1=value1' + ), + array( + 'url' => 'index.php?var1=value1', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server1, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => 'index.php?var1=value1' + ), + array( + 'url' => '/joomla/blog/test.json', + 'mode' => JROUTER_MODE_SEF, + 'map' => array(array('sef_suffix', null, '1')), + 'server' => $server1, + 'expVars' => array('format' => 'json', 'option' => 'com_test3', 'Itemid' => '45'), + 'expUrl' => 'joomla/blog/test.json' + ), + array( + 'url' => '/joomla/blog/test.json/', + 'mode' => JROUTER_MODE_SEF, + 'map' => array(array('sef_suffix', null, '1')), + 'server' => $server1, + 'expVars' => array('option' => 'com_test3', 'Itemid' => '45'), + 'expUrl' => 'joomla/blog/test.json' + ), + array( + 'url' => '/joomla/blog/test%202', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server1, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => 'joomla/blog/test 2' + ), + array( + 'url' => '/joomla/blog/test', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server2, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => 'blog/test' + ), + array( + 'url' => '/joomla/blog/te%20st', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server2, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => 'blog/te st' + ), + array( + 'url' => '/otherfolder/blog/test', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server2, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => 'older/blog/test' + ), + array( + 'url' => '/cli/deletefiles.php?var1=value1', + 'mode' => JROUTER_MODE_RAW, + 'map' => array(), + 'server' => $server3, + 'expVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expUrl' => '?var1=value1' + ), + ); } /** * Tests the parse method * - * @param string $url An associative array with variables - * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF - * @param array $map An associative array with app config vars - * @param array $server An associative array with $_SERVER vars - * @param array $expected Expected vars - * @param string $expected2 Expected URI string + * @param string $url An associative array with variables + * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF + * @param array $map An associative array with app config vars + * @param array $server An associative array with $_SERVER vars + * @param array $expectedVars Expected vars + * @param string $expectedUris Expected URI string * * @return void * * @dataProvider casesParse + * @testdox URLs are transformed into proper variables * @since 3.4 */ - public function testParse($url, $mode, $map, $server, $expected, $expected2) + public function testParse($url, $mode, $map, $server, $expectedVars, $expectedUris) { $_SERVER = array_merge($_SERVER, $server); - $app = $this->object->getApp(); - $app->expects($this->any())->method('get')->will($this->returnValueMap($map)); - $this->object->setApp($app); - $this->object->setMode($mode); + + $app = $this->getMockCmsApp(); + $app->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); + + $object = new JRouterSite( + array(), + $app, + TestMockMenu::create($this) + ); + + $object->setMode($mode); $uri = new JUri($url); - $vars = $this->object->parse($uri); + $vars = $object->parse($uri); - $this->assertEquals($expected, $vars); - $this->assertEquals($expected2, $uri->toString()); + $this->assertEquals($expectedVars, $vars); + $this->assertEquals($expectedUris, (string)$uri); } /** * Tests the parse methods redirect * * @return void - * + * @testdox External URLs trigger a redirect * @since 3.4 */ public function testParseRedirect() { $uri = new JUri('http://www.example.com/index.php'); - $app = $this->object->getApp(); - $app->expects($this->any())->method('get')->will($this->returnValue(2)); - $app->expects($this->once())->method('redirect'); - $this->object->setApp($app); - $this->object->parse($uri); + $app = $this->getMockCmsApp(); + $app->expects($this->any()) + ->method('get') + ->will($this->returnValue(2)); + $app->expects($this->once()) + ->method('redirect'); + + $object = new JRouterSite( + array(), + $app, + TestMockMenu::create($this) + ); + + $object->parse($uri); } /** @@ -218,137 +285,205 @@ public function casesBuild() 'REQUEST_URI' => '/joomla/index.php?var=value 10' ); - $cases = array(); - - $cases[] = array('', JROUTER_MODE_RAW, array(), array(), $server1, '/'); - - $cases[] = array('blog/test', JROUTER_MODE_RAW, array(), array(), $server1, '/blog/test'); - - $cases[] = array('', JROUTER_MODE_RAW, array(), array(), $server2, '/joomla/'); - - $cases[] = array('blog/test', JROUTER_MODE_RAW, array(), array(), $server2, '/joomla/blog/test'); - - $cases[] = array('', JROUTER_MODE_SEF, array(), array(), $server1, '/'); - - $cases[] = array('blog/test', JROUTER_MODE_SEF, array(), array(), $server1, '/blog/test'); - - $cases[] = array('', JROUTER_MODE_SEF, array(), array(), $server2, '/joomla/'); - - $cases[] = array('blog/test', JROUTER_MODE_SEF, array(), array(), $server2, '/joomla/blog/test'); - - $cases[] = array('index.php', JROUTER_MODE_SEF, array(), + return array( array( - array('sef_rewrite', null, 1) + 'url' => '', + 'mode' => JROUTER_MODE_RAW, + 'vars' => array(), + 'map' => array(), + 'server' => $server1, + 'expected' => '/' ), - $server2, '/joomla/'); - - $cases[] = array('index.php/blog/test', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1) + 'url' => 'blog/test', + 'mode' => JROUTER_MODE_RAW, + 'vars' => array(), + 'map' => array(), + 'server' => $server1, + 'expected' => '/blog/test' ), - $server2, '/joomla/blog/test'); - - $cases[] = array('index.php', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1) + 'url' => '', + 'mode' => JROUTER_MODE_RAW, + 'vars' => array(), + 'map' => array(), + 'server' => $server2, + 'expected' => '/joomla/' ), - $server1, '/'); - - $cases[] = array('index.php/blog/test', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1) + 'url' => 'blog/test', + 'mode' => JROUTER_MODE_RAW, + 'vars' => array(), + 'map' => array(), + 'server' => $server2, + 'expected' => '/joomla/blog/test' ), - $server1, '/blog/test'); - - $cases[] = array('index.php?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_suffix', null, 1) + 'url' => '', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(), + 'server' => $server1, + 'expected' => '/' ), - $server2, '/joomla/index.php?format=json'); - - $cases[] = array('index.php/blog/test?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_suffix', null, 1) + 'url' => 'blog/test', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(), + 'server' => $server1, + 'expected' => '/blog/test' ), - $server2, '/joomla/index.php/blog/test.json'); - - $cases[] = array('index.php?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_suffix', null, 1) + 'url' => '', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(), + 'server' => $server2, + 'expected' => '/joomla/' ), - $server1, '/index.php?format=json'); - - $cases[] = array('index.php/blog/test?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_suffix', null, 1) + 'url' => 'blog/test', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(), + 'server' => $server2, + 'expected' => '/joomla/blog/test' ), - $server1, '/index.php/blog/test.json'); - - $cases[] = array('index.php?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1), - array('sef_suffix', null, 1) + 'url' => 'index.php', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1)), + 'server' => $server2, + 'expected' => '/joomla/' ), - $server2, '/joomla/?format=json'); - - $cases[] = array('index.php/blog/test?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1), - array('sef_suffix', null, 1) + 'url' => 'index.php/blog/test', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1)), + 'server' => $server2, + 'expected' => '/joomla/blog/test' ), - $server2, '/joomla/blog/test.json'); - - $cases[] = array('index.php?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1), - array('sef_suffix', null, 1) + 'url' => 'index.php', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1)), + 'server' => $server1, + 'expected' => '/' ), - $server1, '/?format=json'); - - $cases[] = array('index.php/blog/test?format=json', JROUTER_MODE_SEF, array(), array( - array('sef_rewrite', null, 1), - array('sef_suffix', null, 1) + 'url' => 'index.php/blog/test', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1)), + 'server' => $server1, + 'expected' => '/blog/test' ), - $server1, '/blog/test.json'); - - return $cases; + array( + 'url' => 'index.php?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_suffix', null, 1)), + 'server' => $server2, + 'expected' => '/joomla/index.php?format=json' + ), + array( + 'url' => 'index.php/blog/test?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_suffix', null, 1)), + 'server' => $server2, + 'expected' => '/joomla/index.php/blog/test.json' + ), + array( + 'url' => 'index.php?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_suffix', null, 1)), + 'server' => $server1, + 'expected' => '/index.php?format=json' + ), + array( + 'url' => 'index.php/blog/test?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_suffix', null, 1)), + 'server' => $server1, + 'expected' => '/index.php/blog/test.json' + ), + array( + 'url' => 'index.php?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1), array('sef_suffix', null, 1)), + 'server' => $server2, + 'expected' => '/joomla/?format=json' + ), + array( + 'url' => 'index.php/blog/test?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1), array('sef_suffix', null, 1)), + 'server' => $server2, + 'expected' => '/joomla/blog/test.json' + ), + array( + 'url' => 'index.php?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1), array('sef_suffix', null, 1)), + 'server' => $server1, + 'expected' => '/?format=json' + ), + array( + 'url' => 'index.php/blog/test?format=json', + 'mode' => JROUTER_MODE_SEF, + 'vars' => array(), + 'map' => array(array('sef_rewrite', null, 1), array('sef_suffix', null, 1)), + 'server' => $server1, + 'expected' => '/blog/test.json' + ), + ); } /** * testBuild(). * - * @param string $url The URL - * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF - * @param array $vars An associative array with global variables - * @param array $map Valuemap for JApplication::get() Mock - * @param array $server Values for $_SERVER - * @param array $expected Expected value + * @param string $url The URL + * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF + * @param array $vars An associative array with global variables + * @param array $map Valuemap for JApplication::get() Mock + * @param array $server Values for $_SERVER + * @param array $expected Expected value * * @dataProvider casesBuild * * @return void - * - * @since 3.4 + * @testdox Variables are transformed into proper URLs + * @since 3.4 */ public function testBuild($url, $mode, $vars, $map, $server, $expected) { - //Set $_SERVER variable $_SERVER = array_merge($_SERVER, $server); - $this->object->setMode($mode); - $app = $this->object->getApp(); - $app->expects($this->any())->method('get')->will($this->returnValueMap($map)); - $this->object->setApp($app); + $app = $this->getMockCmsApp(); + $app->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($map)); - $uri = $this->object->build($url); + $object = new JRouterSite( + array(), + $app, + TestMockMenu::create($this) + ); - // Check the expected values - $this->assertEquals($expected, $uri->toString()); + $object->setMode($mode); - // Check that caching works - $juri = $this->object->build($url); - $this->assertEquals($uri, $juri); + // Check the expected values + $this->assertEquals($expected, (string)($object->build($url))); } /** @@ -360,52 +495,90 @@ public function testBuild($url, $mode, $vars, $map, $server, $expected) */ public function casesParseRawRoute() { - $cases = array(); - $cases[] = array('', true, array(), array()); - $cases[] = array('', false, array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), array()); - - $cases[] = array('index.php?option=com_test&Itemid=42&testvar=testvalue', true, array(), array('option' => 'com_test', 'Itemid' => '42', 'testvar' => 'testvalue')); - $cases[] = array('index.php?Itemid=42', true, array('option' => 'com_test', 'view' => 'test'), array('Itemid' => 42)); - - return $cases; + return array( + 'no_url-sef' => array( + 'url' => '', + 'mode' => JROUTER_MODE_SEF, + 'expParseVars' => array(), + 'expObjVars' => array() + ), + 'no_url-raw-default' => array( + 'url' => '', + 'mode' => JROUTER_MODE_RAW, + 'expParseVars' => array('option' => 'com_test3', 'view' => 'test3', 'Itemid' => '45'), + 'expObjVars' => array() + ), + 'url-sef-query-itemid' => array( + 'url' => 'index.php?option=com_test&Itemid=42&testvar=testvalue', + 'mode' => JROUTER_MODE_SEF, + 'expParseVars' => array(), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => '42', 'testvar' => 'testvalue') + ), + 'url-sef-itemid' => array( + 'url' => 'index.php?Itemid=42', + 'mode' => JROUTER_MODE_SEF, + 'expParseVars' => array('option' => 'com_test', 'view' => 'test'), + 'expObjVars' => array('Itemid' => 42) + ), + ); } /** * Tests the parse method * - * @param string $url An associative array with variables - * @param integer $menubool JROUTER_MODE_RAW or JROUTER_MODE_SEF - * @param array $expectedVars An associative array with $_SERVER vars - * @param array $expectedGlobalVars An associative array with $_SERVER vars + * @param string $url An associative array with variables + * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF + * @param array $expectedParseVars An associative array with $_SERVER vars + * @param array $expectedObjectVars An associative array with $_SERVER vars * * @return void * * @dataProvider casesParseRawRoute * @since 3.4 */ - public function testParseRawRoute($url, $menubool, $expectedVars, $expectedGlobalVars) + public function testParseRawRoute($url, $mode, $expectedParseVars, $expectedObjectVars) { - $uri = new JUri($url); + $app = $this->getMockCmsApp(); - if (isset($expectedGlobalVars['Itemid'])) + if (isset($expectedObjectVars['Itemid'])) { - $app = $this->object->getApp(); - $app->input->set('Itemid', $expectedGlobalVars['Itemid']); - $this->object->setApp($app); + $app->input->set('Itemid', $expectedObjectVars['Itemid']); } - if ($menubool) + if ($mode == JROUTER_MODE_SEF) { $menu = TestMockMenu::create($this, false); - $menu->expects($this->any())->method('getDefault')->will($this->returnValue(null)); - $this->object->setMenu($menu); + $menu + ->expects($this->any()) + ->method('getDefault') + ->will($this->returnValue(null)); } + else + { + $menu = TestMockMenu::create($this, true); + } + + $object = new JRouterSite( + array(), + $app, + $menu + ); - $vars = $this->object->runParseRawRoute($uri); + $parseRawRouteMethod = new ReflectionMethod('JRouterSite', 'parseRawRoute'); + $parseRawRouteMethod->setAccessible(true); - $this->assertEquals($expectedVars, $vars); + $vars = $parseRawRouteMethod->invoke($object, new JUri($url)); - $this->assertEquals($expectedGlobalVars, $this->object->getVars()); + $this->assertEquals( + $expectedParseVars, + $vars, + "JRouterSite::parseRawRoute() did not return the expected values." + ); + $this->assertEquals( + $expectedObjectVars, + $object->getVars(), + "JRouterSite did not have the expected values internally." + ); } /** @@ -417,211 +590,515 @@ public function testParseRawRoute($url, $menubool, $expectedVars, $expectedGloba */ public function casesParseSefRoute() { - $cases = array(); - - // Empty URLs without a default menu item return nothing - $cases[] = array('', true, array(), array(), array()); - - // Absolute URLs to the domain of the site - $cases[] = array('/test/path', true, array(), array(), array()); - $cases[] = array('/test/path?testvar=testvalue', true, array(), array('testvar' => 'testvalue'), array('testvar' => 'testvalue')); - $cases[] = array('?testvar=testvalue', true, array(), array('testvar' => 'testvalue'), array()); - - $cases[] = array('/test/path.json', true, array(), array(), array()); - $cases[] = array('/test/path.json?testvar=testvalue', true, array(), array('testvar' => 'testvalue'), array('testvar' => 'testvalue')); - - $cases[] = array('/test/path.json', true, array(array('sef_suffix', null, '1')), array(), array()); - $cases[] = array('/test/path.json?testvar=testvalue', true, array(array('sef_suffix', null, '1')), array('testvar' => 'testvalue'), array('testvar' => 'testvalue')); - - $cases[] = array('', false, array(), array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3'), array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3')); - $cases[] = array('/test/path', false, array(), array(), array('Itemid' => '45', 'option' => 'com_test3')); - $cases[] = array('/test/path?testvar=testvalue', false, array(), array(), array('testvar' => 'testvalue', 'Itemid' => '45', 'option' => 'com_test3')); - $cases[] = array('?testvar=testvalue', false, array(), array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3'), array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3')); - - $cases[] = array('/test/path.json', false, array(), array(), array('Itemid' => '45', 'option' => 'com_test3')); - $cases[] = array('/test/path.json?testvar=testvalue', false, array(), array(), array('testvar' => 'testvalue', 'Itemid' => '45', 'option' => 'com_test3')); - - $cases[] = array('/test/path.json', false, array(array('sef_suffix', null, '1')), array(), array('Itemid' => '45', 'option' => 'com_test3')); - $cases[] = array('/test/path.json?testvar=testvalue', false, array(array('sef_suffix', null, '1')), array(), array('testvar' => 'testvalue', 'Itemid' => '45', 'option' => 'com_test3')); - - // Non-SEF URLs - $cases[] = array('?option=com_test', true, array(), array(), array('option' => 'com_test', 'Itemid' => NULL)); - $cases[] = array('?Itemid=42', true, array(), array(), array('Itemid' => NULL)); - $cases[] = array('?Itemid=42&option=com_test', true, array(), array(), array('option' => 'com_test', 'Itemid' => NULL)); - $cases[] = array('?option=com_test', false, array(), array(), array('option' => 'com_test', 'Itemid' => NULL)); - - // 20 - $cases[] = array('?Itemid=42', false, array(), array(), array('Itemid' => NULL)); - $cases[] = array('?Itemid=42&option=com_test', false, array(), array(), array('option' => 'com_test', 'Itemid' => NULL)); - - // URLs with /component/something - $cases[] = array('component/test', true, array(), array('option' => 'com_test', 'Itemid' => NULL), array('option' => 'com_test', 'Itemid' => NULL)); - $cases[] = array('component/test', false, array(), array('option' => 'com_test', 'Itemid' => NULL), array('option' => 'com_test', 'Itemid' => NULL)); - $cases[] = array('component/test2/something', true, array(), array('testvar' => 'testvalue'), array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => NULL)); - $cases[] = array('component/test2/something', false, array(), array('testvar' => 'testvalue'), array('option' => 'com_test2', 'Itemid' => NULL, 'testvar' => 'testvalue')); - - // Parse actual menu items - $cases[] = array('test2/sub-menu', true, array(), array('option' => 'com_test2', 'Itemid' => 44), array('option' => 'com_test2', 'Itemid' => 44)); - $cases[] = array('test2/sub-menu', false, array(), array('option' => 'com_test2', 'Itemid' => 44), array('option' => 'com_test2', 'Itemid' => 44)); - $cases[] = array('test2/sub-menu/something', true, array(), array('testvar' => 'testvalue'), array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => 44)); - $cases[] = array('test2/sub-menu/something', false, array(), array('testvar' => 'testvalue'), array('option' => 'com_test2', 'Itemid' => 44, 'testvar' => 'testvalue')); - - $cases[] = array('test2/sub-menu', true, array('languagefilter' => true), array('option' => 'com_test2', 'Itemid' => 44), array('option' => 'com_test2', 'Itemid' => 44)); - $cases[] = array('test2/sub-menu', false, array('languagefilter' => true), array('option' => 'com_test2', 'Itemid' => 44), array('option' => 'com_test2', 'Itemid' => 44)); - $cases[] = array('test2/sub-menu/something', true, array('languagefilter' => true), array('testvar' => 'testvalue'), array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => 44)); - $cases[] = array('test2/sub-menu/something', false, array('languagefilter' => true), array('testvar' => 'testvalue'), array('option' => 'com_test2', 'Itemid' => 44, 'testvar' => 'testvalue')); - - $cases[] = array('english-test', false, array('languagefilter' => true), array('option' => 'com_test', 'view' => 'test2'), array('option' => 'com_test', 'Itemid' => '47'), 47); - - return $cases; + return array( + // Empty URLs without a default menu item return nothing + 'empty-sef' => array( + 'url' => '', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array() + ), + // Absolute URLs to the domain of the site + 'abs-sef-path-no_qs-no_sfx' => array( + 'url' => '/test/path', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array() + ), + 'abs-sef-path-qs-no_sfx' => array( + 'url' => '/test/path?testvar=testvalue', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('testvar' => 'testvalue') + ), + 'abs-sef-no_path-qs-no_sfx' => array( + 'url' => '?testvar=testvalue', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array() + ), + 'abs-sef-path.ext-no_qs-no_sfx' => array( + 'url' => '/test/path.json', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array() + ), + 'abs-sef-path.ext-qs-no_sfx' => array( + 'url' => '/test/path.json?testvar=testvalue', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('testvar' => 'testvalue') + ), + 'abs-sef-path.ext-no_qs-sfx' => array( + 'url' => '/test/path.json', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(array('sef_suffix', null, '1')), + 'expParseVars' => array(), + 'expObjVars' => array() + ), + 'abs-sef-path.ext-qs-sfx' => array( + 'url' => '/test/path.json?testvar=testvalue', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(array('sef_suffix', null, '1')), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('testvar' => 'testvalue') + ), + 'empty-raw' => array( + 'url' => '', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3'), + 'expObjVars' => array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3') + ), + 'abs-raw-path-no_qs-no_sfx' => array( + 'url' => '/test/path', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('Itemid' => '45', 'option' => 'com_test3') + ), + 'abs-raw-path-qs-no_sfx' => array( + 'url' => '/test/path?testvar=testvalue', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('testvar' => 'testvalue', 'Itemid' => '45', 'option' => 'com_test3') + ), + 'abs-raw-no_path-qs-no_sfx' => array( + 'url' => '?testvar=testvalue', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3'), + 'expObjVars' => array('Itemid' => '45', 'option' => 'com_test3', 'view' => 'test3') + ), + 'abs-raw-path.ext-no_qs-no_sfx' => array( + 'url' => '/test/path.json', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('Itemid' => '45', 'option' => 'com_test3') + ), + 'abs-raw-path.ext-qs-no_sfx' => array( + 'url' => '/test/path.json?testvar=testvalue', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('testvar' => 'testvalue', 'Itemid' => '45', 'option' => 'com_test3') + ), + 'abs-raw-path.ext-no_qs-sfx' => array( + 'url' => '/test/path.json', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(array('sef_suffix', null, '1')), + 'expParseVars' => array(), + 'expObjVars' => array('Itemid' => '45', 'option' => 'com_test3') + ), + 'abs-raw-path.ext-qs-sfx' => array( + 'url' => '/test/path.json?testvar=testvalue', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(array('sef_suffix', null, '1')), + 'expParseVars' => array(), + 'expObjVars' => array('testvar' => 'testvalue', 'Itemid' => '45', 'option' => 'com_test3') + ), + // Non-SEF URLs + 'raw-sef-no_id-no_opt' => array( + 'url' => '?option=com_test', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => null) + ), + 'raw-sef-id-no_opt' => array( + 'url' => '?Itemid=42', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('Itemid' => null) + ), + 'raw-sef-id-opt' => array( + 'url' => '?Itemid=42&option=com_test', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => null) + ), + 'raw-raw-no_id-opt' => array( + 'url' => '?option=com_test', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => null) + ), + // 20 + '20-raw-id-no_opt' => array( + 'url' => '?Itemid=42', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('Itemid' => null) + ), + '20-raw-id-opt' => array( + 'url' => '?Itemid=42&option=com_test', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array(), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => null) + ), + // URLs with /component/something + 'comp-sef-2lvl' => array( + 'url' => 'component/test', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('option' => 'com_test', 'Itemid' => null), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => null) + ), + 'comp-raw-2lvl' => array( + 'url' => 'component/test', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array('option' => 'com_test', 'Itemid' => null), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => null) + ), + 'comp-sef-3lvl' => array( + 'url' => 'component/test2/something', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => null) + ), + 'comp-raw-3lvl' => array( + 'url' => 'component/test2/something', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => null, 'testvar' => 'testvalue') + ), + // Parse current menu items + 'curr-sef-no_lang-2lvl' => array( + 'url' => 'test2/sub-menu', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('option' => 'com_test2', 'Itemid' => 44), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => 44) + ), + 'curr-raw-no_lang-2lvl' => array( + 'url' => 'test2/sub-menu', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array('option' => 'com_test2', 'Itemid' => 44), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => 44) + ), + 'curr-sef-no_lang-3lvl' => array( + 'url' => 'test2/sub-menu/something', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => 44) + ), + 'curr-raw-no_lang-3lvl' => array( + 'url' => 'test2/sub-menu/something', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array(), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => 44, 'testvar' => 'testvalue') + ), + 'curr-sef-lang-2lvl' => array( + 'url' => 'test2/sub-menu', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array('languagefilter' => true), + 'expParseVars' => array('option' => 'com_test2', 'Itemid' => 44), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => 44) + ), + 'curr-raw-lang-2lvl' => array( + 'url' => 'test2/sub-menu', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array('languagefilter' => true), + 'expParseVars' => array('option' => 'com_test2', 'Itemid' => 44), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => 44) + ), + 'curr-sef-lang-3lvl' => array( + 'url' => 'test2/sub-menu/something', + 'mode' => JROUTER_MODE_SEF, + 'appConfig' => array('languagefilter' => true), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('testvar' => 'testvalue', 'option' => 'com_test2', 'Itemid' => 44) + ), + 'curr-raw-lang-3lvl' => array( + 'url' => 'test2/sub-menu/something', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array('languagefilter' => true), + 'expParseVars' => array('testvar' => 'testvalue'), + 'expObjVars' => array('option' => 'com_test2', 'Itemid' => 44, 'testvar' => 'testvalue') + ), + 'engl-raw-lang' => array( + 'url' => 'english-test', + 'mode' => JROUTER_MODE_RAW, + 'appConfig' => array('languagefilter' => true), + 'expParseVars' => array('option' => 'com_test', 'view' => 'test2'), + 'expObjVars' => array('option' => 'com_test', 'Itemid' => '47'), + 'itemid' => 47 + ), + ); } /** * Tests the parseSefRoute method * - * @param string $url An associative array with variables - * @param integer $menubool JROUTER_MODE_RAW or JROUTER_MODE_SEF - * @param array $appConfig An associative array with app config vars - * @param array $expected An associative array with $_SERVER vars - * @param array $expectedGlobals An associative array with $_SERVER vars - * @param boolean $activeMenu Flag if the item is the active menu + * @param string $url An associative array with variables + * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF + * @param array $appConfig An associative array with app config vars + * @param array $expectedParseVars An associative array with $_SERVER vars + * @param array $expectedObjectVars An associative array with $_SERVER vars + * @param boolean $setActive Flag if the item is the active menu * * @return void * * @dataProvider casesParseSefRoute + * @testdox Parse SEF route * @since 3.4 */ - public function testParseSefRoute($url, $menubool, $appConfig, $expected, $expectedGlobals, $activeMenu = false) + public function testParseSefRoute($url, $mode, $appConfig, $expectedParseVars, $expectedObjectVars, $setActive = false) { - $uri = new JUri($url); - $app = $this->object->getApp(); + $app = $this->getMockCmsApp(); - if (isset($expected['Itemid'])) + if (isset($expectedParseVars['Itemid'])) { - $app->input->set('Itemid', $expected['Itemid']); + $app->input->set('Itemid', $expectedParseVars['Itemid']); } if (isset($appConfig['languagefilter'])) { - $app->expects($this->any())->method('getLanguageFilter')->will($this->returnValue(true)); + $app->expects($this->any()) + ->method('getLanguageFilter') + ->will($this->returnValue(true)); unset($appConfig['languagefilter']); } - $app->expects($this->any())->method('get')->will($this->returnValueMap($appConfig)); - $this->object->setApp($app); + $app->expects($this->any()) + ->method('get') + ->will($this->returnValueMap($appConfig)); - if ($menubool) + if ($mode == JROUTER_MODE_SEF) { - $menu = TestMockMenu::create($this, false, $activeMenu); - $menu->expects($this->any())->method('getDefault')->will($this->returnValue(null)); - $this->object->setMenu($menu); + $menu = TestMockMenu::create($this, false, $setActive); + $menu + ->expects($this->any()) + ->method('getDefault') + ->will($this->returnValue(null)); } else { - $menu = TestMockMenu::create($this, true, $activeMenu); - $this->object->setMenu($menu); + $menu = TestMockMenu::create($this, true, $setActive); } - // The method should return an array of variables - $vars = $this->object->runParseSefRoute($uri); - $this->assertEquals($expected, $vars); + $object = new JRouterSite( + array(), + $app, + $menu + ); + + $parseSefRouteMethod = new ReflectionMethod('JRouterSite', 'parseSefRoute'); + $parseSefRouteMethod->setAccessible(true); + + $vars = $parseSefRouteMethod->invoke($object, new JUri($url)); - $this->assertEquals($expectedGlobals, $this->object->getVars(), 'global vars'); + $this->assertEquals( + $expectedParseVars, + $vars, + "JRouterSite::parseSefRoute() did not return the expected values." + ); + $this->assertEquals( + $expectedObjectVars, + $object->getVars(), + "JRouterSite did not have the expected values internally." + ); } /** * Tests the buildRawRoute() method * * @return void - * + * @testdox JRouterSite::buildRawRoute() does not change a URL without an option * @since 3.4 */ public function testBuildRawRoute() { $uri = new JUri('index.php'); - // Test if a URL without an option is returned identical - $this->object->runBuildRawRoute($uri); - $this->assertEquals('index.php', $uri->toString()); - - // Test if a component routers preprocess method is executed - $uri->setVar('option', 'com_test'); - $this->object->runBuildRawRoute($uri); - $this->assertEquals('index.php?option=com_test&testvar=testvalue', $uri->toString()); + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); - // Test if a broken option is properly sanitised to get the right router - $uri->setVar('option', 'com_ te?st'); - $uri->delVar('testvar'); - $this->object->runBuildRawRoute($uri); - $this->assertEquals('index.php?option=com_ te?st&testvar=testvalue', $uri->toString()); + $buildRawRouteMethod = new ReflectionMethod('JRouterSite', 'buildRawRoute'); + $buildRawRouteMethod->setAccessible(true); - // Test if a legacy component routers preprocess method is executed - $uri->setVar('option', 'com_test3'); - $uri->delVar('testvar'); - $this->object->runBuildRawRoute($uri); - $this->assertEquals('index.php?option=com_test3', $uri->toString()); + $buildRawRouteMethod->invokeArgs($object, array(&$uri)); + $this->assertEquals('index.php', (string)$uri); } /** - * Cases for testBuildSefRoute - * - * @return array + * Tests the buildRawRoute() method * + * @return void + * @testdox JRouterSite::buildRawRoute() executes a component router's preprocess method * @since 3.4 */ - public function casesBuildSefRoute() + public function testAComponentRoutersPreprocessMethodIsExecuted() { - $cases = array(); + $uri = new JUri('index.php'); + + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); - // Check empty URLs are returned identically - $cases[] = array('', ''); + $buildRawRouteMethod = new ReflectionMethod('JRouterSite', 'buildRawRoute'); + $buildRawRouteMethod->setAccessible(true); - // Check if URLs without an option are returned identically - $cases[] = array('index.php?var1=value1', 'index.php?var1=value1'); + $uri->setVar('option', 'com_test'); + $buildRawRouteMethod->invokeArgs($object, array(&$uri)); + $this->assertEquals('index.php?option=com_test&testvar=testvalue', (string)$uri); + } - // Check if the menu item is properly prepended - $cases[] = array('index.php?option=com_test&var1=value1&Itemid=42', 'index.php/test?var1=value1'); + /** + * Tests the buildRawRoute() method + * + * @return void + * @testdox JRouterSite::buildRawRoute() sanitizes broken options to get the right router + * @since 3.4 + */ + public function testABrokenOptionIsProperlySanitisedToGetTheRightRouter() + { + $uri = new JUri('index.php'); - // Check if a non existing menu item is correctly ignored - $cases[] = array('index.php?option=com_test&var1=value1&Itemid=41', 'index.php/component/test/?var1=value1&Itemid=41'); + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); - // Check if a menu item with a parent is properly prepended - $cases[] = array('index.php?option=com_test&var1=value1&Itemid=46', 'index.php/test/sub-menu?var1=value1'); + $buildRawRouteMethod = new ReflectionMethod('JRouterSite', 'buildRawRoute'); + $buildRawRouteMethod->setAccessible(true); - // Component router build: Check if the menu item is properly prepended - $cases[] = array('index.php?option=com_test2&var1=value1&Itemid=43', 'index.php/test2/router-test/another-segment?var1=value1'); + $uri->setVar('option', 'com_ te?st'); + $uri->delVar('testvar'); + $buildRawRouteMethod->invokeArgs($object, array(&$uri)); + $this->assertEquals('index.php?option=com_ te?st&testvar=testvalue', (string)$uri); + } - // Component router build: Check if a non existing menu item is correctly ignored - $cases[] = array('index.php?option=com_test2&var1=value1&Itemid=41', 'index.php/component/test2/router-test/another-segment?var1=value1&Itemid=41'); + /** + * Tests the buildRawRoute() method + * + * @return void + * @testdox JRouterSite::buildRawRoute() executes a legacy component router's preprocess method + * @since 3.4 + */ + public function testALegacyComponentRoutersPreprocessMethodIsExecuted() + { + $uri = new JUri('index.php'); - // Component router build: Check if a menu item with a parent is properly prepended - $cases[] = array('index.php?option=com_test2&var1=value1&Itemid=44', 'index.php/test2/sub-menu/router-test/another-segment?var1=value1'); + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); - // Check if a home menu item is treated properly - $cases[] = array('index.php?Itemid=45&option=com_test3', 'index.php/component/test3/?Itemid=45'); + $buildRawRouteMethod = new ReflectionMethod('JRouterSite', 'buildRawRoute'); + $buildRawRouteMethod->setAccessible(true); - // Check if a home menu item is treated properly - $cases[] = array('index.php?Itemid=45&option=com_test3&testvar=testvalue', 'index.php/component/test3/?testvar=testvalue&Itemid=45'); + $uri->setVar('option', 'com_test3'); + $uri->delVar('testvar'); + $buildRawRouteMethod->invokeArgs($object, array(&$uri)); + $this->assertEquals('index.php?option=com_test3', (string)$uri); + } - return $cases; + /** + * Cases for testBuildSefRoute + * + * @return array + * + * @since 3.4 + */ + public function casesBuildSefRoute() + { + return array( + 'Empty URLs are returned identically' => array( + 'url' => '', + 'expected' => '' + ), + 'URLs without an option are returned identically' => array( + 'url' => 'index.php?var1=value1', + 'expected' => 'index.php?var1=value1' + ), + 'The menu item is properly prepended' => array( + 'url' => 'index.php?option=com_test&var1=value1&Itemid=42', + 'expected' => 'index.php/test?var1=value1' + ), + 'A non existing menu item is correctly ignored' => array( + 'url' => 'index.php?option=com_test&var1=value1&Itemid=41', + 'expected' => 'index.php/component/test/?var1=value1&Itemid=41' + ), + 'A menu item with a parent is properly prepended' => array( + 'url' => 'index.php?option=com_test&var1=value1&Itemid=46', + 'expected' => 'index.php/test/sub-menu?var1=value1' + ), + 'Component router build: The menu item is properly prepended' => array( + 'url' => 'index.php?option=com_test2&var1=value1&Itemid=43', + 'expected' => 'index.php/test2/router-test/another-segment?var1=value1' + ), + 'Component router build: A non existing menu item is correctly ignored' => array( + 'url' => 'index.php?option=com_test2&var1=value1&Itemid=41', + 'expected' => 'index.php/component/test2/router-test/another-segment?var1=value1&Itemid=41' + ), + 'Component router build: A menu item with a parent is properly prepended' => array( + 'url' => 'index.php?option=com_test2&var1=value1&Itemid=44', + 'expected' => 'index.php/test2/sub-menu/router-test/another-segment?var1=value1' + ), + 'A home menu item is treated properly (without vars)' => array( + 'url' => 'index.php?Itemid=45&option=com_test3', + 'expected' => 'index.php/component/test3/?Itemid=45' + ), + 'A home menu item is treated properly (with vars)' => array( + 'url' => 'index.php?Itemid=45&option=com_test3&testvar=testvalue', + 'expected' => 'index.php/component/test3/?testvar=testvalue&Itemid=45' + ), + ); } /** * testBuildSefRoute(). * - * @param string $url Input URL - * @param string $expected Expected return value + * @param string $url Input URL + * @param string $expected Expected return value * * @dataProvider casesBuildSefRoute * * @return void - * - * @since 3.4 + * @testdox Build SEF route + * @since 3.4 */ public function testBuildSefRoute($url, $expected) { $uri = new JUri($url); - $this->object->runBuildSefRoute($uri); - $this->assertEquals($expected, $uri->toString()); + + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + + $buildSefRouteMethod = new ReflectionMethod('JRouterSite', 'buildSefRoute'); + $buildSefRouteMethod->setAccessible(true); + $buildSefRouteMethod->invokeArgs($object, array(&$uri)); + + $this->assertEquals($expected, (string)$uri); } /** @@ -633,13 +1110,22 @@ public function testBuildSefRoute($url, $expected) */ public function testProcessParseRules() { - $url = 'index.php?start=42'; - $expected = 'index.php'; - $uri = new JUri($url); - $this->object->setMode(JROUTER_MODE_SEF); - $vars = $this->object->runProcessParseRules($uri); - $this->assertEquals($uri->toString(), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); - $this->assertEquals($vars, array('limitstart' => '42'), __METHOD__ . ':' . __LINE__ . ': value is not expected'); + $uri = new JUri('index.php?start=42'); + + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + $object->setMode(JROUTER_MODE_SEF); + + $processParseRulesMethod = new ReflectionMethod('JRouterSite', 'processParseRules'); + $processParseRulesMethod->setAccessible(true); + + $vars = $processParseRulesMethod->invokeArgs($object, array(&$uri)); + + $this->assertEquals('index.php', $uri->toString()); + $this->assertEquals(array('limitstart' => '42'), $vars); } /** @@ -651,52 +1137,72 @@ public function testProcessParseRules() */ public function casesProcessBuildRules() { - $cases = array(); - - // Check if an empty URL is returned as an empty URL - $cases[] = array('', JROUTER_MODE_RAW, ''); - - /** - * Check if a URL with an Itemid and another query parameter - * is replaced with the query of the menu item plus the Itemid - * when mode is not SEF - */ - $cases[] = array('index.php?Itemid=42&test=true', JROUTER_MODE_RAW, 'index.php?option=com_test&view=test&Itemid=42'); - - /** - * Check if a URL with an Itemid and another query parameter - * is returned identical when mode is SEF - */ - $cases[] = array('index.php?Itemid=42&test=true', JROUTER_MODE_SEF, 'index.php?Itemid=42&test=true'); - - /** - * Check if a URL with a path and limitstart gets the limitstart - * parameter converted to start when mode is SEF - */ - $cases[] = array('test?limitstart=42', JROUTER_MODE_SEF, 'test?start=42'); - - return $cases; + return array( + // Check if an empty URL is returned as an empty URL + 'empty' => array( + 'url' => '', + 'mode' => JROUTER_MODE_RAW, + 'expected' => '' + ), + /** + * Check if a URL with an Itemid and another query parameter + * is replaced with the query of the menu item plus the Itemid + * when mode is not SEF + */ + 'raw' => array( + 'url' => 'index.php?Itemid=42&test=true', + 'mode' => JROUTER_MODE_RAW, + 'expected' => 'index.php?option=com_test&view=test&Itemid=42' + ), + /** + * Check if a URL with an Itemid and another query parameter + * is returned identical when mode is SEF + */ + 'sef' => array( + 'url' => 'index.php?Itemid=42&test=true', + 'mode' => JROUTER_MODE_SEF, + 'expected' => 'index.php?Itemid=42&test=true' + ), + /** + * Check if a URL with a path and limitstart gets the limitstart + * parameter converted to start when mode is SEF + */ + 'limitstart' => array( + 'url' => 'test?limitstart=42', + 'mode' => JROUTER_MODE_SEF, + 'expected' => 'test?start=42' + ), + ); } /** * testProcessBuildRules(). * - * @param string $url Input URL - * @param array $functions Callback to execute - * @param string $expected Expected return value + * @param string $url Input URL + * @param int $mode + * @param string $expected Expected return value * * @dataProvider casesProcessBuildRules * - * @return void - * - * @since 3.4 + * @since 3.4 */ public function testProcessBuildRules($url, $mode, $expected) { $uri = new JUri($url); - $this->object->setMode($mode); - $this->object->runProcessBuildRules($uri); - $this->assertEquals($uri->toString(), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); + + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + $object->setMode($mode); + + $processBuildRulesMethod = new ReflectionMethod('JRouterSite', 'processBuildRules'); + $processBuildRulesMethod->setAccessible(true); + + $processBuildRulesMethod->invokeArgs($object, array(&$uri)); + + $this->assertEquals($expected, (string)$uri); } /** @@ -708,69 +1214,87 @@ public function testProcessBuildRules($url, $mode, $expected) */ public function casesCreateURI() { - $cases = array(); - - // Check if a rather non-URL is returned identical - $cases[] = array('index.php?var1=value&var2=value2', array(), 'index.php?var1=value&var2=value2'); - - // Check if a URL with Itemid and option is returned identically - $cases[] = array('index.php?option=com_test&Itemid=42&var1=value1', array(), 'index.php?option=com_test&Itemid=42&var1=value1'); - - // Check if a URL with existing Itemid and no option is added the right option - $cases[] = array('index.php?Itemid=42&var1=value1', array(), 'index.php?Itemid=42&var1=value1&option=com_test'); - - // Check if a URL with non-existing Itemid and no option is returned identically - $cases[] = array('index.php?Itemid=41&var1=value1', array(), 'index.php?Itemid=41&var1=value1'); - - /** - * Check if a URL with no Itemid and no option, - * but globally set option is added the option - */ - $cases[] = array('index.php?var1=value1', array('option' => 'com_test'), 'index.php?var1=value1&option=com_test'); - - /** - * Check if a URL with no Itemid and no option, - * but globally set Itemid is added the Itemid - */ - $cases[] = array('index.php?var1=value1', array('Itemid' => '42'), 'index.php?var1=value1&Itemid=42'); - - /** - * Check if a URL without an Itemid, but with an option set - * and a global Itemid available, which fits the option of - * the menu item gets the Itemid appended - */ - $cases[] = array('index.php?var1=value&option=com_test', array('Itemid' => '42'), 'index.php?var1=value&option=com_test&Itemid=42'); - - /** - * Check if a URL without an Itemid, but with an option set - * and a global Itemid available, which does not fit the - * option of the menu item gets returned identically - */ - $cases[] = array('index.php?var1=value&option=com_test3', array('Itemid' => '42'), 'index.php?var1=value&option=com_test3'); - - return $cases; + return array( + // Check if a rather non-URL is returned identical + array( + 'url' => 'index.php?var1=value&var2=value2', + 'preset' => array(), + 'expected' => 'index.php?var1=value&var2=value2' + ), + // Check if a URL with Itemid and option is returned identically + array( + 'url' => 'index.php?option=com_test&Itemid=42&var1=value1', + 'preset' => array(), + 'expected' => 'index.php?option=com_test&Itemid=42&var1=value1' + ), + // Check if a URL with existing Itemid and no option is added the right option + array( + 'url' => 'index.php?Itemid=42&var1=value1', + 'preset' => array(), + 'expected' => 'index.php?Itemid=42&var1=value1&option=com_test' + ), + // Check if a URL with non-existing Itemid and no option is returned identically + array( + 'url' => 'index.php?Itemid=41&var1=value1', + 'preset' => array(), + 'expected' => 'index.php?Itemid=41&var1=value1' + ), + // Check if a URL with no Itemid and no option, but globally set option is added the option + array( + 'url' => 'index.php?var1=value1', + 'preset' => array('option' => 'com_test'), + 'expected' => 'index.php?var1=value1&option=com_test' + ), + // Check if a URL with no Itemid and no option, but globally set Itemid is added the Itemid + array( + 'url' => 'index.php?var1=value1', + 'preset' => array('Itemid' => '42'), + 'expected' => 'index.php?var1=value1&Itemid=42' + ), + // Check if a URL without an Itemid, but with an option set and a global Itemid available, which fits the option of the menu item gets the Itemid appended + array( + 'url' => 'index.php?var1=value&option=com_test', + 'preset' => array('Itemid' => '42'), + 'expected' => 'index.php?var1=value&option=com_test&Itemid=42' + ), + // Check if a URL without an Itemid, but with an option set and a global Itemid available, which does not fit the option of the menu item gets returned identically + array( + 'url' => 'index.php?var1=value&option=com_test3', + 'preset' => array('Itemid' => '42'), + 'expected' => 'index.php?var1=value&option=com_test3' + ), + ); } /** * Tests createURI() method * - * @param array $url valid inputs to the createURI() method - * @param array $globalVars global Vars that should be merged into the URL - * @param string $expected expected URI string + * @param array $url valid inputs to the createURI() method + * @param array $preset global Vars that should be merged into the URL + * @param string $expected expected URI string * * @dataProvider casesCreateURI * * @return void - * - * @since 3.4 + * @testdox Create URI + * @since 3.4 */ - public function testCreateURI($url, $globalVars, $expected) + public function testCreateURI($url, $preset, $expected) { - $this->object->setVars($globalVars, false); - $juri = $this->object->runCreateURI($url); + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + $object->setVars($preset); + + $createUriMethod = new ReflectionMethod('JRouterSite', 'createUri'); + $createUriMethod->setAccessible(true); + + $uri = $createUriMethod->invoke($object, $url); - $this->assertTrue(is_a($juri, 'JUri')); - $this->assertEquals($juri->toString(), $expected); + $this->assertInstanceOf('JUri', $uri); + $this->assertEquals($expected, (string)$uri); } /** @@ -782,25 +1306,32 @@ public function testCreateURI($url, $globalVars, $expected) */ public function testGetComponentRouter() { + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + /** * Get the TestRouter and check if you get the * same object instance the second time */ - $router = $this->object->getComponentRouter('com_test'); + $router = $object->getComponentRouter('com_test'); + $this->assertInstanceOf('TestRouter', $router); - $this->assertSame($router, $this->object->getComponentRouter('com_test')); + $this->assertSame($router, $object->getComponentRouter('com_test')); /** * Check if a proper router is automatically loaded * by loading the router of com_content */ - $this->assertInstanceOf('ContentRouter', $this->object->getComponentRouter('com_content')); + $this->assertInstanceOf('ContentRouter', $object->getComponentRouter('com_content')); /** * Check if an instance of JComponentRouterLegacy * is returned for non-existing routers */ - $this->assertInstanceOf('JComponentRouterLegacy', $this->object->getComponentRouter('com_legacy')); + $this->assertInstanceOf('JComponentRouterLegacy', $object->getComponentRouter('com_legacy')); } /** @@ -810,14 +1341,35 @@ public function testGetComponentRouter() * * @since 3.4 */ - public function testSetComponentRouter() + public function testValidRouterGetsAccepted() { - // Check if a router that implements JComponentRouterInterface gets accepted + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + $router = new TestRouter; - $this->assertEquals($this->object->setComponentRouter('com_test', $router), true); - $this->assertSame($this->object->getComponentRouter('com_test'), $router); - // Check if a false router is correctly rejected - $this->assertFalse($this->object->setComponentRouter('com_test3', new stdClass)); + $this->assertTrue($object->setComponentRouter('com_test', $router)); + $this->assertSame($router, $object->getComponentRouter('com_test')); + } + + /** + * Tests the setComponentRouter() method + * + * @return void + * + * @since 3.4 + */ + public function testInvalidRouterIsRejected() + { + $object = new JRouterSite( + array(), + $this->getMockCmsApp(), + TestMockMenu::create($this) + ); + + $this->assertFalse($object->setComponentRouter('com_test3', new stdClass)); } } diff --git a/tests/unit/suites/libraries/cms/router/JRouterTest.php b/tests/unit/suites/libraries/cms/router/JRouterTest.php index 03af5cdafcf7e..2c357d9a19e3d 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterTest.php @@ -7,17 +7,24 @@ * @license GNU General Public License version 2 or later; see LICENSE */ -require_once __DIR__ . '/stubs/JRouterInspector.php'; - /** * Test class for JRouter. * * @package Joomla.UnitTest * @subpackage Router + * @group Router * @since 3.1 */ class JRouterTest extends TestCase { + /** + * Backup of the $_SERVER variable + * + * @var array + * @since 4.0 + */ + private $server; + /** * Object under test * @@ -30,584 +37,503 @@ class JRouterTest extends TestCase * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. * - * @return void - * * @since 3.1 */ protected function setUp() { parent::setUp(); - JUri::reset(); + $this->server = $_SERVER; + + /* + * The following is needed to work around a bug in JApplicationWeb::detectRequestUri() + * @see https://github.com/joomla-projects/joomla-pythagoras/issues/2 + */ + if (!isset($_SERVER['HTTP_HOST'])) + { + $_SERVER['HTTP_HOST'] = ''; + } $this->object = new JRouter; } /** - * Tests the getInstance() method + * Overrides the parent tearDown method. * * @return void * - * @since 3.4 + * @see PHPUnit_Framework_TestCase::tearDown() + * @since 4.0 */ - public function testGetInstance() + protected function tearDown() { - // Check if a proper object is returned and that the mode is properly set - JRouterInspector::clearInstanceCache(); - $object = JRouter::getInstance('administrator', array('mode' => 'test', 'randomKey' => 'randomValue')); - $this->assertTrue(is_a($object, 'JRouterAdministrator')); - $this->assertEquals($object->getMode(), 'test'); - - // This test is commented, since the feature is not implemented (yet) - // $this->assertEquals($object->get('randomKey'), 'randomValue'); - - // Check if the same object is returned by getInstance() - $object2 = JRouter::getInstance('administrator'); - $this->assertSame($object, $object2); + $_SERVER = $this->server; - require_once JPATH_TESTS . '/suites/libraries/cms/application/stubs/JApplicationHelperInspector.php'; - $apps = JApplicationHelperInspector::get(); - $obj = new stdClass(); - $obj->id = 3; - $obj->name = 'tester'; - $obj->path = dirname(__FILE__).'/example'; - $apps[3] = $obj; - JApplicationHelperInspector::set($apps); - - // Test if legacy app routers are still loaded - $object3 = JRouter::getInstance('tester'); - $this->assertTrue(is_a($object, 'JRouter')); + parent::tearDown(); } /** - * Tests the getInstance() method throwing a proper exception - * - * @return void - * - * @since 3.4 - * @expectedException RuntimeException + * @return array + * @since 4.0 */ - public function testGetInstanceException() + public function casesClients() { - // Check if a proper exception is thrown if there is no router class - $object = JRouter::getInstance('exception'); + return array( + // 'site' => array('site'), + 'admin' => array('administrator'), + ); } /** - * Cases for testParse + * @dataProvider casesClients + * @testdox JRouter::getInstance() returns a router of the required type with correct mode + * @since 3.4 * - * @return array - * - * @since 3.4 + * @param $client */ - public function casesParse() + public function testProperTypeAndMode($client) { - $cases = array(); - $cases[] = array('', JROUTER_MODE_RAW, array(), array()); - $cases[] = array('index.php?var1=value1', JROUTER_MODE_RAW, array(), array()); - $cases[] = array('', JROUTER_MODE_RAW, array('var1' => 'value1'), array('var1' => 'value1')); + $cache = new ReflectionProperty('JRouter', 'instances'); + $cache->setAccessible(true); + $cache->setValue(array()); - $cases[] = array('', JROUTER_MODE_SEF, array(), array()); - $cases[] = array('index.php?var1=value1', JROUTER_MODE_SEF, array(), array()); - $cases[] = array('', JROUTER_MODE_SEF, array('var1' => 'value1'), array('var1' => 'value1')); + #$this->markTestSkipped('Untestable due to global instance cache not clearable.'); - return $cases; + $object = JRouter::getInstance($client, array('mode' => 'test')); + + $expected = 'JRouter' . ucfirst($client); + + $this->assertInstanceOf($expected, $object); + $this->assertEquals('test', $object->getMode()); } /** - * Tests the parse method - * - * @param array $uri An associative array with variables - * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF - * @param array $vars An associative array with global variables - * @param array $expected Expected value - * - * @return void + * @dataProvider casesClients + * @testdox Subsequent calls to getInstance() return the same instance + * @since 3.4 * - * @dataProvider casesParse - * @since 3.4 + * @param $client */ - public function testParse($url, $mode, $vars, $expected) + public function testSubsequentCallsReturnTheSameInstance($client) { - $this->object->setMode($mode); - $this->object->setVars($vars); - $uri = new JUri($url); + $object = JRouter::getInstance($client); - $this->assertEquals($this->object->parse($uri), $expected); + $this->assertSame($object, JRouter::getInstance($client)); } /** - * Tests the build() method - * - * @return void - * * @since 3.4 */ - public function testBuild() + public function testLegacyApplicationRouterIsStillLoaded() { - $uri = new JUri('index.php?var1=value1'); - $result = $this->object->build('index.php?var1=value1'); - $this->assertEquals($uri, $result); + JApplicationHelper::addClientInfo(array( + 'id' => 3, + 'name' => 'tester', + 'path' => __DIR__ . '/data' + )); - $this->assertEquals($uri, $this->object->build('index.php?var1=value1')); - - $object = new JRouter; - $object->setMode(JROUTER_MODE_SEF); - $result = $object->build('index.php?var1=value1'); - $this->assertEquals($uri, $result); + $this->assertInstanceOf('JRouter', JRouter::getInstance('tester')); } /** - * Tests the getMode() method - * - * @return void - * * @since 3.4 + * @expectedException RuntimeException + * @testdox getInstance() throws a RuntimeException, if a router for an unknown client is requested */ - public function testGetMode() + public function testGetInstanceException() { - $this->assertEquals($this->object->getMode(), JROUTER_MODE_RAW); - - $this->object->setMode(JROUTER_MODE_SEF); - $this->assertEquals($this->object->getMode(), JROUTER_MODE_SEF); + JRouter::getInstance('unknown'); } /** - * Tests the setMode() method - * - * @return void - * * @since 3.4 */ - public function testSetMode() + public function casesParse() { - $this->object->setMode(JROUTER_MODE_SEF); - $this->assertEquals($this->object->getMode(), JROUTER_MODE_SEF); - - $this->object->setMode(42); - $this->assertEquals($this->object->getMode(), 42); + return array( + 'raw-no_url-no_var' => array('', JROUTER_MODE_RAW, array(), array()), + 'raw-url-no_var' => array('index.php?var1=value1', JROUTER_MODE_RAW, array(), array()), + 'raw-no_url-var' => array('', JROUTER_MODE_RAW, array('var2' => 'value2'), array('var2' => 'value2')), + 'raw-url-var' => array( + 'index.php?var1=value1', + JROUTER_MODE_RAW, + array('var2' => 'value2'), + array('var2' => 'value2') + ), + 'sef-no_url-no_var' => array('', JROUTER_MODE_SEF, array(), array()), + 'sef-url-no_var' => array('index.php?var1=value1', JROUTER_MODE_SEF, array(), array()), + 'sef-no_url-var' => array('', JROUTER_MODE_SEF, array('var2' => 'value2'), array('var2' => 'value2')), + 'sef-url-var' => array( + 'index.php?var1=value1', + JROUTER_MODE_RAW, + array('var2' => 'value2'), + array('var2' => 'value2') + ), + ); } /** - * Cases for testSetVar - * - * @return array + * @param string $url A URL + * @param integer $mode JROUTER_MODE_RAW or JROUTER_MODE_SEF + * @param array $vars An associative array with global variables + * @param array $expected Expected value * - * @since 3.1 + * @dataProvider casesParse + * @testdox parse() does not evaluate URL parameters + * @since 3.4 */ - public function casesSetVar() + public function testRouterDoesNotEvaluateUrlParameters($url, $mode, $vars, $expected) { - $cases = array(); - $cases[] = array(array(), 'myvar', 'myvalue', true, 'myvalue'); - $cases[] = array(array(), 'myvar', 'myvalue', false, null); - $cases[] = array(array('myvar' => 'myvalue1'), 'myvar', 'myvalue2', true, 'myvalue2'); - $cases[] = array(array('myvar' => 'myvalue1'), 'myvar', 'myvalue2', false, 'myvalue2'); + $this->object->setMode($mode); + $this->object->setVars($vars); + $uri = new JUri($url); - return $cases; + $this->assertEquals($this->object->parse($uri), $expected); } /** - * Tests the setVar method - * - * @param array $vars An associative array with variables - * @param string $var The name of the variable - * @param mixed $value The value of the variable - * @param boolean $create If True, the variable will be created if it doesn't exist yet - * @param string $expected Expected return value - * - * @return void - * - * @dataProvider casesSetVar - * @since 3.1 + * @return array */ - public function testSetVar($vars, $var, $value, $create, $expected) + public function casesModes() { - $this->object->setVars($vars, false); - $this->object->setVar($var, $value, $create); - $this->assertEquals($this->object->getVar($var), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); + return array( + 'default' => array(null), + 'raw' => array(JROUTER_MODE_RAW), + 'sef' => array(JROUTER_MODE_SEF) + ); } /** - * Tests the setVars() method - * - * @return void + * @dataProvider casesModes + * @testdox build() gives the same result as the JUri constructor + * @since 3.4 * - * @since 3.4 + * @param $mode */ - public function testSetVars() + public function testBuildGivesTheSameResultAsTheJuriConstructor($mode) { - $this->assertEquals($this->object->getVars(), array()); - $this->object->setVars(array('var1' => 'value1')); - $this->assertEquals($this->object->getVars(), array('var1' => 'value1')); - - $this->object->setVars(array('var2' => 'value2')); - $this->assertEquals($this->object->getVars(), array('var1' => 'value1', 'var2' => 'value2')); - - $this->object->setVars(array('var3' => 'value3'), false); - $this->assertEquals($this->object->getVars(), array('var3' => 'value3')); - - $this->object->setVars(array(), false); - $this->assertEquals($this->object->getVars(), array()); + $uri = new JUri('index.php?var1=value1'); + $object = new JRouter; + if (!empty($mode)) + { + $object->setMode($mode); + } + $result = $this->object->build('index.php?var1=value1'); + $this->assertEquals($uri, $result); } /** - * Cases for testGetVar - * - * @return array - * + * @testdox Default mode is handling raw URLs * @since 3.4 */ - public function casesGetVar() + public function testDefaultModeIsHandlingRawUrls() { - $cases = array(); - $cases[] = array(array(), 'myvar', 'myvalue', true, 'myvalue'); - $cases[] = array(array(), 'myvar', 'myvalue', false, null); - $cases[] = array(array('myvar' => 'myvalue1'), 'myvar', 'myvalue2', true, 'myvalue2'); - $cases[] = array(array('myvar' => 'myvalue1'), 'myvar', 'myvalue2', false, 'myvalue2'); + $this->assertEquals(JROUTER_MODE_RAW, $this->object->getMode()); + } - return $cases; + /** + * @since 3.4 + */ + public function testModeCanBeChangedAfterInstantiation() + { + $this->object->setMode(JROUTER_MODE_SEF); + $this->assertEquals(JROUTER_MODE_SEF, $this->object->getMode()); } /** - * Tests the getVar method - * - * @param array $vars An associative array with variables - * @param string $var The name of the variable - * @param mixed $value The value of the variable - * @param boolean $create If True, the variable will be created if it doesn't exist yet - * @param string $expected Expected return value - * - * @return void - * - * @dataProvider casesGetVar - * @since 3.4 + * @since 3.4 */ - public function testGetVar($vars, $var, $value, $create, $expected) + public function testModeCanBeSetToAnyArbitraryValue() { - $this->object->setVars($vars, false); - $this->object->setVar($var, $value, $create); - $this->assertEquals($this->object->getVar($var), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); + $this->object->setMode(42); + $this->assertEquals(42, $this->object->getMode()); } /** - * Tests the getVars() method - * - * @return void - * - * @since 3.4 + * @see https://github.com/joomla-projects/joomla-pythagoras/issues/3 + * @since 3.4 */ - public function testGetVars() + public function testMultipleVariablesCanBeAddedAtOnceAndOptionallyReplaceExistingVariables() { - $this->assertEquals($this->object->getVars(), array()); + $this->assertEquals(array(), $this->object->getVars()); + $this->object->setVars(array('var1' => 'value1')); - $this->assertEquals($this->object->getVars(), array('var1' => 'value1')); + $this->assertEquals(array('var1' => 'value1'), $this->object->getVars()); $this->object->setVars(array('var2' => 'value2')); - $this->assertEquals($this->object->getVars(), array('var1' => 'value1', 'var2' => 'value2')); + $this->assertEquals(array('var1' => 'value1', 'var2' => 'value2'), $this->object->getVars()); $this->object->setVars(array('var3' => 'value3'), false); - $this->assertEquals($this->object->getVars(), array('var3' => 'value3')); + $this->assertEquals(array('var3' => 'value3'), $this->object->getVars()); $this->object->setVars(array(), false); - $this->assertEquals($this->object->getVars(), array()); + $this->assertEquals(array(), $this->object->getVars()); } /** - * Cases for testAttachBuildRule - * - * @return array + * Cases for testSetVar * - * @since 3.4 + * @since 3.1 */ - public function casesAttachBuildRule() + public function casesVariables() { - $cases = array(); - $cases[] = array(array(), JRouter::PROCESS_DURING, - array( - 'buildpreprocess' => array(), - 'build' => array(), - 'buildpostprocess' => array(), - 'parsepreprocess' => array(), - 'parse' => array(), - 'parsepostprocess' => array() - ) - ); - $callbacks = array(function (&$router, &$uri) {}); - $cases[] = array($callbacks, JRouter::PROCESS_DURING, - array( - 'buildpreprocess' => array(), - 'build' => $callbacks, - 'buildpostprocess' => array(), - 'parsepreprocess' => array(), - 'parse' => array(), - 'parsepostprocess' => array() - ) - ); - $cases[] = array($callbacks, JRouter::PROCESS_BEFORE, - array( - 'buildpreprocess' => $callbacks, - 'build' => array(), - 'buildpostprocess' => array(), - 'parsepreprocess' => array(), - 'parse' => array(), - 'parsepostprocess' => array() - ) - ); - $cases[] = array($callbacks, JRouter::PROCESS_AFTER, - array( - 'buildpreprocess' => array(), - 'build' => array(), - 'buildpostprocess' => $callbacks, - 'parsepreprocess' => array(), - 'parse' => array(), - 'parsepostprocess' => array() - ) + $cases = array( + array(array(), 'var', 'value', true, 'value'), + array(array(), 'var', 'value', false, null), + array(array('var' => 'value1'), 'var', 'value2', true, 'value2'), + array(array('var' => 'value1'), 'var', 'value2', false, 'value2'), ); return $cases; } /** - * Tests the attachBuildRule method - * - * @param callback $callbacks Callbacks to be attached - * @param string $stage Stage to process - * @param array $expected The expected internal rules array - * - * @return void + * @param array $preset An associative array with variables + * @param string $var The name of the variable + * @param mixed $value The value of the variable + * @param boolean $create If True, the variable will be created if it doesn't exist yet + * @param string $expected Expected return value * - * @dataProvider casesAttachBuildRule - * @since 3.4 + * @dataProvider casesVariables + * @since 3.1 */ - public function testAttachBuildRule($callbacks, $stage, $expected) + public function testSingleVariablesCanBeAddedAndOptionallyReplaceExistingVariables($preset, $var, $value, $create, $expected) { - $object = new JRouterInspector; + $this->object->setVars($preset, false); - foreach ($callbacks as $callback) - { - $object->attachBuildRule($callback, $stage); - } - - $this->assertEquals($object->getRules(), $expected); + $this->object->setVar($var, $value, $create); + $this->assertEquals($expected, $this->object->getVar($var)); } /** - * Tests the attachBuildRule() method throwing a proper exception - * - * @return void - * * @since 3.4 + * @testdox Router throws an InvalidArgumentException when attaching a build rule to an undefined stage * @expectedException InvalidArgumentException */ - public function testAttachBuildRuleException() + public function testRouterThrowsInvalidArgumentExceptionWhenAttachingBuildRuleToUndefinedStage() { - $callback = array(function (&$router, &$uri) {}); - $this->object->attachBuildRule($callback, 'wrongStage'); + $callback = array( + function (JRouter $router, JUri $uri) + { + } + ); + $this->object->attachBuildRule($callback, 'undefined'); } /** - * Cases for testAttachParseRule - * - * @return array - * * @since 3.4 + * @testdox Router throws an InvalidArgumentException when attaching a parse rule to an undefined stage + * @expectedException InvalidArgumentException */ - public function casesAttachParseRule() + public function testRouterThrowsInvalidArgumentExceptionWhenAttachingParseRuleToUndefinedStage() { - $cases = array(); - $cases[] = array(array(), JRouter::PROCESS_DURING, - array( - 'buildpreprocess' => array(), - 'build' => array(), - 'buildpostprocess' => array(), - 'parsepreprocess' => array(), - 'parse' => array(), - 'parsepostprocess' => array() - ) - ); - $callbacks = array(function (&$router, &$uri) {}); - $cases[] = array($callbacks, JRouter::PROCESS_DURING, - array( - 'buildpreprocess' => array(), - 'build' => array(), - 'buildpostprocess' => array(), - 'parsepreprocess' => array(), - 'parse' => $callbacks, - 'parsepostprocess' => array() - ) + $callback = array( + function (JRouter $router, JUri $uri) + { + } ); - $cases[] = array($callbacks, JRouter::PROCESS_BEFORE, - array( - 'buildpreprocess' => array(), - 'build' => array(), - 'buildpostprocess' => array(), - 'parsepreprocess' => $callbacks, - 'parse' => array(), - 'parsepostprocess' => array() - ) - ); - $cases[] = array($callbacks, JRouter::PROCESS_AFTER, - array( - 'buildpreprocess' => array(), - 'build' => array(), - 'buildpostprocess' => array(), - 'parsepreprocess' => array(), - 'parse' => array(), - 'parsepostprocess' => $callbacks - ) + $this->object->attachParseRule($callback, 'undefined'); + } + + /** + * @return array + */ + public function casesParseRulesForReplace() + { + return array( + 'before' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var1' => 'before'); + } + ), + 'stage' => JRouter::PROCESS_BEFORE, + 'expected' => array('var1' => 'before', 'var2' => 'value2') + ), + 'during' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var1' => 'during'); + } + ), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => array('var1' => 'during', 'var2' => 'value2') + ), + 'after' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var1' => 'after'); + } + ), + 'stage' => JRouter::PROCESS_AFTER, + 'expected' => array('var1' => 'after', 'var2' => 'value2') + ), ); - - return $cases; } /** - * Tests the attachParseRule method - * - * @param callback $callbacks Callbacks to be attached - * @param string $stage Stage to process - * @param array $expected The expected internal rules array + * @param array $preset Initial router variables + * @param array $rules Callback to execute + * @param string $stage Stage to process + * @param string $expected Expected return value * - * @return void - * - * @dataProvider casesAttachParseRule + * @dataProvider casesParseRulesForReplace * @since 3.4 */ - public function testAttachParseRule($callbacks, $stage, $expected) + public function testParseRulesCanReplacePresetVariables($preset, $rules, $stage, $expected) { - $object = new JRouterInspector; - - foreach ($callbacks as $callback) + $this->object->setVars($preset, false); + foreach ($rules as $rule) { - $object->attachParseRule($callback, $stage); + $this->object->attachParseRule($rule, $stage); } - $this->assertEquals($object->getRules(), $expected); + $uri = $this->getMock('JUri'); + $this->assertEquals($expected, $this->object->parse($uri)); + } + + /** + * @return array + */ + public function casesParseRulesForAdd() + { + return array( + 'before' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var3' => 'value3'); + }, + ), + 'stage' => JRouter::PROCESS_BEFORE, + 'expected' => array('var1' => 'value1', 'var2' => 'value2', 'var3' => 'value3') + ), + 'during' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var3' => 'value3'); + }, + ), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => array('var1' => 'value1', 'var2' => 'value2', 'var3' => 'value3') + ), + 'after' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var3' => 'value3'); + }, + ), + 'stage' => JRouter::PROCESS_AFTER, + 'expected' => array('var1' => 'value1', 'var2' => 'value2', 'var3' => 'value3') + ), + ); } /** - * Tests the attachParseRule() method throwing a proper exception - * - * @return void + * @param array $preset Initial router variables + * @param array $rules Callback to execute + * @param string $stage Stage to process + * @param string $expected Expected return value * - * @since 3.4 - * @expectedException InvalidArgumentException + * @dataProvider casesParseRulesForAdd + * @since 3.4 */ - public function testAttachParseRuleException() + public function testParseRulesCanAddVariables($preset, $rules, $stage, $expected) { - $callback = array(function (&$router, &$uri) {}); - $this->object->attachParseRule($callback, 'wrongStage'); - } + $this->object->setVars($preset, false); + foreach ($rules as $rule) + { + $this->object->attachParseRule($rule, $stage); + } - /** - * Cases for testProcessParseRules - * - * @return array - * - * @since 3.1 - */ - public function casesProcessParseRules() - { - $cases = array(); - $cases[] = array(array(), JRouter::PROCESS_DURING, array()); - $cases[] = array( - array( - function (&$router, &$uri) - { - return array('myvar' => 'myvalue'); - } - ), JRouter::PROCESS_DURING, - array('myvar' => 'myvalue') - ); - $cases[] = array( - array( - function (&$router, &$uri) - { - return array('myvar1' => 'myvalue1'); - }, - function (&$router, &$uri) - { - return array('myvar2' => 'myvalue2'); - }, - ), JRouter::PROCESS_DURING, - array('myvar1' => 'myvalue1', 'myvar2' => 'myvalue2') - ); - $cases[] = array( - array( - function (&$router, &$uri) - { - return array('myvar1' => 'myvalue1'); - }, - function (&$router, &$uri) - { - return array('myvar2' => 'myvalue2'); - }, - function (&$router, &$uri) - { - return array('myvar1' => 'myvalue3'); - }, - ), JRouter::PROCESS_DURING, - array('myvar1' => 'myvalue1', 'myvar2' => 'myvalue2') + $uri = $this->getMock('JUri'); + $this->assertEquals($expected, $this->object->parse($uri)); + } + + /** + * @return array + */ + public function casesParseRulesForPrecedence() + { + return array( + 'before-same_var' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var1' => 'before1'); + }, + function (JRouter $router, JUri $uri) + { + return array('var1' => 'before2'); + }, + ), + 'stage' => JRouter::PROCESS_BEFORE, + 'expected' => array('var1' => 'before1', 'var2' => 'value2') + ), + 'during-same_var' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var1' => 'during1'); + }, + function (JRouter $router, JUri $uri) + { + return array('var1' => 'during2'); + }, + ), + 'stage' => JRouter::PROCESS_BEFORE, + 'expected' => array('var1' => 'during1', 'var2' => 'value2') + ), + 'after-same_var' => array( + 'preset' => array('var1' => 'value1', 'var2' => 'value2'), + 'rules' => array( + function (JRouter $router, JUri $uri) + { + return array('var1' => 'after1'); + }, + function (JRouter $router, JUri $uri) + { + return array('var1' => 'after2'); + }, + ), + 'stage' => JRouter::PROCESS_BEFORE, + 'expected' => array('var1' => 'after1', 'var2' => 'value2') + ), ); - $cases[] = array( - array( - function (&$router, &$uri) - { - return array('stage' => 'before'); - } - ), JRouter::PROCESS_BEFORE, - array('stage' => 'before') - ); - $cases[] = array( - array( - function (&$router, &$uri) - { - return array('stage' => 'after'); - } - ), JRouter::PROCESS_AFTER, - array('stage' => 'after') - ); - - return $cases; } /** - * testProcessParseRules(). + * @param array $preset Initial router variables + * @param array $rules Callback to execute + * @param string $stage Stage to process + * @param string $expected Expected return value * - * @param array $functions Callback to execute - * @param string $stage Stage to process - * @param string $expected Expected return value - * - * @return void - * - * @dataProvider casesProcessParseRules + * @dataProvider casesParseRulesForPrecedence * @since 3.4 */ - public function testProcessParseRules($functions, $stage, $expected) + public function testFirstParseRuleTakesPrecedence($preset, $rules, $stage, $expected) { - $myuri = 'http://localhost'; - $stub = $this->getMock('JRouter', array('parseRawRoute')); - $stub->expects($this->any())->method('parseRawRoute')->will($this->returnValue(array())); - - foreach ($functions as $function) + $this->object->setVars($preset, false); + foreach ($rules as $rule) { - $stub->attachParseRule($function, $stage); + $this->object->attachParseRule($rule, $stage); } - $this->assertEquals($stub->parse($myuri), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); - } - - /** - * Tests the attachParseRule() method throwing a proper exception - * - * @return void - * - * @since 3.4 - * @expectedException InvalidArgumentException - */ - public function testProcessParseRulesException() - { - $object = new JRouterInspector; - $object->runProcessParseRules(new JUri, 'wrongStage'); + $uri = $this->getMock('JUri'); + $this->assertEquals($expected, $this->object->parse($uri)); } /** @@ -619,118 +545,188 @@ public function testProcessParseRulesException() */ public function casesProcessBuildRules() { - $cases = array(); - $cases[] = array(array(), JRouter::PROCESS_DURING, 'index.php?var1=value1&var2=value2'); - $cases[] = array( + return array( array( - function (&$router, &$uri) - { - $uri->setPath('value1'); - } - ), JRouter::PROCESS_DURING, - 'value1?var1=value1&var2=value2' - ); - $cases[] = array( + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array(), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => 'index.php?var1=value1&var2=value2' + ), array( - function (&$router, &$uri) - { - $uri->setPath('value1'); - }, - function (&$router, &$uri) - { - $uri->delVar('var1'); - }, - ), JRouter::PROCESS_DURING, - 'value1?var2=value2' - ); - $cases[] = array( + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array( + function (JRouter $router, JUri $uri) + { + $uri->setPath('value1'); + } + ), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => 'value1?var1=value1&var2=value2' + ), array( - function (&$router, &$uri) - { - $uri->setPath('value1/value2'); - }, - function (&$router, &$uri) - { - $uri->delVar('var1'); - }, - function (&$router, &$uri) - { - $uri->delVar('var2'); - }, - ), JRouter::PROCESS_DURING, - 'value1/value2' - ); - $cases[] = array( + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array( + function (JRouter $router, JUri $uri) + { + $uri->setPath('value1'); + }, + function (JRouter $router, JUri $uri) + { + $uri->delVar('var1'); + }, + ), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => 'value1?var2=value2' + ), array( - function (&$router, &$uri) - { - $uri->setVar('stage', 'during'); - } - ), JRouter::PROCESS_DURING, - 'index.php?var1=value1&var2=value2&stage=during' - ); - $cases[] = array( + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array( + function (JRouter $router, JUri $uri) + { + $uri->setPath('value1/value2'); + }, + function (JRouter $router, JUri $uri) + { + $uri->delVar('var1'); + }, + function (JRouter $router, JUri $uri) + { + $uri->delVar('var2'); + }, + ), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => 'value1/value2' + ), array( - function (&$router, &$uri) - { - $uri->setVar('stage', 'before'); - } - ), JRouter::PROCESS_BEFORE, - 'index.php?var1=value1&var2=value2&stage=before' - ); - $cases[] = array( + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array( + function (JRouter $router, JUri $uri) + { + $uri->setVar('stage', 'during'); + } + ), + 'stage' => JRouter::PROCESS_DURING, + 'expected' => 'index.php?var1=value1&var2=value2&stage=during' + ), + array( + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array( + function (JRouter $router, JUri $uri) + { + $uri->setVar('stage', 'before'); + } + ), + 'stage' => JRouter::PROCESS_BEFORE, + 'expected' => 'index.php?var1=value1&var2=value2&stage=before' + ), array( - function (&$router, &$uri) - { - $uri->setVar('stage', 'after'); - } - ), JRouter::PROCESS_AFTER, - 'index.php?var1=value1&var2=value2&stage=after' + 'url' => 'index.php?var1=value1&var2=value2', + 'rules' => array( + function (JRouter $router, JUri $uri) + { + $uri->setVar('stage', 'after'); + } + ), + 'stage' => JRouter::PROCESS_AFTER, + 'expected' => 'index.php?var1=value1&var2=value2&stage=after' + ), ); - - return $cases; } /** - * testProcessBuildRules(). - * - * @param array $functions Callback to execute - * @param string $stage Stage to process - * @param string $expected Expected return value + * @param string $url The URL + * @param array $functions Callback to execute + * @param string $stage Stage to process + * @param string $expected Expected return value * * @dataProvider casesProcessBuildRules * - * @return void - * - * @since 3.4 + * @testdox Processing the build rules gives the right URIs + * @since 3.4 */ - public function testProcessBuildRules($functions, $stage, $expected) + public function testProcessingTheBuildRulesGivesTheRightUris($url, $functions, $stage, $expected) { - $myuri = 'index.php?var1=value1&var2=value2'; - $stub = $this->getMock('JRouter', array('buildRawRoute')); - $stub->expects($this->any())->method('buildRawRoute')->will($this->returnValue(array())); - foreach ($functions as $function) { - $stub->attachBuildRule($function); + $this->object->attachBuildRule($function, $stage); } - $juri = $stub->build($myuri); - $this->assertEquals($juri->toString(), $expected, __METHOD__ . ':' . __LINE__ . ': value is not expected'); + $this->assertEquals($expected, (string)$this->object->build($url)); } /** - * Tests the attachBuildRules() method throwing a proper exception - * - * @return void + * @return array * * @since 3.4 - * @expectedException InvalidArgumentException */ - public function testProcessBuildRulesException() + public function casesProcessBuildRulesOrder() { - $object = new JRouterInspector; - $object->runProcessBuildRules(new JUri, 'wrongStage'); + return array( + array( + 'url' => 'index.php', + 'expected' => 'index.php?var1=after&var3=before&var4=during&var5=after' + ), + array( + 'url' => 'index.php?var1=value1', + 'expected' => 'index.php?var1=after&var3=before&var4=during&var5=after' + ), + array( + 'url' => 'index.php?var2=value2', + 'expected' => 'index.php?var2=value2&var1=after&var3=before&var4=during&var5=after' + ), + array( + 'url' => 'index.php?var3=value3', + 'expected' => 'index.php?var3=before&var1=after&var4=during&var5=after' + ), + array( + 'url' => 'index.php?var4=value4', + 'expected' => 'index.php?var4=during&var1=after&var3=before&var5=after' + ), + array( + 'url' => 'index.php?var5=value5', + 'expected' => 'index.php?var5=after&var1=after&var3=before&var4=during' + ), + ); + } + + /** + * @param string $url The URL + * @param string $expected Expected return value + * + * @dataProvider casesProcessBuildRulesOrder + * + * @since 4.0 + */ + public function testStagesAreProcessedInCorrectOrder($url, $expected) + { + $this->object->attachBuildRule( + function (JRouter $router, JUri $uri) + { + $uri->setVar('var1', 'before'); + $uri->setVar('var3', 'before'); + $uri->setVar('var4', 'before'); + }, + JRouter::PROCESS_BEFORE + ); + $this->object->attachBuildRule( + function (JRouter $router, JUri $uri) + { + $uri->setVar('var1', 'during'); + $uri->setVar('var4', 'during'); + $uri->setVar('var5', 'during'); + }, + JRouter::PROCESS_DURING + ); + $this->object->attachBuildRule( + function (JRouter $router, JUri $uri) + { + $uri->setVar('var1', 'after'); + $uri->setVar('var5', 'after'); + }, + JRouter::PROCESS_AFTER + ); + + $this->assertEquals($expected, (string)$this->object->build($url)); } /** @@ -740,120 +736,137 @@ public function testProcessBuildRulesException() * * @since 3.4 */ - public function casesCreateURI() + public function casesCreateUri() { - $cases = array(); - - $cases[] = array('', array(), ''); - $cases[] = array('index.php', array(), 'index.php'); - - $cases[] = array(array('var1' => 'value1', 'var2' => 'value2'), array(), 'index.php?var1=value1&var2=value2'); - $cases[] = array(array('var1' => 'value1', 'var2' => 'value2'), array('var3' => 'value3'), 'index.php?var3=value3&var1=value1&var2=value2'); - $cases[] = array(array('var1' => 'value1', 'var2' => 'value2'), array('var2' => 'value3'), 'index.php?var2=value2&var1=value1'); - - $cases[] = array('&var1=value1&var2=value2', array(), 'index.php?var1=value1&var2=value2'); - $cases[] = array('&var1=value1&var2=value2', array('var3' => 'value3'), 'index.php?var3=value3&var1=value1&var2=value2'); - $cases[] = array('&var1=value1&var2=value2', array('var2' => 'value3'), 'index.php?var2=value2&var1=value1'); - - $cases[] = array('&var1=value1&var2=', array(), 'index.php?var1=value1'); - - $cases[] = array('&var1=value1&var2=value2', array(), 'index.php?var1=value1&var2=value2'); - - return $cases; + return array( + array( + 'url' => '', + 'preset' => array(), + 'expected' => '' + ), + array( + 'url' => 'index.php', + 'preset' => array(), + 'expected' => 'index.php' + ), + array( + 'url' => array('var1' => 'value1', 'var2' => 'value2'), + 'preset' => array(), + 'expected' => 'index.php?var1=value1&var2=value2' + ), + array( + 'url' => array('var1' => 'value1', 'var2' => 'value2'), + 'preset' => array('var3' => 'value3'), + 'expected' => 'index.php?var3=value3&var1=value1&var2=value2' + ), + array( + 'url' => array('var1' => 'value1', 'var2' => 'value2'), + 'preset' => array('var2' => 'value3'), + 'expected' => 'index.php?var2=value2&var1=value1' + ), + array( + 'url' => '&var1=value1&var2=value2', + 'preset' => array(), + 'expected' => 'index.php?var1=value1&var2=value2' + ), + array( + 'url' => '&var1=value1&var2=value2', + 'preset' => array('var3' => 'value3'), + 'expected' => 'index.php?var3=value3&var1=value1&var2=value2' + ), + array( + 'url' => '&var1=value1&var2=value2', + 'preset' => array('var2' => 'value3'), + 'expected' => 'index.php?var2=value2&var1=value1' + ), + array( + 'url' => '&var1=value1&var2=', + 'preset' => array(), + 'expected' => 'index.php?var1=value1' + ), + array( + 'url' => '&var1=value1&var2=value2', + 'preset' => array(), + 'expected' => 'index.php?var1=value1&var2=value2' + ), + ); } /** * Tests createURI() method * - * @param array $url valid inputs to the createURI() method - * @param array $globalVars global Vars that should be merged into the URL - * @param string $expected expected URI string - * - * @dataProvider casesCreateURI - * - * @return void + * @param array $url valid inputs to the createURI() method + * @param array $preset global Vars that should be merged into the URL + * @param string $expected expected URI string * - * @since 3.4 + * @dataProvider casesCreateUri + * @testdox createUri() generates URI combining URL and preset variables + * @since 3.4 */ - public function testCreateURI($url, $globalVars, $expected) + public function testCreateUriGeneratesUriFromUrlAndPreset($url, $preset, $expected) { - $object = new JRouterInspector; - $object->setVars($globalVars, false); - $juri = $object->runCreateURI($url); + $this->object->setVars($preset, false); - $this->assertTrue(is_a($juri, 'JUri')); - $this->assertEquals($expected, $juri->toString()); + $createUriMethod = new ReflectionMethod('JRouter', 'createUri'); + $createUriMethod->setAccessible(true); + $this->assertEquals($expected, (string)($createUriMethod->invoke($this->object, $url))); } /** - * Cases for testEncodeSegments - * - * @return array - * * @since 3.4 */ public function casesEncodeSegments() { - $cases = array(); - $cases[] = array(array('test'), array('test')); - $cases[] = array(array('1:test'), array('1-test')); - $cases[] = array(array('test', '1:test'), array('test', '1-test')); - $cases[] = array(array('42:test', 'testing:this:method'), array('42-test', 'testing-this-method')); - - return $cases; + return array( + array(array('test'), array('test')), + array(array('1:test'), array('1-test')), + array(array('test', '1:test'), array('test', '1-test')), + array(array('42:test', 'testing:this:method'), array('42-test', 'testing-this-method')), + ); } /** * Tests encodeSegments() method * - * @param array $segments Array of unencoded segments of a URL - * @param string $expected Array of encoded segments of a URL + * @param array $segments Array of decoded segments of a URL + * @param string $expected Array of encoded segments of a URL * * @dataProvider casesEncodeSegments - * - * @return void - * - * @since 3.4 + * @since 3.4 */ public function testEncodeSegments($segments, $expected) { - $object = new JRouterInspector; - $this->assertEquals($object->runEncodeSegments($segments), $expected); + $encodeSegmentsMethod = new ReflectionMethod('JRouter', 'encodeSegments'); + $encodeSegmentsMethod->setAccessible(true); + $this->assertEquals($expected, $encodeSegmentsMethod->invoke($this->object, $segments)); } /** - * Cases for testDecodeSegments - * - * @return array - * * @since 3.4 */ public function casesDecodeSegments() { - $cases = array(); - $cases[] = array(array('test'), array('test')); - $cases[] = array(array('1-test'), array('1:test')); - $cases[] = array(array('test', '1-test'), array('test', '1:test')); - $cases[] = array(array('42-test', 'testing-this-method'), array('42:test', 'testing:this-method')); - - return $cases; + return array( + array(array('test'), array('test')), + array(array('1-test'), array('1:test')), + array(array('test', '1-test'), array('test', '1:test')), + array(array('42-test', 'testing-this-method'), array('42:test', 'testing:this-method')), + ); } /** * Tests decodeSegments() method * - * @param array $segments Array of encoded segments of a URL - * @param string $expected Array of decoded segments of a URL + * @param string $encoded Array of encoded segments of a URL + * @param array $expected Array of decoded segments of a URL * * @dataProvider casesDecodeSegments - * - * @return void - * - * @since 3.4 + * @since 3.4 */ - public function testDecodeSegments($segments, $expected) + public function testDecodeSegments($encoded, $expected) { - $object = new JRouterInspector; - $this->assertEquals($object->runDecodeSegments($segments), $expected); + $decodeSegmentsMethod = new ReflectionMethod('JRouter', 'decodeSegments'); + $decodeSegmentsMethod->setAccessible(true); + $this->assertEquals($expected, $decodeSegmentsMethod->invoke($this->object, $encoded)); } } diff --git a/tests/unit/suites/libraries/cms/router/data/TestRouter.php b/tests/unit/suites/libraries/cms/router/data/TestRouter.php new file mode 100644 index 0000000000000..868fbd592c118 --- /dev/null +++ b/tests/unit/suites/libraries/cms/router/data/TestRouter.php @@ -0,0 +1,66 @@ + 'testvalue'); + } + + public function build(&$query) + { + return array('router-test', 'another-segment'); + } +} + +class Test3Router implements JComponentRouterInterface +{ + public function preprocess($query) + { + return $query; + } + + public function parse(&$segments) + { + return array(); + } + + public function build(&$query) + { + unset($query['Itemid']); + + return array(); + } +} diff --git a/tests/unit/suites/libraries/cms/router/example/includes/router.php b/tests/unit/suites/libraries/cms/router/data/includes/router.php similarity index 92% rename from tests/unit/suites/libraries/cms/router/example/includes/router.php rename to tests/unit/suites/libraries/cms/router/data/includes/router.php index c3f16754b8750..8f2fa39208383 100644 --- a/tests/unit/suites/libraries/cms/router/example/includes/router.php +++ b/tests/unit/suites/libraries/cms/router/data/includes/router.php @@ -21,11 +21,11 @@ class JRouterTester extends JRouter /** * Class constructor * - * @param array $options Array of options + * @param array $options Array of options * * @since 3.4 */ public function __construct($options = array()) { } -} \ No newline at end of file +} diff --git a/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php b/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php deleted file mode 100644 index a5ed27acb786b..0000000000000 --- a/tests/unit/suites/libraries/cms/router/stubs/JRouterInspector.php +++ /dev/null @@ -1,117 +0,0 @@ -createURI($url); - } - - /** - * Runs the protected encodeSegments() method - * - * @param array $segments array of URL segments - * - * @return mixed Array of encoded segments - * - * @since 3.4 - */ - public function runEncodeSegments($segments) - { - return $this->encodeSegments($segments); - } - - /** - * Runs the protected decodeSegments() method - * - * @param array $segments array of URL segments - * - * @return mixed Array of decoded segments - * - * @since 3.4 - */ - public function runDecodeSegments($segments) - { - return $this->decodeSegments($segments); - } - - /** - * Returns the rules-array - * - * @return array Array of rules - * - * @since 3.4 - */ - public function getRules() - { - return $this->_rules; - } - - /** - * Clear instance of JRouter - * - * @return void - * - * @since 3.4 - */ - public static function clearInstanceCache() - { - foreach (self::$instances as $key => $value) - { - unset(self::$instances[$key]); - } - } - - /** - * Runs the protected processParseRules() method - * - * @param JUri &$uri The URI to parse - * @param string $stage The stage that should be processed. - * - * @return mixed Array of decoded segments - * - * @since 3.4 - */ - public function runProcessParseRules(&$uri, $stage = self::PROCESS_DURING) - { - return $this->processParseRules($uri, $stage); - } - - /** - * Runs the protected processBuildRules() method - * - * @param JUri &$uri The URI to parse - * @param string $stage The stage that should be processed. - * - * @return mixed Array of decoded segments - * - * @since 3.4 - */ - public function runProcessBuildRules(&$uri, $stage = self::PROCESS_DURING) - { - return $this->processBuildRules($uri, $stage); - } -} diff --git a/tests/unit/suites/libraries/cms/router/stubs/JRouterSiteInspector.php b/tests/unit/suites/libraries/cms/router/stubs/JRouterSiteInspector.php deleted file mode 100644 index cef2b62d13d2c..0000000000000 --- a/tests/unit/suites/libraries/cms/router/stubs/JRouterSiteInspector.php +++ /dev/null @@ -1,194 +0,0 @@ -app; - } - - public function setApp($app) - { - $this->app = $app; - } - - public function getMenu() - { - return $this->menu; - } - - public function setMenu($menu) - { - $this->menu = $menu; - } - - /** - * Runs the protected parseRawRoute() method - * - * @param JUri $uri JUri object of the URL - * - * @return array Array of URL vars - * - * @since 3.4 - */ - public function runParseRawRoute(&$uri) - { - return $this->parseRawRoute($uri); - } - - /** - * Runs the protected parseSefRoute() method - * - * @param JUri $uri JUri object of the URL - * - * @return array Array of URL vars - * - * @since 3.4 - */ - public function runParseSefRoute(&$uri) - { - return $this->parseSefRoute($uri); - } - - /** - * Runs the protected buildRawRoute() method - * - * @param JUri $uri JUri object of the URL - * - * @return array Array of URL vars - * - * @since 3.4 - */ - public function runBuildRawRoute(&$uri) - { - return $this->buildRawRoute($uri); - } - - /** - * Runs the protected buildSefRoute() method - * - * @param JUri $uri JUri object of the URL - * - * @return array Array of URL vars - * - * @since 3.4 - */ - public function runBuildSefRoute(&$uri) - { - return $this->buildSefRoute($uri); - } - - /** - * Runs the protected processParseRules() method - * - * @param JUri $uri JUri object of the URL - * - * @return array Array of URL vars - * - * @since 3.4 - */ - public function runProcessParseRules(&$uri) - { - return $this->processParseRules($uri); - } - - /** - * Runs the protected processBuildRules() method - * - * @param JUri $uri JUri object of the URL - * - * @return array Array of URL vars - * - * @since 3.4 - */ - public function runProcessBuildRules(&$uri) - { - return $this->processBuildRules($uri); - } - - /** - * Runs the protected createURI() method - * - * @param mixed $url URL to process - * - * @return JUri JUri object of the URL - * - * @since 3.4 - */ - public function runCreateURI($url) - { - return $this->createURI($url); - } -} - -class TestRouter implements JComponentRouterInterface -{ - public function preprocess($query) - { - $query['testvar'] = 'testvalue'; - - return $query; - } - - public function parse(&$segments) - { - return array(); - } - - public function build(&$query) - { - return array(); - } -} - -class Test2Router implements JComponentRouterInterface -{ - public function preprocess($query) - { - return $query; - } - - public function parse(&$segments) - { - return array('testvar' => 'testvalue'); - } - - public function build(&$query) - { - return array('router-test', 'another-segment'); - } -} - -class Test3Router implements JComponentRouterInterface -{ - public function preprocess($query) - { - return $query; - } - - public function parse(&$segments) - { - return array(); - } - - public function build(&$query) - { - unset($query['Itemid']); - - return array(); - } -}