Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 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 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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       * @expectedException coding_exception
 126       */
 127      public function test_moodle_url_set_bad_scheme() {
 128          $url = new moodle_url('http://moodle.org/foo/bar');
 129          $url->set_scheme('not a valid $ scheme');
 130      }
 131  
 132      public function test_moodle_url_round_trip_array_params() {
 133          $strurl = 'http://example.com/?a%5B1%5D=1&a%5B2%5D=2';
 134          $url = new moodle_url($strurl);
 135          $this->assertSame($strurl, $url->out(false));
 136  
 137          $url = new moodle_url('http://example.com/?a[1]=1&a[2]=2');
 138          $this->assertSame($strurl, $url->out(false));
 139  
 140          // For un-keyed array params, we expect 0..n keys to be returned.
 141          $strurl = 'http://example.com/?a%5B0%5D=0&a%5B1%5D=1';
 142          $url = new moodle_url('http://example.com/?a[]=0&a[]=1');
 143          $this->assertSame($strurl, $url->out(false));
 144      }
 145  
 146      public function test_compare_url() {
 147          $url1 = new moodle_url('index.php', array('var1' => 1, 'var2' => 2));
 148          $url2 = new moodle_url('index2.php', array('var1' => 1, 'var2' => 2, 'var3' => 3));
 149  
 150          $this->assertFalse($url1->compare($url2, URL_MATCH_BASE));
 151          $this->assertFalse($url1->compare($url2, URL_MATCH_PARAMS));
 152          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 153  
 154          $url2 = new moodle_url('index.php', array('var1' => 1, 'var3' => 3));
 155  
 156          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 157          $this->assertFalse($url1->compare($url2, URL_MATCH_PARAMS));
 158          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 159  
 160          $url2 = new moodle_url('index.php', array('var1' => 1, 'var2' => 2, 'var3' => 3));
 161  
 162          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 163          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 164          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 165  
 166          $url2 = new moodle_url('index.php', array('var2' => 2, 'var1' => 1));
 167  
 168          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 169          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 170          $this->assertTrue($url1->compare($url2, URL_MATCH_EXACT));
 171  
 172          $url1->set_anchor('test');
 173          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 174          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 175          $this->assertFalse($url1->compare($url2, URL_MATCH_EXACT));
 176  
 177          $url2->set_anchor('test');
 178          $this->assertTrue($url1->compare($url2, URL_MATCH_BASE));
 179          $this->assertTrue($url1->compare($url2, URL_MATCH_PARAMS));
 180          $this->assertTrue($url1->compare($url2, URL_MATCH_EXACT));
 181      }
 182  
 183      public function test_out_as_local_url() {
 184          global $CFG;
 185          // Test http url.
 186          $url1 = new moodle_url('/lib/tests/weblib_test.php');
 187          $this->assertSame('/lib/tests/weblib_test.php', $url1->out_as_local_url());
 188  
 189          // Test https url.
 190          $httpswwwroot = str_replace("http://", "https://", $CFG->wwwroot);
 191          $url2 = new moodle_url($httpswwwroot.'/login/profile.php');
 192          $this->assertSame('/login/profile.php', $url2->out_as_local_url());
 193  
 194          // Test http url matching wwwroot.
 195          $url3 = new moodle_url($CFG->wwwroot);
 196          $this->assertSame('', $url3->out_as_local_url());
 197  
 198          // Test http url matching wwwroot ending with slash (/).
 199          $url3 = new moodle_url($CFG->wwwroot.'/');
 200          $this->assertSame('/', $url3->out_as_local_url());
 201      }
 202  
 203      /**
 204       * @expectedException coding_exception
 205       * @return void
 206       */
 207      public function test_out_as_local_url_error() {
 208          $url2 = new moodle_url('http://www.google.com/lib/tests/weblib_test.php');
 209          $url2->out_as_local_url();
 210      }
 211  
 212      /**
 213       * You should get error with modified url
 214       *
 215       * @expectedException coding_exception
 216       * @return void
 217       */
 218      public function test_modified_url_out_as_local_url_error() {
 219          global $CFG;
 220  
 221          $modifiedurl = $CFG->wwwroot.'1';
 222          $url3 = new moodle_url($modifiedurl.'/login/profile.php');
 223          $url3->out_as_local_url();
 224      }
 225  
 226      /**
 227       * Try get local url from external https url and you should get error
 228       *
 229       * @expectedException coding_exception
 230       */
 231      public function test_https_out_as_local_url_error() {
 232          $url4 = new moodle_url('https://www.google.com/lib/tests/weblib_test.php');
 233          $url4->out_as_local_url();
 234      }
 235  
 236      public function test_moodle_url_get_scheme() {
 237          // Should return the scheme only.
 238          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
 239          $this->assertSame('http', $url->get_scheme());
 240  
 241          // Should work for secure URLs.
 242          $url = new moodle_url('https://www.example.org:447/my/file/is/here.txt?really=1');
 243          $this->assertSame('https', $url->get_scheme());
 244  
 245          // Should return an empty string if no scheme is specified.
 246          $url = new moodle_url('www.example.org:447/my/file/is/here.txt?really=1');
 247          $this->assertSame('', $url->get_scheme());
 248      }
 249  
 250      public function test_moodle_url_get_host() {
 251          // Should return the host part only.
 252          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
 253          $this->assertSame('www.example.org', $url->get_host());
 254      }
 255  
 256      public function test_moodle_url_get_port() {
 257          // Should return the port if one provided.
 258          $url = new moodle_url('http://www.example.org:447/my/file/is/here.txt?really=1');
 259          $this->assertSame(447, $url->get_port());
 260  
 261          // Should return an empty string if port not specified.
 262          $url = new moodle_url('http://www.example.org/some/path/here.php');
 263          $this->assertSame('', $url->get_port());
 264      }
 265  
 266      /**
 267       * Test the make_pluginfile_url function.
 268       *
 269       * @dataProvider make_pluginfile_url_provider
 270       * @param   bool    $slashargs
 271       * @param   array   $args Args to be provided to make_pluginfile_url
 272       * @param   string  $expected The expected result
 273       */
 274      public function test_make_pluginfile_url($slashargs, $args, $expected) {
 275          global $CFG;
 276  
 277          $this->resetAfterTest();
 278  
 279          $CFG->slasharguments = $slashargs;
 280          $url = call_user_func_array('moodle_url::make_pluginfile_url', $args);
 281          $this->assertRegexp($expected, $url->out(true));
 282      }
 283  
 284      /**
 285       * Data provider for make_pluginfile_url tests.
 286       *
 287       * @return  array[]
 288       */
 289      public function make_pluginfile_url_provider() {
 290          $baseurl = "https://www.example.com/moodle/pluginfile.php";
 291          $tokenbaseurl = "https://www.example.com/moodle/tokenpluginfile.php";
 292          return [
 293              'Standard with slashargs' => [
 294                  'slashargs' => true,
 295                  'args' => [
 296                      1,
 297                      'mod_forum',
 298                      'posts',
 299                      422,
 300                      '/my/location/',
 301                      'file.png',
 302                  ],
 303                  'expected' => "@{$baseurl}/1/mod_forum/posts/422/my/location/file.png@",
 304              ],
 305              'Standard without slashargs' => [
 306                  'slashargs' => false,
 307                  'args' => [
 308                      1,
 309                      'mod_forum',
 310                      'posts',
 311                      422,
 312                      '/my/location/',
 313                      'file.png',
 314                  ],
 315                  'expected' => "@{$baseurl}\?file=%2F1%2Fmod_forum%2Fposts%2F422%2Fmy%2Flocation%2Ffile.png@",
 316              ],
 317              'Token included with slashargs' => [
 318                  'slashargs' => true,
 319                  'args' => [
 320                      1,
 321                      'mod_forum',
 322                      'posts',
 323                      422,
 324                      '/my/location/',
 325                      'file.png',
 326                      false,
 327                      true,
 328                  ],
 329                  'expected' => "@{$tokenbaseurl}/[^/]*/1/mod_forum/posts/422/my/location/file.png@",
 330              ],
 331              'Token included without slashargs' => [
 332                  'slashargs' => false,
 333                  'args' => [
 334                      1,
 335                      'mod_forum',
 336                      'posts',
 337                      422,
 338                      '/my/location/',
 339                      'file.png',
 340                      false,
 341                      true,
 342                  ],
 343                  'expected' => "@{$tokenbaseurl}\?file=%2F1%2Fmod_forum%2Fposts%2F422%2Fmy%2Flocation%2Ffile.png&amp;token=[a-z0-9]*@",
 344              ],
 345          ];
 346      }
 347  }