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