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   * Unit tests for some mod URL lib stuff.
  19   *
  20   * @package    mod_url
  21   * @category   phpunit
  22   * @copyright  2012 Petr Skoda {@link http://skodak.org}
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  
  29  /**
  30   * mod_url tests
  31   *
  32   * @package    mod_url
  33   * @category   phpunit
  34   * @copyright  2011 Petr Skoda {@link http://skodak.org}
  35   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  36   */
  37  class mod_url_lib_testcase extends advanced_testcase {
  38  
  39      /**
  40       * Prepares things before this test case is initialised
  41       * @return void
  42       */
  43      public static function setUpBeforeClass(): void {
  44          global $CFG;
  45          require_once($CFG->dirroot . '/mod/url/lib.php');
  46          require_once($CFG->dirroot . '/mod/url/locallib.php');
  47      }
  48  
  49      /**
  50       * Tests the url_appears_valid_url function
  51       * @return void
  52       */
  53      public function test_url_appears_valid_url() {
  54          $this->assertTrue(url_appears_valid_url('http://example'));
  55          $this->assertTrue(url_appears_valid_url('http://www.example.com'));
  56          $this->assertTrue(url_appears_valid_url('http://www.examplé.com'));
  57          $this->assertTrue(url_appears_valid_url('http://💩.la'));
  58          $this->assertTrue(url_appears_valid_url('http://香港大學.香港'));
  59          $this->assertTrue(url_appears_valid_url('http://وزارة-الأتصالات.مصر'));
  60          $this->assertTrue(url_appears_valid_url('http://www.теннис-алт.рф'));
  61          $this->assertTrue(url_appears_valid_url('http://имена.бг'));
  62          $this->assertTrue(url_appears_valid_url('http://straße.de'));
  63          $this->assertTrue(url_appears_valid_url('http://キース.コム'));
  64          $this->assertTrue(url_appears_valid_url('http://太亞.中国'));
  65          $this->assertTrue(url_appears_valid_url('http://www.რეგისტრაცია.გე'));
  66          $this->assertTrue(url_appears_valid_url('http://уміц.укр'));
  67          $this->assertTrue(url_appears_valid_url('http://현대.한국'));
  68          $this->assertTrue(url_appears_valid_url('http://мон.мон'));
  69          $this->assertTrue(url_appears_valid_url('http://тест.қаз'));
  70          $this->assertTrue(url_appears_valid_url('http://рнидс.срб'));
  71          $this->assertTrue(url_appears_valid_url('http://اسماء.شبكة'));
  72          $this->assertTrue(url_appears_valid_url('http://www.informationssäkerhet.se'));
  73          $this->assertTrue(url_appears_valid_url('http://москва.рф/services'));
  74          $this->assertTrue(url_appears_valid_url('http://detdumærker.dk'));
  75          $this->assertTrue(url_appears_valid_url('http://www.exa-mple2.com'));
  76          $this->assertTrue(url_appears_valid_url('http://www.example.com/~nobody/index.html'));
  77          $this->assertTrue(url_appears_valid_url('http://www.example.com#hmm'));
  78          $this->assertTrue(url_appears_valid_url('http://www.example.com/#hmm'));
  79          $this->assertTrue(url_appears_valid_url('http://www.example.com/žlutý koníček/lala.txt'));
  80          $this->assertTrue(url_appears_valid_url('http://www.example.com/žlutý koníček/lala.txt#hmmmm'));
  81          $this->assertTrue(url_appears_valid_url('http://www.example.com/index.php?xx=yy&zz=aa'));
  82          $this->assertTrue(url_appears_valid_url('http://www.example.com:80/index.php?xx=yy&zz=aa'));
  83          $this->assertTrue(url_appears_valid_url('https://user:password@www.example.com/žlutý koníček/lala.txt'));
  84          $this->assertTrue(url_appears_valid_url('ftp://user:password@www.example.com/žlutý koníček/lala.txt'));
  85  
  86          $this->assertFalse(url_appears_valid_url('http:example.com'));
  87          $this->assertFalse(url_appears_valid_url('http:/example.com'));
  88          $this->assertFalse(url_appears_valid_url('http://'));
  89          $this->assertFalse(url_appears_valid_url('http://www.exa mple.com'));
  90          $this->assertFalse(url_appears_valid_url('http://@www.example.com'));
  91          $this->assertFalse(url_appears_valid_url('http://user:@www.example.com'));
  92  
  93          $this->assertTrue(url_appears_valid_url('lalala://@:@/'));
  94      }
  95  
  96      /**
  97       * Test url_view
  98       * @return void
  99       */
 100      public function test_url_view() {
 101          global $CFG;
 102  
 103          $CFG->enablecompletion = 1;
 104          $this->resetAfterTest();
 105  
 106          // Setup test data.
 107          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 108          $url = $this->getDataGenerator()->create_module('url', array('course' => $course->id),
 109                                                              array('completion' => 2, 'completionview' => 1));
 110          $context = context_module::instance($url->cmid);
 111          $cm = get_coursemodule_from_instance('url', $url->id);
 112  
 113          // Trigger and capture the event.
 114          $sink = $this->redirectEvents();
 115  
 116          $this->setAdminUser();
 117          url_view($url, $course, $cm, $context);
 118  
 119          $events = $sink->get_events();
 120          // 2 additional events thanks to completion.
 121          $this->assertCount(3, $events);
 122          $event = array_shift($events);
 123  
 124          // Checking that the event contains the expected values.
 125          $this->assertInstanceOf('\mod_url\event\course_module_viewed', $event);
 126          $this->assertEquals($context, $event->get_context());
 127          $url = new \moodle_url('/mod/url/view.php', array('id' => $cm->id));
 128          $this->assertEquals($url, $event->get_url());
 129          $this->assertEventContextNotUsed($event);
 130          $this->assertNotEmpty($event->get_name());
 131  
 132          // Check completion status.
 133          $completion = new completion_info($course);
 134          $completiondata = $completion->get_data($cm);
 135          $this->assertEquals(1, $completiondata->completionstate);
 136      }
 137  
 138      /**
 139       * Test mod_url_core_calendar_provide_event_action with user override
 140       */
 141      public function test_url_core_calendar_provide_event_action_user_override() {
 142          global $CFG, $USER;
 143  
 144          $this->resetAfterTest();
 145          $this->setAdminUser();
 146          $user = $this->getDataGenerator()->create_user();
 147          $CFG->enablecompletion = 1;
 148  
 149          // Create the activity.
 150          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 151          $url = $this->getDataGenerator()->create_module('url', array('course' => $course->id),
 152              array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
 153  
 154          // Get some additional data.
 155          $cm = get_coursemodule_from_instance('url', $url->id);
 156  
 157          // Create a calendar event.
 158          $event = $this->create_action_event($course->id, $url->id,
 159              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 160  
 161          // Mark the activity as completed.
 162          $completion = new completion_info($course);
 163          $completion->set_module_viewed($cm);
 164  
 165          // Create an action factory.
 166          $factory = new \core_calendar\action_factory();
 167  
 168          // Decorate action event.
 169          $actionevent = mod_url_core_calendar_provide_event_action($event, $factory, $USER->id);
 170  
 171          // Decorate action with a userid override.
 172          $actionevent2 = mod_url_core_calendar_provide_event_action($event, $factory, $user->id);
 173  
 174          // Ensure result was null because it has been marked as completed for the associated user.
 175          // Logic was brought across from the "_already_completed" function.
 176          $this->assertNull($actionevent);
 177  
 178          // Confirm the event was decorated.
 179          $this->assertNotNull($actionevent2);
 180          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent2);
 181          $this->assertEquals(get_string('view'), $actionevent2->get_name());
 182          $this->assertInstanceOf('moodle_url', $actionevent2->get_url());
 183          $this->assertEquals(1, $actionevent2->get_item_count());
 184          $this->assertTrue($actionevent2->is_actionable());
 185      }
 186  
 187      public function test_url_core_calendar_provide_event_action() {
 188          $this->resetAfterTest();
 189          $this->setAdminUser();
 190  
 191          // Create the activity.
 192          $course = $this->getDataGenerator()->create_course();
 193          $url = $this->getDataGenerator()->create_module('url', array('course' => $course->id));
 194  
 195          // Create a calendar event.
 196          $event = $this->create_action_event($course->id, $url->id,
 197              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 198  
 199          // Create an action factory.
 200          $factory = new \core_calendar\action_factory();
 201  
 202          // Decorate action event.
 203          $actionevent = mod_url_core_calendar_provide_event_action($event, $factory);
 204  
 205          // Confirm the event was decorated.
 206          $this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
 207          $this->assertEquals(get_string('view'), $actionevent->get_name());
 208          $this->assertInstanceOf('moodle_url', $actionevent->get_url());
 209          $this->assertEquals(1, $actionevent->get_item_count());
 210          $this->assertTrue($actionevent->is_actionable());
 211      }
 212  
 213      public function test_url_core_calendar_provide_event_action_already_completed() {
 214          global $CFG;
 215  
 216          $this->resetAfterTest();
 217          $this->setAdminUser();
 218  
 219          $CFG->enablecompletion = 1;
 220  
 221          // Create the activity.
 222          $course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
 223          $url = $this->getDataGenerator()->create_module('url', array('course' => $course->id),
 224              array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
 225  
 226          // Get some additional data.
 227          $cm = get_coursemodule_from_instance('url', $url->id);
 228  
 229          // Create a calendar event.
 230          $event = $this->create_action_event($course->id, $url->id,
 231              \core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
 232  
 233          // Mark the activity as completed.
 234          $completion = new completion_info($course);
 235          $completion->set_module_viewed($cm);
 236  
 237          // Create an action factory.
 238          $factory = new \core_calendar\action_factory();
 239  
 240          // Decorate action event.
 241          $actionevent = mod_url_core_calendar_provide_event_action($event, $factory);
 242  
 243          // Ensure result was null.
 244          $this->assertNull($actionevent);
 245      }
 246  
 247      /**
 248       * Creates an action event.
 249       *
 250       * @param int $courseid The course id.
 251       * @param int $instanceid The instance id.
 252       * @param string $eventtype The event type.
 253       * @return bool|calendar_event
 254       */
 255      private function create_action_event($courseid, $instanceid, $eventtype) {
 256          $event = new stdClass();
 257          $event->name = 'Calendar event';
 258          $event->modulename  = 'url';
 259          $event->courseid = $courseid;
 260          $event->instance = $instanceid;
 261          $event->type = CALENDAR_EVENT_TYPE_ACTION;
 262          $event->eventtype = $eventtype;
 263          $event->timestart = time();
 264  
 265          return calendar_event::create($event);
 266      }
 267  }