Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

   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  namespace core_calendar;
  18  
  19  use core_calendar\external\calendar_event_exporter;
  20  use core_calendar\local\event\container;
  21  
  22  defined('MOODLE_INTERNAL') || die();
  23  require_once (__DIR__ . '/helpers.php');
  24  
  25  /**
  26   * Calendar event exporter testcase.
  27   *
  28   * @package core_calendar
  29   * @copyright 2017 Ryan Wyllie <ryan@moodle.com>
  30   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  31   */
  32  class calendar_event_exporter_test extends \advanced_testcase {
  33      /**
  34       * Data provider for the timestamp min limit test case to confirm
  35       * that the minimum time limit is set correctly on the boundary cases.
  36       */
  37      public function get_timestamp_min_limit_test_cases() {
  38          $now = time();
  39          $todaymidnight = usergetmidnight($now);
  40          $tomorrowmidnight = $todaymidnight + DAYSECS;
  41          $eightam = $todaymidnight + (60 * 60 * 8);
  42          $starttime = (new \DateTime())->setTimestamp($eightam);
  43  
  44          return [
  45              'before min' => [
  46                  $starttime,
  47                  [
  48                      ($starttime->getTimestamp() + 1),
  49                      'some error'
  50                  ],
  51                  $tomorrowmidnight
  52              ],
  53              'equal min' => [
  54                  $starttime,
  55                  [
  56                      $starttime->getTimestamp(),
  57                      'some error'
  58                  ],
  59                  $todaymidnight
  60              ],
  61              'after min' => [
  62                  $starttime,
  63                  [
  64                      ($starttime->getTimestamp() - 1),
  65                      'some error'
  66                  ],
  67                  $todaymidnight
  68              ]
  69          ];
  70      }
  71  
  72      /**
  73       * @dataProvider get_timestamp_min_limit_test_cases()
  74       */
  75      public function test_get_timestamp_min_limit($starttime, $min, $expected) {
  76          $class = calendar_event_exporter::class;
  77          $mock = $this->getMockBuilder($class)
  78              ->disableOriginalConstructor()
  79              ->onlyMethods([])
  80              ->getMock();
  81          $reflector = new \ReflectionClass($class);
  82          $method = $reflector->getMethod('get_timestamp_min_limit');
  83          $method->setAccessible(true);
  84  
  85          $result = $method->invoke($mock, $starttime, $min);
  86          $this->assertEquals($expected, $result['mindaytimestamp']);
  87          $this->assertEquals($min[1], $result['mindayerror']);
  88      }
  89  
  90      /**
  91       * Data provider for the timestamp max limit test case to confirm
  92       * that the maximum time limit is set correctly on the boundary cases.
  93       */
  94      public function get_timestamp_max_limit_test_cases() {
  95          $now = time();
  96          $todaymidnight = usergetmidnight($now);
  97          $yesterdaymidnight = $todaymidnight - DAYSECS;
  98          $eightam = $todaymidnight + (60 * 60 * 8);
  99          $starttime = (new \DateTime())->setTimestamp($eightam);
 100  
 101          return [
 102              'before max' => [
 103                  $starttime,
 104                  [
 105                      ($starttime->getTimestamp() + 1),
 106                      'some error'
 107                  ],
 108                  $todaymidnight
 109              ],
 110              'equal max' => [
 111                  $starttime,
 112                  [
 113                      $starttime->getTimestamp(),
 114                      'some error'
 115                  ],
 116                  $todaymidnight
 117              ],
 118              'after max' => [
 119                  $starttime,
 120                  [
 121                      ($starttime->getTimestamp() - 1),
 122                      'some error'
 123                  ],
 124                  $yesterdaymidnight
 125              ]
 126          ];
 127      }
 128  
 129      /**
 130       * @dataProvider get_timestamp_max_limit_test_cases()
 131       */
 132      public function test_get_timestamp_max_limit($starttime, $max, $expected) {
 133          $class = calendar_event_exporter::class;
 134          $mock = $this->getMockBuilder($class)
 135              ->disableOriginalConstructor()
 136              ->onlyMethods([])
 137              ->getMock();
 138          $reflector = new \ReflectionClass($class);
 139          $method = $reflector->getMethod('get_timestamp_max_limit');
 140          $method->setAccessible(true);
 141  
 142          $result = $method->invoke($mock, $starttime, $max);
 143          $this->assertEquals($expected, $result['maxdaytimestamp']);
 144          $this->assertEquals($max[1], $result['maxdayerror']);
 145      }
 146  
 147      /**
 148       * Exporting a course event should generate the course URL.
 149       */
 150      public function test_calendar_event_exporter_course_url_course_event() {
 151          global $CFG, $PAGE;
 152          require_once($CFG->dirroot . '/course/lib.php');
 153  
 154          $this->resetAfterTest(true);
 155          $this->setAdminUser();
 156          $generator = $this->getDataGenerator();
 157          $user = $generator->create_user();
 158          $course = $generator->create_course();
 159          $context = \context_course::instance($course->id);
 160          $now = time();
 161          $mapper = container::get_event_mapper();
 162          $legacyevent = create_event([
 163              'courseid' => $course->id,
 164              'userid' => 1,
 165              'eventtype' => 'course',
 166              'timestart' => $now
 167          ]);
 168          $event = $mapper->from_legacy_event_to_event($legacyevent);
 169          $exporter = new calendar_event_exporter($event, [
 170              'context' => $context,
 171              'course' => $course,
 172              'moduleinstance' => null,
 173              'daylink' => new \moodle_url(''),
 174              'type' => type_factory::get_calendar_instance(),
 175              'today' => $now
 176          ]);
 177  
 178          $courseurl = course_get_url($course->id);
 179          $expected = $courseurl->out(false);
 180          $renderer = $PAGE->get_renderer('core_calendar');
 181          $exportedevent = $exporter->export($renderer);
 182  
 183          // The exported URL should be for the course.
 184          $this->assertEquals($expected, $exportedevent->url);
 185      }
 186  
 187      /**
 188       * Exporting a user event should generate the site course URL.
 189       */
 190      public function test_calendar_event_exporter_course_url_user_event() {
 191          global $CFG, $PAGE;
 192          require_once($CFG->dirroot . '/course/lib.php');
 193  
 194          $this->resetAfterTest(true);
 195          $this->setAdminUser();
 196          $generator = $this->getDataGenerator();
 197          $user = $generator->create_user();
 198          $context = \context_user::instance($user->id);
 199          $now = time();
 200          $mapper = container::get_event_mapper();
 201          $legacyevent = create_event([
 202              'courseid' => 0,
 203              'userid' => $user->id,
 204              'eventtype' => 'user',
 205              'timestart' => $now
 206          ]);
 207          $event = $mapper->from_legacy_event_to_event($legacyevent);
 208          $exporter = new calendar_event_exporter($event, [
 209              'context' => $context,
 210              'course' => null,
 211              'moduleinstance' => null,
 212              'daylink' => new \moodle_url(''),
 213              'type' => type_factory::get_calendar_instance(),
 214              'today' => $now
 215          ]);
 216  
 217          $courseurl = course_get_url(SITEID);
 218          $expected = $courseurl->out(false);
 219          $renderer = $PAGE->get_renderer('core_calendar');
 220          $exportedevent = $exporter->export($renderer);
 221  
 222          // The exported URL should be for the site course.
 223          $this->assertEquals($expected, $exportedevent->url);
 224      }
 225  
 226      /**
 227       * Popup name respects filters for course shortname.
 228       */
 229      public function test_calendar_event_exporter_popupname_course_shortname_strips_links() {
 230          global $CFG, $PAGE;
 231  
 232          $this->resetAfterTest(true);
 233          $this->setAdminUser();
 234          $generator = $this->getDataGenerator();
 235          $user = $generator->create_user();
 236          $rawshortname = 'Shortname <a href="#">link</a>';
 237          $nolinkshortname = strip_links($rawshortname);
 238          $course = $generator->create_course(['shortname' => $rawshortname]);
 239          $coursecontext = \context_course::instance($course->id);
 240          $now = time();
 241          $mapper = container::get_event_mapper();
 242          $renderer = $PAGE->get_renderer('core_calendar');
 243          $legacyevent = create_event([
 244              'courseid' => $course->id,
 245              'userid' => 1,
 246              'eventtype' => 'course',
 247              'timestart' => $now
 248          ]);
 249          $event = $mapper->from_legacy_event_to_event($legacyevent);
 250          $exporter = new calendar_event_exporter($event, [
 251              'context' => $coursecontext,
 252              'course' => $course,
 253              'moduleinstance' => null,
 254              'daylink' => new \moodle_url(''),
 255              'type' => type_factory::get_calendar_instance(),
 256              'today' => $now
 257          ]);
 258  
 259          $exportedevent = $exporter->export($renderer);
 260          // Links should always be stripped from the course short name.
 261          $this->assertMatchesRegularExpression("/$nolinkshortname/", $exportedevent->popupname);
 262      }
 263  
 264      /**
 265       * Exported event contains the exported course.
 266       */
 267      public function test_calendar_event_exporter_exports_course() {
 268          global $CFG, $PAGE;
 269  
 270          $this->resetAfterTest(true);
 271          $this->setAdminUser();
 272          $generator = $this->getDataGenerator();
 273          $user = $generator->create_user();
 274          $rawshortname = 'Shortname <a href="#">link</a>';
 275          $nolinkshortname = strip_links($rawshortname);
 276          $course = $generator->create_course(['shortname' => $rawshortname]);
 277          $coursecontext = \context_course::instance($course->id);
 278          $now = time();
 279          $mapper = container::get_event_mapper();
 280          $renderer = $PAGE->get_renderer('core_calendar');
 281          $legacyevent = create_event([
 282              'courseid' => $course->id,
 283              'userid' => 1,
 284              'eventtype' => 'course',
 285              'timestart' => $now
 286          ]);
 287          $event = $mapper->from_legacy_event_to_event($legacyevent);
 288          $exporter = new calendar_event_exporter($event, [
 289              'context' => $coursecontext,
 290              'course' => $course,
 291              'moduleinstance' => null,
 292              'daylink' => new \moodle_url(''),
 293              'type' => type_factory::get_calendar_instance(),
 294              'today' => $now
 295          ]);
 296  
 297          $exportedevent = $exporter->export($renderer);
 298          $courseexporter = new \core_course\external\course_summary_exporter($course, [
 299              'context' => $coursecontext
 300          ]);
 301          $exportedcourse = $courseexporter->export($renderer);
 302          $this->assertEquals($exportedevent->course, $exportedcourse);
 303      }
 304  }