Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  /**
  18   * Tests for moodle_url.
  19   *
  20   * @package     core
  21   * @copyright   2018 Andrew Nicols <andrew@nicols.co.uk>
  22   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  /**
  28   * Tests for moodle_url.
  29   *
  30   * @copyright   2018 Andrew Nicols <andrew@nicols.co.uk>
  31   * @license     http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  32   */
  33  class core_moodle_url_testcase extends advanced_testcase {
  34      /**
  35       * Test basic moodle_url construction.
  36       */
  37      public function test_moodle_url_constructor() {
  38          global $CFG;
  39  
  40          $url = new moodle_url('/index.php');
  41          $this->assertSame($CFG->wwwroot.'/index.php', $url->out());
  42  
  43          $url = new moodle_url('/index.php', array());
  44          $this->assertSame($CFG->wwwroot.'/index.php', $url->out());
  45  
  46          $url = new moodle_url('/index.php', array('id' => 2));
  47          $this->assertSame($CFG->wwwroot.'/index.php?id=2', $url->out());
  48  
  49          $url = new moodle_url('/index.php', array('id' => 'two'));
  50          $this->assertSame($CFG->wwwroot.'/index.php?id=two', $url->out());
  51  
  52          $url = new moodle_url('/index.php', array('id' => 1, 'cid' => '2'));
  53          $this->assertSame($CFG->wwwroot.'/index.php?id=1&amp;cid=2', $url->out());
  54          $this->assertSame($CFG->wwwroot.'/index.php?id=1&cid=2', $url->out(false));
  55  
  56          $url = new moodle_url('/index.php', null, 'test');
  57          $this->assertSame($CFG->wwwroot.'/index.php#test', $url->out());
  58  
  59          $url = new moodle_url('/index.php', array('id' => 2), 'test');
  60          $this->assertSame($CFG->wwwroot.'/index.php?id=2#test', $url->out());
  61      }
  62  
  63      /**
  64       * Tests moodle_url::get_path().
  65       */
  66      public function test_moodle_url_get_path() {
  67          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
  68          $this->assertSame('/my/file/is/here.txt', $url->get_path());
  69  
  70          $url = new moodle_url('http://www.example.org/');
  71          $this->assertSame('/', $url->get_path());
  72  
  73          $url = new moodle_url('http://www.example.org/pluginfile.php/slash/arguments');
  74          $this->assertSame('/pluginfile.php/slash/arguments', $url->get_path());
  75          $this->assertSame('/pluginfile.php', $url->get_path(false));
  76      }
  77  
  78      public function test_moodle_url_round_trip() {
  79          $strurl = 'http://moodle.org/course/view.php?id=5';
  80          $url = new moodle_url($strurl);
  81          $this->assertSame($strurl, $url->out(false));
  82  
  83          $strurl = 'http://moodle.org/user/index.php?contextid=53&sifirst=M&silast=D';
  84          $url = new moodle_url($strurl);
  85          $this->assertSame($strurl, $url->out(false));
  86      }
  87  
  88      /**
  89       * Test Moodle URL objects created with a param with empty value.
  90       */
  91      public function test_moodle_url_empty_param_values() {
  92          $strurl = 'http://moodle.org/course/view.php?id=0';
  93          $url = new moodle_url($strurl, array('id' => 0));
  94          $this->assertSame($strurl, $url->out(false));
  95  
  96          $strurl = 'http://moodle.org/course/view.php?id';
  97          $url = new moodle_url($strurl, array('id' => false));
  98          $this->assertSame($strurl, $url->out(false));
  99  
 100          $strurl = 'http://moodle.org/course/view.php?id';
 101          $url = new moodle_url($strurl, array('id' => null));
 102          $this->assertSame($strurl, $url->out(false));
 103  
 104          $strurl = 'http://moodle.org/course/view.php?id';
 105          $url = new moodle_url($strurl, array('id' => ''));
 106          $this->assertSame($strurl, $url->out(false));
 107  
 108          $strurl = 'http://moodle.org/course/view.php?id';
 109          $url = new moodle_url($strurl);
 110          $this->assertSame($strurl, $url->out(false));
 111      }
 112  
 113      /**
 114       * Test set good scheme on Moodle URL objects.
 115       */
 116      public function test_moodle_url_set_good_scheme() {
 117          $url = new moodle_url('http://moodle.org/foo/bar');
 118          $url->set_scheme('myscheme');
 119          $this->assertSame('myscheme://moodle.org/foo/bar', $url->out());
 120      }
 121  
 122      /**
 123       * Test set bad scheme on Moodle URL objects.
 124       */
 125      public function test_moodle_url_set_bad_scheme() {
 126          $url = new moodle_url('http://moodle.org/foo/bar');
 127          $this->expectException(coding_exception::class);
 128          $url->set_scheme('not a valid $ scheme');
 129      }
 130  
 131      public function test_moodle_url_round_trip_array_params() {
 132          $strurl = 'http://example.com/?a%5B1%5D=1&a%5B2%5D=2';
 133          $url = new moodle_url($strurl);
 134          $this->assertSame($strurl, $url->out(false));
 135  
 136          $url = new moodle_url('http://example.com/?a[1]=1&a[2]=2');
 137          $this->assertSame($strurl, $url->out(false));
 138  
 139          // For un-keyed array params, we expect 0..n keys to be returned.
 140          $strurl = 'http://example.com/?a%5B0%5D=0&a%5B1%5D=1';
 141          $url = new moodle_url('http://example.com/?a[]=0&a[]=1');
 142          $this->assertSame($strurl, $url->out(false));
 143      }
 144  
 145      public function test_compare_url() {
 146          $url1 = new moodle_url('index.php', array('var1' => 1, 'var2' => 2));
 147          $url2 = new moodle_url('index2.php', array('var1' => 1, 'var2' => 2, 'var3' => 3));
 148  
 149          $this->assertFalse($url1->compare($url2, URL_MATCH_BASE));
 150          $this->assertFalse($url1->compare($url2, URL_MATCH_PARAMS));
 151          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 152  
 153          $url2 = new moodle_url('index.php', array('var1' => 1, 'var3' => 3));
 154  
 155          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 156          $this->assertFalse($url1->compare($url2, URL_MATCH_PARAMS));
 157          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 158  
 159          $url2 = new moodle_url('index.php', array('var1' => 1, 'var2' => 2, 'var3' => 3));
 160  
 161          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 162          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 163          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 164  
 165          $url2 = new moodle_url('index.php', array('var2' => 2, 'var1' => 1));
 166  
 167          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 168          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 169          $this->assertTrue($url1->compare($url2, URL_MATCH_EXACT));
 170  
 171          $url1->set_anchor('test');
 172          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 173          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 174          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 175  
 176          $url2->set_anchor('test');
 177          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 178          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 179          $this->assertTrue($url1->compare($url2, URL_MATCH_EXACT));
 180      }
 181  
 182      public function test_out_as_local_url() {
 183          global $CFG;
 184          // Test http url.
 185          $url1 = new moodle_url('/lib/tests/weblib_test.php');
 186          $this->assertSame('/lib/tests/weblib_test.php', $url1->out_as_local_url());
 187  
 188          // Test https url.
 189          $httpswwwroot = str_replace("http://", "https://", $CFG->wwwroot);
 190          $url2 = new moodle_url($httpswwwroot.'/login/profile.php');
 191          $this->assertSame('/login/profile.php', $url2->out_as_local_url());
 192  
 193          // Test http url matching wwwroot.
 194          $url3 = new moodle_url($CFG->wwwroot);
 195          $this->assertSame('', $url3->out_as_local_url());
 196  
 197          // Test http url matching wwwroot ending with slash (/).
 198          $url3 = new moodle_url($CFG->wwwroot.'/');
 199          $this->assertSame('/', $url3->out_as_local_url());
 200      }
 201  
 202      public function test_out_as_local_url_error() {
 203          $url2 = new moodle_url('http://www.google.com/lib/tests/weblib_test.php');
 204          $this->expectException(coding_exception::class);
 205          $url2->out_as_local_url();
 206      }
 207  
 208      /**
 209       * You should get error with modified url
 210       */
 211      public function test_modified_url_out_as_local_url_error() {
 212          global $CFG;
 213  
 214          $modifiedurl = $CFG->wwwroot.'1';
 215          $url3 = new moodle_url($modifiedurl.'/login/profile.php');
 216          $this->expectException(coding_exception::class);
 217          $url3->out_as_local_url();
 218      }
 219  
 220      /**
 221       * Try get local url from external https url and you should get error
 222       */
 223      public function test_https_out_as_local_url_error() {
 224          $url4 = new moodle_url('https://www.google.com/lib/tests/weblib_test.php');
 225          $this->expectException(coding_exception::class);
 226          $url4->out_as_local_url();
 227      }
 228  
 229      public function test_moodle_url_get_scheme() {
 230          // Should return the scheme only.
 231          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
 232          $this->assertSame('http', $url->get_scheme());
 233  
 234          // Should work for secure URLs.
 235          $url = new moodle_url('https://www.example.org:447/my/file/is/here.txt?really=1');
 236          $this->assertSame('https', $url->get_scheme());
 237  
 238          // Should return an empty string if no scheme is specified.
 239          $url = new moodle_url('www.example.org:447/my/file/is/here.txt?really=1');
 240          $this->assertSame('', $url->get_scheme());
 241      }
 242  
 243      public function test_moodle_url_get_host() {
 244          // Should return the host part only.
 245          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
 246          $this->assertSame('www.example.org', $url->get_host());
 247      }
 248  
 249      public function test_moodle_url_get_port() {
 250          // Should return the port if one provided.
 251          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
 252          $this->assertSame(447, $url->get_port());
 253  
 254          // Should return an empty string if port not specified.
 255          $url = new moodle_url('http://www.example.org/some/path/here.php');
 256          $this->assertSame('', $url->get_port());
 257      }
 258  
 259      /**
 260       * Test the make_pluginfile_url function.
 261       *
 262       * @dataProvider make_pluginfile_url_provider
 263       * @param   bool    $slashargs
 264       * @param   array   $args Args to be provided to make_pluginfile_url
 265       * @param   string  $expected The expected result
 266       */
 267      public function test_make_pluginfile_url($slashargs, $args, $expected) {
 268          global $CFG;
 269  
 270          $this->resetAfterTest();
 271  
 272          $CFG->slasharguments = $slashargs;
 273          $url = call_user_func_array('moodle_url::make_pluginfile_url', $args);
 274          $this->assertRegexp($expected, $url->out(true));
 275      }
 276  
 277      /**
 278       * Data provider for make_pluginfile_url tests.
 279       *
 280       * @return  array[]
 281       */
 282      public function make_pluginfile_url_provider() {
 283          $baseurl = "https://www.example.com/moodle/pluginfile.php";
 284          $tokenbaseurl = "https://www.example.com/moodle/tokenpluginfile.php";
 285          return [
 286              'Standard with slashargs' => [
 287                  'slashargs' => true,
 288                  'args' => [
 289                      1,
 290                      'mod_forum',
 291                      'posts',
 292                      422,
 293                      '/my/location/',
 294                      'file.png',
 295                  ],
 296                  'expected' => "@{$baseurl}/1/mod_forum/posts/422/my/location/file.png@",
 297              ],
 298              'Standard without slashargs' => [
 299                  'slashargs' => false,
 300                  'args' => [
 301                      1,
 302                      'mod_forum',
 303                      'posts',
 304                      422,
 305                      '/my/location/',
 306                      'file.png',
 307                  ],
 308                  'expected' => "@{$baseurl}\?file=%2F1%2Fmod_forum%2Fposts%2F422%2Fmy%2Flocation%2Ffile.png@",
 309              ],
 310              'Token included with slashargs' => [
 311                  'slashargs' => true,
 312                  'args' => [
 313                      1,
 314                      'mod_forum',
 315                      'posts',
 316                      422,
 317                      '/my/location/',
 318                      'file.png',
 319                      false,
 320                      true,
 321                  ],
 322                  'expected' => "@{$tokenbaseurl}/[^/]*/1/mod_forum/posts/422/my/location/file.png@",
 323              ],
 324              'Token included without slashargs' => [
 325                  'slashargs' => false,
 326                  'args' => [
 327                      1,
 328                      'mod_forum',
 329                      'posts',
 330                      422,
 331                      '/my/location/',
 332                      'file.png',
 333                      false,
 334                      true,
 335                  ],
 336                  'expected' => "@{$tokenbaseurl}\?file=%2F1%2Fmod_forum%2Fposts%2F422%2Fmy%2Flocation%2Ffile.png&amp;token=[a-z0-9]*@",
 337              ],
 338          ];
 339      }
 340  }