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