mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 10:39:59 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			862 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			862 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * @link https://www.yiiframework.com/
 | |
|  * @copyright Copyright (c) 2008 Yii Software LLC
 | |
|  * @license https://www.yiiframework.com/license/
 | |
|  */
 | |
| 
 | |
| namespace yiiunit\framework\web;
 | |
| 
 | |
| use Yii;
 | |
| use yii\caching\ArrayCache;
 | |
| use yii\web\UrlManager;
 | |
| use yii\web\UrlRule;
 | |
| use yiiunit\framework\web\stubs\CachedUrlRule;
 | |
| use yiiunit\TestCase;
 | |
| 
 | |
| /**
 | |
|  * This class implements the tests for URL creation with "pretty" url format.
 | |
|  *
 | |
|  * See [[UrlManagerTest]] for tests with "default" URL format.
 | |
|  * See [[UrlManagerParseUrlTest]] for url parsing with "pretty" URL format.
 | |
|  *
 | |
|  * Behavior of UrlManager::createUrl() for the "pretty" URL format varies among the following options:
 | |
|  *  - show script name = true / false
 | |
|  *  - rules format
 | |
|  *    - key => value
 | |
|  *    - array config
 | |
|  *
 | |
|  * The following features are tested:
 | |
|  *  - route only Url::to(['post/index']);
 | |
|  *  - with params Url::to(['post/view', 'id' => 100]);
 | |
|  *  - with anchor Url::to(['post/view', 'id' => 100, '#' => 'content']);
 | |
|  *  - named parameters
 | |
|  *    - as query params
 | |
|  *    - as controller/actions '<controller:(post|comment)>/<id:\d+>/<action:(update|delete)>' => '<controller>/<action>',
 | |
|  *  - Rules with Server Names
 | |
|  *    - with protocol (TODO)
 | |
|  *    - without protocol i.e protocol relative, see https://github.com/yiisoft/yii2/pull/12697 (TODO)
 | |
|  *    - with parameters
 | |
|  *  - with suffix
 | |
|  *  - with default values
 | |
|  *  - with HTTP methods (TODO)
 | |
|  *  - absolute/relative
 | |
|  *
 | |
|  *  - Adding rules dynamically (TODO)
 | |
|  *  - Test custom rules that only implement the interface (TODO)
 | |
|  *
 | |
|  * NOTE: if a test is added here, you probably also need to add one in UrlManagerParseUrlTest.
 | |
|  *
 | |
|  * @group web
 | |
|  */
 | |
| class UrlManagerCreateUrlTest extends TestCase
 | |
| {
 | |
|     protected function getUrlManager($config = [], $showScriptName = true)
 | |
|     {
 | |
|         // in this test class, all tests have enablePrettyUrl enabled.
 | |
|         $config['enablePrettyUrl'] = true;
 | |
| 
 | |
|         // set default values if they are not set
 | |
|         $config = array_merge([
 | |
|             'baseUrl' => '',
 | |
|             'scriptUrl' => '/index.php',
 | |
|             'hostInfo' => 'http://www.example.com',
 | |
|             'cache' => null,
 | |
|             'showScriptName' => $showScriptName,
 | |
|         ], $config);
 | |
| 
 | |
|         return new UrlManager($config);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function variationsProvider()
 | |
|     {
 | |
|         $baseUrlConfig = [
 | |
|             'baseUrl' => '/test',
 | |
|             'scriptUrl' => '/test/index.php',
 | |
|         ];
 | |
| 
 | |
|         return [
 | |
|             // method name, $showScriptName, expected URL prefix
 | |
|             ['createUrl', true, '/index.php', []],
 | |
|             ['createUrl', false, '', []],
 | |
|             ['createAbsoluteUrl', true, 'http://www.example.com/index.php', []],
 | |
|             ['createAbsoluteUrl', false, 'http://www.example.com', []],
 | |
| 
 | |
|             // with different baseUrl
 | |
|             ['createUrl', true, '/test/index.php', $baseUrlConfig],
 | |
|             ['createUrl', false, '/test', $baseUrlConfig],
 | |
|             ['createAbsoluteUrl', true, 'http://www.example.com/test/index.php', $baseUrlConfig],
 | |
|             ['createAbsoluteUrl', false, 'http://www.example.com/test', $baseUrlConfig],
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl()
 | |
|      * with varying $showScriptName
 | |
|      * without rules.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testWithoutRules($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         $url = $manager->$method('post/view');
 | |
|         $this->assertEquals("$prefix/post/view", $url);
 | |
|         $url = $manager->$method(['post/view']);
 | |
|         $this->assertEquals("$prefix/post/view", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/post/view?id=1&title=sample+post", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/view#testhash", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/view?id=1&title=sample+post#testhash", $url);
 | |
| 
 | |
|         // with defaultAction
 | |
|         $url = $manager->$method(['/post', 'page' => 1]);
 | |
|         $this->assertEquals("$prefix/post?page=1", $url);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl().
 | |
|      *
 | |
|      * - with varying $showScriptName,
 | |
|      * - without rules,
 | |
|      * - with UrlManager::$suffix.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testWithoutRulesWithSuffix($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['suffix'] = '.html';
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         $url = $manager->$method('post/view');
 | |
|         $this->assertEquals("$prefix/post/view.html", $url);
 | |
|         $url = $manager->$method(['post/view']);
 | |
|         $this->assertEquals("$prefix/post/view.html", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/post/view.html?id=1&title=sample+post", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/view.html#testhash", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/view.html?id=1&title=sample+post#testhash", $url);
 | |
| 
 | |
|         // with defaultAction
 | |
|         $url = $manager->$method(['/post', 'page' => 1]);
 | |
|         $this->assertEquals("$prefix/post.html?page=1", $url);
 | |
| 
 | |
| 
 | |
|         // test suffix '/' as it may be trimmed
 | |
|         $config['suffix'] = '/';
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         $url = $manager->$method('post/view');
 | |
|         $this->assertEquals("$prefix/post/view/", $url);
 | |
|         $url = $manager->$method(['post/view']);
 | |
|         $this->assertEquals("$prefix/post/view/", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/post/view/?id=1&title=sample+post", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/view/#testhash", $url);
 | |
| 
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/view/?id=1&title=sample+post#testhash", $url);
 | |
| 
 | |
|         // with defaultAction
 | |
|         $url = $manager->$method(['/post', 'page' => 1]);
 | |
|         $this->assertEquals("$prefix/post/?page=1", $url);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl()
 | |
|      * with varying $showScriptName
 | |
|      * with simple rules.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testSimpleRules($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             'post/<id:\d+>' => 'post/view',
 | |
|             'posts' => 'post/index',
 | |
|             'book/<id:\d+>/<title>' => 'book/view',
 | |
|             'POST posts' => 'post/create',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         // does not match any rule
 | |
|         $url = $manager->$method(['post/view']);
 | |
|         $this->assertEquals("$prefix/post/view", $url);
 | |
| 
 | |
|         // with defaultAction also does not match any rule
 | |
|         $url = $manager->$method(['/post', 'page' => 1]);
 | |
|         $this->assertEquals("$prefix/post?page=1", $url);
 | |
| 
 | |
|         // match first rule
 | |
|         $url = $manager->$method(['post/view', 'id' => 1]);
 | |
|         $this->assertEquals("$prefix/post/1", $url);
 | |
| 
 | |
|         // match first rule with additional param
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/post/1?title=sample+post", $url);
 | |
|         // match first rule with hash
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/1#testhash", $url);
 | |
| 
 | |
|         // match second rule
 | |
|         $url = $manager->$method(['post/index']);
 | |
|         $this->assertEquals("$prefix/posts", $url);
 | |
| 
 | |
|         // match second rule with additional param
 | |
|         $url = $manager->$method(['post/index', 'category' => 'test']);
 | |
|         $this->assertEquals("$prefix/posts?category=test", $url);
 | |
| 
 | |
|         // match third rule, ensure encoding of params
 | |
|         $url = $manager->$method(['book/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/book/1/sample+post", $url);
 | |
| 
 | |
|         // match fourth rule, since 2.0.41 non-GET verbs are allowed
 | |
|         $url = $manager->$method(['post/create']);
 | |
|         $this->assertEquals("$prefix/posts", $url);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl().
 | |
|      *
 | |
|      * - with varying $showScriptName,
 | |
|      * - with simple rules,
 | |
|      * - with UrlManager::$suffix.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testSimpleRulesWithSuffix($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             'post/<id:\d+>' => 'post/view',
 | |
|             'posts' => 'post/index',
 | |
|             'book/<id:\d+>/<title>' => 'book/view',
 | |
|         ];
 | |
|         $config['suffix'] = '/';
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         // does not match any rule
 | |
|         $url = $manager->$method(['post/view']);
 | |
|         $this->assertEquals("$prefix/post/view/", $url);
 | |
| 
 | |
|         // with defaultAction also does not match any rule
 | |
|         $url = $manager->$method(['/post', 'page' => 1]);
 | |
|         $this->assertEquals("$prefix/post/?page=1", $url);
 | |
| 
 | |
|         // match first rule
 | |
|         $url = $manager->$method(['post/view', 'id' => 1]);
 | |
|         $this->assertEquals("$prefix/post/1/", $url);
 | |
| 
 | |
|         // match first rule with additional param
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/post/1/?title=sample+post", $url);
 | |
|         // match first rule with hash
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/1/#testhash", $url);
 | |
| 
 | |
|         // match second rule
 | |
|         $url = $manager->$method(['post/index']);
 | |
|         $this->assertEquals("$prefix/posts/", $url);
 | |
| 
 | |
|         // match second rule with additional param
 | |
|         $url = $manager->$method(['post/index', 'category' => 'test']);
 | |
|         $this->assertEquals("$prefix/posts/?category=test", $url);
 | |
| 
 | |
|         // match third rule, ensure encoding of params
 | |
|         $url = $manager->$method(['book/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/book/1/sample+post/", $url);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl()
 | |
|      * with varying $showScriptName
 | |
|      * with rules that have varadic controller/actions.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testControllerActionParams($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             '<controller>/<id:\d+>' => '<controller>/view',
 | |
|             '<controller>s' => '<controller>/index',
 | |
|             '<controller>/default' => '<controller>', // rule to match default action
 | |
|             '<controller>/test/<action:\w+>' => '<controller>/<action>',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         // match last rule
 | |
|         $url = $manager->$method(['post/view']);
 | |
|         $this->assertEquals("$prefix/post/test/view", $url);
 | |
| 
 | |
|         // defaultAction should match third rule
 | |
|         $url = $manager->$method(['/post/']);
 | |
|         $this->assertEquals("$prefix/post/default", $url);
 | |
|         $url = $manager->$method(['/post']);
 | |
|         $this->assertEquals("$prefix/post/default", $url);
 | |
| 
 | |
|         // match first rule
 | |
|         $url = $manager->$method(['post/view', 'id' => 1]);
 | |
|         $this->assertEquals("$prefix/post/1", $url);
 | |
| 
 | |
|         // match first rule with additional param
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, 'title' => 'sample post']);
 | |
|         $this->assertEquals("$prefix/post/1?title=sample+post", $url);
 | |
|         // match first rule with hash
 | |
|         $url = $manager->$method(['post/view', 'id' => 1, '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/post/1#testhash", $url);
 | |
| 
 | |
|         // match second rule
 | |
|         $url = $manager->$method(['post/index']);
 | |
|         $this->assertEquals("$prefix/posts", $url);
 | |
| 
 | |
|         // match second rule with additional param
 | |
|         $url = $manager->$method(['post/index', 'category' => 'test']);
 | |
|         $this->assertEquals("$prefix/posts?category=test", $url);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl()
 | |
|      * with varying $showScriptName
 | |
|      * with rules that have default values for parameters.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testRulesWithDefaultParams($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             [
 | |
|                 'pattern' => '',
 | |
|                 'route' => 'frontend/page/view',
 | |
|                 'defaults' => ['slug' => 'index'],
 | |
|             ],
 | |
|             'page/<slug>' => 'frontend/page/view',
 | |
|             [
 | |
|                 'pattern' => '<language>',
 | |
|                 'route' => 'site/index',
 | |
|                 'defaults' => [
 | |
|                     'language' => 'en',
 | |
|                 ],
 | |
|             ],
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         // match first rule
 | |
|         $url = $manager->$method(['frontend/page/view', 'slug' => 'index']);
 | |
|         $this->assertEquals("$prefix/", $url);
 | |
| 
 | |
|         // match first rule with additional param
 | |
|         $url = $manager->$method(['frontend/page/view', 'slug' => 'index', 'sort' => 'name']);
 | |
|         $this->assertEquals("$prefix/?sort=name", $url);
 | |
| 
 | |
|         // match first rule with hash
 | |
|         $url = $manager->$method(['frontend/page/view', 'slug' => 'index', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/#testhash", $url);
 | |
| 
 | |
|         // match second rule
 | |
|         $url = $manager->$method(['frontend/page/view', 'slug' => 'services']);
 | |
|         $this->assertEquals("$prefix/page/services", $url);
 | |
| 
 | |
|         // match second rule with additional param
 | |
|         $url = $manager->$method(['frontend/page/view', 'slug' => 'services', 'sort' => 'name']);
 | |
|         $this->assertEquals("$prefix/page/services?sort=name", $url);
 | |
| 
 | |
|         // match second rule with hash
 | |
|         $url = $manager->$method(['frontend/page/view', 'slug' => 'services', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/page/services#testhash", $url);
 | |
| 
 | |
|         // match third rule
 | |
|         $url = $manager->$method(['site/index', 'language' => 'en']);
 | |
|         $this->assertEquals("$prefix/", $url);
 | |
|         $url = $manager->$method(['site/index', 'language' => 'de']);
 | |
|         $this->assertEquals("$prefix/de", $url);
 | |
| 
 | |
|         // match third rule with additional param
 | |
|         $url = $manager->$method(['site/index', 'language' => 'en', 'sort' => 'name']);
 | |
|         $this->assertEquals("$prefix/?sort=name", $url);
 | |
|         $url = $manager->$method(['site/index', 'language' => 'de', 'sort' => 'name']);
 | |
|         $this->assertEquals("$prefix/de?sort=name", $url);
 | |
| 
 | |
|         // match first rule with hash
 | |
|         $url = $manager->$method(['site/index', 'language' => 'en', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/#testhash", $url);
 | |
|         $url = $manager->$method(['site/index', 'language' => 'de', '#' => 'testhash']);
 | |
|         $this->assertEquals("$prefix/de#testhash", $url);
 | |
| 
 | |
|         // matches none of the rules
 | |
|         $url = $manager->$method(['frontend/page/view']);
 | |
|         $this->assertEquals("$prefix/frontend/page/view", $url);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl()
 | |
|      * with varying $showScriptName
 | |
|      * with empty or null parameters.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @see https://github.com/yiisoft/yii2/issues/10935
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testWithNullParams($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             '<param1>/<param2>' => 'site/index',
 | |
|             '<param1>' => 'site/index',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
| 
 | |
|         // match first rule
 | |
|         $url = $manager->$method(['site/index', 'param1' => 111, 'param2' => 222]);
 | |
|         $this->assertEquals("$prefix/111/222", $url);
 | |
|         $url = $manager->$method(['site/index', 'param1' => 112, 'param2' => 222]);
 | |
|         $this->assertEquals("$prefix/112/222", $url);
 | |
| 
 | |
|         // match second rule
 | |
|         $url = $manager->$method(['site/index', 'param1' => 111, 'param2' => null]);
 | |
|         $this->assertEquals("$prefix/111", $url);
 | |
|         $url = $manager->$method(['site/index', 'param1' => 123, 'param2' => null]);
 | |
|         $this->assertEquals("$prefix/123", $url);
 | |
| 
 | |
|         // match none of the rules
 | |
|         $url = $manager->$method(['site/index', 'param1' => null, 'param2' => 111]);
 | |
|         $this->assertEquals("$prefix/site/index?param2=111", $url);
 | |
|         $url = $manager->$method(['site/index', 'param1' => null, 'param2' => 123]);
 | |
|         $this->assertEquals("$prefix/site/index?param2=123", $url);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     /**
 | |
|      * Test createUrl() and createAbsoluteUrl()
 | |
|      * with varying $showScriptName
 | |
|      * with empty pattern.
 | |
|      *
 | |
|      * @dataProvider variationsProvider
 | |
|      * @see https://github.com/yiisoft/yii2/issues/6717
 | |
|      * @param string $method
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testWithEmptyPattern($method, $showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $assertations = function ($manager) use ($method, $prefix) {
 | |
|             // match first rule
 | |
|             $url = $manager->$method(['front/site/index']);
 | |
|             $this->assertEquals("$prefix/", $url);
 | |
|             $url = $manager->$method(['/front/site/index']);
 | |
|             $this->assertEquals("$prefix/", $url);
 | |
| 
 | |
|             // match first rule with additional parameter
 | |
|             $url = $manager->$method(['front/site/index', 'page' => 1]);
 | |
|             $this->assertEquals("$prefix/?page=1", $url);
 | |
|             $url = $manager->$method(['/front/site/index', 'page' => 1]);
 | |
|             $this->assertEquals("$prefix/?page=1", $url);
 | |
| 
 | |
|             // no match
 | |
|             $url = $manager->$method(['']);
 | |
|             $this->assertEquals("$prefix/", $url);
 | |
|             $url = $manager->$method(['/']);
 | |
|             $this->assertEquals("$prefix/", $url);
 | |
|         };
 | |
| 
 | |
|         // normal rule
 | |
|         $config['rules'] = [
 | |
|             '' => 'front/site/index',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
|         $assertations($manager);
 | |
| 
 | |
|         // rule prefixed with /
 | |
|         $config['rules'] = [
 | |
|             '' => '/front/site/index',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
|         $assertations($manager);
 | |
| 
 | |
|         // with suffix
 | |
|         $config['rules'] = [
 | |
|             '' => 'front/site/index',
 | |
|         ];
 | |
|         $config['suffix'] = '/';
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
|         $assertations($manager);
 | |
|     }
 | |
| 
 | |
| 
 | |
|     public function absolutePatternsVariations()
 | |
|     {
 | |
|         $baseUrlConfig = [
 | |
|             'baseUrl' => '/test',
 | |
|             'scriptUrl' => '/test/index.php',
 | |
|         ];
 | |
| 
 | |
|         return [
 | |
|             // $showScriptName, expected URL prefix
 | |
|             [true, '/index.php', []],
 | |
|             [false, '', []],
 | |
| 
 | |
|             // with different baseUrl
 | |
|             [true, '/test/index.php', $baseUrlConfig],
 | |
|             [false, '/test', $baseUrlConfig],
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test rules that have host info in the patterns.
 | |
|      * @dataProvider absolutePatternsVariations
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testAbsolutePatterns($showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             [
 | |
|                 'pattern' => 'post/<id>/<title>',
 | |
|                 'route' => 'post/view',
 | |
|                 'host' => 'http://<lang:en|fr>.example.com',
 | |
|             ],
 | |
|             // note: baseUrl is not included in the pattern
 | |
|             'http://www.example.com/login' => 'site/login',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
|         // first rule matches
 | |
|         $urlParams = ['post/view', 'id' => 1, 'title' => 'sample post', 'lang' => 'en'];
 | |
|         $expected = "http://en.example.com$prefix/post/1/sample+post";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals('https' . substr($expected, 4), $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals(substr($expected, 5), $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         $urlParams = ['post/view', 'id' => 1, 'title' => 'sample post', 'lang' => 'en', '#' => 'testhash'];
 | |
|         $expected = "http://en.example.com$prefix/post/1/sample+post#testhash";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams));
 | |
| 
 | |
|         // second rule matches
 | |
|         $urlParams = ['site/login'];
 | |
|         $expected = "http://www.example.com$prefix/login";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals('https' . substr($expected, 4), $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals(substr($expected, 5), $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         // none of the rules matches
 | |
|         $urlParams = ['post/index', 'page' => 1];
 | |
|         $this->assertEquals("$prefix/post/index?page=1", $manager->createUrl($urlParams));
 | |
|         $expected = "http://www.example.com$prefix/post/index?page=1";
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals('https' . substr($expected, 4), $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals(substr($expected, 5), $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         $urlParams = ['post/index', 'page' => 1, '#' => 'testhash'];
 | |
|         $this->assertEquals("$prefix/post/index?page=1#testhash", $manager->createUrl($urlParams));
 | |
|         $expected = "http://www.example.com$prefix/post/index?page=1#testhash";
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test rules that have host info in the patterns, that are protocol relative.
 | |
|      * @dataProvider absolutePatternsVariations
 | |
|      * @see https://github.com/yiisoft/yii2/issues/12691
 | |
|      * @param bool $showScriptName
 | |
|      * @param string $prefix
 | |
|      * @param array $config
 | |
|      */
 | |
|     public function testProtocolRelativeAbsolutePattern($showScriptName, $prefix, $config)
 | |
|     {
 | |
|         $config['rules'] = [
 | |
|             [
 | |
|                 'pattern' => 'post/<id>/<title>',
 | |
|                 'route' => 'post/view',
 | |
|                 'host' => '//<lang:en|fr>.example.com',
 | |
|             ],
 | |
|             // note: baseUrl is not included in the pattern
 | |
|             '//www.example.com/login' => 'site/login',
 | |
|             '//app.example.com' => 'app/index',
 | |
|             '//app2.example.com/' => 'app2/index',
 | |
|         ];
 | |
|         $manager = $this->getUrlManager($config, $showScriptName);
 | |
|         // first rule matches
 | |
|         $urlParams = ['post/view', 'id' => 1, 'title' => 'sample post', 'lang' => 'en'];
 | |
|         $expected = "//en.example.com$prefix/post/1/sample+post";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals("https:$expected", $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         $urlParams = ['post/view', 'id' => 1, 'title' => 'sample post', 'lang' => 'en', '#' => 'testhash'];
 | |
|         $expected = "//en.example.com$prefix/post/1/sample+post#testhash";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams));
 | |
| 
 | |
|         // second rule matches
 | |
|         $urlParams = ['site/login'];
 | |
|         $expected = "//www.example.com$prefix/login";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals("https:$expected", $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         // third rule matches
 | |
|         $urlParams = ['app/index'];
 | |
|         $expected = "//app.example.com$prefix";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals("https:$expected", $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         // fourth rule matches
 | |
|         $urlParams = ['app2/index'];
 | |
|         $expected = "//app2.example.com$prefix";
 | |
|         $this->assertEquals($expected, $manager->createUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals("https:$expected", $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         // none of the rules matches
 | |
|         $urlParams = ['post/index', 'page' => 1];
 | |
|         $this->assertEquals("$prefix/post/index?page=1", $manager->createUrl($urlParams));
 | |
|         $expected = "//www.example.com$prefix/post/index?page=1";
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, true));
 | |
|         $this->assertEquals("http:$expected", $manager->createAbsoluteUrl($urlParams, 'http'));
 | |
|         $this->assertEquals("https:$expected", $manager->createAbsoluteUrl($urlParams, 'https'));
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams, '')); // protocol relative Url
 | |
| 
 | |
|         $urlParams = ['post/index', 'page' => 1, '#' => 'testhash'];
 | |
|         $this->assertEquals("$prefix/post/index?page=1#testhash", $manager->createUrl($urlParams));
 | |
|         $expected = "http://www.example.com$prefix/post/index?page=1#testhash";
 | |
|         $this->assertEquals($expected, $manager->createAbsoluteUrl($urlParams));
 | |
|     }
 | |
| 
 | |
|     public function multipleHostsRulesDataProvider()
 | |
|     {
 | |
|         return [
 | |
|             ['http://example.com'],
 | |
|             ['https://example.com'],
 | |
|             ['http://example.fr'],
 | |
|             ['https://example.fr'],
 | |
|         ];
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Test matching of Url rules dependent on the current host info.
 | |
|      *
 | |
|      * @dataProvider multipleHostsRulesDataProvider
 | |
|      * @see https://github.com/yiisoft/yii2/issues/7948
 | |
|      * @param string $host
 | |
|      */
 | |
|     public function testMultipleHostsRules($host)
 | |
|     {
 | |
|         $manager = new UrlManager([
 | |
|             'enablePrettyUrl' => true,
 | |
|             'cache' => null,
 | |
|             'rules' => [
 | |
|                 ['host' => 'http://example.com', 'pattern' => '<slug:(search)>', 'route' => 'products/search', 'defaults' => ['lang' => 'en']],
 | |
|                 ['host' => 'http://example.fr', 'pattern' => '<slug:(search)>', 'route' => 'products/search', 'defaults' => ['lang' => 'fr']],
 | |
|             ],
 | |
|             'hostInfo' => $host,
 | |
|             'baseUrl' => '/',
 | |
|             'scriptUrl' => '',
 | |
|         ]);
 | |
|         $url = $manager->createAbsoluteUrl(['products/search', 'lang' => 'en', 'slug' => 'search'], 'https');
 | |
|         $this->assertEquals('https://example.com/search', $url);
 | |
|         $url = $manager->createUrl(['products/search', 'lang' => 'en', 'slug' => 'search']);
 | |
|         $this->assertEquals('http://example.com/search', $url);
 | |
|         $url = $manager->createUrl(['products/search', 'lang' => 'en', 'slug' => 'search', 'param1' => 'value1']);
 | |
|         $this->assertEquals('http://example.com/search?param1=value1', $url);
 | |
|         $url = $manager->createAbsoluteUrl(['products/search', 'lang' => 'fr', 'slug' => 'search'], 'https');
 | |
|         $this->assertEquals('https://example.fr/search', $url);
 | |
|         $url = $manager->createUrl(['products/search', 'lang' => 'fr', 'slug' => 'search']);
 | |
|         $this->assertEquals('http://example.fr/search', $url);
 | |
|         $url = $manager->createUrl(['products/search', 'lang' => 'fr', 'slug' => 'search', 'param1' => 'value1']);
 | |
|         $this->assertEquals('http://example.fr/search?param1=value1', $url);
 | |
|     }
 | |
| 
 | |
|     public function testCreateUrlCache()
 | |
|     {
 | |
|         /** @var CachedUrlRule[] $rules */
 | |
|         $rules = [
 | |
|             Yii::createObject([
 | |
|                 'class' => CachedUrlRule::className(),
 | |
|                 'route' => 'user/show',
 | |
|                 'pattern' => 'user/<name:[\w-]+>',
 | |
|             ]),
 | |
|             Yii::createObject([
 | |
|                 'class' => CachedUrlRule::className(),
 | |
|                 'route' => '<controller>/<action>',
 | |
|                 'pattern' => '<controller:\w+>/<action:\w+>',
 | |
|             ]),
 | |
|         ];
 | |
|         $manager = $this->getUrlManager([
 | |
|             'rules' => $rules,
 | |
|         ], false);
 | |
| 
 | |
|         $this->assertEquals('/user/rob006', $manager->createUrl(['user/show', 'name' => 'rob006']));
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_SUCCESS, $rules[0]->getCreateUrlStatus());
 | |
|         $this->assertEquals(1, $rules[0]->createCounter);
 | |
|         $this->assertEquals(0, $rules[1]->createCounter);
 | |
| 
 | |
|         $this->assertEquals('/user/show?name=John+Doe', $manager->createUrl(['user/show', 'name' => 'John Doe']));
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_PARAMS_MISMATCH, $rules[0]->getCreateUrlStatus());
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_SUCCESS, $rules[1]->getCreateUrlStatus());
 | |
|         $this->assertEquals(2, $rules[0]->createCounter);
 | |
|         $this->assertEquals(1, $rules[1]->createCounter);
 | |
| 
 | |
|         $this->assertEquals('/user/profile?name=rob006', $manager->createUrl(['user/profile', 'name' => 'rob006']));
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_ROUTE_MISMATCH, $rules[0]->getCreateUrlStatus());
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_SUCCESS, $rules[1]->getCreateUrlStatus());
 | |
|         $this->assertEquals(3, $rules[0]->createCounter);
 | |
|         $this->assertEquals(2, $rules[1]->createCounter);
 | |
| 
 | |
|         $this->assertEquals('/user/profile?name=John+Doe', $manager->createUrl(['user/profile', 'name' => 'John Doe']));
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_ROUTE_MISMATCH, $rules[0]->getCreateUrlStatus());
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_SUCCESS, $rules[1]->getCreateUrlStatus());
 | |
|         // fist rule is skipped - cached rule has precedence
 | |
|         $this->assertEquals(3, $rules[0]->createCounter);
 | |
|         $this->assertEquals(3, $rules[1]->createCounter);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @see https://github.com/yiisoft/yii2/pull/1335
 | |
|      */
 | |
|     public function testUrlCreateCacheWithParameterMismatch()
 | |
|     {
 | |
|         /** @var CachedUrlRule[] $rules */
 | |
|         $rules = [
 | |
|             Yii::createObject([
 | |
|                 'class' => CachedUrlRule::className(),
 | |
|                 'route' => 'user/show',
 | |
|                 'pattern' => 'user/<name:[\w-]+>',
 | |
|             ]),
 | |
|             Yii::createObject([
 | |
|                 'class' => CachedUrlRule::className(),
 | |
|                 'route' => '<controller>/<action>',
 | |
|                 'pattern' => '<controller:\w+>/<action:\w+>',
 | |
|             ]),
 | |
|         ];
 | |
|         $manager = $this->getUrlManager([
 | |
|             'rules' => $rules,
 | |
|         ], false);
 | |
| 
 | |
|         $this->assertEquals('/user/show?name=John+Doe', $manager->createUrl(['user/show', 'name' => 'John Doe']));
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_PARAMS_MISMATCH, $rules[0]->getCreateUrlStatus());
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_SUCCESS, $rules[1]->getCreateUrlStatus());
 | |
|         $this->assertEquals(1, $rules[0]->createCounter);
 | |
|         $this->assertEquals(1, $rules[1]->createCounter);
 | |
| 
 | |
|         $this->assertEquals('/user/rob006', $manager->createUrl(['user/show', 'name' => 'rob006']));
 | |
|         $this->assertEquals(UrlRule::CREATE_STATUS_SUCCESS, $rules[0]->getCreateUrlStatus());
 | |
|         $this->assertEquals(2, $rules[0]->createCounter);
 | |
|         $this->assertEquals(1, $rules[1]->createCounter);
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * @see https://github.com/yiisoft/yii2/issues/14406
 | |
|      */
 | |
|     public function testCreatingRulesWithDifferentRuleConfigAndEnabledCache()
 | |
|     {
 | |
|         $this->mockWebApplication([
 | |
|             'components' => [
 | |
|                 'cache' => ArrayCache::className(),
 | |
|             ],
 | |
|         ]);
 | |
|         $urlManager = $this->getUrlManager([
 | |
|             'cache' => 'cache',
 | |
|             'rules' => [
 | |
|                 '/' => 'site/index',
 | |
|             ],
 | |
|         ]);
 | |
| 
 | |
|         $cachedUrlManager = $this->getUrlManager([
 | |
|             'cache' => 'cache',
 | |
|             'ruleConfig' => [
 | |
|                 'class' => CachedUrlRule::className(),
 | |
|             ],
 | |
|             'rules' => [
 | |
|                 '/' => 'site/index',
 | |
|             ],
 | |
|         ]);
 | |
| 
 | |
|         $this->assertNotEquals($urlManager->rules, $cachedUrlManager->rules);
 | |
|         $this->assertInstanceOf(UrlRule::className(), $urlManager->rules[0]);
 | |
|         $this->assertInstanceOf(CachedUrlRule::className(), $cachedUrlManager->rules[0]);
 | |
|     }
 | |
| 
 | |
|     public function testNotEnsuringCacheForEmptyRuleset()
 | |
|     {
 | |
|         $this->mockWebApplication([
 | |
|             'components' => [
 | |
|                 'cache' => ArrayCache::className(),
 | |
|             ],
 | |
|         ]);
 | |
|         // no rules - don't ensure cache
 | |
|         $urlManager = $this->getUrlManager([
 | |
|             'cache' => 'cache',
 | |
|             'rules' => [],
 | |
|         ]);
 | |
|         $this->assertSame('cache', $urlManager->cache);
 | |
|         // with rules - ensure cache
 | |
|         $urlManager = $this->getUrlManager([
 | |
|             'cache' => 'cache',
 | |
|             'rules' => ['/' => 'site/index'],
 | |
|         ]);
 | |
|         $this->assertInstanceOf(ArrayCache::className(), $urlManager->cache);
 | |
|     }
 | |
| }
 | 
