Search moodle.org's
Developer Documentation

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