Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * External calendar functions unit tests 19 * 20 * @package core_calendar 21 * @category external 22 * @copyright 2012 Ankit Agarwal 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 global $CFG; 29 30 require_once($CFG->dirroot . '/webservice/tests/helpers.php'); 31 32 /** 33 * External course functions unit tests 34 * 35 * @package core_calendar 36 * @category external 37 * @copyright 2012 Ankit Agarwal 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 * @since Moodle 2.5 40 */ 41 class core_calendar_externallib_testcase extends externallib_advanced_testcase { 42 43 /** 44 * Tests set up 45 */ 46 protected function setUp(): void { 47 global $CFG; 48 require_once($CFG->dirroot . '/calendar/externallib.php'); 49 } 50 51 /** Create calendar events or update them 52 * Set $prop->id, if you want to do an update instead of creating an new event 53 * 54 * @param string $name Event title 55 * @param int $userid User id 56 * @param string $type Event type 57 * @param int $repeats Number of repeated events to create 58 * @param int $timestart Time stamp of the event start 59 * @param mixed $prop List of event properties as array or object 60 * @return mixed Event object or false; 61 * @since Moodle 2.5 62 */ 63 64 public static function create_calendar_event($name, $userid = 0, $type = 'user', $repeats = 0, $timestart = null, $prop = null) { 65 global $CFG, $DB, $SITE; 66 67 require_once("$CFG->dirroot/calendar/lib.php"); 68 if (!empty($prop)) { 69 if (is_array($prop)) { 70 $prop = (object)$prop; 71 } 72 } else { 73 $prop = new stdClass(); 74 } 75 $prop->name = $name; 76 if (empty($prop->eventtype)) { 77 $prop->eventtype = $type; 78 } 79 if (empty($prop->repeats)) { 80 $prop->repeats = $repeats; 81 } 82 if (empty($prop->timestart)) { 83 $prop->timestart = time(); 84 } 85 if (empty($prop->timeduration)) { 86 $prop->timeduration = 0; 87 } 88 if (empty($prop->timesort)) { 89 $prop->timesort = 0; 90 } 91 if (empty($prop->type)) { 92 $prop->type = CALENDAR_EVENT_TYPE_STANDARD; 93 } 94 if (empty($prop->repeats)) { 95 $prop->repeat = 0; 96 } else { 97 $prop->repeat = 1; 98 } 99 if (empty($prop->userid)) { 100 if (!empty($userid)) { 101 $prop->userid = $userid; 102 } else { 103 $prop->userid = 0; 104 } 105 } 106 if (!isset($prop->courseid)) { 107 // Set a default value of the event's course ID field. 108 if ($type === 'user') { 109 // If it's a user event, course ID should be zero. 110 $prop->courseid = 0; 111 } else { 112 // Otherwise, default to the site ID. 113 $prop->courseid = $SITE->id; 114 } 115 } 116 117 // Determine event priority. 118 if ($prop->courseid == 0 && isset($prop->groupid) && $prop->groupid == 0 && !empty($prop->userid)) { 119 // User override event. 120 $prop->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY; 121 } else if ($prop->courseid != $SITE->id && !empty($prop->groupid)) { 122 // Group override event. 123 $priorityparams = ['courseid' => $prop->courseid, 'groupid' => $prop->groupid]; 124 // Group override event with the highest priority. 125 $groupevents = $DB->get_records('event', $priorityparams, 'priority DESC', 'id, priority', 0, 1); 126 $priority = 1; 127 if (!empty($groupevents)) { 128 $event = reset($groupevents); 129 if (!empty($event->priority)) { 130 $priority = $event->priority + 1; 131 } 132 } 133 $prop->priority = $priority; 134 } 135 136 $event = new calendar_event($prop); 137 return $event->create($prop); 138 } 139 140 public function test_create_calendar_events () { 141 global $DB, $USER; 142 143 $this->setAdminUser(); 144 $this->resetAfterTest(); 145 $prevcount = count($DB->get_records("event")); 146 147 // Create a few events and do asserts. 148 $this->create_calendar_event('test', $USER->id); 149 $where = $DB->sql_compare_text('name') ." = ?"; 150 $count = count($DB->get_records_select("event", $where, array('test'))); 151 $this->assertEquals(1, $count); 152 $aftercount = count($DB->get_records("event")); 153 $this->assertEquals($prevcount + 1, $aftercount); 154 155 $this->create_calendar_event('user', $USER->id, 'user', 3); 156 $where = $DB->sql_compare_text('name') ." = ?"; 157 $count = count($DB->get_records_select("event", $where, array('user'))); 158 159 $this->assertEquals(3, $count); 160 $aftercount = count($DB->get_records("event")); 161 $this->assertEquals($prevcount + 4, $aftercount); 162 163 } 164 165 /** 166 * Test delete_calendar_events 167 */ 168 public function test_delete_calendar_events() { 169 global $DB, $USER; 170 171 $this->resetAfterTest(true); 172 $this->setAdminUser(); 173 174 // Create a few stuff to test with. 175 $user = $this->getDataGenerator()->create_user(); 176 $course = $this->getDataGenerator()->create_course(); 177 $record = new stdClass(); 178 $record->courseid = $course->id; 179 $group = $this->getDataGenerator()->create_group($record); 180 181 $notdeletedcount = $DB->count_records('event'); 182 183 // Let's create a few events. 184 $siteevent = $this->create_calendar_event('site', $USER->id, 'site'); 185 $record = new stdClass(); 186 $record->courseid = $course->id; 187 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record); 188 $userevent = $this->create_calendar_event('user', $USER->id); 189 $record = new stdClass(); 190 $record->courseid = $course->id; 191 $record->groupid = $group->id; 192 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record); 193 194 // Now lets try to delete stuff with proper rights. 195 $events = array( 196 array('eventid' => $siteevent->id, 'repeat' => 0), 197 array('eventid' => $courseevent->id, 'repeat' => 1), 198 array('eventid' => $userevent->id, 'repeat' => 0), 199 array('eventid' => $groupevent->id, 'repeat' => 0) 200 ); 201 core_calendar_external::delete_calendar_events($events); 202 203 // Check to see if things were deleted properly. 204 $deletedcount = $DB->count_records('event'); 205 $this->assertEquals($notdeletedcount, $deletedcount); 206 207 // Let's create a few events. 208 $siteevent = $this->create_calendar_event('site', $USER->id, 'site'); 209 $record = new stdClass(); 210 $record->courseid = $course->id; 211 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 3, time(), $record); 212 $userevent = $this->create_calendar_event('user', $user->id); 213 $record = new stdClass(); 214 $record->courseid = $course->id; 215 $record->groupid = $group->id; 216 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record); 217 218 $this->setuser($user); 219 $sitecontext = context_system::instance(); 220 $coursecontext = context_course::instance($course->id); 221 $usercontext = context_user::instance($user->id); 222 $role = $DB->get_record('role', array('shortname' => 'student')); 223 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 224 225 // Remove all caps. 226 $this->unassignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id); 227 $this->unassignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id); 228 $this->unassignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id); 229 $this->unassignUserCapability('moodle/calendar:manageownentries', $usercontext->id, $role->id); 230 231 // Assign proper caps and attempt delete. 232 $this->assignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id); 233 $events = array( 234 array('eventid' => $siteevent->id, 'repeat' => 0), 235 ); 236 core_calendar_external::delete_calendar_events($events); 237 $deletedcount = $DB->count_records('event'); 238 $count = $notdeletedcount+5; 239 $this->assertEquals($count, $deletedcount); 240 241 $this->assignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id); 242 $events = array( 243 array('eventid' => $courseevent->id, 'repeat' => 0), 244 ); 245 core_calendar_external::delete_calendar_events($events); 246 $deletedcount = $DB->count_records('event'); 247 $count = $notdeletedcount+4; 248 $this->assertEquals($count, $deletedcount); 249 250 $this->assignUserCapability('moodle/calendar:manageownentries', $usercontext->id, $role->id); 251 $events = array( 252 array('eventid' => $userevent->id, 'repeat' => 0), 253 ); 254 core_calendar_external::delete_calendar_events($events); 255 $deletedcount = $DB->count_records('event'); 256 $count = $notdeletedcount+3; 257 $this->assertEquals($count, $deletedcount); 258 259 $this->assignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id); 260 $events = array( 261 array('eventid' => $groupevent->id, 'repeat' => 0), 262 ); 263 core_calendar_external::delete_calendar_events($events); 264 $deletedcount = $DB->count_records('event'); 265 $count = $notdeletedcount+2; 266 $this->assertEquals($count, $deletedcount); 267 268 $notdeletedcount = $deletedcount; 269 270 // Let us try deleting without caps. 271 272 $siteevent = $this->create_calendar_event('site', $USER->id, 'site'); 273 $record = new stdClass(); 274 $record->courseid = $course->id; 275 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 3, time(), $record); 276 $userevent = $this->create_calendar_event('user', $USER->id); 277 $record = new stdClass(); 278 $record->courseid = $course->id; 279 $record->groupid = $group->id; 280 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record); 281 282 $this->setGuestUser(); 283 284 $events = array( 285 array('eventid' => $siteevent->id, 'repeat' => 0), 286 array('eventid' => $courseevent->id, 'repeat' => 0), 287 array('eventid' => $userevent->id, 'repeat' => 0), 288 array('eventid' => $groupevent->id, 'repeat' => 0) 289 ); 290 $this->expectException(moodle_exception::class); 291 core_calendar_external::delete_calendar_events($events); 292 } 293 294 /** 295 * Test get_calendar_events 296 */ 297 public function test_get_calendar_events() { 298 global $DB, $USER; 299 300 $this->resetAfterTest(true); 301 set_config('calendar_adminseesall', 1); 302 $this->setAdminUser(); 303 304 // Create a few stuff to test with. 305 $user = $this->getDataGenerator()->create_user(); 306 $user2 = $this->getDataGenerator()->create_user(); 307 $course = $this->getDataGenerator()->create_course(); 308 309 $category = $this->getDataGenerator()->create_category(); 310 311 $category2 = $this->getDataGenerator()->create_category(); 312 $category2b = $this->getDataGenerator()->create_category(['parent' => $category2->id]); 313 $course3 = $this->getDataGenerator()->create_course(['category' => $category2b->id]); 314 315 $role = $DB->get_record('role', array('shortname' => 'student')); 316 $this->getDataGenerator()->enrol_user($user2->id, $course3->id, $role->id); 317 318 $record = new stdClass(); 319 $record->courseid = $course->id; 320 $group = $this->getDataGenerator()->create_group($record); 321 322 $beforecount = $DB->count_records('event'); 323 324 // Let's create a few events. 325 $siteevent = $this->create_calendar_event('site', $USER->id, 'site'); 326 327 // This event will have description with an inline fake image. 328 $draftidfile = file_get_unused_draft_itemid(); 329 $usercontext = context_course::instance($course->id); 330 $filerecord = array( 331 'contextid' => $usercontext->id, 332 'component' => 'user', 333 'filearea' => 'draft', 334 'itemid' => $draftidfile, 335 'filepath' => '/', 336 'filename' => 'fakeimage.png', 337 ); 338 $fs = get_file_storage(); 339 $fs->create_file_from_string($filerecord, 'img contents'); 340 341 $record = new stdClass(); 342 $record->courseid = $course->id; 343 $record->groupid = 0; 344 $record->description = array( 345 'format' => FORMAT_HTML, 346 'text' => 'Text with img <img src="@@PLUGINFILE@@/fakeimage.png">', 347 'itemid' => $draftidfile 348 ); 349 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record); 350 351 $record = new stdClass(); 352 $record->courseid = 0; 353 $record->groupid = 0; 354 $userevent = $this->create_calendar_event('user', $USER->id, 'user', 0, time(), $record); 355 356 $record = new stdClass(); 357 $record->courseid = $course->id; 358 $record->groupid = $group->id; 359 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record); 360 361 $paramevents = array ('eventids' => array($siteevent->id), 'courseids' => array($course->id), 362 'groupids' => array($group->id), 'categoryids' => array($category->id)); 363 364 $options = array ('siteevents' => true, 'userevents' => true); 365 $events = core_calendar_external::get_calendar_events($paramevents, $options); 366 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 367 368 // Check to see if we got all events. 369 $this->assertEquals(5, count($events['events'])); 370 $this->assertEquals(0, count($events['warnings'])); 371 $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7*WEEKSECS); 372 $events = core_calendar_external::get_calendar_events($paramevents, $options); 373 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 374 $this->assertEquals(5, count($events['events'])); 375 $this->assertEquals(0, count($events['warnings'])); 376 377 // Expect the same URL in the description of two different events (because they are repeated). 378 $coursecontext = context_course::instance($course->id); 379 $expectedurl = "webservice/pluginfile.php/$coursecontext->id/calendar/event_description/$courseevent->id/fakeimage.png"; 380 $withdescription = 0; 381 foreach ($events['events'] as $event) { 382 if (!empty($event['description'])) { 383 $withdescription++; 384 $this->assertStringContainsString($expectedurl, $event['description']); 385 } 386 } 387 $this->assertEquals(2, $withdescription); 388 389 // Let's play around with caps. 390 391 // Create user event for the user $user. 392 $record = new stdClass(); 393 $record->courseid = 0; 394 $record->groupid = 0; 395 $this->create_calendar_event('user', $user->id, 'user', 0, time(), $record); 396 397 $this->setUser($user); 398 $events = core_calendar_external::get_calendar_events($paramevents, $options); 399 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 400 $this->assertEquals(2, count($events['events'])); // site, user. 401 $this->assertEquals(2, count($events['warnings'])); // course, group. 402 403 $role = $DB->get_record('role', array('shortname' => 'student')); 404 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 405 $events = core_calendar_external::get_calendar_events($paramevents, $options); 406 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 407 $this->assertEquals(4, count($events['events'])); // site, user, both course events. 408 $this->assertEquals(1, count($events['warnings'])); // group. 409 410 $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS); 411 $events = core_calendar_external::get_calendar_events($paramevents, $options); 412 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 413 $this->assertEquals(3, count($events['events'])); // site, user, one course event. 414 $this->assertEquals(1, count($events['warnings'])); // group. 415 416 groups_add_member($group, $user); 417 $events = core_calendar_external::get_calendar_events($paramevents, $options); 418 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 419 $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. 420 $this->assertEquals(0, count($events['warnings'])); 421 422 $paramevents = array ('courseids' => array($course->id), 'groupids' => array($group->id)); 423 $events = core_calendar_external::get_calendar_events($paramevents, $options); 424 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 425 $this->assertEquals(4, count($events['events'])); // site, user, group, one course event. 426 $this->assertEquals(0, count($events['warnings'])); 427 428 $paramevents = array ('groupids' => array($group->id, 23)); 429 $events = core_calendar_external::get_calendar_events($paramevents, $options); 430 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 431 $this->assertEquals(3, count($events['events'])); // site, user, group. 432 $this->assertEquals(1, count($events['warnings'])); 433 434 $paramevents = array ('courseids' => array(23)); 435 $events = core_calendar_external::get_calendar_events($paramevents, $options); 436 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 437 $this->assertEquals(2, count($events['events'])); // site, user. 438 $this->assertEquals(1, count($events['warnings'])); 439 440 $paramevents = array (); 441 $options = array ('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7*WEEKSECS); 442 $events = core_calendar_external::get_calendar_events($paramevents, $options); 443 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 444 $this->assertEquals(0, count($events['events'])); // nothing returned. 445 $this->assertEquals(0, count($events['warnings'])); 446 447 $paramevents = array ('eventids' => array($siteevent->id, $groupevent->id)); 448 $options = array ('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7*WEEKSECS); 449 $events = core_calendar_external::get_calendar_events($paramevents, $options); 450 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 451 $this->assertEquals(2, count($events['events'])); // site, group. 452 $this->assertEquals(0, count($events['warnings'])); 453 454 $paramevents = array ('eventids' => array($siteevent->id)); 455 $events = core_calendar_external::get_calendar_events($paramevents, $options); 456 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 457 $this->assertEquals(1, count($events['events'])); // site. 458 $this->assertEquals(0, count($events['warnings'])); 459 460 // Try getting a course event by its id. 461 $paramevents = array ('eventids' => array($courseevent->id)); 462 $events = core_calendar_external::get_calendar_events($paramevents, $options); 463 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 464 $this->assertEquals(1, count($events['events'])); 465 $this->assertEquals(0, count($events['warnings'])); 466 467 // Now, create an activity event. 468 $this->setAdminUser(); 469 $nexttime = time() + DAYSECS; 470 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime)); 471 472 $this->setUser($user); 473 $paramevents = array ('courseids' => array($course->id)); 474 $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS); 475 $events = core_calendar_external::get_calendar_events($paramevents, $options); 476 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 477 478 $this->assertCount(5, $events['events']); 479 480 // Hide the assignment. 481 set_coursemodule_visible($assign->cmid, 0); 482 // Empty all the caches that may be affected by this change. 483 accesslib_clear_all_caches_for_unit_testing(); 484 course_modinfo::clear_instance_cache(); 485 486 $events = core_calendar_external::get_calendar_events($paramevents, $options); 487 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 488 // Expect one less. 489 $this->assertCount(4, $events['events']); 490 491 // Create some category events. 492 $this->setAdminUser(); 493 $record = new stdClass(); 494 $record->courseid = 0; 495 $record->categoryid = $category->id; 496 $record->timestart = time() - DAYSECS; 497 $catevent1 = $this->create_calendar_event('category a', $USER->id, 'category', 0, time(), $record); 498 499 $record = new stdClass(); 500 $record->courseid = 0; 501 $record->categoryid = $category2->id; 502 $record->timestart = time() + DAYSECS; 503 $catevent2 = $this->create_calendar_event('category b', $USER->id, 'category', 0, time(), $record); 504 505 // Now as student, make sure we get the events of the courses I am enrolled. 506 $this->setUser($user2); 507 $paramevents = array('categoryids' => array($category2b->id)); 508 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false); 509 $events = core_calendar_external::get_calendar_events($paramevents, $options); 510 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 511 512 // Should be just one, since there's just one category event of the course I am enrolled (course3 - cat2b). 513 $this->assertEquals(1, count($events['events'])); 514 $this->assertEquals($catevent2->id, $events['events'][0]['id']); 515 $this->assertEquals($category2->id, $events['events'][0]['categoryid']); 516 $this->assertEquals(0, count($events['warnings'])); 517 518 // Now get category events but by course (there aren't course events in the course). 519 $paramevents = array('courseids' => array($course3->id)); 520 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false); 521 $events = core_calendar_external::get_calendar_events($paramevents, $options); 522 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 523 $this->assertEquals(1, count($events['events'])); 524 $this->assertEquals($catevent2->id, $events['events'][0]['id']); 525 $this->assertEquals(0, count($events['warnings'])); 526 527 // Empty events in one where I'm not enrolled and one parent category 528 // (parent of a category where this is a course where the user is enrolled). 529 $paramevents = array('categoryids' => array($category2->id, $category->id)); 530 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false); 531 $events = core_calendar_external::get_calendar_events($paramevents, $options); 532 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 533 $this->assertEquals(1, count($events['events'])); 534 $this->assertEquals($catevent2->id, $events['events'][0]['id']); 535 $this->assertEquals(0, count($events['warnings'])); 536 537 // Admin can see all category events. 538 $this->setAdminUser(); 539 $paramevents = array('categoryids' => array($category->id, $category2->id, $category2b->id)); 540 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false); 541 $events = core_calendar_external::get_calendar_events($paramevents, $options); 542 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 543 $this->assertEquals(2, count($events['events'])); 544 $this->assertEquals(0, count($events['warnings'])); 545 $this->assertEquals($catevent1->id, $events['events'][0]['id']); 546 $this->assertEquals($category->id, $events['events'][0]['categoryid']); 547 $this->assertEquals($catevent2->id, $events['events'][1]['id']); 548 $this->assertEquals($category2->id, $events['events'][1]['categoryid']); 549 } 550 551 /** 552 * Test get_calendar_events with mathjax in the name. 553 */ 554 public function test_get_calendar_events_with_mathjax() { 555 global $USER; 556 557 $this->resetAfterTest(true); 558 set_config('calendar_adminseesall', 1); 559 $this->setAdminUser(); 560 561 // Enable MathJax filter in content and headings. 562 $this->configure_filters([ 563 ['name' => 'mathjaxloader', 'state' => TEXTFILTER_ON, 'move' => -1, 'applytostrings' => true], 564 ]); 565 566 // Create a site event with mathjax in the name and description. 567 $siteevent = $this->create_calendar_event('Site Event $$(a+b)=2$$', $USER->id, 'site', 0, time(), 568 ['description' => 'Site Event Description $$(a+b)=2$$']); 569 570 // Now call the WebService. 571 $events = core_calendar_external::get_calendar_events(); 572 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 573 574 // Format the original data. 575 $sitecontext = context_system::instance(); 576 $siteevent->name = $siteevent->format_external_name(); 577 list($siteevent->description, $siteevent->descriptionformat) = $siteevent->format_external_text(); 578 579 // Check that the event data is formatted. 580 $this->assertCount(1, $events['events']); 581 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', $events['events'][0]['name']); 582 $this->assertStringContainsString('<span class="filter_mathjaxloader_equation">', $events['events'][0]['description']); 583 $this->assertEquals($siteevent->name, $events['events'][0]['name']); 584 $this->assertEquals($siteevent->description, $events['events'][0]['description']); 585 } 586 587 /** 588 * Test core_calendar_external::create_calendar_events 589 */ 590 public function test_core_create_calendar_events() { 591 global $DB, $USER, $SITE; 592 593 $this->resetAfterTest(true); 594 $this->setAdminUser(); 595 596 // Create a few stuff to test with. 597 $user = $this->getDataGenerator()->create_user(); 598 $course = $this->getDataGenerator()->create_course(); 599 $record = new stdClass(); 600 $record->courseid = $course->id; 601 $group = $this->getDataGenerator()->create_group($record); 602 603 $prevcount = $DB->count_records('event'); 604 605 // Let's create a few events. 606 $events = array ( 607 array('name' => 'site', 'courseid' => $SITE->id, 'eventtype' => 'site'), 608 array('name' => 'course', 'courseid' => $course->id, 'eventtype' => 'course', 'repeats' => 2), 609 array('name' => 'group', 'courseid' => $course->id, 'groupid' => $group->id, 'eventtype' => 'group'), 610 array('name' => 'user') 611 ); 612 $eventsret = core_calendar_external::create_calendar_events($events); 613 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret); 614 615 // Check to see if things were created properly. 616 $aftercount = $DB->count_records('event'); 617 $this->assertEquals($prevcount + 5, $aftercount); 618 $this->assertEquals(5, count($eventsret['events'])); 619 $this->assertEquals(0, count($eventsret['warnings'])); 620 621 $sitecontext = context_system::instance(); 622 $coursecontext = context_course::instance($course->id); 623 624 $this->setUser($user); 625 $prevcount = $aftercount; 626 $events = array ( 627 array('name' => 'course', 'courseid' => $course->id, 'eventtype' => 'course', 'repeats' => 2), 628 array('name' => 'group', 'courseid' => $course->id, 'groupid' => $group->id, 'eventtype' => 'group'), 629 array('name' => 'user') 630 ); 631 $role = $DB->get_record('role', array('shortname' => 'student')); 632 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 633 groups_add_member($group, $user); 634 $this->assignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id); 635 $this->assignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id); 636 $eventsret = core_calendar_external::create_calendar_events($events); 637 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret); 638 // Check to see if things were created properly. 639 $aftercount = $DB->count_records('event'); 640 $this->assertEquals($prevcount + 4, $aftercount); 641 $this->assertEquals(4, count($eventsret['events'])); 642 $this->assertEquals(0, count($eventsret['warnings'])); 643 644 // Check to see nothing was created without proper permission. 645 $this->setGuestUser(); 646 $prevcount = $DB->count_records('event'); 647 $eventsret = core_calendar_external::create_calendar_events($events); 648 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret); 649 $aftercount = $DB->count_records('event'); 650 $this->assertEquals($prevcount, $aftercount); 651 $this->assertEquals(0, count($eventsret['events'])); 652 $this->assertEquals(3, count($eventsret['warnings'])); 653 654 $this->setUser($user); 655 $this->unassignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id); 656 $this->unassignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id); 657 $prevcount = $DB->count_records('event'); 658 $eventsret = core_calendar_external::create_calendar_events($events); 659 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret); 660 $aftercount = $DB->count_records('event'); 661 $this->assertEquals($prevcount + 1, $aftercount); // User event. 662 $this->assertEquals(1, count($eventsret['events'])); 663 $this->assertEquals(2, count($eventsret['warnings'])); 664 } 665 666 /** 667 * Requesting calendar events from a given time should return all events with a sort 668 * time at or after the requested time. All events prior to that time should not 669 * be return. 670 * 671 * If there are no events on or after the given time then an empty result set should 672 * be returned. 673 */ 674 public function test_get_calendar_action_events_by_timesort_after_time() { 675 $user = $this->getDataGenerator()->create_user(); 676 $course = $this->getDataGenerator()->create_course(); 677 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 678 $moduleinstance = $generator->create_instance(['course' => $course->id]); 679 680 $this->getDataGenerator()->enrol_user($user->id, $course->id); 681 $this->resetAfterTest(true); 682 $this->setUser($user); 683 684 $params = [ 685 'type' => CALENDAR_EVENT_TYPE_ACTION, 686 'modulename' => 'assign', 687 'instance' => $moduleinstance->id, 688 'courseid' => $course->id, 689 ]; 690 691 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1])); 692 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2])); 693 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3])); 694 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4])); 695 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5])); 696 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6])); 697 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7])); 698 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8])); 699 700 $result = core_calendar_external::get_calendar_action_events_by_timesort(5); 701 $result = external_api::clean_returnvalue( 702 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 703 $result 704 ); 705 $events = $result['events']; 706 707 $this->assertCount(4, $events); 708 $this->assertEquals('Event 5', $events[0]['name']); 709 $this->assertEquals('Event 6', $events[1]['name']); 710 $this->assertEquals('Event 7', $events[2]['name']); 711 $this->assertEquals('Event 8', $events[3]['name']); 712 $this->assertEquals($event5->id, $result['firstid']); 713 $this->assertEquals($event8->id, $result['lastid']); 714 715 $result = core_calendar_external::get_calendar_action_events_by_timesort(9); 716 $result = external_api::clean_returnvalue( 717 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 718 $result 719 ); 720 721 $this->assertEmpty($result['events']); 722 $this->assertNull($result['firstid']); 723 $this->assertNull($result['lastid']); 724 725 // Requesting action events on behalf of another user. 726 $this->setAdminUser(); 727 $result = core_calendar_external::get_calendar_action_events_by_timesort(5, null, 0, 20, false, $user->id); 728 $result = external_api::clean_returnvalue( 729 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 730 $result 731 ); 732 $events = $result['events']; 733 734 $this->assertCount(4, $events); 735 $this->assertEquals('Event 5', $events[0]['name']); 736 $this->assertEquals('Event 6', $events[1]['name']); 737 $this->assertEquals('Event 7', $events[2]['name']); 738 $this->assertEquals('Event 8', $events[3]['name']); 739 $this->assertEquals($event5->id, $result['firstid']); 740 $this->assertEquals($event8->id, $result['lastid']); 741 } 742 743 /** 744 * Requesting calendar events before a given time should return all events with a sort 745 * time at or before the requested time (inclusive). All events after that time 746 * should not be returned. 747 * 748 * If there are no events before the given time then an empty result set should be 749 * returned. 750 */ 751 public function test_get_calendar_action_events_by_timesort_before_time() { 752 $user = $this->getDataGenerator()->create_user(); 753 $course = $this->getDataGenerator()->create_course(); 754 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 755 $moduleinstance = $generator->create_instance(['course' => $course->id]); 756 757 $this->getDataGenerator()->enrol_user($user->id, $course->id); 758 $this->resetAfterTest(true); 759 $this->setUser($user); 760 761 $params = [ 762 'type' => CALENDAR_EVENT_TYPE_ACTION, 763 'modulename' => 'assign', 764 'instance' => $moduleinstance->id, 765 'courseid' => $course->id, 766 ]; 767 768 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2])); 769 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3])); 770 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4])); 771 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5])); 772 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6])); 773 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7])); 774 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8])); 775 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 9])); 776 777 $result = core_calendar_external::get_calendar_action_events_by_timesort(null, 5); 778 $result = external_api::clean_returnvalue( 779 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 780 $result 781 ); 782 $events = $result['events']; 783 784 $this->assertCount(4, $events); 785 $this->assertEquals('Event 1', $events[0]['name']); 786 $this->assertEquals('Event 2', $events[1]['name']); 787 $this->assertEquals('Event 3', $events[2]['name']); 788 $this->assertEquals('Event 4', $events[3]['name']); 789 $this->assertEquals($event1->id, $result['firstid']); 790 $this->assertEquals($event4->id, $result['lastid']); 791 792 $result = core_calendar_external::get_calendar_action_events_by_timesort(null, 1); 793 $result = external_api::clean_returnvalue( 794 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 795 $result 796 ); 797 798 $this->assertEmpty($result['events']); 799 $this->assertNull($result['firstid']); 800 $this->assertNull($result['lastid']); 801 802 // Requesting action events on behalf of another user. 803 $this->setAdminUser(); 804 805 $result = core_calendar_external::get_calendar_action_events_by_timesort(null, 5, 0, 20, false, $user->id); 806 $result = external_api::clean_returnvalue( 807 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 808 $result 809 ); 810 $events = $result['events']; 811 812 $this->assertCount(4, $events); 813 $this->assertEquals('Event 1', $events[0]['name']); 814 $this->assertEquals('Event 2', $events[1]['name']); 815 $this->assertEquals('Event 3', $events[2]['name']); 816 $this->assertEquals('Event 4', $events[3]['name']); 817 $this->assertEquals($event1->id, $result['firstid']); 818 $this->assertEquals($event4->id, $result['lastid']); 819 } 820 821 /** 822 * Test retrieving event that was overridden for a user 823 */ 824 public function test_get_calendar_events_override() { 825 $user = $this->getDataGenerator()->create_user(); 826 $user2 = $this->getDataGenerator()->create_user(); 827 $teacher = $this->getDataGenerator()->create_user(); 828 $anotheruser = $this->getDataGenerator()->create_user(); 829 $course = $this->getDataGenerator()->create_course(); 830 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 831 $moduleinstance = $generator->create_instance(['course' => $course->id]); 832 833 $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student'); 834 $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student'); 835 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher'); 836 $this->resetAfterTest(true); 837 $this->setAdminUser(); 838 839 $params = [ 840 'type' => CALENDAR_EVENT_TYPE_ACTION, 841 'modulename' => 'assign', 842 'instance' => $moduleinstance->id, 843 ]; 844 845 $now = time(); 846 // Create two events - one for everybody in the course and one only for the first student. 847 $event1 = $this->create_calendar_event('Base event', 0, 'due', 0, $now + DAYSECS, $params + ['courseid' => $course->id]); 848 $event2 = $this->create_calendar_event('User event', $user->id, 'due', 0, $now + 2*DAYSECS, $params + ['courseid' => 0]); 849 850 // Retrieve course events for the second student - only one "Base event" is returned. 851 $this->setUser($user2); 852 $paramevents = array('courseids' => array($course->id)); 853 $options = array ('siteevents' => true, 'userevents' => true); 854 $events = core_calendar_external::get_calendar_events($paramevents, $options); 855 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 856 $this->assertEquals(1, count($events['events'])); 857 $this->assertEquals(0, count($events['warnings'])); 858 $this->assertEquals('Base event', $events['events'][0]['name']); 859 860 // Retrieve events for the first student - both events are returned. 861 $this->setUser($user); 862 $events = core_calendar_external::get_calendar_events($paramevents, $options); 863 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 864 $this->assertEquals(2, count($events['events'])); 865 $this->assertEquals(0, count($events['warnings'])); 866 $this->assertEquals('Base event', $events['events'][0]['name']); 867 $this->assertEquals('User event', $events['events'][1]['name']); 868 869 // Retrieve events by id as a teacher, 'User event' should be returned since teacher has access to this course. 870 $this->setUser($teacher); 871 $paramevents = ['eventids' => [$event2->id]]; 872 $events = core_calendar_external::get_calendar_events($paramevents, $options); 873 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 874 $this->assertEquals(1, count($events['events'])); 875 $this->assertEquals(0, count($events['warnings'])); 876 $this->assertEquals('User event', $events['events'][0]['name']); 877 878 // Retrieve events by id as another user, nothing should be returned. 879 $this->setUser($anotheruser); 880 $paramevents = ['eventids' => [$event2->id, $event1->id]]; 881 $events = core_calendar_external::get_calendar_events($paramevents, $options); 882 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events); 883 $this->assertEquals(0, count($events['events'])); 884 $this->assertEquals(0, count($events['warnings'])); 885 } 886 887 /** 888 * Requesting calendar events within a given time range should return all events with 889 * a sort time between the lower and upper time bound (inclusive). 890 * 891 * If there are no events in the given time range then an empty result set should be 892 * returned. 893 */ 894 public function test_get_calendar_action_events_by_timesort_time_range() { 895 $user = $this->getDataGenerator()->create_user(); 896 $course = $this->getDataGenerator()->create_course(); 897 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 898 $moduleinstance = $generator->create_instance(['course' => $course->id]); 899 900 $this->getDataGenerator()->enrol_user($user->id, $course->id); 901 $this->resetAfterTest(true); 902 $this->setUser($user); 903 904 $params = [ 905 'type' => CALENDAR_EVENT_TYPE_ACTION, 906 'modulename' => 'assign', 907 'instance' => $moduleinstance->id, 908 'courseid' => $course->id, 909 ]; 910 911 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1])); 912 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2])); 913 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3])); 914 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4])); 915 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5])); 916 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6])); 917 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7])); 918 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8])); 919 920 $result = core_calendar_external::get_calendar_action_events_by_timesort(3, 6); 921 $result = external_api::clean_returnvalue( 922 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 923 $result 924 ); 925 $events = $result['events']; 926 927 $this->assertCount(4, $events); 928 $this->assertEquals('Event 3', $events[0]['name']); 929 $this->assertEquals('Event 4', $events[1]['name']); 930 $this->assertEquals('Event 5', $events[2]['name']); 931 $this->assertEquals('Event 6', $events[3]['name']); 932 $this->assertEquals($event3->id, $result['firstid']); 933 $this->assertEquals($event6->id, $result['lastid']); 934 935 $result = core_calendar_external::get_calendar_action_events_by_timesort(10, 15); 936 $result = external_api::clean_returnvalue( 937 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 938 $result 939 ); 940 941 $this->assertEmpty($result['events']); 942 $this->assertNull($result['firstid']); 943 $this->assertNull($result['lastid']); 944 } 945 946 /** 947 * Requesting calendar events within a given time range and a limit and offset should return 948 * the number of events up to the given limit value that have a sort time between the lower 949 * and uppper time bound (inclusive) where the result set is shifted by the offset value. 950 * 951 * If there are no events in the given time range then an empty result set should be 952 * returned. 953 */ 954 public function test_get_calendar_action_events_by_timesort_time_limit_offset() { 955 $user = $this->getDataGenerator()->create_user(); 956 $course = $this->getDataGenerator()->create_course(); 957 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 958 $moduleinstance = $generator->create_instance(['course' => $course->id]); 959 960 $this->getDataGenerator()->enrol_user($user->id, $course->id); 961 $this->resetAfterTest(true); 962 $this->setUser($user); 963 964 $params = [ 965 'type' => CALENDAR_EVENT_TYPE_ACTION, 966 'modulename' => 'assign', 967 'instance' => $moduleinstance->id, 968 'courseid' => $course->id, 969 ]; 970 971 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1])); 972 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2])); 973 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3])); 974 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4])); 975 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5])); 976 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6])); 977 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7])); 978 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8])); 979 980 $result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event3->id, 2); 981 $result = external_api::clean_returnvalue( 982 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 983 $result 984 ); 985 $events = $result['events']; 986 987 $this->assertCount(2, $events); 988 $this->assertEquals('Event 4', $events[0]['name']); 989 $this->assertEquals('Event 5', $events[1]['name']); 990 $this->assertEquals($event4->id, $result['firstid']); 991 $this->assertEquals($event5->id, $result['lastid']); 992 993 $result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event5->id, 2); 994 $result = external_api::clean_returnvalue( 995 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 996 $result 997 ); 998 $events = $result['events']; 999 1000 $this->assertCount(2, $events); 1001 $this->assertEquals('Event 6', $events[0]['name']); 1002 $this->assertEquals('Event 7', $events[1]['name']); 1003 $this->assertEquals($event6->id, $result['firstid']); 1004 $this->assertEquals($event7->id, $result['lastid']); 1005 1006 $result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event7->id, 2); 1007 $result = external_api::clean_returnvalue( 1008 core_calendar_external::get_calendar_action_events_by_timesort_returns(), 1009 $result 1010 ); 1011 1012 $this->assertEmpty($result['events']); 1013 $this->assertNull($result['firstid']); 1014 $this->assertNull($result['lastid']); 1015 } 1016 1017 /** 1018 * Check that it is possible to restrict the calendar events to events where the user is not suspended in the course. 1019 */ 1020 public function test_get_calendar_action_events_by_timesort_suspended_course() { 1021 $this->resetAfterTest(); 1022 $user1 = $this->getDataGenerator()->create_user(); 1023 $user2 = $this->getDataGenerator()->create_user(); 1024 $course = $this->getDataGenerator()->create_course(); 1025 $this->setAdminUser(); 1026 $lesson = $this->getDataGenerator()->create_module('lesson', [ 1027 'name' => 'Lesson 1', 1028 'course' => $course->id, 1029 'available' => time(), 1030 'deadline' => (time() + (60 * 60 * 24 * 5)) 1031 ] 1032 ); 1033 $this->getDataGenerator()->enrol_user($user1->id, $course->id, null, 'manual', 0, 0, ENROL_USER_SUSPENDED); 1034 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 1035 1036 $this->setUser($user1); 1037 $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true); 1038 $this->assertEmpty($result->events); 1039 $this->setUser($user2); 1040 $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true); 1041 $this->assertCount(1, $result->events); 1042 $this->assertEquals('Lesson 1 closes', $result->events[0]->name); 1043 } 1044 1045 /** 1046 * Check that it is possible to get other user's events without the permission. 1047 */ 1048 public function test_get_calendar_action_events_by_timesort_for_other_users() { 1049 $this->resetAfterTest(); 1050 // Create test users. 1051 $user1 = $this->getDataGenerator()->create_user(['email' => 'student1@localhost.com']); 1052 $user2 = $this->getDataGenerator()->create_user(['email' => 'student2@localhost.com']); 1053 // Create test course. 1054 $course = $this->getDataGenerator()->create_course(); 1055 $this->setAdminUser(); 1056 // Create test activity and make it available only for student2. 1057 $lesson = $this->getDataGenerator()->create_module('lesson', [ 1058 'name' => 'Lesson 1', 1059 'course' => $course->id, 1060 'available' => time(), 1061 'deadline' => (time() + (60 * 60 * 24 * 5)), 1062 'availability' => '{"op":"&","c":[{"type":"profile","sf":"email","op":"isequalto","v":"student2@localhost.com"}],"showc":[true]}' 1063 ] 1064 ); 1065 // Enrol. 1066 $this->getDataGenerator()->enrol_user($user1->id, $course->id); 1067 $this->getDataGenerator()->enrol_user($user2->id, $course->id); 1068 1069 // Student2 can see the event. 1070 $this->setUser($user2); 1071 $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true); 1072 $this->assertCount(1, $result->events); 1073 $this->assertEquals('Lesson 1 closes', $result->events[0]->name); 1074 1075 // Student1 cannot see the event. 1076 $this->setUser($user1); 1077 $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true); 1078 $this->assertEmpty($result->events); 1079 1080 // Admin, Manager, Teacher can view student2's data. 1081 $this->setAdminUser(); 1082 $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true, $user2->id); 1083 $this->assertCount(1, $result->events); 1084 $this->assertEquals('Lesson 1 closes', $result->events[0]->name); 1085 1086 // Student1 will see an exception if he/she trying to view student2's data. 1087 $this->setUser($user1); 1088 $this->expectException(required_capability_exception::class); 1089 $this->expectExceptionMessage('error/nopermission'); 1090 $result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true, $user2->id); 1091 } 1092 1093 /** 1094 * Requesting calendar events from a given course and time should return all 1095 * events with a sort time at or after the requested time. All events prior 1096 * to that time should not be return. 1097 * 1098 * If there are no events on or after the given time then an empty result set should 1099 * be returned. 1100 */ 1101 public function test_get_calendar_action_events_by_course_after_time() { 1102 $user = $this->getDataGenerator()->create_user(); 1103 $course1 = $this->getDataGenerator()->create_course(); 1104 $course2 = $this->getDataGenerator()->create_course(); 1105 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1106 $instance1 = $generator->create_instance(['course' => $course1->id]); 1107 $instance2 = $generator->create_instance(['course' => $course2->id]); 1108 $records = []; 1109 1110 $this->getDataGenerator()->enrol_user($user->id, $course1->id); 1111 $this->getDataGenerator()->enrol_user($user->id, $course2->id); 1112 $this->resetAfterTest(true); 1113 $this->setUser($user); 1114 1115 for ($i = 1; $i < 19; $i++) { 1116 $courseid = ($i < 9) ? $course1->id : $course2->id; 1117 $instance = ($i < 9) ? $instance1->id : $instance2->id; 1118 $records[] = $this->create_calendar_event( 1119 sprintf('Event %d', $i), 1120 $user->id, 1121 'user', 1122 0, 1123 1, 1124 [ 1125 'type' => CALENDAR_EVENT_TYPE_ACTION, 1126 'courseid' => $courseid, 1127 'timesort' => $i, 1128 'modulename' => 'assign', 1129 'instance' => $instance, 1130 ] 1131 ); 1132 } 1133 1134 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 5); 1135 $result = external_api::clean_returnvalue( 1136 core_calendar_external::get_calendar_action_events_by_course_returns(), 1137 $result 1138 ); 1139 $result = $result['events']; 1140 1141 $this->assertCount(4, $result); 1142 $this->assertEquals('Event 5', $result[0]['name']); 1143 $this->assertEquals('Event 6', $result[1]['name']); 1144 $this->assertEquals('Event 7', $result[2]['name']); 1145 $this->assertEquals('Event 8', $result[3]['name']); 1146 1147 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 9); 1148 $result = external_api::clean_returnvalue( 1149 core_calendar_external::get_calendar_action_events_by_course_returns(), 1150 $result 1151 ); 1152 $result = $result['events']; 1153 1154 $this->assertEmpty($result); 1155 } 1156 1157 /** 1158 * Requesting calendar events for a course and before a given time should return 1159 * all events with a sort time at or before the requested time (inclusive). All 1160 * events after that time should not be returned. 1161 * 1162 * If there are no events before the given time then an empty result set should be 1163 * returned. 1164 */ 1165 public function test_get_calendar_action_events_by_course_before_time() { 1166 $user = $this->getDataGenerator()->create_user(); 1167 $course1 = $this->getDataGenerator()->create_course(); 1168 $course2 = $this->getDataGenerator()->create_course(); 1169 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1170 $instance1 = $generator->create_instance(['course' => $course1->id]); 1171 $instance2 = $generator->create_instance(['course' => $course2->id]); 1172 $records = []; 1173 1174 $this->getDataGenerator()->enrol_user($user->id, $course1->id); 1175 $this->getDataGenerator()->enrol_user($user->id, $course2->id); 1176 $this->resetAfterTest(true); 1177 $this->setUser($user); 1178 1179 for ($i = 1; $i < 19; $i++) { 1180 $courseid = ($i < 9) ? $course1->id : $course2->id; 1181 $instance = ($i < 9) ? $instance1->id : $instance2->id; 1182 $records[] = $this->create_calendar_event( 1183 sprintf('Event %d', $i), 1184 $user->id, 1185 'user', 1186 0, 1187 1, 1188 [ 1189 'type' => CALENDAR_EVENT_TYPE_ACTION, 1190 'courseid' => $courseid, 1191 'timesort' => $i + 1, 1192 'modulename' => 'assign', 1193 'instance' => $instance, 1194 ] 1195 ); 1196 } 1197 1198 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, null, 5); 1199 $result = external_api::clean_returnvalue( 1200 core_calendar_external::get_calendar_action_events_by_course_returns(), 1201 $result 1202 ); 1203 $result = $result['events']; 1204 1205 $this->assertCount(4, $result); 1206 $this->assertEquals('Event 1', $result[0]['name']); 1207 $this->assertEquals('Event 2', $result[1]['name']); 1208 $this->assertEquals('Event 3', $result[2]['name']); 1209 $this->assertEquals('Event 4', $result[3]['name']); 1210 1211 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, null, 1); 1212 $result = external_api::clean_returnvalue( 1213 core_calendar_external::get_calendar_action_events_by_course_returns(), 1214 $result 1215 ); 1216 $result = $result['events']; 1217 1218 $this->assertEmpty($result); 1219 } 1220 1221 /** 1222 * Requesting calendar events for a course and within a given time range should 1223 * return all events with a sort time between the lower and upper time bound 1224 * (inclusive). 1225 * 1226 * If there are no events in the given time range then an empty result set should be 1227 * returned. 1228 */ 1229 public function test_get_calendar_action_events_by_course_time_range() { 1230 $user = $this->getDataGenerator()->create_user(); 1231 $course1 = $this->getDataGenerator()->create_course(); 1232 $course2 = $this->getDataGenerator()->create_course(); 1233 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1234 $instance1 = $generator->create_instance(['course' => $course1->id]); 1235 $instance2 = $generator->create_instance(['course' => $course2->id]); 1236 $records = []; 1237 1238 $this->getDataGenerator()->enrol_user($user->id, $course1->id); 1239 $this->getDataGenerator()->enrol_user($user->id, $course2->id); 1240 $this->resetAfterTest(true); 1241 $this->setUser($user); 1242 1243 for ($i = 1; $i < 19; $i++) { 1244 $courseid = ($i < 9) ? $course1->id : $course2->id; 1245 $instance = ($i < 9) ? $instance1->id : $instance2->id; 1246 $records[] = $this->create_calendar_event( 1247 sprintf('Event %d', $i), 1248 $user->id, 1249 'user', 1250 0, 1251 1, 1252 [ 1253 'type' => CALENDAR_EVENT_TYPE_ACTION, 1254 'courseid' => $courseid, 1255 'timesort' => $i, 1256 'modulename' => 'assign', 1257 'instance' => $instance, 1258 ] 1259 ); 1260 } 1261 1262 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 3, 6); 1263 $result = external_api::clean_returnvalue( 1264 core_calendar_external::get_calendar_action_events_by_course_returns(), 1265 $result 1266 ); 1267 $result = $result['events']; 1268 1269 $this->assertCount(4, $result); 1270 $this->assertEquals('Event 3', $result[0]['name']); 1271 $this->assertEquals('Event 4', $result[1]['name']); 1272 $this->assertEquals('Event 5', $result[2]['name']); 1273 $this->assertEquals('Event 6', $result[3]['name']); 1274 1275 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 10, 15); 1276 $result = external_api::clean_returnvalue( 1277 core_calendar_external::get_calendar_action_events_by_course_returns(), 1278 $result 1279 ); 1280 $result = $result['events']; 1281 1282 $this->assertEmpty($result); 1283 } 1284 1285 /** 1286 * Requesting calendar events for a course and within a given time range and a limit 1287 * and offset should return the number of events up to the given limit value that have 1288 * a sort time between the lower and uppper time bound (inclusive) where the result 1289 * set is shifted by the offset value. 1290 * 1291 * If there are no events in the given time range then an empty result set should be 1292 * returned. 1293 */ 1294 public function test_get_calendar_action_events_by_course_time_limit_offset() { 1295 $user = $this->getDataGenerator()->create_user(); 1296 $course1 = $this->getDataGenerator()->create_course(); 1297 $course2 = $this->getDataGenerator()->create_course(); 1298 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1299 $instance1 = $generator->create_instance(['course' => $course1->id]); 1300 $instance2 = $generator->create_instance(['course' => $course2->id]); 1301 $records = []; 1302 1303 $this->getDataGenerator()->enrol_user($user->id, $course1->id); 1304 $this->getDataGenerator()->enrol_user($user->id, $course2->id); 1305 $this->resetAfterTest(true); 1306 $this->setUser($user); 1307 1308 for ($i = 1; $i < 19; $i++) { 1309 $courseid = ($i < 9) ? $course1->id : $course2->id; 1310 $instance = ($i < 9) ? $instance1->id : $instance2->id; 1311 $records[] = $this->create_calendar_event( 1312 sprintf('Event %d', $i), 1313 $user->id, 1314 'user', 1315 0, 1316 1, 1317 [ 1318 'type' => CALENDAR_EVENT_TYPE_ACTION, 1319 'courseid' => $courseid, 1320 'timesort' => $i, 1321 'modulename' => 'assign', 1322 'instance' => $instance, 1323 ] 1324 ); 1325 } 1326 1327 $result = core_calendar_external::get_calendar_action_events_by_course( 1328 $course1->id, 2, 7, $records[2]->id, 2); 1329 $result = external_api::clean_returnvalue( 1330 core_calendar_external::get_calendar_action_events_by_course_returns(), 1331 $result 1332 ); 1333 $result = $result['events']; 1334 1335 $this->assertCount(2, $result); 1336 $this->assertEquals('Event 4', $result[0]['name']); 1337 $this->assertEquals('Event 5', $result[1]['name']); 1338 1339 $result = core_calendar_external::get_calendar_action_events_by_course( 1340 $course1->id, 2, 7, $records[4]->id, 2); 1341 $result = external_api::clean_returnvalue( 1342 core_calendar_external::get_calendar_action_events_by_course_returns(), 1343 $result 1344 ); 1345 $result = $result['events']; 1346 1347 $this->assertCount(2, $result); 1348 $this->assertEquals('Event 6', $result[0]['name']); 1349 $this->assertEquals('Event 7', $result[1]['name']); 1350 1351 $result = core_calendar_external::get_calendar_action_events_by_course( 1352 $course1->id, 2, 7, $records[6]->id, 2); 1353 $result = external_api::clean_returnvalue( 1354 core_calendar_external::get_calendar_action_events_by_course_returns(), 1355 $result 1356 ); 1357 $result = $result['events']; 1358 1359 $this->assertEmpty($result); 1360 } 1361 1362 /** 1363 * Test that get_action_events_by_courses will return a list of events for each 1364 * course you provided as long as the user is enrolled in the course. 1365 */ 1366 public function test_get_action_events_by_courses() { 1367 $user = $this->getDataGenerator()->create_user(); 1368 $course1 = $this->getDataGenerator()->create_course(); 1369 $course2 = $this->getDataGenerator()->create_course(); 1370 $course3 = $this->getDataGenerator()->create_course(); 1371 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign'); 1372 $instance1 = $generator->create_instance(['course' => $course1->id]); 1373 $instance2 = $generator->create_instance(['course' => $course2->id]); 1374 $instance3 = $generator->create_instance(['course' => $course3->id]); 1375 $records = []; 1376 $mapresult = function($result) { 1377 $groupedbycourse = []; 1378 foreach ($result['groupedbycourse'] as $group) { 1379 $events = $group['events']; 1380 $courseid = $group['courseid']; 1381 $groupedbycourse[$courseid] = $events; 1382 } 1383 1384 return $groupedbycourse; 1385 }; 1386 1387 $this->getDataGenerator()->enrol_user($user->id, $course1->id); 1388 $this->getDataGenerator()->enrol_user($user->id, $course2->id); 1389 $this->resetAfterTest(true); 1390 $this->setUser($user); 1391 1392 for ($i = 1; $i < 10; $i++) { 1393 if ($i < 3) { 1394 $courseid = $course1->id; 1395 $instance = $instance1->id; 1396 } else if ($i < 6) { 1397 $courseid = $course2->id; 1398 $instance = $instance2->id; 1399 } else { 1400 $courseid = $course3->id; 1401 $instance = $instance3->id; 1402 } 1403 1404 $records[] = $this->create_calendar_event( 1405 sprintf('Event %d', $i), 1406 $user->id, 1407 'user', 1408 0, 1409 1, 1410 [ 1411 'type' => CALENDAR_EVENT_TYPE_ACTION, 1412 'courseid' => $courseid, 1413 'timesort' => $i, 1414 'modulename' => 'assign', 1415 'instance' => $instance, 1416 ] 1417 ); 1418 } 1419 1420 $result = core_calendar_external::get_calendar_action_events_by_courses([], 1); 1421 $result = external_api::clean_returnvalue( 1422 core_calendar_external::get_calendar_action_events_by_courses_returns(), 1423 $result 1424 ); 1425 $result = $result['groupedbycourse']; 1426 1427 $this->assertEmpty($result); 1428 1429 $result = core_calendar_external::get_calendar_action_events_by_courses([$course1->id], 3); 1430 $result = external_api::clean_returnvalue( 1431 core_calendar_external::get_calendar_action_events_by_courses_returns(), 1432 $result 1433 ); 1434 1435 $groupedbycourse = $mapresult($result); 1436 1437 $this->assertEmpty($groupedbycourse[$course1->id]); 1438 1439 $result = core_calendar_external::get_calendar_action_events_by_courses([$course1->id], 1); 1440 $result = external_api::clean_returnvalue( 1441 core_calendar_external::get_calendar_action_events_by_courses_returns(), 1442 $result 1443 ); 1444 $groupedbycourse = $mapresult($result); 1445 1446 $this->assertCount(2, $groupedbycourse[$course1->id]); 1447 $this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']); 1448 $this->assertEquals('Event 2', $groupedbycourse[$course1->id][1]['name']); 1449 1450 $result = core_calendar_external::get_calendar_action_events_by_courses( 1451 [$course1->id, $course2->id], 1); 1452 $result = external_api::clean_returnvalue( 1453 core_calendar_external::get_calendar_action_events_by_courses_returns(), 1454 $result 1455 ); 1456 $groupedbycourse = $mapresult($result); 1457 1458 $this->assertCount(2, $groupedbycourse[$course1->id]); 1459 $this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']); 1460 $this->assertEquals('Event 2', $groupedbycourse[$course1->id][1]['name']); 1461 $this->assertCount(3, $groupedbycourse[$course2->id]); 1462 $this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']); 1463 $this->assertEquals('Event 4', $groupedbycourse[$course2->id][1]['name']); 1464 $this->assertEquals('Event 5', $groupedbycourse[$course2->id][2]['name']); 1465 1466 $result = core_calendar_external::get_calendar_action_events_by_courses( 1467 [$course1->id, $course2->id], 2, 4); 1468 $result = external_api::clean_returnvalue( 1469 core_calendar_external::get_calendar_action_events_by_courses_returns(), 1470 $result 1471 ); 1472 $groupedbycourse = $mapresult($result); 1473 1474 $this->assertCount(2, $groupedbycourse); 1475 $this->assertCount(1, $groupedbycourse[$course1->id]); 1476 $this->assertEquals('Event 2', $groupedbycourse[$course1->id][0]['name']); 1477 $this->assertCount(2, $groupedbycourse[$course2->id]); 1478 $this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']); 1479 $this->assertEquals('Event 4', $groupedbycourse[$course2->id][1]['name']); 1480 1481 $result = core_calendar_external::get_calendar_action_events_by_courses( 1482 [$course1->id, $course2->id], 1, null, 1); 1483 $result = external_api::clean_returnvalue( 1484 core_calendar_external::get_calendar_action_events_by_courses_returns(), 1485 $result 1486 ); 1487 $groupedbycourse = $mapresult($result); 1488 1489 $this->assertCount(2, $groupedbycourse); 1490 $this->assertCount(1, $groupedbycourse[$course1->id]); 1491 $this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']); 1492 $this->assertCount(1, $groupedbycourse[$course2->id]); 1493 $this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']); 1494 } 1495 1496 /** 1497 * Test for deleting module events. 1498 */ 1499 public function test_delete_calendar_events_for_modules() { 1500 $this->resetAfterTest(); 1501 $this->setAdminUser(); 1502 $course = $this->getDataGenerator()->create_course(); 1503 $nexttime = time() + DAYSECS; 1504 $this->getDataGenerator()->create_module('assign', ['course' => $course->id, 'duedate' => $nexttime]); 1505 $events = calendar_get_events(time(), $nexttime, true, true, true); 1506 $this->assertCount(1, $events); 1507 $params = []; 1508 foreach ($events as $event) { 1509 $params[] = [ 1510 'eventid' => $event->id, 1511 'repeat' => false 1512 ]; 1513 } 1514 1515 $this->expectException('moodle_exception'); 1516 core_calendar_external::delete_calendar_events($params); 1517 } 1518 1519 /** 1520 * Updating the event start day should change the date value but leave 1521 * the time of day unchanged. 1522 */ 1523 public function test_update_event_start_day() { 1524 $generator = $this->getDataGenerator(); 1525 $user = $generator->create_user(); 1526 $roleid = $generator->create_role(); 1527 $context = \context_system::instance(); 1528 $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00'); 1529 $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00'); 1530 $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00'); 1531 1532 $generator->role_assign($roleid, $user->id, $context->id); 1533 assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true); 1534 1535 $this->setUser($user); 1536 $this->resetAfterTest(true); 1537 1538 $event = $this->create_calendar_event( 1539 'Test event', 1540 $user->id, 1541 'user', 1542 0, 1543 null, 1544 [ 1545 'courseid' => 0, 1546 'timestart' => $originalstarttime->getTimestamp() 1547 ] 1548 ); 1549 1550 $result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp()); 1551 $result = external_api::clean_returnvalue( 1552 core_calendar_external::update_event_start_day_returns(), 1553 $result 1554 ); 1555 1556 $this->assertEquals($expected->getTimestamp(), $result['event']['timestart']); 1557 } 1558 1559 /** 1560 * A user should not be able to edit an event that they don't have 1561 * capabilities for. 1562 */ 1563 public function test_update_event_start_day_no_permission() { 1564 $generator = $this->getDataGenerator(); 1565 $user = $generator->create_user(); 1566 $roleid = $generator->create_role(); 1567 $context = \context_system::instance(); 1568 $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00'); 1569 $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00'); 1570 $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00'); 1571 1572 $generator->role_assign($roleid, $user->id, $context->id); 1573 assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true); 1574 1575 $this->setUser($user); 1576 $this->resetAfterTest(true); 1577 1578 $event = $this->create_calendar_event( 1579 'Test event', 1580 $user->id, 1581 'user', 1582 0, 1583 null, 1584 [ 1585 'courseid' => 0, 1586 'timestart' => $originalstarttime->getTimestamp() 1587 ] 1588 ); 1589 1590 assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true); 1591 $this->expectException('moodle_exception'); 1592 $result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp()); 1593 $result = external_api::clean_returnvalue( 1594 core_calendar_external::update_event_start_day_returns(), 1595 $result 1596 ); 1597 } 1598 1599 /** 1600 * A user should not be able to update a module event. 1601 */ 1602 public function test_update_event_start_day_module_event() { 1603 $generator = $this->getDataGenerator(); 1604 $user = $generator->create_user(); 1605 $course = $generator->create_course(); 1606 $plugingenerator = $generator->get_plugin_generator('mod_assign'); 1607 $moduleinstance = $plugingenerator->create_instance(['course' => $course->id]); 1608 $roleid = $generator->create_role(); 1609 $context = \context_course::instance($course->id); 1610 $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00'); 1611 $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00'); 1612 $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00'); 1613 1614 $generator->role_assign($roleid, $user->id, $context->id); 1615 $generator->enrol_user($user->id, $course->id); 1616 1617 $this->setUser($user); 1618 $this->resetAfterTest(true); 1619 1620 $event = $this->create_calendar_event( 1621 'Test event', 1622 $user->id, 1623 'user', 1624 0, 1625 null, 1626 [ 1627 'modulename' => 'assign', 1628 'instance' => $moduleinstance->id, 1629 'courseid' => $course->id, 1630 'timestart' => $originalstarttime->getTimestamp() 1631 ] 1632 ); 1633 1634 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 1635 $this->expectException('moodle_exception'); 1636 $result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp()); 1637 $result = external_api::clean_returnvalue( 1638 core_calendar_external::update_event_start_day_returns(), 1639 $result 1640 ); 1641 } 1642 1643 /** 1644 * Submit a request where the time duration until is earlier than the time 1645 * start in order to get a validation error from the server. 1646 */ 1647 public function test_submit_create_update_form_validation_error() { 1648 $user = $this->getDataGenerator()->create_user(); 1649 $timestart = new DateTime(); 1650 $interval = new DateInterval("P1D"); // One day. 1651 $timedurationuntil = new DateTime(); 1652 $timedurationuntil->sub($interval); 1653 $formdata = [ 1654 'id' => 0, 1655 'userid' => $user->id, 1656 'modulename' => '', 1657 'instance' => 0, 1658 'visible' => 1, 1659 'name' => 'Test', 1660 'timestart' => [ 1661 'day' => $timestart->format('j'), 1662 'month' => $timestart->format('n'), 1663 'year' => $timestart->format('Y'), 1664 'hour' => $timestart->format('G'), 1665 'minute' => 0, 1666 ], 1667 'eventtype' => 'user', 1668 'description' => [ 1669 'text' => '', 1670 'format' => 1, 1671 ], 1672 'location' => 'Test', 1673 'duration' => 1, 1674 'timedurationuntil' => [ 1675 'day' => $timedurationuntil->format('j'), 1676 'month' => $timedurationuntil->format('n'), 1677 'year' => $timedurationuntil->format('Y'), 1678 'hour' => $timedurationuntil->format('G'), 1679 'minute' => 0, 1680 ] 1681 ]; 1682 1683 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 1684 1685 $querystring = http_build_query($formdata, '', '&'); 1686 1687 $this->resetAfterTest(true); 1688 $this->setUser($user); 1689 1690 $result = external_api::clean_returnvalue( 1691 core_calendar_external::submit_create_update_form_returns(), 1692 core_calendar_external::submit_create_update_form($querystring) 1693 ); 1694 1695 $this->assertTrue($result['validationerror']); 1696 } 1697 1698 /** 1699 * A user with the moodle/calendar:manageownentries capability at the 1700 * system context should be able to create a user event. 1701 */ 1702 public function test_submit_create_update_form_create_user_event() { 1703 $generator = $this->getDataGenerator(); 1704 $user = $generator->create_user(); 1705 $roleid = $generator->create_role(); 1706 $context = \context_system::instance(); 1707 $timestart = new DateTime(); 1708 $interval = new DateInterval("P1D"); // One day. 1709 $timedurationuntil = new DateTime(); 1710 $timedurationuntil->add($interval); 1711 $formdata = [ 1712 'id' => 0, 1713 'userid' => $user->id, 1714 'modulename' => '', 1715 'instance' => 0, 1716 'visible' => 1, 1717 'name' => 'Test', 1718 'timestart' => [ 1719 'day' => $timestart->format('j'), 1720 'month' => $timestart->format('n'), 1721 'year' => $timestart->format('Y'), 1722 'hour' => $timestart->format('G'), 1723 'minute' => 0, 1724 ], 1725 'eventtype' => 'user', 1726 'description' => [ 1727 'text' => '', 1728 'format' => 1, 1729 'itemid' => 0 1730 ], 1731 'location' => 'Test', 1732 'duration' => 1, 1733 'timedurationuntil' => [ 1734 'day' => $timedurationuntil->format('j'), 1735 'month' => $timedurationuntil->format('n'), 1736 'year' => $timedurationuntil->format('Y'), 1737 'hour' => $timedurationuntil->format('G'), 1738 'minute' => 0, 1739 ] 1740 ]; 1741 1742 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 1743 $querystring = http_build_query($formdata, '', '&'); 1744 1745 $generator->role_assign($roleid, $user->id, $context->id); 1746 assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true); 1747 1748 $user->ignoresesskey = true; 1749 $this->resetAfterTest(true); 1750 $this->setUser($user); 1751 1752 $result = external_api::clean_returnvalue( 1753 core_calendar_external::submit_create_update_form_returns(), 1754 core_calendar_external::submit_create_update_form($querystring) 1755 ); 1756 1757 $event = $result['event']; 1758 $this->assertEquals($user->id, $event['userid']); 1759 $this->assertEquals($formdata['eventtype'], $event['eventtype']); 1760 $this->assertEquals($formdata['name'], $event['name']); 1761 } 1762 1763 /** 1764 * A user without the moodle/calendar:manageownentries capability at the 1765 * system context should not be able to create a user event. 1766 */ 1767 public function test_submit_create_update_form_create_user_event_no_permission() { 1768 $generator = $this->getDataGenerator(); 1769 $user = $generator->create_user(); 1770 $roleid = $generator->create_role(); 1771 $context = \context_system::instance(); 1772 $timestart = new DateTime(); 1773 $interval = new DateInterval("P1D"); // One day. 1774 $timedurationuntil = new DateTime(); 1775 $timedurationuntil->add($interval); 1776 $formdata = [ 1777 'id' => 0, 1778 'userid' => $user->id, 1779 'modulename' => '', 1780 'instance' => 0, 1781 'visible' => 1, 1782 'name' => 'Test', 1783 'timestart' => [ 1784 'day' => $timestart->format('j'), 1785 'month' => $timestart->format('n'), 1786 'year' => $timestart->format('Y'), 1787 'hour' => $timestart->format('G'), 1788 'minute' => 0, 1789 ], 1790 'eventtype' => 'user', 1791 'description' => [ 1792 'text' => '', 1793 'format' => 1, 1794 ], 1795 'location' => 'Test', 1796 'duration' => 1, 1797 'timedurationuntil' => [ 1798 'day' => $timedurationuntil->format('j'), 1799 'month' => $timedurationuntil->format('n'), 1800 'year' => $timedurationuntil->format('Y'), 1801 'hour' => $timedurationuntil->format('G'), 1802 'minute' => 0, 1803 ] 1804 ]; 1805 1806 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 1807 $querystring = http_build_query($formdata, '', '&'); 1808 1809 $generator->role_assign($roleid, $user->id, $context->id); 1810 assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true); 1811 1812 $user->ignoresesskey = true; 1813 $this->resetAfterTest(true); 1814 $this->setUser($user); 1815 1816 $this->expectException(moodle_exception::class); 1817 external_api::clean_returnvalue( 1818 core_calendar_external::submit_create_update_form_returns(), 1819 core_calendar_external::submit_create_update_form($querystring) 1820 ); 1821 } 1822 1823 /** 1824 * A user with the moodle/calendar:manageentries capability at the 1825 * site course context should be able to create a site event. 1826 */ 1827 public function test_submit_create_update_form_create_site_event() { 1828 $generator = $this->getDataGenerator(); 1829 $user = $generator->create_user(); 1830 $context = context_system::instance(); 1831 $roleid = $generator->create_role(); 1832 $timestart = new DateTime(); 1833 $interval = new DateInterval("P1D"); // One day. 1834 $timedurationuntil = new DateTime(); 1835 $timedurationuntil->add($interval); 1836 $formdata = [ 1837 'id' => 0, 1838 'userid' => $user->id, 1839 'modulename' => '', 1840 'instance' => 0, 1841 'visible' => 1, 1842 'name' => 'Test', 1843 'timestart' => [ 1844 'day' => $timestart->format('j'), 1845 'month' => $timestart->format('n'), 1846 'year' => $timestart->format('Y'), 1847 'hour' => $timestart->format('G'), 1848 'minute' => 0, 1849 ], 1850 'eventtype' => 'site', 1851 'description' => [ 1852 'text' => '', 1853 'format' => 1, 1854 'itemid' => 0 1855 ], 1856 'location' => 'Test', 1857 'duration' => 1, 1858 'timedurationuntil' => [ 1859 'day' => $timedurationuntil->format('j'), 1860 'month' => $timedurationuntil->format('n'), 1861 'year' => $timedurationuntil->format('Y'), 1862 'hour' => $timedurationuntil->format('G'), 1863 'minute' => 0, 1864 ] 1865 ]; 1866 1867 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 1868 $querystring = http_build_query($formdata, '', '&'); 1869 1870 $generator->role_assign($roleid, $user->id, $context->id); 1871 1872 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 1873 1874 $user->ignoresesskey = true; 1875 $this->resetAfterTest(true); 1876 $this->setUser($user); 1877 1878 $result = external_api::clean_returnvalue( 1879 core_calendar_external::submit_create_update_form_returns(), 1880 core_calendar_external::submit_create_update_form($querystring) 1881 ); 1882 1883 $event = $result['event']; 1884 $this->assertEquals($user->id, $event['userid']); 1885 $this->assertEquals($formdata['eventtype'], $event['eventtype']); 1886 $this->assertEquals($formdata['name'], $event['name']); 1887 } 1888 1889 /** 1890 * A user without the moodle/calendar:manageentries capability at the 1891 * site course context should not be able to create a site event. 1892 */ 1893 public function test_submit_create_update_form_create_site_event_no_permission() { 1894 $generator = $this->getDataGenerator(); 1895 $user = $generator->create_user(); 1896 $context = context_course::instance(SITEID); 1897 $roleid = $generator->create_role(); 1898 $timestart = new DateTime(); 1899 $interval = new DateInterval("P1D"); // One day. 1900 $timedurationuntil = new DateTime(); 1901 $timedurationuntil->add($interval); 1902 $formdata = [ 1903 'id' => 0, 1904 'userid' => $user->id, 1905 'modulename' => '', 1906 'instance' => 0, 1907 'visible' => 1, 1908 'name' => 'Test', 1909 'timestart' => [ 1910 'day' => $timestart->format('j'), 1911 'month' => $timestart->format('n'), 1912 'year' => $timestart->format('Y'), 1913 'hour' => $timestart->format('G'), 1914 'minute' => 0, 1915 ], 1916 'eventtype' => 'site', 1917 'description' => [ 1918 'text' => '', 1919 'format' => 1, 1920 ], 1921 'location' => 'Test', 1922 'duration' => 1, 1923 'timedurationuntil' => [ 1924 'day' => $timedurationuntil->format('j'), 1925 'month' => $timedurationuntil->format('n'), 1926 'year' => $timedurationuntil->format('Y'), 1927 'hour' => $timedurationuntil->format('G'), 1928 'minute' => 0, 1929 ] 1930 ]; 1931 1932 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 1933 $querystring = http_build_query($formdata, '', '&'); 1934 1935 $generator->role_assign($roleid, $user->id, $context->id); 1936 1937 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); 1938 1939 $user->ignoresesskey = true; 1940 $this->resetAfterTest(true); 1941 $this->setUser($user); 1942 1943 $result = external_api::clean_returnvalue( 1944 core_calendar_external::submit_create_update_form_returns(), 1945 core_calendar_external::submit_create_update_form($querystring) 1946 ); 1947 1948 $this->assertTrue($result['validationerror']); 1949 } 1950 1951 /** 1952 * A user that has the moodle/calendar:manageentries in a course that they 1953 * are enrolled in should be able to create a course event in that course. 1954 */ 1955 public function test_submit_create_update_form_create_course_event() { 1956 $generator = $this->getDataGenerator(); 1957 $user = $generator->create_user(); 1958 $course = $generator->create_course(); 1959 $context = context_course::instance($course->id); 1960 $roleid = $generator->create_role(); 1961 $timestart = new DateTime(); 1962 $interval = new DateInterval("P1D"); // One day. 1963 $timedurationuntil = new DateTime(); 1964 $timedurationuntil->add($interval); 1965 $formdata = [ 1966 'id' => 0, 1967 'userid' => $user->id, 1968 'modulename' => '', 1969 'instance' => 0, 1970 'visible' => 1, 1971 'name' => 'Test', 1972 'timestart' => [ 1973 'day' => $timestart->format('j'), 1974 'month' => $timestart->format('n'), 1975 'year' => $timestart->format('Y'), 1976 'hour' => $timestart->format('G'), 1977 'minute' => 0, 1978 ], 1979 'eventtype' => 'course', 1980 'courseid' => $course->id, 1981 'description' => [ 1982 'text' => '', 1983 'format' => 1, 1984 'itemid' => 0, 1985 ], 1986 'location' => 'Test', 1987 'duration' => 1, 1988 'timedurationuntil' => [ 1989 'day' => $timedurationuntil->format('j'), 1990 'month' => $timedurationuntil->format('n'), 1991 'year' => $timedurationuntil->format('Y'), 1992 'hour' => $timedurationuntil->format('G'), 1993 'minute' => 0, 1994 ] 1995 ]; 1996 1997 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 1998 $querystring = http_build_query($formdata, '', '&'); 1999 2000 $generator->enrol_user($user->id, $course->id, 'student'); 2001 $generator->role_assign($roleid, $user->id, $context->id); 2002 2003 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 2004 2005 $user->ignoresesskey = true; 2006 $this->resetAfterTest(true); 2007 $this->setUser($user); 2008 2009 $result = external_api::clean_returnvalue( 2010 core_calendar_external::submit_create_update_form_returns(), 2011 core_calendar_external::submit_create_update_form($querystring) 2012 ); 2013 2014 $event = $result['event']; 2015 $this->assertEquals($user->id, $event['userid']); 2016 $this->assertEquals($formdata['eventtype'], $event['eventtype']); 2017 $this->assertEquals($formdata['name'], $event['name']); 2018 $this->assertEquals($formdata['courseid'], $event['course']['id']); 2019 } 2020 2021 /** 2022 * A user without the moodle/calendar:manageentries capability in a course 2023 * that they are enrolled in should not be able to create a course event in that course. 2024 */ 2025 public function test_submit_create_update_form_create_course_event_no_permission() { 2026 $generator = $this->getDataGenerator(); 2027 $user = $generator->create_user(); 2028 $course = $generator->create_course(); 2029 $context = context_course::instance($course->id); 2030 $roleid = $generator->create_role(); 2031 $timestart = new DateTime(); 2032 $interval = new DateInterval("P1D"); // One day. 2033 $timedurationuntil = new DateTime(); 2034 $timedurationuntil->add($interval); 2035 $formdata = [ 2036 'id' => 0, 2037 'userid' => $user->id, 2038 'modulename' => '', 2039 'instance' => 0, 2040 'visible' => 1, 2041 'name' => 'Test', 2042 'timestart' => [ 2043 'day' => $timestart->format('j'), 2044 'month' => $timestart->format('n'), 2045 'year' => $timestart->format('Y'), 2046 'hour' => $timestart->format('G'), 2047 'minute' => 0, 2048 ], 2049 'eventtype' => 'course', 2050 'courseid' => $course->id, 2051 'description' => [ 2052 'text' => '', 2053 'format' => 1, 2054 ], 2055 'location' => 'Test', 2056 'duration' => 1, 2057 'timedurationuntil' => [ 2058 'day' => $timedurationuntil->format('j'), 2059 'month' => $timedurationuntil->format('n'), 2060 'year' => $timedurationuntil->format('Y'), 2061 'hour' => $timedurationuntil->format('G'), 2062 'minute' => 0, 2063 ] 2064 ]; 2065 2066 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2067 $querystring = http_build_query($formdata, '', '&'); 2068 2069 $generator->enrol_user($user->id, $course->id, 'student'); 2070 $generator->role_assign($roleid, $user->id, $context->id); 2071 2072 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); 2073 2074 $user->ignoresesskey = true; 2075 $this->resetAfterTest(true); 2076 $this->setUser($user); 2077 2078 $result = external_api::clean_returnvalue( 2079 core_calendar_external::submit_create_update_form_returns(), 2080 core_calendar_external::submit_create_update_form($querystring) 2081 ); 2082 2083 $this->assertTrue($result['validationerror']); 2084 } 2085 2086 /** 2087 * A user should not be able to create an event for a course that they are 2088 * not enrolled in. 2089 */ 2090 public function test_submit_create_update_form_create_course_event_not_enrolled() { 2091 $generator = $this->getDataGenerator(); 2092 $user = $generator->create_user(); 2093 $course = $generator->create_course(); 2094 $course2 = $generator->create_course(); 2095 $context = context_course::instance($course->id); 2096 $roleid = $generator->create_role(); 2097 $timestart = new DateTime(); 2098 $interval = new DateInterval("P1D"); // One day. 2099 $timedurationuntil = new DateTime(); 2100 $timedurationuntil->add($interval); 2101 $formdata = [ 2102 'id' => 0, 2103 'userid' => $user->id, 2104 'modulename' => '', 2105 'instance' => 0, 2106 'visible' => 1, 2107 'name' => 'Test', 2108 'timestart' => [ 2109 'day' => $timestart->format('j'), 2110 'month' => $timestart->format('n'), 2111 'year' => $timestart->format('Y'), 2112 'hour' => $timestart->format('G'), 2113 'minute' => 0, 2114 ], 2115 'eventtype' => 'course', 2116 'courseid' => $course2->id, // Not enrolled. 2117 'description' => [ 2118 'text' => '', 2119 'format' => 1, 2120 ], 2121 'location' => 'Test', 2122 'duration' => 1, 2123 'timedurationuntil' => [ 2124 'day' => $timedurationuntil->format('j'), 2125 'month' => $timedurationuntil->format('n'), 2126 'year' => $timedurationuntil->format('Y'), 2127 'hour' => $timedurationuntil->format('G'), 2128 'minute' => 0, 2129 ] 2130 ]; 2131 2132 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2133 $querystring = http_build_query($formdata, '', '&'); 2134 2135 $generator->enrol_user($user->id, $course->id, 'student'); 2136 $generator->role_assign($roleid, $user->id, $context->id); 2137 2138 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 2139 2140 $user->ignoresesskey = true; 2141 $this->resetAfterTest(true); 2142 $this->setUser($user); 2143 2144 $result = external_api::clean_returnvalue( 2145 core_calendar_external::submit_create_update_form_returns(), 2146 core_calendar_external::submit_create_update_form($querystring) 2147 ); 2148 2149 $this->assertTrue($result['validationerror']); 2150 } 2151 2152 /** 2153 * A user should be able to create an event for a group that they are a member of in 2154 * a course in which they are enrolled and have the moodle/calendar:manageentries capability. 2155 */ 2156 public function test_submit_create_update_form_create_group_event_group_member_manage_course() { 2157 $generator = $this->getDataGenerator(); 2158 $user = $generator->create_user(); 2159 $course = $generator->create_course(); 2160 $group = $generator->create_group(array('courseid' => $course->id)); 2161 $context = context_course::instance($course->id); 2162 $roleid = $generator->create_role(); 2163 $timestart = new DateTime(); 2164 $interval = new DateInterval("P1D"); // One day. 2165 $timedurationuntil = new DateTime(); 2166 $timedurationuntil->add($interval); 2167 $formdata = [ 2168 'id' => 0, 2169 'userid' => $user->id, 2170 'modulename' => '', 2171 'instance' => 0, 2172 'visible' => 1, 2173 'name' => 'Test', 2174 'timestart' => [ 2175 'day' => $timestart->format('j'), 2176 'month' => $timestart->format('n'), 2177 'year' => $timestart->format('Y'), 2178 'hour' => $timestart->format('G'), 2179 'minute' => 0, 2180 ], 2181 'eventtype' => 'group', 2182 'groupid' => $group->id, 2183 'groupcourseid' => $course->id, 2184 'description' => [ 2185 'text' => '', 2186 'format' => 1, 2187 'itemid' => 0 2188 ], 2189 'location' => 'Test', 2190 'duration' => 1, 2191 'timedurationuntil' => [ 2192 'day' => $timedurationuntil->format('j'), 2193 'month' => $timedurationuntil->format('n'), 2194 'year' => $timedurationuntil->format('Y'), 2195 'hour' => $timedurationuntil->format('G'), 2196 'minute' => 0, 2197 ] 2198 ]; 2199 2200 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2201 $querystring = http_build_query($formdata, '', '&'); 2202 2203 $generator->enrol_user($user->id, $course->id, 'student'); 2204 $generator->role_assign($roleid, $user->id, $context->id); 2205 $generator->create_group_member(['groupid' => $group->id, 'userid' => $user->id]); 2206 2207 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 2208 2209 $user->ignoresesskey = true; 2210 $this->resetAfterTest(true); 2211 $this->setUser($user); 2212 2213 $result = external_api::clean_returnvalue( 2214 core_calendar_external::submit_create_update_form_returns(), 2215 core_calendar_external::submit_create_update_form($querystring) 2216 ); 2217 2218 $event = $result['event']; 2219 $this->assertEquals($user->id, $event['userid']); 2220 $this->assertEquals($formdata['eventtype'], $event['eventtype']); 2221 $this->assertEquals($formdata['name'], $event['name']); 2222 $this->assertEquals($group->id, $event['groupid']); 2223 } 2224 2225 /** 2226 * A user should be able to create an event for a group that they are a member of in 2227 * a course in which they are enrolled and have the moodle/calendar:managegroupentries capability. 2228 */ 2229 public function test_submit_create_update_form_create_group_event_group_member_manage_group_entries() { 2230 $generator = $this->getDataGenerator(); 2231 $user = $generator->create_user(); 2232 $course = $generator->create_course(); 2233 $group = $generator->create_group(array('courseid' => $course->id)); 2234 $context = context_course::instance($course->id); 2235 $roleid = $generator->create_role(); 2236 $timestart = new DateTime(); 2237 $interval = new DateInterval("P1D"); // One day. 2238 $timedurationuntil = new DateTime(); 2239 $timedurationuntil->add($interval); 2240 $formdata = [ 2241 'id' => 0, 2242 'userid' => $user->id, 2243 'modulename' => '', 2244 'instance' => 0, 2245 'visible' => 1, 2246 'name' => 'Test', 2247 'timestart' => [ 2248 'day' => $timestart->format('j'), 2249 'month' => $timestart->format('n'), 2250 'year' => $timestart->format('Y'), 2251 'hour' => $timestart->format('G'), 2252 'minute' => 0, 2253 ], 2254 'eventtype' => 'group', 2255 'groupid' => $group->id, 2256 'groupcourseid' => $course->id, 2257 'description' => [ 2258 'text' => '', 2259 'format' => 1, 2260 'itemid' => 0 2261 ], 2262 'location' => 'Test', 2263 'duration' => 1, 2264 'timedurationuntil' => [ 2265 'day' => $timedurationuntil->format('j'), 2266 'month' => $timedurationuntil->format('n'), 2267 'year' => $timedurationuntil->format('Y'), 2268 'hour' => $timedurationuntil->format('G'), 2269 'minute' => 0, 2270 ] 2271 ]; 2272 2273 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2274 $querystring = http_build_query($formdata, '', '&'); 2275 2276 $generator->enrol_user($user->id, $course->id, 'student'); 2277 $generator->role_assign($roleid, $user->id, $context->id); 2278 $generator->create_group_member(['groupid' => $group->id, 'userid' => $user->id]); 2279 2280 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true); 2281 assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true); 2282 2283 $user->ignoresesskey = true; 2284 $this->resetAfterTest(true); 2285 $this->setUser($user); 2286 2287 $result = external_api::clean_returnvalue( 2288 core_calendar_external::submit_create_update_form_returns(), 2289 core_calendar_external::submit_create_update_form($querystring) 2290 ); 2291 2292 $event = $result['event']; 2293 $this->assertEquals($user->id, $event['userid']); 2294 $this->assertEquals($formdata['eventtype'], $event['eventtype']); 2295 $this->assertEquals($formdata['name'], $event['name']); 2296 $this->assertEquals($group->id, $event['groupid']); 2297 } 2298 2299 /** 2300 * A user should be able to create an event for any group in a course in which 2301 * they are enrolled and have the moodle/site:accessallgroups capability. 2302 */ 2303 public function test_submit_create_update_form_create_group_event_access_all_groups() { 2304 $generator = $this->getDataGenerator(); 2305 $user = $generator->create_user(); 2306 $course = $generator->create_course(); 2307 $group = $generator->create_group(array('courseid' => $course->id)); 2308 $context = context_course::instance($course->id); 2309 $roleid = $generator->create_role(); 2310 $timestart = new DateTime(); 2311 $interval = new DateInterval("P1D"); // One day. 2312 $timedurationuntil = new DateTime(); 2313 $timedurationuntil->add($interval); 2314 $formdata = [ 2315 'id' => 0, 2316 'userid' => $user->id, 2317 'modulename' => '', 2318 'instance' => 0, 2319 'visible' => 1, 2320 'name' => 'Test', 2321 'timestart' => [ 2322 'day' => $timestart->format('j'), 2323 'month' => $timestart->format('n'), 2324 'year' => $timestart->format('Y'), 2325 'hour' => $timestart->format('G'), 2326 'minute' => 0, 2327 ], 2328 'eventtype' => 'group', 2329 'groupid' => $group->id, 2330 'groupcourseid' => $course->id, 2331 'description' => [ 2332 'text' => '', 2333 'format' => 1, 2334 'itemid' => 0 2335 ], 2336 'location' => 'Test', 2337 'duration' => 1, 2338 'timedurationuntil' => [ 2339 'day' => $timedurationuntil->format('j'), 2340 'month' => $timedurationuntil->format('n'), 2341 'year' => $timedurationuntil->format('Y'), 2342 'hour' => $timedurationuntil->format('G'), 2343 'minute' => 0, 2344 ] 2345 ]; 2346 2347 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2348 $querystring = http_build_query($formdata, '', '&'); 2349 2350 $generator->enrol_user($user->id, $course->id, 'student'); 2351 $generator->role_assign($roleid, $user->id, $context->id); 2352 2353 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 2354 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true); 2355 2356 $user->ignoresesskey = true; 2357 $this->resetAfterTest(true); 2358 $this->setUser($user); 2359 2360 $result = external_api::clean_returnvalue( 2361 core_calendar_external::submit_create_update_form_returns(), 2362 core_calendar_external::submit_create_update_form($querystring) 2363 ); 2364 2365 $event = $result['event']; 2366 $this->assertEquals($user->id, $event['userid']); 2367 $this->assertEquals($formdata['eventtype'], $event['eventtype']); 2368 $this->assertEquals($formdata['name'], $event['name']); 2369 $this->assertEquals($group->id, $event['groupid']); 2370 } 2371 2372 /** 2373 * A user should not be able to create an event for any group that they are not a 2374 * member of in a course in which they are enrolled but don't have the 2375 * moodle/site:accessallgroups capability. 2376 */ 2377 public function test_submit_create_update_form_create_group_event_non_member_no_permission() { 2378 $generator = $this->getDataGenerator(); 2379 $user = $generator->create_user(); 2380 $course = $generator->create_course(); 2381 $group = $generator->create_group(array('courseid' => $course->id)); 2382 $context = context_course::instance($course->id); 2383 $roleid = $generator->create_role(); 2384 $timestart = new DateTime(); 2385 $interval = new DateInterval("P1D"); // One day. 2386 $timedurationuntil = new DateTime(); 2387 $timedurationuntil->add($interval); 2388 $formdata = [ 2389 'id' => 0, 2390 'userid' => $user->id, 2391 'modulename' => '', 2392 'instance' => 0, 2393 'visible' => 1, 2394 'name' => 'Test', 2395 'timestart' => [ 2396 'day' => $timestart->format('j'), 2397 'month' => $timestart->format('n'), 2398 'year' => $timestart->format('Y'), 2399 'hour' => $timestart->format('G'), 2400 'minute' => 0, 2401 ], 2402 'eventtype' => 'group', 2403 'groupid' => $group->id, 2404 'groupcourseid' => $course->id, 2405 'description' => [ 2406 'text' => '', 2407 'format' => 1, 2408 ], 2409 'location' => 'Test', 2410 'duration' => 1, 2411 'timedurationuntil' => [ 2412 'day' => $timedurationuntil->format('j'), 2413 'month' => $timedurationuntil->format('n'), 2414 'year' => $timedurationuntil->format('Y'), 2415 'hour' => $timedurationuntil->format('G'), 2416 'minute' => 0, 2417 ] 2418 ]; 2419 2420 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2421 $querystring = http_build_query($formdata, '', '&'); 2422 2423 $generator->enrol_user($user->id, $course->id, 'student'); 2424 $generator->role_assign($roleid, $user->id, $context->id); 2425 2426 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true); 2427 assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true); 2428 2429 $user->ignoresesskey = true; 2430 $this->resetAfterTest(true); 2431 $this->setUser($user); 2432 2433 $result = external_api::clean_returnvalue( 2434 core_calendar_external::submit_create_update_form_returns(), 2435 core_calendar_external::submit_create_update_form($querystring) 2436 ); 2437 2438 $this->assertTrue($result['validationerror']); 2439 } 2440 2441 /** 2442 * A user should not be able load the calendar monthly view for a course they cannot access. 2443 */ 2444 public function test_get_calendar_monthly_view_no_course_permission() { 2445 global $USER; 2446 $this->resetAfterTest(true); 2447 $this->setAdminUser(); 2448 2449 $generator = $this->getDataGenerator(); 2450 $user1 = $generator->create_user(); 2451 $user2 = $generator->create_user(); 2452 $course = $generator->create_course(); 2453 $generator->enrol_user($user1->id, $course->id, 'student'); 2454 $name = 'Course Event (course' . $course->id . ')'; 2455 $record = new stdClass(); 2456 $record->courseid = $course->id; 2457 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record); 2458 2459 $timestart = new DateTime(); 2460 // Admin can load the course. 2461 $data = external_api::clean_returnvalue( 2462 core_calendar_external::get_calendar_monthly_view_returns(), 2463 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'), 2464 $course->id, null, false, true, $timestart->format('j')) 2465 ); 2466 $this->assertEquals($data['courseid'], $course->id); 2467 // User enrolled in the course can load the course calendar. 2468 $this->setUser($user1); 2469 $data = external_api::clean_returnvalue( 2470 core_calendar_external::get_calendar_monthly_view_returns(), 2471 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'), 2472 $course->id, null, false, true, $timestart->format('j')) 2473 ); 2474 $this->assertEquals($data['courseid'], $course->id); 2475 // User not enrolled in the course cannot load the course calendar. 2476 $this->setUser($user2); 2477 $this->expectException('require_login_exception'); 2478 $data = external_api::clean_returnvalue( 2479 core_calendar_external::get_calendar_monthly_view_returns(), 2480 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'), 2481 $course->id, null, false, false, $timestart->format('j')) 2482 ); 2483 } 2484 2485 /** 2486 * Test get_calendar_monthly_view when a day parameter is provided. 2487 */ 2488 public function test_get_calendar_monthly_view_with_day_provided() { 2489 $this->resetAfterTest(); 2490 $this->setAdminUser(); 2491 2492 $timestart = new DateTime(); 2493 $data = external_api::clean_returnvalue( 2494 core_calendar_external::get_calendar_monthly_view_returns(), 2495 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'), 2496 SITEID, null, false, true, $timestart->format('j')) 2497 ); 2498 $this->assertEquals($data['date']['mday'], $timestart->format('d')); 2499 } 2500 2501 /** 2502 * A user should not be able load the calendar day view for a course they cannot access. 2503 */ 2504 public function test_get_calendar_day_view_no_course_permission() { 2505 global $USER; 2506 $this->resetAfterTest(true); 2507 $this->setAdminUser(); 2508 2509 $generator = $this->getDataGenerator(); 2510 $user1 = $generator->create_user(); 2511 $user2 = $generator->create_user(); 2512 $course = $generator->create_course(); 2513 $generator->enrol_user($user1->id, $course->id, 'student'); 2514 $name = 'Course Event (course' . $course->id . ')'; 2515 $record = new stdClass(); 2516 $record->courseid = $course->id; 2517 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record); 2518 2519 $timestart = new DateTime(); 2520 // Admin can load the course. 2521 $data = external_api::clean_returnvalue( 2522 core_calendar_external::get_calendar_day_view_returns(), 2523 core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'), 2524 $timestart->format('j'), $course->id, null) 2525 ); 2526 $this->assertEquals($data['courseid'], $course->id); 2527 // User enrolled in the course can load the course calendar. 2528 $this->setUser($user1); 2529 $data = external_api::clean_returnvalue( 2530 core_calendar_external::get_calendar_day_view_returns(), 2531 core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'), 2532 $timestart->format('j'), $course->id, null) 2533 ); 2534 $this->assertEquals($data['courseid'], $course->id); 2535 // User not enrolled in the course cannot load the course calendar. 2536 $this->setUser($user2); 2537 $this->expectException('require_login_exception'); 2538 $data = external_api::clean_returnvalue( 2539 core_calendar_external::get_calendar_day_view_returns(), 2540 core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'), 2541 $timestart->format('j'), $course->id, null) 2542 ); 2543 } 2544 2545 /** 2546 * A user should not be able load the calendar upcoming view for a course they cannot access. 2547 */ 2548 public function test_get_calendar_upcoming_view_no_course_permission() { 2549 global $USER; 2550 $this->resetAfterTest(true); 2551 $this->setAdminUser(); 2552 2553 $generator = $this->getDataGenerator(); 2554 $user1 = $generator->create_user(); 2555 $user2 = $generator->create_user(); 2556 $course = $generator->create_course(); 2557 $generator->enrol_user($user1->id, $course->id, 'student'); 2558 $name = 'Course Event (course' . $course->id . ')'; 2559 $record = new stdClass(); 2560 $record->courseid = $course->id; 2561 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record); 2562 2563 // Admin can load the course. 2564 $data = external_api::clean_returnvalue( 2565 core_calendar_external::get_calendar_upcoming_view_returns(), 2566 core_calendar_external::get_calendar_upcoming_view($course->id, null) 2567 ); 2568 $this->assertEquals($data['courseid'], $course->id); 2569 // User enrolled in the course can load the course calendar. 2570 $this->setUser($user1); 2571 $data = external_api::clean_returnvalue( 2572 core_calendar_external::get_calendar_upcoming_view_returns(), 2573 core_calendar_external::get_calendar_upcoming_view($course->id, null) 2574 ); 2575 $this->assertEquals($data['courseid'], $course->id); 2576 // User not enrolled in the course cannot load the course calendar. 2577 $this->setUser($user2); 2578 $this->expectException('require_login_exception'); 2579 $data = external_api::clean_returnvalue( 2580 core_calendar_external::get_calendar_upcoming_view_returns(), 2581 core_calendar_external::get_calendar_upcoming_view($course->id, null) 2582 ); 2583 } 2584 2585 /** 2586 * A user should not be able load the calendar event for a course they cannot access. 2587 */ 2588 public function test_get_calendar_event_by_id_no_course_permission() { 2589 global $USER; 2590 $this->resetAfterTest(true); 2591 $this->setAdminUser(); 2592 2593 $generator = $this->getDataGenerator(); 2594 $user1 = $generator->create_user(); 2595 $user2 = $generator->create_user(); 2596 $course = $generator->create_course(); 2597 $generator->enrol_user($user1->id, $course->id, 'student'); 2598 $name = 'Course Event (course' . $course->id . ')'; 2599 $record = new stdClass(); 2600 $record->courseid = $course->id; 2601 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record); 2602 2603 // Admin can load the course event. 2604 $data = external_api::clean_returnvalue( 2605 core_calendar_external::get_calendar_event_by_id_returns(), 2606 core_calendar_external::get_calendar_event_by_id($courseevent->id) 2607 ); 2608 $this->assertEquals($data['event']['id'], $courseevent->id); 2609 // User enrolled in the course can load the course event. 2610 $this->setUser($user1); 2611 $data = external_api::clean_returnvalue( 2612 core_calendar_external::get_calendar_event_by_id_returns(), 2613 core_calendar_external::get_calendar_event_by_id($courseevent->id) 2614 ); 2615 $this->assertEquals($data['event']['id'], $courseevent->id); 2616 // User not enrolled in the course cannot load the course event. 2617 $this->setUser($user2); 2618 $this->expectException(moodle_exception::class); 2619 $data = external_api::clean_returnvalue( 2620 core_calendar_external::get_calendar_event_by_id_returns(), 2621 core_calendar_external::get_calendar_event_by_id($courseevent->id) 2622 ); 2623 } 2624 2625 /** 2626 * User data for testing reading calendar events. 2627 * 2628 * @return array 2629 */ 2630 public function test_get_calendar_event_by_id_prevent_read_other_users_events_data_provider(): array { 2631 $syscontext = context_system::instance(); 2632 $managerrole = 'manager'; 2633 return [ 2634 [true, false, $syscontext, $managerrole, true], 2635 [false, false, $syscontext, $managerrole, false], 2636 [false, false, null, null, true], 2637 [false, true, null, null, false], 2638 ]; 2639 } 2640 2641 /** 2642 * Prevent user from reading other user's event. 2643 * 2644 * @covers \core_calendar_external::get_calendar_event_by_id 2645 * @dataProvider test_get_calendar_event_by_id_prevent_read_other_users_events_data_provider 2646 * 2647 * @param bool $isadminevent Is admin's event 2648 * @param bool $isadmin Is current user admin user 2649 * @param null|stdClass $readerrolecontext Reader role context 2650 * @param null|string $readerrolename Role name 2651 * @param bool $expectexception Should the test throw exception 2652 */ 2653 public function test_get_calendar_event_by_id_prevent_read_other_users_events( 2654 bool $isadminevent, bool $isadmin, ?stdClass $readerrolecontext, 2655 ?string $readerrolename, bool $expectexception) { 2656 global $USER, $DB; 2657 2658 $this->resetAfterTest(); 2659 $generator = $this->getDataGenerator(); 2660 2661 if ($isadminevent) { 2662 $this->setAdminUser(); 2663 } else { 2664 $user = $generator->create_user(); 2665 $this->setUser($user); 2666 } 2667 $userevent = $this->create_calendar_event('user event', $USER->id, 'user', 0, time()); 2668 $results = external_api::clean_returnvalue( 2669 core_calendar_external::get_calendar_event_by_id_returns(), 2670 core_calendar_external::get_calendar_event_by_id($userevent->id) 2671 ); 2672 $event = reset($results); 2673 $this->assertEquals($userevent->id, $event['id']); 2674 2675 if ($isadmin) { 2676 $this->setAdminUser(); 2677 } else { 2678 $reader = $generator->create_user(); 2679 if ($readerrolename && $readerrolecontext) { 2680 $managerroleid = $DB->get_field('role', 'id', ['shortname' => $readerrolename]); 2681 role_assign($managerroleid, $reader->id, $readerrolecontext->id); 2682 } 2683 $this->setUser($reader); 2684 } 2685 2686 if ($expectexception) { 2687 // Setup if exception is expected for the test. 2688 $this->expectException(moodle_exception::class); 2689 } 2690 external_api::clean_returnvalue( 2691 core_calendar_external::get_calendar_event_by_id_returns(), 2692 core_calendar_external::get_calendar_event_by_id($userevent->id) 2693 ); 2694 } 2695 2696 /** 2697 * User data for testing editing or deleting calendar events. 2698 * 2699 * @return array 2700 */ 2701 public function test_edit_or_delete_other_users_events_data_provider(): array { 2702 $syscontext = context_system::instance(); 2703 $managerrole = 'manager'; 2704 return [ 2705 [false, false, $syscontext, $managerrole, false], 2706 [false, true, $syscontext, $managerrole, true], 2707 [false, false, null, null, true], 2708 [true, false, null, null, false], 2709 ]; 2710 } 2711 2712 /** 2713 * Test the behavior of deleting other users' user events. 2714 * 2715 * @dataProvider test_edit_or_delete_other_users_events_data_provider 2716 * @covers \core_calendar_external::delete_calendar_events 2717 * @param bool $isadmin Whether the current user is admin. 2718 * @param bool $isadminevent Whether it's an admin event or not. 2719 * @param stdClass|null $writerrolecontext The reader role context. 2720 * @param string|null $writerrolename The role name. 2721 * @param bool $expectexception Whether the test should throw an exception or not. 2722 */ 2723 public function test_delete_other_users_events(bool $isadmin, bool $isadminevent, 2724 ?stdClass $writerrolecontext, ?string $writerrolename, bool $expectexception) { 2725 global $DB, $USER; 2726 2727 $this->resetAfterTest(); 2728 $generator = $this->getDataGenerator(); 2729 2730 if ($isadminevent) { 2731 $this->setAdminUser(); 2732 $user = $USER; 2733 } else { 2734 $user = $generator->create_user(); 2735 $this->setUser($user); 2736 } 2737 $userevent = $this->create_calendar_event('user event', $user->id, 'user', 0, time()); 2738 2739 if ($isadmin) { 2740 $this->setAdminUser(); 2741 } else { 2742 $writer = $generator->create_user(); 2743 if ($writerrolename && $writerrolecontext) { 2744 $managerroleid = $DB->get_field('role', 'id', ['shortname' => $writerrolename]); 2745 role_assign($managerroleid, $writer->id, $writerrolecontext->id); 2746 } 2747 $this->setUser($writer); 2748 } 2749 2750 if ($expectexception) { 2751 $this->expectException(moodle_exception::class); 2752 } 2753 $events = [ 2754 ['eventid' => $userevent->id, 'repeat' => 0] 2755 ]; 2756 core_calendar_external::delete_calendar_events($events); 2757 } 2758 2759 /** 2760 * Test the behavior of editing other users' user events 2761 * 2762 * @dataProvider test_edit_or_delete_other_users_events_data_provider 2763 * @covers \core_calendar_external::submit_create_update_form 2764 * @param bool $isadmin Whether the current user is admin. 2765 * @param bool $isadminevent Whether it's an admin event or not. 2766 * @param stdClass|null $writerrolecontext The reader role context. 2767 * @param string|null $writerrolename The role name. 2768 * @param bool $expectexception Whether the test should throw an exception or not. 2769 */ 2770 public function test_edit_other_users_events(bool $isadmin, bool $isadminevent, 2771 ?stdClass $writerrolecontext, ?string $writerrolename, bool $expectexception) { 2772 global $DB, $USER; 2773 2774 $this->resetAfterTest(); 2775 2776 $generator = $this->getDataGenerator(); 2777 if ($isadminevent) { 2778 $this->setAdminUser(); 2779 $user = $USER; 2780 } else { 2781 $user = $generator->create_user(); 2782 } 2783 2784 $formdata = [ 2785 'id' => 0, 2786 'userid' => $user->id, 2787 'modulename' => '', 2788 'instance' => 0, 2789 'visible' => 1, 2790 'eventtype' => 'user', 2791 'name' => 'Test', 2792 'timestart' => [ 2793 'day' => 1, 2794 'month' => 1, 2795 'year' => 2021, 2796 'hour' => 1, 2797 'minute' => 0, 2798 ], 2799 'description' => [ 2800 'text' => 'xxxxx', 2801 'format' => 1, 2802 'itemid' => 0 2803 ], 2804 'location' => 'Test', 2805 'duration' => 0, 2806 ]; 2807 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata); 2808 2809 $querystring = http_build_query($formdata, '', '&'); 2810 2811 if ($isadmin) { 2812 $this->setAdminUser(); 2813 } else { 2814 $writer = $generator->create_user(); 2815 if ($writerrolename && $writerrolecontext) { 2816 $managerroleid = $DB->get_field('role', 'id', ['shortname' => $writerrolename]); 2817 role_assign($managerroleid, $writer->id, $writerrolecontext->id); 2818 } 2819 $this->setUser($writer); 2820 } 2821 $USER->ignoresesskey = true; 2822 2823 if ($expectexception) { 2824 $this->expectException(moodle_exception::class); 2825 } 2826 core_calendar_external::submit_create_update_form($querystring); 2827 } 2828 2829 /** 2830 * A user should not be able load the calendar events for a category they cannot see. 2831 */ 2832 public function test_get_calendar_events_hidden_category() { 2833 global $USER; 2834 $this->resetAfterTest(true); 2835 $this->setAdminUser(); 2836 2837 $generator = $this->getDataGenerator(); 2838 $user1 = $generator->create_user(); 2839 $category = $generator->create_category(['visible' => 0]); 2840 $name = 'Category Event (category: ' . $category->id . ')'; 2841 $record = new stdClass(); 2842 $record->categoryid = $category->id; 2843 $categoryevent = $this->create_calendar_event($name, $USER->id, 'category', 0, time(), $record); 2844 2845 $events = [ 2846 'eventids' => [$categoryevent->id] 2847 ]; 2848 $options = []; 2849 // Admin can load the category event. 2850 $data = external_api::clean_returnvalue( 2851 core_calendar_external::get_calendar_events_returns(), 2852 core_calendar_external::get_calendar_events($events, $options) 2853 ); 2854 $this->assertEquals($data['events'][0]['id'], $categoryevent->id); 2855 // User with no special permission to see hidden categories will not see the event. 2856 $this->setUser($user1); 2857 $data = external_api::clean_returnvalue( 2858 core_calendar_external::get_calendar_events_returns(), 2859 core_calendar_external::get_calendar_events($events, $options) 2860 ); 2861 $this->assertCount(0, $data['events']); 2862 $this->assertEquals('nopermissions', $data['warnings'][0]['warningcode']); 2863 } 2864 2865 /** 2866 * Test get_calendar_access_information for admins. 2867 */ 2868 public function test_get_calendar_access_information_for_admins() { 2869 global $CFG; 2870 $this->resetAfterTest(true); 2871 $this->setAdminUser(); 2872 2873 $CFG->calendar_adminseesall = 1; 2874 2875 $data = external_api::clean_returnvalue( 2876 core_calendar_external::get_calendar_access_information_returns(), 2877 core_calendar_external::get_calendar_access_information() 2878 ); 2879 $this->assertTrue($data['canmanageownentries']); 2880 $this->assertTrue($data['canmanagegroupentries']); 2881 $this->assertTrue($data['canmanageentries']); 2882 } 2883 2884 /** 2885 * Test get_calendar_access_information for authenticated users. 2886 */ 2887 public function test_get_calendar_access_information_for_authenticated_users() { 2888 $this->resetAfterTest(true); 2889 $this->setUser($this->getDataGenerator()->create_user()); 2890 2891 $data = external_api::clean_returnvalue( 2892 core_calendar_external::get_calendar_access_information_returns(), 2893 core_calendar_external::get_calendar_access_information() 2894 ); 2895 $this->assertTrue($data['canmanageownentries']); 2896 $this->assertFalse($data['canmanagegroupentries']); 2897 $this->assertFalse($data['canmanageentries']); 2898 } 2899 2900 /** 2901 * Test get_calendar_access_information for student users. 2902 */ 2903 public function test_get_calendar_access_information_for_student_users() { 2904 global $DB; 2905 $this->resetAfterTest(true); 2906 2907 $user = $this->getDataGenerator()->create_user(); 2908 $course = $this->getDataGenerator()->create_course(); 2909 $role = $DB->get_record('role', array('shortname' => 'student')); 2910 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 2911 2912 $this->setUser($user); 2913 2914 $data = external_api::clean_returnvalue( 2915 core_calendar_external::get_calendar_access_information_returns(), 2916 core_calendar_external::get_calendar_access_information($course->id) 2917 ); 2918 $this->assertTrue($data['canmanageownentries']); 2919 $this->assertFalse($data['canmanagegroupentries']); 2920 $this->assertFalse($data['canmanageentries']); 2921 } 2922 2923 /** 2924 * Test get_calendar_access_information for teacher users. 2925 */ 2926 public function test_get_calendar_access_information_for_teacher_users() { 2927 global $DB; 2928 $this->resetAfterTest(true); 2929 2930 $user = $this->getDataGenerator()->create_user(); 2931 $course = $this->getDataGenerator()->create_course(['groupmode' => 1]); 2932 $role = $DB->get_record('role', array('shortname' => 'editingteacher')); 2933 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 2934 $this->getDataGenerator()->create_group(['courseid' => $course->id]); 2935 2936 $this->setUser($user); 2937 2938 $data = external_api::clean_returnvalue( 2939 core_calendar_external::get_calendar_access_information_returns(), 2940 core_calendar_external::get_calendar_access_information($course->id) 2941 ); 2942 $this->assertTrue($data['canmanageownentries']); 2943 $this->assertTrue($data['canmanagegroupentries']); 2944 $this->assertTrue($data['canmanageentries']); 2945 } 2946 2947 /** 2948 * Test get_allowed_event_types for admins. 2949 */ 2950 public function test_get_allowed_event_types_for_admins() { 2951 global $CFG; 2952 $this->resetAfterTest(true); 2953 $this->setAdminUser(); 2954 $CFG->calendar_adminseesall = 1; 2955 $data = external_api::clean_returnvalue( 2956 core_calendar_external::get_allowed_event_types_returns(), 2957 core_calendar_external::get_allowed_event_types() 2958 ); 2959 $this->assertEquals(['user', 'site', 'course', 'category'], $data['allowedeventtypes']); 2960 } 2961 /** 2962 * Test get_allowed_event_types for authenticated users. 2963 */ 2964 public function test_get_allowed_event_types_for_authenticated_users() { 2965 $this->resetAfterTest(true); 2966 $this->setUser($this->getDataGenerator()->create_user()); 2967 $data = external_api::clean_returnvalue( 2968 core_calendar_external::get_allowed_event_types_returns(), 2969 core_calendar_external::get_allowed_event_types() 2970 ); 2971 $this->assertEquals(['user'], $data['allowedeventtypes']); 2972 } 2973 /** 2974 * Test get_allowed_event_types for student users. 2975 */ 2976 public function test_get_allowed_event_types_for_student_users() { 2977 global $DB; 2978 $this->resetAfterTest(true); 2979 $user = $this->getDataGenerator()->create_user(); 2980 $course = $this->getDataGenerator()->create_course(); 2981 $role = $DB->get_record('role', array('shortname' => 'student')); 2982 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 2983 $this->setUser($user); 2984 $data = external_api::clean_returnvalue( 2985 core_calendar_external::get_allowed_event_types_returns(), 2986 core_calendar_external::get_allowed_event_types($course->id) 2987 ); 2988 $this->assertEquals(['user'], $data['allowedeventtypes']); 2989 } 2990 /** 2991 * Test get_allowed_event_types for teacher users. 2992 */ 2993 public function test_get_allowed_event_types_for_teacher_users() { 2994 global $DB; 2995 $this->resetAfterTest(true); 2996 $user = $this->getDataGenerator()->create_user(); 2997 $course = $this->getDataGenerator()->create_course(['groupmode' => 1]); 2998 $role = $DB->get_record('role', array('shortname' => 'editingteacher')); 2999 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id); 3000 $this->getDataGenerator()->create_group(['courseid' => $course->id]); 3001 $this->setUser($user); 3002 $data = external_api::clean_returnvalue( 3003 core_calendar_external::get_allowed_event_types_returns(), 3004 core_calendar_external::get_allowed_event_types($course->id) 3005 ); 3006 $this->assertEquals(['user', 'course', 'group'], $data['allowedeventtypes']); 3007 } 3008 3009 /** 3010 * Test get_timestamps with string keys, with and without optional hour/minute values. 3011 */ 3012 public function test_get_timestamps_string_keys() { 3013 $this->resetAfterTest(true); 3014 $this->setAdminUser(); 3015 3016 $time1 = new DateTime('2018-12-30 00:00:00'); 3017 $time2 = new DateTime('2019-03-27 23:59:00'); 3018 3019 $dates = [ 3020 [ 3021 'key' => 'from', 3022 'year' => $time1->format('Y'), 3023 'month' => $time1->format('m'), 3024 'day' => $time1->format('d'), 3025 ], 3026 [ 3027 'key' => 'to', 3028 'year' => $time2->format('Y'), 3029 'month' => (int) $time2->format('m'), 3030 'day' => $time2->format('d'), 3031 'hour' => $time2->format('H'), 3032 'minute' => $time2->format('i'), 3033 ], 3034 ]; 3035 3036 $expectedtimestamps = [ 3037 'from' => $time1->getTimestamp(), 3038 'to' => $time2->getTimestamp(), 3039 ]; 3040 3041 $result = core_calendar_external::get_timestamps($dates); 3042 3043 $this->assertEquals(['timestamps'], array_keys($result)); 3044 $this->assertEquals(2, count($result['timestamps'])); 3045 3046 foreach ($result['timestamps'] as $data) { 3047 $this->assertTrue(in_array($data['key'], ['from', 'to'])); 3048 $this->assertEquals($expectedtimestamps[$data['key']], $data['timestamp']); 3049 } 3050 } 3051 3052 /** 3053 * Test get_timestamps with no keys specified, with and without optional hour/minute values. 3054 */ 3055 public function test_get_timestamps_no_keys() { 3056 $this->resetAfterTest(true); 3057 $this->setAdminUser(); 3058 3059 $time1 = new DateTime('2018-12-30 00:00:00'); 3060 $time2 = new DateTime('2019-03-27 23:59:00'); 3061 3062 $dates = [ 3063 [ 3064 'year' => $time1->format('Y'), 3065 'month' => $time1->format('m'), 3066 'day' => $time1->format('d'), 3067 ], 3068 [ 3069 'year' => $time2->format('Y'), 3070 'month' => (int) $time2->format('m'), 3071 'day' => $time2->format('d'), 3072 'hour' => $time2->format('H'), 3073 'minute' => $time2->format('i'), 3074 ], 3075 ]; 3076 3077 $expectedtimestamps = [ 3078 0 => $time1->getTimestamp(), 3079 1 => $time2->getTimestamp(), 3080 ]; 3081 3082 $result = core_calendar_external::get_timestamps($dates); 3083 3084 $this->assertEquals(['timestamps'], array_keys($result)); 3085 $this->assertEquals(2, count($result['timestamps'])); 3086 3087 foreach ($result['timestamps'] as $data) { 3088 $this->assertEquals($expectedtimestamps[$data['key']], $data['timestamp']); 3089 } 3090 } 3091 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body