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   * Raw event retrieval strategy tests.
  19   *
  20   * @package core_calendar
  21   * @copyright 2017 Cameron Ball <cameron@cameron1729.xyz>
  22   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  global $CFG;
  28  require_once($CFG->dirroot . '/calendar/tests/helpers.php');
  29  
  30  use core_calendar\local\event\strategies\raw_event_retrieval_strategy;
  31  
  32  /**
  33   * Raw event retrieval strategy testcase.
  34   *
  35   * @copyright 2017 Cameron Ball <cameron@cameron1729.xyz>
  36   * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testcase {
  39      /**
  40       * Test retrieval strategy when module is disabled.
  41       */
  42      public function test_get_raw_events_with_disabled_module() {
  43          global $DB;
  44  
  45          $this->resetAfterTest();
  46          $retrievalstrategy = new raw_event_retrieval_strategy();
  47          $generator = $this->getDataGenerator();
  48          $course = $generator->create_course();
  49          $student = $generator->create_user();
  50          $generator->enrol_user($student->id, $course->id, 'student');
  51          $this->setUser($student);
  52          $events = [
  53              [
  54                  'name' => 'Start of assignment',
  55                  'description' => '',
  56                  'location' => 'Test',
  57                  'format' => 1,
  58                  'courseid' => $course->id,
  59                  'groupid' => 0,
  60                  'userid' => 2,
  61                  'modulename' => 'assign',
  62                  'instance' => 1,
  63                  'eventtype' => 'due',
  64                  'timestart' => time(),
  65                  'timeduration' => 86400,
  66                  'visible' => 1
  67              ], [
  68                  'name' => 'Start of lesson',
  69                  'description' => '',
  70                  'location' => 'Test',
  71                  'format' => 1,
  72                  'courseid' => $course->id,
  73                  'groupid' => 0,
  74                  'userid' => 2,
  75                  'modulename' => 'lesson',
  76                  'instance' => 1,
  77                  'eventtype' => 'end',
  78                  'timestart' => time(),
  79                  'timeduration' => 86400,
  80                  'visible' => 1
  81              ]
  82          ];
  83  
  84          foreach ($events as $event) {
  85              calendar_event::create($event, false);
  86          }
  87  
  88          // Get all events.
  89          $events = $retrievalstrategy->get_raw_events(null, [0], null);
  90          $this->assertCount(2, $events);
  91  
  92          // Disable the lesson module.
  93          $DB->set_field('modules', 'visible', 0, ['name' => 'lesson']);
  94  
  95          // Check that we only return the assign event.
  96          $events = $retrievalstrategy->get_raw_events(null, [0], null);
  97          $this->assertCount(1, $events);
  98          $event = reset($events);
  99          $this->assertEquals('assign', $event->modulename);
 100  
 101          // Now, log out and repeat the above test in the reverse order.
 102          $this->setUser();
 103  
 104          // Check that we only return the assign event (given that the lesson module is still disabled).
 105          $events = $retrievalstrategy->get_raw_events([$student->id], [0], null);
 106          $this->assertCount(1, $events);
 107          $event = reset($events);
 108          $this->assertEquals('assign', $event->modulename);
 109  
 110          // Enable the lesson module.
 111          $DB->set_field('modules', 'visible', 1, ['name' => 'lesson']);
 112  
 113          // Get all events.
 114          $events = $retrievalstrategy->get_raw_events(null, [0], null);
 115          $this->assertCount(2, $events);
 116      }
 117  
 118      /**
 119       * Test retrieval strategy when there are overrides.
 120       */
 121      public function test_get_raw_event_strategy_with_overrides() {
 122          $this->resetAfterTest();
 123  
 124          $retrievalstrategy = new raw_event_retrieval_strategy();
 125          $generator = $this->getDataGenerator();
 126          $course = $generator->create_course();
 127          $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
 128  
 129          $instance = $plugingenerator->create_instance(['course' => $course->id]);
 130  
 131          // Create users.
 132          $useroverridestudent = $generator->create_user();
 133          $group1student = $generator->create_user();
 134          $group2student = $generator->create_user();
 135          $group12student = $generator->create_user();
 136          $nogroupstudent = $generator->create_user();
 137  
 138          // Enrol users.
 139          $generator->enrol_user($useroverridestudent->id, $course->id, 'student');
 140          $generator->enrol_user($group1student->id, $course->id, 'student');
 141          $generator->enrol_user($group2student->id, $course->id, 'student');
 142          $generator->enrol_user($group12student->id, $course->id, 'student');
 143  
 144          $generator->enrol_user($nogroupstudent->id, $course->id, 'student');
 145  
 146          // Create groups.
 147          $group1 = $generator->create_group(['courseid' => $course->id, 'name' => 'Group 1']);
 148          $group2 = $generator->create_group(['courseid' => $course->id, 'name' => 'Group 2']);
 149  
 150          // Add members to groups.
 151          $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group1student->id]);
 152          $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group2student->id]);
 153          $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group12student->id]);
 154          $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group12student->id]);
 155  
 156          $now = time();
 157  
 158          // Events with the same module name, instance and event type.
 159          $events = [
 160              [
 161                  'name' => 'Assignment 1 due date',
 162                  'description' => '',
 163                  'location' => 'Test',
 164                  'format' => 0,
 165                  'courseid' => $course->id,
 166                  'groupid' => 0,
 167                  'userid' => 2,
 168                  'modulename' => 'assign',
 169                  'instance' => $instance->id,
 170                  'eventtype' => 'due',
 171                  'timestart' => $now,
 172                  'timeduration' => 0,
 173                  'visible' => 1
 174              ], [
 175                  'name' => 'Assignment 1 due date - User override',
 176                  'description' => '',
 177                  'location' => 'Test',
 178                  'format' => 1,
 179                  'courseid' => 0,
 180                  'groupid' => 0,
 181                  'userid' => $useroverridestudent->id,
 182                  'modulename' => 'assign',
 183                  'instance' => $instance->id,
 184                  'eventtype' => 'due',
 185                  'timestart' => $now + 86400,
 186                  'timeduration' => 0,
 187                  'visible' => 1,
 188                  'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY
 189              ], [
 190                  'name' => 'Assignment 1 due date - Group A override',
 191                  'description' => '',
 192                  'location' => 'Test',
 193                  'format' => 1,
 194                  'courseid' => $course->id,
 195                  'groupid' => $group1->id,
 196                  'userid' => 2,
 197                  'modulename' => 'assign',
 198                  'instance' => $instance->id,
 199                  'eventtype' => 'due',
 200                  'timestart' => $now + (2 * 86400),
 201                  'timeduration' => 0,
 202                  'visible' => 1,
 203                  'priority' => 1,
 204              ], [
 205                  'name' => 'Assignment 1 due date - Group B override',
 206                  'description' => '',
 207                  'location' => 'Test',
 208                  'format' => 1,
 209                  'courseid' => $course->id,
 210                  'groupid' => $group2->id,
 211                  'userid' => 2,
 212                  'modulename' => 'assign',
 213                  'instance' => $instance->id,
 214                  'eventtype' => 'due',
 215                  'timestart' => $now + (3 * 86400),
 216                  'timeduration' => 0,
 217                  'visible' => 1,
 218                  'priority' => 2,
 219              ],
 220          ];
 221  
 222          foreach ($events as $event) {
 223              calendar_event::create($event, false);
 224          }
 225  
 226          $groups = [$group1->id, $group2->id];
 227  
 228          // Do the following tests multiple times when logged in with different users. Also run the whole set when logged out.
 229          // In any cases, the tests should not depend on the logged-in user.
 230          foreach ([$useroverridestudent, $nogroupstudent, $group12student, $group1student, null] as $login) {
 231              $this->setUser($login);
 232  
 233              // Get user override events.
 234              $events = $retrievalstrategy->get_raw_events([$useroverridestudent->id], $groups, [$course->id]);
 235              $this->assertCount(1, $events);
 236              $event = reset($events);
 237              $this->assertEquals('Assignment 1 due date - User override', $event->name);
 238  
 239              // Get events for user that does not belong to any group and has no user override events.
 240              $events = $retrievalstrategy->get_raw_events([$nogroupstudent->id], $groups, [$course->id]);
 241              $this->assertCount(1, $events);
 242              $event = reset($events);
 243              $this->assertEquals('Assignment 1 due date', $event->name);
 244  
 245              // Get events for user that belongs to groups A and B and has no user override events.
 246              $events = $retrievalstrategy->get_raw_events([$group12student->id], $groups, [$course->id]);
 247              $this->assertCount(1, $events);
 248              $event = reset($events);
 249              $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
 250  
 251              // Get events for user that belongs to group A and has no user override events.
 252              $events = $retrievalstrategy->get_raw_events([$group1student->id], $groups, [$course->id]);
 253              $this->assertCount(1, $events);
 254              $event = reset($events);
 255              $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
 256          }
 257  
 258          // Add repeating events.
 259          $repeatingevents = [
 260              [
 261                  'name' => 'Repeating site event',
 262                  'description' => '',
 263                  'location' => 'Test',
 264                  'format' => 1,
 265                  'courseid' => SITEID,
 266                  'groupid' => 0,
 267                  'userid' => 2,
 268                  'repeatid' => 1,
 269                  'modulename' => '0',
 270                  'instance' => 0,
 271                  'eventtype' => 'site',
 272                  'timestart' => $now + 86400,
 273                  'timeduration' => 0,
 274                  'visible' => 1,
 275              ],
 276              [
 277                  'name' => 'Repeating site event',
 278                  'description' => '',
 279                  'location' => 'Test',
 280                  'format' => 1,
 281                  'courseid' => SITEID,
 282                  'groupid' => 0,
 283                  'userid' => 2,
 284                  'repeatid' => 1,
 285                  'modulename' => '0',
 286                  'instance' => 0,
 287                  'eventtype' => 'site',
 288                  'timestart' => $now + (2 * 86400),
 289                  'timeduration' => 0,
 290                  'visible' => 1,
 291              ],
 292          ];
 293  
 294          foreach ($repeatingevents as $event) {
 295              calendar_event::create($event, false);
 296          }
 297  
 298          // Make sure repeating events are not filtered out.
 299          $events = $retrievalstrategy->get_raw_events();
 300          $this->assertCount(3, $events);
 301      }
 302  
 303      /**
 304       * Test retrieval strategy with category specifications.
 305       */
 306      public function test_get_raw_events_category() {
 307          $this->resetAfterTest();
 308          $retrievalstrategy = new raw_event_retrieval_strategy();
 309          $generator = $this->getDataGenerator();
 310          $category1 = $generator->create_category();
 311          $category2 = $generator->create_category();
 312          $events = [
 313              [
 314                  'name' => 'E1',
 315                  'eventtype' => 'category',
 316                  'description' => '',
 317                  'location' => 'Test',
 318                  'format' => 1,
 319                  'categoryid' => $category1->id,
 320                  'userid' => 2,
 321                  'timestart' => time(),
 322              ],
 323              [
 324                  'name' => 'E2',
 325                  'eventtype' => 'category',
 326                  'description' => '',
 327                  'location' => 'Test',
 328                  'format' => 1,
 329                  'categoryid' => $category2->id,
 330                  'userid' => 2,
 331                  'timestart' => time() + 1,
 332              ],
 333          ];
 334  
 335          foreach ($events as $event) {
 336              calendar_event::create($event, false);
 337          }
 338  
 339          // Get all events.
 340          $events = $retrievalstrategy->get_raw_events(null, null, null, null);
 341          $this->assertCount(2, $events);
 342  
 343          $event = array_shift($events);
 344          $this->assertEquals('E1', $event->name);
 345          $event = array_shift($events);
 346          $this->assertEquals('E2', $event->name);
 347  
 348          // Get events for C1 events.
 349          $events = $retrievalstrategy->get_raw_events(null, null, null, [$category1->id]);
 350          $this->assertCount(1, $events);
 351  
 352          $event = array_shift($events);
 353          $this->assertEquals('E1', $event->name);
 354  
 355          // Get events for C2 events.
 356          $events = $retrievalstrategy->get_raw_events(null, null, null, [$category2->id]);
 357          $this->assertCount(1, $events);
 358  
 359          $event = array_shift($events);
 360          $this->assertEquals('E2', $event->name);
 361  
 362          // Get events for several categories.
 363          $events = $retrievalstrategy->get_raw_events(null, null, null, [$category1->id, $category2->id]);
 364          $this->assertCount(2, $events);
 365      }
 366  
 367      public function test_get_raw_events_for_multiple_users() {
 368          $this->resetAfterTest();
 369  
 370          $generator = $this->getDataGenerator();
 371  
 372          // Create users.
 373          $user1 = $generator->create_user();
 374          $user2 = $generator->create_user();
 375          $user3 = $generator->create_user();
 376  
 377          // Create user events.
 378          $events = [
 379              [
 380                  'name' => 'User1 Event',
 381                  'eventtype' => 'user',
 382                  'userid' => $user1->id,
 383                  'timestart' => time(),
 384              ], [
 385                  'name' => 'User2 Event',
 386                  'eventtype' => 'user',
 387                  'userid' => $user2->id,
 388                  'timestart' => time(),
 389              ], [
 390                  'name' => 'User3 Event',
 391                  'eventtype' => 'user',
 392                  'userid' => $user3->id,
 393                  'timestart' => time(),
 394              ]
 395          ];
 396          foreach ($events as $event) {
 397              calendar_event::create($event, false);
 398          }
 399  
 400          $retrievalstrategy = new raw_event_retrieval_strategy();
 401  
 402          // Get all events.
 403          $events = $retrievalstrategy->get_raw_events([$user1->id, $user2->id]);
 404          $this->assertCount(2, $events);
 405          $this->assertEqualsCanonicalizing(
 406                  ['User1 Event', 'User2 Event'],
 407                  array_column($events, 'name'));
 408      }
 409  
 410      public function test_get_raw_events_for_groups_with_no_members() {
 411          $this->resetAfterTest();
 412  
 413          $generator = $this->getDataGenerator();
 414  
 415          $course = $generator->create_course();
 416  
 417          // Create groups.
 418          $group1 = $generator->create_group(['courseid' => $course->id, 'name' => 'Group 1']);
 419          $group2 = $generator->create_group(['courseid' => $course->id, 'name' => 'Group 2']);
 420  
 421          // Create group events.
 422          $events = [
 423              [
 424                  'name' => 'Group 1 Event',
 425                  'eventtype' => 'group',
 426                  'groupid' => $group1->id,
 427                  'timestart' => time(),
 428              ], [
 429                  'name' => 'Group 2 Event',
 430                  'eventtype' => 'group',
 431                  'groupid' => $group2->id,
 432                  'timestart' => time(),
 433              ]
 434          ];
 435          foreach ($events as $event) {
 436              calendar_event::create($event, false);
 437          }
 438  
 439          $retrievalstrategy = new raw_event_retrieval_strategy;
 440  
 441          // Get group eventsl.
 442          $events = $retrievalstrategy->get_raw_events(null, [$group1->id, $group2->id]);
 443          $this->assertCount(2, $events);
 444          $this->assertEqualsCanonicalizing(
 445                  ['Group 1 Event', 'Group 2 Event'],
 446                  array_column($events, 'name'));
 447      }
 448  
 449      /**
 450       * Test retrieval strategy with empty filters.
 451       * This covers a edge case not covered elsewhere to ensure its SQL is cross
 452       * db compatible. The test is ensuring we don't get a DML Exception with
 453       * the filters setup this way.
 454       */
 455      public function test_get_raw_events_with_empty_user_and_category_lists() {
 456          $retrievalstrategy = new raw_event_retrieval_strategy;
 457          $retrievalstrategy->get_raw_events([], null, null, []);
 458      }
 459  }