Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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