Search moodle.org's
Developer Documentation

  • Bug fixes for general core bugs in 3.7.x will end 11 May 2020 (12 months).
  • Bug fixes for security issues in 3.7.x will end 9 November 2020 (18 months) - Support has ended.
  • minimum PHP 7.1.0 Note: minimum PHP version has increased since Moodle 3.6. PHP 7.2.x and 7.3.x are supported too. PHP 7.x could have some engine limitations.
  • Differences Between: [Versions 35 and 37] [Versions 36 and 37] [Versions 37 and 310] [Versions 37 and 311]

       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   * Contains the class containing unit tests for the calendar lib.
      19   *
      20   * @package    core_calendar
      21   * @copyright  2017 Mark Nelson <markn@moodle.com>
      22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      23   */
      24  
      25  defined('MOODLE_INTERNAL') || die();
      26  
      27  require_once (__DIR__ . '/helpers.php');
      28  
      29  /**
      30   * Class contaning unit tests for the calendar lib.
      31   *
      32   * @package    core_calendar
      33   * @copyright  2017 Mark Nelson <markn@moodle.com>
      34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      35   */
      36  class core_calendar_lib_testcase extends advanced_testcase {
      37  
      38      /**
      39       * Tests set up
      40       */
      41      protected function setUp() {
      42          $this->resetAfterTest();
      43      }
      44  
      45      /**
      46       * Test that the get_events() function only returns activity events that are enabled.
      47       */
      48      public function test_get_events_with_disabled_module() {
      49          global $DB;
      50          $this->setAdminUser();
      51          $generator = $this->getDataGenerator();
      52          $course = $generator->create_course();
      53          $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
      54          $assigninstance = $assigngenerator->create_instance(['course' => $course->id]);
      55          $lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
      56          $lessoninstance = $lessongenerator->create_instance(['course' => $course->id]);
      57          $student = $generator->create_user();
      58          $generator->enrol_user($student->id, $course->id, 'student');
      59          $this->setUser($student);
      60          $events = [
      61              [
      62                  'name' => 'Start of assignment',
      63                  'description' => '',
      64                  'location' => 'Test',
      65                  'format' => 1,
      66                  'courseid' => $course->id,
      67                  'groupid' => 0,
      68                  'userid' => 2,
      69                  'modulename' => 'assign',
      70                  'instance' => $assigninstance->id,
      71                  'eventtype' => 'due',
      72                  'timestart' => time(),
      73                  'timeduration' => 86400,
      74                  'visible' => 1
      75              ], [
      76                  'name' => 'Start of lesson',
      77                  'description' => '',
      78                  'location' => 'Test',
      79                  'format' => 1,
      80                  'courseid' => $course->id,
      81                  'groupid' => 0,
      82                  'userid' => 2,
      83                  'modulename' => 'lesson',
      84                  'instance' => $lessoninstance->id,
      85                  'eventtype' => 'end',
      86                  'timestart' => time(),
      87                  'timeduration' => 86400,
      88                  'visible' => 1
      89              ]
      90          ];
      91          foreach ($events as $event) {
      92              calendar_event::create($event, false);
      93          }
      94          $timestart = time() - 60;
      95          $timeend = time() + 60;
      96          // Get all events.
      97          $events = calendar_get_events($timestart, $timeend, true, 0, true);
      98          $this->assertCount(2, $events);
      99          // Disable the lesson module.
     100          $modulerecord = $DB->get_record('modules', ['name' => 'lesson']);
     101          $modulerecord->visible = 0;
     102          $DB->update_record('modules', $modulerecord);
     103          // Check that we only return the assign event.
     104          $events = calendar_get_events($timestart, $timeend, true, 0, true);
     105          $this->assertCount(1, $events);
     106          $event = reset($events);
     107          $this->assertEquals('assign', $event->modulename);
     108      }
     109  
     110      public function test_get_course_cached() {
     111          // Setup some test courses.
     112          $course1 = $this->getDataGenerator()->create_course();
     113          $course2 = $this->getDataGenerator()->create_course();
     114          $course3 = $this->getDataGenerator()->create_course();
     115  
     116          // Load courses into cache.
     117          $coursecache = null;
     118          calendar_get_course_cached($coursecache, $course1->id);
     119          calendar_get_course_cached($coursecache, $course2->id);
     120          calendar_get_course_cached($coursecache, $course3->id);
     121  
     122          // Verify the cache.
     123          $this->assertArrayHasKey($course1->id, $coursecache);
     124          $cachedcourse1 = $coursecache[$course1->id];
     125          $this->assertEquals($course1->id, $cachedcourse1->id);
     126          $this->assertEquals($course1->shortname, $cachedcourse1->shortname);
     127          $this->assertEquals($course1->fullname, $cachedcourse1->fullname);
     128  
     129          $this->assertArrayHasKey($course2->id, $coursecache);
     130          $cachedcourse2 = $coursecache[$course2->id];
     131          $this->assertEquals($course2->id, $cachedcourse2->id);
     132          $this->assertEquals($course2->shortname, $cachedcourse2->shortname);
     133          $this->assertEquals($course2->fullname, $cachedcourse2->fullname);
     134  
     135          $this->assertArrayHasKey($course3->id, $coursecache);
     136          $cachedcourse3 = $coursecache[$course3->id];
     137          $this->assertEquals($course3->id, $cachedcourse3->id);
     138          $this->assertEquals($course3->shortname, $cachedcourse3->shortname);
     139          $this->assertEquals($course3->fullname, $cachedcourse3->fullname);
     140      }
     141  
     142      /**
     143       * Test the update_subscription() function.
     144       */
     145      public function test_update_subscription() {
     146          $this->resetAfterTest(true);
     147  
     148          $subscription = new stdClass();
     149          $subscription->eventtype = 'site';
     150          $subscription->name = 'test';
     151          $id = calendar_add_subscription($subscription);
     152  
     153          $subscription = calendar_get_subscription($id);
     154          $subscription->name = 'awesome';
     155          calendar_update_subscription($subscription);
     156          $sub = calendar_get_subscription($id);
     157          $this->assertEquals($subscription->name, $sub->name);
     158  
     159          $subscription = calendar_get_subscription($id);
     160          $subscription->name = 'awesome2';
     161          $subscription->pollinterval = 604800;
     162          calendar_update_subscription($subscription);
     163          $sub = calendar_get_subscription($id);
     164          $this->assertEquals($subscription->name, $sub->name);
     165          $this->assertEquals($subscription->pollinterval, $sub->pollinterval);
     166  
     167          $subscription = new stdClass();
     168          $subscription->name = 'awesome4';
     169          $this->expectException('coding_exception');
     170          calendar_update_subscription($subscription);
     171      }
     172  
     173      public function test_add_subscription() {
     174          global $DB, $CFG;
     175  
     176          require_once($CFG->dirroot . '/lib/bennu/bennu.inc.php');
     177  
     178          $this->resetAfterTest(true);
     179  
     180          // Test for Microsoft Outlook 2010.
     181          $subscription = new stdClass();
     182          $subscription->name = 'Microsoft Outlook 2010';
     183          $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
     184          $subscription->eventtype = 'site';
     185          $id = calendar_add_subscription($subscription);
     186  
     187          $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/ms_outlook_2010.ics');
     188          $ical = new iCalendar();
     189          $ical->unserialize($calendar);
     190          $this->assertEquals($ical->parser_errors, array());
     191  
     192          $sub = calendar_get_subscription($id);
     193          calendar_import_icalendar_events($ical, null, $sub->id);
     194          $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
     195          $this->assertEquals($count, 1);
     196  
     197          // Test for OSX Yosemite.
     198          $subscription = new stdClass();
     199          $subscription->name = 'OSX Yosemite';
     200          $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
     201          $subscription->eventtype = 'site';
     202          $id = calendar_add_subscription($subscription);
     203  
     204          $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/osx_yosemite.ics');
     205          $ical = new iCalendar();
     206          $ical->unserialize($calendar);
     207          $this->assertEquals($ical->parser_errors, array());
     208  
     209          $sub = calendar_get_subscription($id);
     210          calendar_import_icalendar_events($ical, null, $sub->id);
     211          $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
     212          $this->assertEquals($count, 1);
     213  
     214          // Test for Google Gmail.
     215          $subscription = new stdClass();
     216          $subscription->name = 'Google Gmail';
     217          $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
     218          $subscription->eventtype = 'site';
     219          $id = calendar_add_subscription($subscription);
     220  
     221          $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/google_gmail.ics');
     222          $ical = new iCalendar();
     223          $ical->unserialize($calendar);
     224          $this->assertEquals($ical->parser_errors, array());
     225  
     226          $sub = calendar_get_subscription($id);
     227          calendar_import_icalendar_events($ical, null, $sub->id);
     228          $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
     229          $this->assertEquals($count, 1);
     230  
     231          // Test for ICS file with repeated events.
     232          $subscription = new stdClass();
     233          $subscription->name = 'Repeated events';
     234          $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
     235          $subscription->eventtype = 'site';
     236          $id = calendar_add_subscription($subscription);
     237          $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/repeated_events.ics');
     238          $ical = new iCalendar();
     239          $ical->unserialize($calendar);
     240          $this->assertEquals($ical->parser_errors, []);
     241  
     242          $sub = calendar_get_subscription($id);
     243          $output = calendar_import_icalendar_events($ical, null, $sub->id);
     244          $this->assertStringNotContainsString('Events deleted: 17', $output);
     245          $this->assertStringContainsString('Events imported: 1', $output);
     246          $this->assertStringContainsString('Events skipped: 0', $output);
     247          $this->assertStringContainsString('Events updated: 0', $output);
     248      }
     249  
     250      /**
     251       * Test for calendar_get_legacy_events() when there are user and group overrides.
     252       */
     253      public function test_get_legacy_events_with_overrides() {
     254          $generator = $this->getDataGenerator();
     255  
     256          $course = $generator->create_course();
     257  
     258          $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
     259          if (!isset($params['course'])) {
     260              $params['course'] = $course->id;
     261          }
     262  
     263          $instance = $plugingenerator->create_instance($params);
     264  
     265          // Create users.
     266          $useroverridestudent = $generator->create_user();
     267          $group1student = $generator->create_user();
     268          $group2student = $generator->create_user();
     269          $group12student = $generator->create_user();
     270          $nogroupstudent = $generator->create_user();
     271  
     272          // Enrol users.
     273          $generator->enrol_user($useroverridestudent->id, $course->id, 'student');
     274          $generator->enrol_user($group1student->id, $course->id, 'student');
     275          $generator->enrol_user($group2student->id, $course->id, 'student');
     276          $generator->enrol_user($group12student->id, $course->id, 'student');
     277          $generator->enrol_user($nogroupstudent->id, $course->id, 'student');
     278  
     279          // Create groups.
     280          $group1 = $generator->create_group(['courseid' => $course->id]);
     281          $group2 = $generator->create_group(['courseid' => $course->id]);
     282  
     283          // Add members to groups.
     284          $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group1student->id]);
     285          $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group2student->id]);
     286          $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group12student->id]);
     287          $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group12student->id]);
     288          $now = time();
     289  
     290          // Events with the same module name, instance and event type.
     291          $events = [
     292              [
     293                  'name' => 'Assignment 1 due date',
     294                  'description' => '',
     295                  'location' => 'Test',
     296                  'format' => 0,
     297                  'courseid' => $course->id,
     298                  'groupid' => 0,
     299                  'userid' => 2,
     300                  'modulename' => 'assign',
     301                  'instance' => $instance->id,
     302                  'eventtype' => 'due',
     303                  'timestart' => $now,
     304                  'timeduration' => 0,
     305                  'visible' => 1
     306              ], [
     307                  'name' => 'Assignment 1 due date - User override',
     308                  'description' => '',
     309                  'location' => 'Test',
     310                  'format' => 1,
     311                  'courseid' => 0,
     312                  'groupid' => 0,
     313                  'userid' => $useroverridestudent->id,
     314                  'modulename' => 'assign',
     315                  'instance' => $instance->id,
     316                  'eventtype' => 'due',
     317                  'timestart' => $now + 86400,
     318                  'timeduration' => 0,
     319                  'visible' => 1,
     320                  'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY
     321              ], [
     322                  'name' => 'Assignment 1 due date - Group A override',
     323                  'description' => '',
     324                  'location' => 'Test',
     325                  'format' => 1,
     326                  'courseid' => $course->id,
     327                  'groupid' => $group1->id,
     328                  'userid' => 2,
     329                  'modulename' => 'assign',
     330                  'instance' => $instance->id,
     331                  'eventtype' => 'due',
     332                  'timestart' => $now + (2 * 86400),
     333                  'timeduration' => 0,
     334                  'visible' => 1,
     335                  'priority' => 1,
     336              ], [
     337                  'name' => 'Assignment 1 due date - Group B override',
     338                  'description' => '',
     339                  'location' => 'Test',
     340                  'format' => 1,
     341                  'courseid' => $course->id,
     342                  'groupid' => $group2->id,
     343                  'userid' => 2,
     344                  'modulename' => 'assign',
     345                  'instance' => $instance->id,
     346                  'eventtype' => 'due',
     347                  'timestart' => $now + (3 * 86400),
     348                  'timeduration' => 0,
     349                  'visible' => 1,
     350                  'priority' => 2,
     351              ],
     352          ];
     353  
     354          foreach ($events as $event) {
     355              calendar_event::create($event, false);
     356          }
     357  
     358          $timestart = $now - 100;
     359          $timeend = $now + (3 * 86400);
     360          $groups = [$group1->id, $group2->id];
     361  
     362          // Get user override events.
     363          $this->setUser($useroverridestudent);
     364          $events = calendar_get_legacy_events($timestart, $timeend, $useroverridestudent->id, $groups, $course->id);
     365          $this->assertCount(1, $events);
     366          $event = reset($events);
     367          $this->assertEquals('Assignment 1 due date - User override', $event->name);
     368  
     369          // Get event for user with override but with the timestart and timeend parameters only covering the original event.
     370          $events = calendar_get_legacy_events($timestart, $now, $useroverridestudent->id, $groups, $course->id);
     371          $this->assertCount(0, $events);
     372  
     373          // Get events for user that does not belong to any group and has no user override events.
     374          $this->setUser($nogroupstudent);
     375          $events = calendar_get_legacy_events($timestart, $timeend, $nogroupstudent->id, $groups, $course->id);
     376          $this->assertCount(1, $events);
     377          $event = reset($events);
     378          $this->assertEquals('Assignment 1 due date', $event->name);
     379  
     380          // Get events for user that belongs to groups A and B and has no user override events.
     381          $this->setUser($group12student);
     382          $events = calendar_get_legacy_events($timestart, $timeend, $group12student->id, $groups, $course->id);
     383          $this->assertCount(1, $events);
     384          $event = reset($events);
     385          $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
     386  
     387          // Get events for user that belongs to group A and has no user override events.
     388          $this->setUser($group1student);
     389          $events = calendar_get_legacy_events($timestart, $timeend, $group1student->id, $groups, $course->id);
     390          $this->assertCount(1, $events);
     391          $event = reset($events);
     392          $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
     393  
     394          // Add repeating events.
     395          $repeatingevents = [
     396              [
     397                  'name' => 'Repeating site event',
     398                  'description' => '',
     399                  'location' => 'Test',
     400                  'format' => 1,
     401                  'courseid' => SITEID,
     402                  'groupid' => 0,
     403                  'userid' => 2,
     404                  'repeatid' => $event->id,
     405                  'modulename' => '0',
     406                  'instance' => 0,
     407                  'eventtype' => 'site',
     408                  'timestart' => $now + 86400,
     409                  'timeduration' => 0,
     410                  'visible' => 1,
     411              ],
     412              [
     413                  'name' => 'Repeating site event',
     414                  'description' => '',
     415                  'location' => 'Test',
     416                  'format' => 1,
     417                  'courseid' => SITEID,
     418                  'groupid' => 0,
     419                  'userid' => 2,
     420                  'repeatid' => $event->id,
     421                  'modulename' => '0',
     422                  'instance' => 0,
     423                  'eventtype' => 'site',
     424                  'timestart' => $now + (2 * 86400),
     425                  'timeduration' => 0,
     426                  'visible' => 1,
     427              ],
     428          ];
     429  
     430          foreach ($repeatingevents as $event) {
     431              calendar_event::create($event, false);
     432          }
     433  
     434          // Make sure repeating events are not filtered out.
     435          $events = calendar_get_legacy_events($timestart, $timeend, true, true, true);
     436          $this->assertCount(3, $events);
     437      }
     438  
     439      public function test_calendar_get_default_courses() {
     440          global $USER, $CFG;
     441  
     442          $this->resetAfterTest(true);
     443  
     444          $generator = $this->getDataGenerator();
     445          $user = $generator->create_user();
     446          $course1 = $generator->create_course();
     447          $course2 = $generator->create_course();
     448          $course3 = $generator->create_course();
     449          $context = context_course::instance($course1->id);
     450  
     451          $this->setAdminUser();
     452          $admin = clone $USER;
     453  
     454          $teacher = $generator->create_user();
     455          $generator->enrol_user($teacher->id, $course1->id, 'teacher');
     456          $generator->enrol_user($admin->id, $course1->id, 'teacher');
     457  
     458          $CFG->calendar_adminseesall = false;
     459  
     460          $courses = calendar_get_default_courses();
     461          // Only enrolled in one course.
     462          $this->assertCount(1, $courses);
     463          $courses = calendar_get_default_courses($course2->id);
     464          // Enrolled course + current course.
     465          $this->assertCount(2, $courses);
     466          $CFG->calendar_adminseesall = true;
     467          $courses = calendar_get_default_courses();
     468          // All courses + SITE.
     469          $this->assertCount(4, $courses);
     470          $courses = calendar_get_default_courses($course2->id);
     471          // All courses + SITE.
     472          $this->assertCount(4, $courses);
     473  
     474          $this->setUser($teacher);
     475  
     476          $CFG->calendar_adminseesall = false;
     477  
     478          $courses = calendar_get_default_courses();
     479          // Only enrolled in one course.
     480          $this->assertCount(1, $courses);
     481          $courses = calendar_get_default_courses($course2->id);
     482          // Enrolled course only (ignore current).
     483          $this->assertCount(1, $courses);
     484          // This setting should not affect teachers.
     485          $CFG->calendar_adminseesall = true;
     486          $courses = calendar_get_default_courses();
     487          // Only enrolled in one course.
     488          $this->assertCount(1, $courses);
     489          $courses = calendar_get_default_courses($course2->id);
     490          // Enrolled course only (ignore current).
     491          $this->assertCount(1, $courses);
     492  
     493          // Now, log out and test again.
     494          $this->setUser();
     495  
     496          $CFG->calendar_adminseesall = false;
     497  
     498          $courses = calendar_get_default_courses(null, '*', false, $teacher->id);
     499          // Only enrolled in one course.
     500          $this->assertCount(1, $courses);
     501          $courses = calendar_get_default_courses($course2->id, '*', false, $teacher->id);
     502          // Enrolled course only (ignore current).
     503          $this->assertCount(1, $courses);
     504          // This setting should not affect teachers.
     505          $CFG->calendar_adminseesall = true;
     506          $courses = calendar_get_default_courses(null, '*', false, $teacher->id);
     507          // Only enrolled in one course.
     508          $this->assertCount(1, $courses);
     509          $courses = calendar_get_default_courses($course2->id, '*', false, $teacher->id);
     510          // Enrolled course only (ignore current).
     511          $this->assertCount(1, $courses);
     512  
     513      }
     514  
     515      /**
     516       * Confirm that the skip events flag causes the calendar_get_view function
     517       * to avoid querying for the calendar events.
     518       */
     519      public function test_calendar_get_view_skip_events() {
     520          $this->resetAfterTest(true);
     521          $this->setAdminUser();
     522  
     523          $generator = $this->getDataGenerator();
     524          $user = $generator->create_user();
     525          $skipnavigation = true;
     526          $skipevents = true;
     527          $event = create_event([
     528              'eventtype' => 'user',
     529              'userid' => $user->id
     530          ]);
     531  
     532          $this->setUser($user);
     533          $calendar = \calendar_information::create(time() - 10, SITEID, null);
     534  
     535          list($data, $template) = calendar_get_view($calendar, 'day', $skipnavigation, $skipevents);
     536          $this->assertEmpty($data->events);
     537  
     538          $skipevents = false;
     539          list($data, $template) = calendar_get_view($calendar, 'day', $skipnavigation, $skipevents);
     540  
     541          $this->assertEquals($event->id, $data->events[0]->id);
     542      }
     543  
     544      public function test_calendar_get_allowed_event_types_course() {
     545          $generator = $this->getDataGenerator();
     546          $user = $generator->create_user();
     547          $course1 = $generator->create_course(); // Has capability.
     548          $course2 = $generator->create_course(); // Doesn't have capability.
     549          $course3 = $generator->create_course(); // Not enrolled.
     550          $context1 = context_course::instance($course1->id);
     551          $context2 = context_course::instance($course2->id);
     552          $context3 = context_course::instance($course3->id);
     553          $roleid = $generator->create_role();
     554          $contexts = [$context1, $context2, $context3];
     555          $enrolledcourses = [$course1, $course2];
     556  
     557          foreach ($enrolledcourses as $course) {
     558              $generator->enrol_user($user->id, $course->id, 'student');
     559          }
     560  
     561          foreach ($contexts as $context) {
     562              $generator->role_assign($roleid, $user->id, $context->id);
     563          }
     564  
     565          $this->setUser($user);
     566  
     567          // In general for all courses, they don't have the ability to add course events yet.
     568          $types = calendar_get_allowed_event_types();
     569          $this->assertFalse($types['course']);
     570  
     571          assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context1, true);
     572          assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context2, true);
     573  
     574          // The user only has the correct capability in course 1 so that is the only
     575          // one that should be in the results.
     576          $types = calendar_get_allowed_event_types($course1->id);
     577          $this->assertTrue($types['course']);
     578  
     579          // If calling function without specified course,  there is still a course where they have it.
     580          $types = calendar_get_allowed_event_types();
     581          $this->assertTrue($types['course']);
     582  
     583          assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context1, true);
     584  
     585          // The user only now has the correct capability in both course 1 and 2 so we
     586          // expect both to be in the results.
     587          $types = calendar_get_allowed_event_types($course3->id);
     588          $this->assertFalse($types['course']);
     589  
     590          // They now do not have permission in any course.
     591          $types = calendar_get_allowed_event_types();
     592          $this->assertFalse($types['course']);
     593      }
     594  
     595      public function test_calendar_get_allowed_event_types_group_no_acces_to_diff_groups() {
     596          $generator = $this->getDataGenerator();
     597          $user = $generator->create_user();
     598          $course = $generator->create_course();
     599          $context = context_course::instance($course->id);
     600          $roleid = $generator->create_role();
     601  
     602          $generator->enrol_user($user->id, $course->id, 'student');
     603          $generator->role_assign($roleid, $user->id, $context->id);
     604  
     605          $this->setUser($user);
     606  
     607          assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
     608          assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true);
     609  
     610          // The user has the correct capability in the course but they aren't a member
     611          // of any of the groups and don't have the accessallgroups capability.
     612          $types = calendar_get_allowed_event_types($course->id);
     613          $this->assertTrue($types['course']);
     614          $this->assertFalse($types['group']);
     615  
     616          // Same result applies when not providing a specific course as they are only on one course.
     617          $types = calendar_get_allowed_event_types();
     618          $this->assertTrue($types['course']);
     619          $this->assertFalse($types['group']);
     620      }
     621  
     622      public function test_calendar_get_allowed_event_types_group_no_groups() {
     623          $generator = $this->getDataGenerator();
     624          $user = $generator->create_user();
     625          $course = $generator->create_course();
     626          $context = context_course::instance($course->id);
     627          $roleid = $generator->create_role();
     628          $generator->enrol_user($user->id, $course->id, 'student');
     629          $generator->role_assign($roleid, $user->id, $context->id);
     630          $this->setUser($user);
     631          assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
     632          // The user has the correct capability in the course but there are
     633          // no groups so we shouldn't see a group type.
     634          $types = calendar_get_allowed_event_types($course->id);
     635          $this->assertTrue($types['course']);
     636          $this->assertFalse($types['group']);
     637  
     638          // Same result applies when not providing a specific course as they are only on one course.
     639          $types = calendar_get_allowed_event_types();
     640          $this->assertTrue($types['course']);
     641          $this->assertFalse($types['group']);
     642      }
     643  
     644      public function test_calendar_get_allowed_event_types_group_access_all_groups() {
     645          $generator = $this->getDataGenerator();
     646          $user = $generator->create_user();
     647          $course1 = $generator->create_course();
     648          $course2 = $generator->create_course();
     649          $generator->create_group(array('courseid' => $course1->id));
     650          $generator->create_group(array('courseid' => $course2->id));
     651          $context1 = context_course::instance($course1->id);
     652          $context2 = context_course::instance($course2->id);
     653          $roleid = $generator->create_role();
     654          $generator->enrol_user($user->id, $course1->id, 'student');
     655          $generator->enrol_user($user->id, $course2->id, 'student');
     656          $generator->role_assign($roleid, $user->id, $context1->id);
     657          $generator->role_assign($roleid, $user->id, $context2->id);
     658          $this->setUser($user);
     659          assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context1, true);
     660          assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context2, true);
     661          assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context1, true);
     662          assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context2, true);
     663          // The user has the correct capability in the course and has
     664          // the accessallgroups capability.
     665          $types = calendar_get_allowed_event_types($course1->id);
     666          $this->assertTrue($types['group']);
     667  
     668          // Same result applies when not providing a specific course as they are only on one course.
     669          $types = calendar_get_allowed_event_types();
     670          $this->assertTrue($types['group']);
     671      }
     672  
     673      public function test_calendar_get_allowed_event_types_group_no_access_all_groups() {
     674          $generator = $this->getDataGenerator();
     675          $user = $generator->create_user();
     676          $course = $generator->create_course();
     677          $context = context_course::instance($course->id);
     678          $group1 = $generator->create_group(array('courseid' => $course->id));
     679          $group2 = $generator->create_group(array('courseid' => $course->id));
     680          $roleid = $generator->create_role();
     681          $generator->enrol_user($user->id, $course->id, 'student');
     682          $generator->role_assign($roleid, $user->id, $context->id);
     683          $generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user->id));
     684          $generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user->id));
     685          $this->setUser($user);
     686          assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true);
     687          // The user has the correct capability in the course but can't access
     688          // groups that they are not a member of.
     689          $types = calendar_get_allowed_event_types($course->id);
     690          $this->assertFalse($types['group']);
     691  
     692          // Same result applies when not providing a specific course as they are only on one course.
     693          $types = calendar_get_allowed_event_types();
     694          $this->assertFalse($types['group']);
     695  
     696          assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
     697          assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true);
     698          $types = calendar_get_allowed_event_types($course->id);
     699          $this->assertTrue($types['group']);
     700  
     701          // Same result applies when not providing a specific course as they are only on one course.
     702          $types = calendar_get_allowed_event_types();
     703          $this->assertTrue($types['group']);
     704      }
     705  
     706      public function test_calendar_get_allowed_event_types_group_cap_no_groups() {
     707          $generator = $this->getDataGenerator();
     708          $user = $generator->create_user();
     709          $course = $generator->create_course();
     710          $context = context_course::instance($course->id);
     711          $roleid = $generator->create_role();
     712          $group = $generator->create_group(['courseid' => $course->id]);
     713          $generator->enrol_user($user->id, $course->id, 'student');
     714          $generator->role_assign($roleid, $user->id, $context->id);
     715          assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
     716  
     717          $this->setUser($user);
     718          $types = calendar_get_allowed_event_types($course->id);
     719          $this->assertFalse($types['course']);
     720          $this->assertFalse($types['group']);
     721  
     722          // Check without specifying a course (same result as user only has one course).
     723          $types = calendar_get_allowed_event_types();
     724          $this->assertFalse($types['course']);
     725          $this->assertFalse($types['group']);
     726      }
     727  
     728      public function test_calendar_get_allowed_event_types_group_cap_has_group() {
     729          $generator = $this->getDataGenerator();
     730          $user = $generator->create_user();
     731          $course = $generator->create_course();
     732          $context = context_course::instance($course->id);
     733          $roleid = $generator->create_role();
     734          $group = $generator->create_group(['courseid' => $course->id]);
     735          $generator->enrol_user($user->id, $course->id, 'student');
     736          $generator->role_assign($roleid, $user->id, $context->id);
     737          groups_add_member($group, $user);
     738          assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
     739  
     740          $this->setUser($user);
     741          $types = calendar_get_allowed_event_types($course->id);
     742          $this->assertFalse($types['course']);
     743          $this->assertTrue($types['group']);
     744  
     745          // Check without specifying a course (same result as user only has one course).
     746          $types = calendar_get_allowed_event_types();
     747          $this->assertFalse($types['course']);
     748          $this->assertTrue($types['group']);
     749      }
     750  
     751      public function test_calendar_get_allowed_event_types_group_cap_access_all_groups() {
     752          $generator = $this->getDataGenerator();
     753          $user = $generator->create_user();
     754          $course = $generator->create_course();
     755          $context = context_course::instance($course->id);
     756          $roleid = $generator->create_role();
     757          $group = $generator->create_group(['courseid' => $course->id]);
     758          $generator->enrol_user($user->id, $course->id, 'student');
     759          $generator->role_assign($roleid, $user->id, $context->id);
     760          assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
     761          assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true);
     762  
     763          $this->setUser($user);
     764          $types = calendar_get_allowed_event_types($course->id);
     765          $this->assertFalse($types['course']);
     766          $this->assertTrue($types['group']);
     767  
     768          // Check without specifying a course (same result as user only has one course).
     769          $types = calendar_get_allowed_event_types();
     770          $this->assertFalse($types['course']);
     771          $this->assertTrue($types['group']);
     772      }
     773  
     774      /**
     775       * This is a setup helper function that create some users, courses, groups and group memberships.
     776       * This is useful to prepare the environment for testing the calendar_set_filters function.
     777       *
     778       * @return array An array of ($users, $courses, $coursegroups)
     779       */
     780      protected function setup_test_calendar_set_filters() {
     781          $generator = $this->getDataGenerator();
     782  
     783          // Create some users.
     784          $users = [];
     785          $users[] = $generator->create_user();
     786          $users[] = $generator->create_user();
     787          $users[] = $generator->create_user();
     788  
     789          // Create some courses.
     790          $courses = [];
     791          $courses[] = $generator->create_course();
     792          $courses[] = $generator->create_course();
     793          $courses[] = $generator->create_course();
     794          $courses[] = $generator->create_course();
     795  
     796          // Create some groups.
     797          $coursegroups = [];
     798          $coursegroups[$courses[0]->id] = [];
     799          $coursegroups[$courses[0]->id][] = $generator->create_group(['courseid' => $courses[0]->id]);
     800          $coursegroups[$courses[0]->id][] = $generator->create_group(['courseid' => $courses[0]->id]);
     801          $coursegroups[$courses[2]->id] = [];
     802          $coursegroups[$courses[2]->id][] = $generator->create_group(['courseid' => $courses[2]->id]);
     803          $coursegroups[$courses[2]->id][] = $generator->create_group(['courseid' => $courses[2]->id]);
     804          $coursegroups[$courses[3]->id] = [];
     805          $coursegroups[$courses[3]->id][] = $generator->create_group(['courseid' => $courses[3]->id]);
     806          $coursegroups[$courses[3]->id][] = $generator->create_group(['courseid' => $courses[3]->id]);
     807  
     808          // Create some enrolments and group memberships.
     809          $generator->enrol_user($users[0]->id, $courses[0]->id, 'student');
     810          $generator->create_group_member(['groupid' => $coursegroups[$courses[0]->id][0]->id, 'userid' => $users[0]->id]);
     811          $generator->enrol_user($users[1]->id, $courses[0]->id, 'student');
     812          $generator->create_group_member(['groupid' => $coursegroups[$courses[0]->id][1]->id, 'userid' => $users[1]->id]);
     813          $generator->enrol_user($users[0]->id, $courses[1]->id, 'student');
     814          $generator->enrol_user($users[0]->id, $courses[2]->id, 'student');
     815  
     816          return array($users, $courses, $coursegroups);
     817      }
     818  
     819      /**
     820       * This function tests calendar_set_filters for the case when user is not logged in.
     821       */
     822      public function test_calendar_set_filters_not_logged_in() {
     823          $this->resetAfterTest();
     824  
     825          list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
     826  
     827          $defaultcourses = calendar_get_default_courses(null, '*', false, $users[0]->id);
     828          list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses);
     829  
     830          $this->assertEquals(
     831                  [$courses[0]->id, $courses[1]->id, $courses[2]->id, SITEID],
     832                  array_values($courseids),
     833                  '', 0.0, 10, true);
     834          $this->assertFalse($groupids);
     835          $this->assertFalse($userid);
     836      }
     837  
     838      /**
     839       * This function tests calendar_set_filters for the case when no one is logged in, but a user id is provided.
     840       */
     841      public function test_calendar_set_filters_not_logged_in_with_user() {
     842          $this->resetAfterTest();
     843  
     844          list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
     845  
     846          $defaultcourses = calendar_get_default_courses(null, '*', false, $users[1]->id);
     847          list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false, $users[1]);
     848  
     849          $this->assertEquals(array($courses[0]->id, SITEID), array_values($courseids));
     850          $this->assertEquals(array($coursegroups[$courses[0]->id][1]->id), $groupids);
     851          $this->assertEquals($users[1]->id, $userid);
     852  
     853          $defaultcourses = calendar_get_default_courses(null, '*', false, $users[0]->id);
     854          list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false, $users[0]);
     855  
     856          $this->assertEquals(
     857                  [$courses[0]->id, $courses[1]->id, $courses[2]->id, SITEID],
     858                  array_values($courseids),
     859                  '', 0.0, 10, true);
     860          $this->assertEquals(array($coursegroups[$courses[0]->id][0]->id), $groupids);
     861          $this->assertEquals($users[0]->id, $userid);
     862  
     863      }
     864  
     865      /**
     866       * This function tests calendar_set_filters for the case when user is logged in, but no user id is provided.
     867       */
     868      public function test_calendar_set_filters_logged_in_no_user() {
     869          $this->resetAfterTest();
     870  
     871          list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
     872  
     873          $this->setUser($users[0]);
     874          $defaultcourses = calendar_get_default_courses(null, '*', false, $users[0]->id);
     875          list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false);
     876          $this->assertEquals([$courses[0]->id, $courses[1]->id, $courses[2]->id, SITEID], array_values($courseids), '', 0.0, 10,
     877                  true);
     878          $this->assertEquals(array($coursegroups[$courses[0]->id][0]->id), $groupids);
     879          $this->assertEquals($users[0]->id, $userid);
     880      }
     881  
     882      /**
     883       * This function tests calendar_set_filters for the case when a user is logged in, but another user id is provided.
     884       */
     885      public function test_calendar_set_filters_logged_in_another_user() {
     886          $this->resetAfterTest();
     887  
     888          list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
     889  
     890          $this->setUser($users[0]);
     891          $defaultcourses = calendar_get_default_courses(null, '*', false, $users[1]->id);
     892          list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false, $users[1]);
     893  
     894          $this->assertEquals(array($courses[0]->id, SITEID), array_values($courseids));
     895          $this->assertEquals(array($coursegroups[$courses[0]->id][1]->id), $groupids);
     896          $this->assertEquals($users[1]->id, $userid);
     897      }
     898  
     899      /**
     900       *  Test for calendar_view_event_allowed for course event types.
     901       */
     902      public function test_calendar_view_event_allowed_course_event() {
     903          global $USER;
     904  
     905          $this->setAdminUser();
     906  
     907          $generator = $this->getDataGenerator();
     908  
     909          // A student in a course.
     910          $student = $generator->create_user();
     911          // Some user not enrolled in any course.
     912          $someuser = $generator->create_user();
     913  
     914          // A course with manual enrolments.
     915          $manualcourse = $generator->create_course();
     916  
     917          // Enrol the student to the manual enrolment course.
     918          $generator->enrol_user($student->id, $manualcourse->id);
     919  
     920          // A course that allows guest access.
     921          $guestcourse = $generator->create_course(
     922              (object)[
     923                  'shortname' => 'guestcourse',
     924                  'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
     925                  'enrol_guest_password_0' => ''
     926              ]);
     927  
     928          $manualevent = (object)[
     929              'name' => 'Manual course event',
     930              'description' => '',
     931              'format' => 1,
     932              'categoryid' => 0,
     933              'courseid' => $manualcourse->id,
     934              'groupid' => 0,
     935              'userid' => $USER->id,
     936              'modulename' => 0,
     937              'instance' => 0,
     938              'eventtype' => 'course',
     939              'timestart' => time(),
     940              'timeduration' => 86400,
     941              'visible' => 1
     942          ];
     943          $caleventmanual = calendar_event::create($manualevent, false);
     944  
     945          // Create a course event for the course with guest access.
     946          $guestevent = clone $manualevent;
     947          $guestevent->name = 'Guest course event';
     948          $guestevent->courseid = $guestcourse->id;
     949          $caleventguest = calendar_event::create($guestevent, false);
     950  
     951          // Viewing as admin.
     952          $this->assertTrue(calendar_view_event_allowed($caleventmanual));
     953          $this->assertTrue(calendar_view_event_allowed($caleventguest));
     954  
     955          // Viewing as someone enrolled in a course.
     956          $this->setUser($student);
     957          $this->assertTrue(calendar_view_event_allowed($caleventmanual));
     958  
     959          // Viewing as someone not enrolled in any course.
     960          $this->setUser($someuser);
     961          // Viewing as someone not enrolled in a course without guest access on.
     962          $this->assertFalse(calendar_view_event_allowed($caleventmanual));
     963          // Viewing as someone not enrolled in a course with guest access on.
     964          $this->assertTrue(calendar_view_event_allowed($caleventguest));
     965      }
     966  }