MDL-62384 privacy: Modify user contexts query for auth_oauth2
[moodle.git] / calendar / tests / externallib_test.php
blob9fcf147e005462dd05ef987fedba35539d2a7d5d
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.
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/>.
17 /**
18 * External calendar functions unit tests
20 * @package core_calendar
21 * @category external
22 * @copyright 2012 Ankit Agarwal
23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26 defined('MOODLE_INTERNAL') || die();
28 global $CFG;
30 require_once($CFG->dirroot . '/webservice/tests/helpers.php');
32 /**
33 * External course functions unit tests
35 * @package core_calendar
36 * @category external
37 * @copyright 2012 Ankit Agarwal
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39 * @since Moodle 2.5
41 class core_calendar_externallib_testcase extends externallib_advanced_testcase {
43 /**
44 * Tests set up
46 protected function setUp() {
47 global $CFG;
48 require_once($CFG->dirroot . '/calendar/externallib.php');
51 /** Create calendar events or update them
52 * Set $prop->id, if you want to do an update instead of creating an new event
54 * @param string $name Event title
55 * @param int $userid User id
56 * @param string $type Event type
57 * @param int $repeats Number of repeated events to create
58 * @param int $timestart Time stamp of the event start
59 * @param mixed $prop List of event properties as array or object
60 * @return mixed Event object or false;
61 * @since Moodle 2.5
64 public static function create_calendar_event($name, $userid = 0, $type = 'user', $repeats = 0, $timestart = null, $prop = null) {
65 global $CFG, $DB, $SITE;
67 require_once("$CFG->dirroot/calendar/lib.php");
68 if (!empty($prop)) {
69 if (is_array($prop)) {
70 $prop = (object)$prop;
72 } else {
73 $prop = new stdClass();
75 $prop->name = $name;
76 if (empty($prop->eventtype)) {
77 $prop->eventtype = $type;
79 if (empty($prop->repeats)) {
80 $prop->repeats = $repeats;
82 if (empty($prop->timestart)) {
83 $prop->timestart = time();
85 if (empty($prop->timeduration)) {
86 $prop->timeduration = 0;
88 if (empty($prop->timesort)) {
89 $prop->timesort = 0;
91 if (empty($prop->type)) {
92 $prop->type = CALENDAR_EVENT_TYPE_STANDARD;
94 if (empty($prop->repeats)) {
95 $prop->repeat = 0;
96 } else {
97 $prop->repeat = 1;
99 if (empty($prop->userid)) {
100 if (!empty($userid)) {
101 $prop->userid = $userid;
102 } else {
103 $prop->userid = 0;
106 if (!isset($prop->courseid)) {
107 $prop->courseid = $SITE->id;
110 // Determine event priority.
111 if ($prop->courseid == 0 && isset($prop->groupid) && $prop->groupid == 0 && !empty($prop->userid)) {
112 // User override event.
113 $prop->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY;
114 } else if ($prop->courseid != $SITE->id && !empty($prop->groupid)) {
115 // Group override event.
116 $priorityparams = ['courseid' => $prop->courseid, 'groupid' => $prop->groupid];
117 // Group override event with the highest priority.
118 $groupevents = $DB->get_records('event', $priorityparams, 'priority DESC', 'id, priority', 0, 1);
119 $priority = 1;
120 if (!empty($groupevents)) {
121 $event = reset($groupevents);
122 if (!empty($event->priority)) {
123 $priority = $event->priority + 1;
126 $prop->priority = $priority;
129 $event = new calendar_event($prop);
130 return $event->create($prop);
133 public function test_create_calendar_events () {
134 global $DB, $USER;
136 $this->setAdminUser();
137 $this->resetAfterTest();
138 $prevcount = count($DB->get_records("event"));
140 // Create a few events and do asserts.
141 $this->create_calendar_event('test', $USER->id);
142 $where = $DB->sql_compare_text('name') ." = ?";
143 $count = count($DB->get_records_select("event", $where, array('test')));
144 $this->assertEquals(1, $count);
145 $aftercount = count($DB->get_records("event"));
146 $this->assertEquals($prevcount + 1, $aftercount);
148 $this->create_calendar_event('user', $USER->id, 'user', 3);
149 $where = $DB->sql_compare_text('name') ." = ?";
150 $count = count($DB->get_records_select("event", $where, array('user')));
152 $this->assertEquals(3, $count);
153 $aftercount = count($DB->get_records("event"));
154 $this->assertEquals($prevcount + 4, $aftercount);
159 * Test delete_calendar_events
161 * @expectedException moodle_exception
163 public function test_delete_calendar_events() {
164 global $DB, $USER;
166 $this->resetAfterTest(true);
167 $this->setAdminUser();
169 // Create a few stuff to test with.
170 $user = $this->getDataGenerator()->create_user();
171 $course = $this->getDataGenerator()->create_course();
172 $record = new stdClass();
173 $record->courseid = $course->id;
174 $group = $this->getDataGenerator()->create_group($record);
176 $notdeletedcount = $DB->count_records('event');
178 // Let's create a few events.
179 $siteevent = $this->create_calendar_event('site', $USER->id, 'site');
180 $record = new stdClass();
181 $record->courseid = $course->id;
182 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record);
183 $userevent = $this->create_calendar_event('user', $USER->id);
184 $record = new stdClass();
185 $record->courseid = $course->id;
186 $record->groupid = $group->id;
187 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
189 // Now lets try to delete stuff with proper rights.
190 $events = array(
191 array('eventid' => $siteevent->id, 'repeat' => 0),
192 array('eventid' => $courseevent->id, 'repeat' => 1),
193 array('eventid' => $userevent->id, 'repeat' => 0),
194 array('eventid' => $groupevent->id, 'repeat' => 0)
196 core_calendar_external::delete_calendar_events($events);
198 // Check to see if things were deleted properly.
199 $deletedcount = $DB->count_records('event');
200 $this->assertEquals($notdeletedcount, $deletedcount);
202 // Let's create a few events.
203 $siteevent = $this->create_calendar_event('site', $USER->id, 'site');
204 $record = new stdClass();
205 $record->courseid = $course->id;
206 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 3, time(), $record);
207 $userevent = $this->create_calendar_event('user', $USER->id);
208 $record = new stdClass();
209 $record->courseid = $course->id;
210 $record->groupid = $group->id;
211 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
213 $this->setuser($user);
214 $sitecontext = context_system::instance();
215 $coursecontext = context_course::instance($course->id);
216 $usercontext = context_user::instance($user->id);
217 $role = $DB->get_record('role', array('shortname' => 'student'));
218 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
220 // Remove all caps.
221 $this->unassignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id);
222 $this->unassignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id);
223 $this->unassignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
224 $this->unassignUserCapability('moodle/calendar:manageownentries', $usercontext->id, $role->id);
226 // Assign proper caps and attempt delete.
227 $this->assignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id);
228 $events = array(
229 array('eventid' => $siteevent->id, 'repeat' => 0),
231 core_calendar_external::delete_calendar_events($events);
232 $deletedcount = $DB->count_records('event');
233 $count = $notdeletedcount+5;
234 $this->assertEquals($count, $deletedcount);
236 $this->assignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id);
237 $events = array(
238 array('eventid' => $courseevent->id, 'repeat' => 0),
240 core_calendar_external::delete_calendar_events($events);
241 $deletedcount = $DB->count_records('event');
242 $count = $notdeletedcount+4;
243 $this->assertEquals($count, $deletedcount);
245 $this->assignUserCapability('moodle/calendar:manageownentries', $usercontext->id, $role->id);
246 $events = array(
247 array('eventid' => $userevent->id, 'repeat' => 0),
249 core_calendar_external::delete_calendar_events($events);
250 $deletedcount = $DB->count_records('event');
251 $count = $notdeletedcount+3;
252 $this->assertEquals($count, $deletedcount);
254 $this->assignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
255 $events = array(
256 array('eventid' => $groupevent->id, 'repeat' => 0),
258 core_calendar_external::delete_calendar_events($events);
259 $deletedcount = $DB->count_records('event');
260 $count = $notdeletedcount+2;
261 $this->assertEquals($count, $deletedcount);
263 $notdeletedcount = $deletedcount;
265 // Let us try deleting without caps.
267 $siteevent = $this->create_calendar_event('site', $USER->id, 'site');
268 $record = new stdClass();
269 $record->courseid = $course->id;
270 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 3, time(), $record);
271 $userevent = $this->create_calendar_event('user', $USER->id);
272 $record = new stdClass();
273 $record->courseid = $course->id;
274 $record->groupid = $group->id;
275 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
277 $this->setGuestUser();
279 $events = array(
280 array('eventid' => $siteevent->id, 'repeat' => 0),
281 array('eventid' => $courseevent->id, 'repeat' => 0),
282 array('eventid' => $userevent->id, 'repeat' => 0),
283 array('eventid' => $groupevent->id, 'repeat' => 0)
285 core_calendar_external::delete_calendar_events($events);
289 * Test get_calendar_events
291 public function test_get_calendar_events() {
292 global $DB, $USER;
294 $this->resetAfterTest(true);
295 set_config('calendar_adminseesall', 1);
296 $this->setAdminUser();
298 // Create a few stuff to test with.
299 $user = $this->getDataGenerator()->create_user();
300 $user2 = $this->getDataGenerator()->create_user();
301 $course = $this->getDataGenerator()->create_course();
303 $category = $this->getDataGenerator()->create_category();
305 $category2 = $this->getDataGenerator()->create_category();
306 $category2b = $this->getDataGenerator()->create_category(['parent' => $category2->id]);
307 $course3 = $this->getDataGenerator()->create_course(['category' => $category2b->id]);
309 $role = $DB->get_record('role', array('shortname' => 'student'));
310 $this->getDataGenerator()->enrol_user($user2->id, $course3->id, $role->id);
312 $record = new stdClass();
313 $record->courseid = $course->id;
314 $group = $this->getDataGenerator()->create_group($record);
316 $beforecount = $DB->count_records('event');
318 // Let's create a few events.
319 $siteevent = $this->create_calendar_event('site', $USER->id, 'site');
321 // This event will have description with an inline fake image.
322 $draftidfile = file_get_unused_draft_itemid();
323 $usercontext = context_course::instance($course->id);
324 $filerecord = array(
325 'contextid' => $usercontext->id,
326 'component' => 'user',
327 'filearea' => 'draft',
328 'itemid' => $draftidfile,
329 'filepath' => '/',
330 'filename' => 'fakeimage.png',
332 $fs = get_file_storage();
333 $fs->create_file_from_string($filerecord, 'img contents');
335 $record = new stdClass();
336 $record->courseid = $course->id;
337 $record->groupid = 0;
338 $record->description = array(
339 'format' => FORMAT_HTML,
340 'text' => 'Text with img <img src="@@PLUGINFILE@@/fakeimage.png">',
341 'itemid' => $draftidfile
343 $courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record);
345 $record = new stdClass();
346 $record->courseid = 0;
347 $record->groupid = 0;
348 $userevent = $this->create_calendar_event('user', $USER->id, 'user', 0, time(), $record);
350 $record = new stdClass();
351 $record->courseid = $course->id;
352 $record->groupid = $group->id;
353 $groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
355 $paramevents = array ('eventids' => array($siteevent->id), 'courseids' => array($course->id),
356 'groupids' => array($group->id), 'categoryids' => array($category->id));
358 $options = array ('siteevents' => true, 'userevents' => true);
359 $events = core_calendar_external::get_calendar_events($paramevents, $options);
360 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
362 // Check to see if we got all events.
363 $this->assertEquals(5, count($events['events']));
364 $this->assertEquals(0, count($events['warnings']));
365 $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7*WEEKSECS);
366 $events = core_calendar_external::get_calendar_events($paramevents, $options);
367 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
368 $this->assertEquals(5, count($events['events']));
369 $this->assertEquals(0, count($events['warnings']));
371 // Expect the same URL in the description of two different events (because they are repeated).
372 $coursecontext = context_course::instance($course->id);
373 $expectedurl = "webservice/pluginfile.php/$coursecontext->id/calendar/event_description/$courseevent->id/fakeimage.png";
374 $withdescription = 0;
375 foreach ($events['events'] as $event) {
376 if (!empty($event['description'])) {
377 $withdescription++;
378 $this->assertContains($expectedurl, $event['description']);
381 $this->assertEquals(2, $withdescription);
383 // Let's play around with caps.
385 // Create user event for the user $user.
386 $record = new stdClass();
387 $record->courseid = 0;
388 $record->groupid = 0;
389 $this->create_calendar_event('user', $user->id, 'user', 0, time(), $record);
391 $this->setUser($user);
392 $events = core_calendar_external::get_calendar_events($paramevents, $options);
393 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
394 $this->assertEquals(2, count($events['events'])); // site, user.
395 $this->assertEquals(2, count($events['warnings'])); // course, group.
397 $role = $DB->get_record('role', array('shortname' => 'student'));
398 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
399 $events = core_calendar_external::get_calendar_events($paramevents, $options);
400 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
401 $this->assertEquals(4, count($events['events'])); // site, user, both course events.
402 $this->assertEquals(1, count($events['warnings'])); // group.
404 $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS);
405 $events = core_calendar_external::get_calendar_events($paramevents, $options);
406 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
407 $this->assertEquals(3, count($events['events'])); // site, user, one course event.
408 $this->assertEquals(1, count($events['warnings'])); // group.
410 groups_add_member($group, $user);
411 $events = core_calendar_external::get_calendar_events($paramevents, $options);
412 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
413 $this->assertEquals(4, count($events['events'])); // site, user, group, one course event.
414 $this->assertEquals(0, count($events['warnings']));
416 $paramevents = array ('courseids' => array($course->id), 'groupids' => array($group->id));
417 $events = core_calendar_external::get_calendar_events($paramevents, $options);
418 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
419 $this->assertEquals(4, count($events['events'])); // site, user, group, one course event.
420 $this->assertEquals(0, count($events['warnings']));
422 $paramevents = array ('groupids' => array($group->id, 23));
423 $events = core_calendar_external::get_calendar_events($paramevents, $options);
424 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
425 $this->assertEquals(3, count($events['events'])); // site, user, group.
426 $this->assertEquals(1, count($events['warnings']));
428 $paramevents = array ('courseids' => array(23));
429 $events = core_calendar_external::get_calendar_events($paramevents, $options);
430 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
431 $this->assertEquals(2, count($events['events'])); // site, user.
432 $this->assertEquals(1, count($events['warnings']));
434 $paramevents = array ();
435 $options = array ('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7*WEEKSECS);
436 $events = core_calendar_external::get_calendar_events($paramevents, $options);
437 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
438 $this->assertEquals(0, count($events['events'])); // nothing returned.
439 $this->assertEquals(0, count($events['warnings']));
441 $paramevents = array ('eventids' => array($siteevent->id, $groupevent->id));
442 $options = array ('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7*WEEKSECS);
443 $events = core_calendar_external::get_calendar_events($paramevents, $options);
444 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
445 $this->assertEquals(2, count($events['events'])); // site, group.
446 $this->assertEquals(0, count($events['warnings']));
448 $paramevents = array ('eventids' => array($siteevent->id));
449 $events = core_calendar_external::get_calendar_events($paramevents, $options);
450 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
451 $this->assertEquals(1, count($events['events'])); // site.
452 $this->assertEquals(0, count($events['warnings']));
454 // Try getting a course event by its id.
455 $paramevents = array ('eventids' => array($courseevent->id));
456 $events = core_calendar_external::get_calendar_events($paramevents, $options);
457 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
458 $this->assertEquals(1, count($events['events']));
459 $this->assertEquals(0, count($events['warnings']));
461 // Now, create an activity event.
462 $this->setAdminUser();
463 $nexttime = time() + DAYSECS;
464 $assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime));
466 $this->setUser($user);
467 $paramevents = array ('courseids' => array($course->id));
468 $options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS);
469 $events = core_calendar_external::get_calendar_events($paramevents, $options);
470 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
472 $this->assertCount(5, $events['events']);
474 // Hide the assignment.
475 set_coursemodule_visible($assign->cmid, 0);
476 // Empty all the caches that may be affected by this change.
477 accesslib_clear_all_caches_for_unit_testing();
478 course_modinfo::clear_instance_cache();
480 $events = core_calendar_external::get_calendar_events($paramevents, $options);
481 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
482 // Expect one less.
483 $this->assertCount(4, $events['events']);
485 // Create some category events.
486 $this->setAdminUser();
487 $record = new stdClass();
488 $record->courseid = 0;
489 $record->categoryid = $category->id;
490 $record->timestart = time() - DAYSECS;
491 $catevent1 = $this->create_calendar_event('category a', $USER->id, 'category', 0, time(), $record);
493 $record = new stdClass();
494 $record->courseid = 0;
495 $record->categoryid = $category2->id;
496 $record->timestart = time() + DAYSECS;
497 $catevent2 = $this->create_calendar_event('category b', $USER->id, 'category', 0, time(), $record);
499 // Now as student, make sure we get the events of the courses I am enrolled.
500 $this->setUser($user2);
501 $paramevents = array('categoryids' => array($category2b->id));
502 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
503 $events = core_calendar_external::get_calendar_events($paramevents, $options);
504 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
506 // Should be just one, since there's just one category event of the course I am enrolled (course3 - cat2b).
507 $this->assertEquals(1, count($events['events']));
508 $this->assertEquals($catevent2->id, $events['events'][0]['id']);
509 $this->assertEquals($category2->id, $events['events'][0]['categoryid']);
510 $this->assertEquals(0, count($events['warnings']));
512 // Now get category events but by course (there aren't course events in the course).
513 $paramevents = array('courseids' => array($course3->id));
514 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
515 $events = core_calendar_external::get_calendar_events($paramevents, $options);
516 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
517 $this->assertEquals(1, count($events['events']));
518 $this->assertEquals($catevent2->id, $events['events'][0]['id']);
519 $this->assertEquals(0, count($events['warnings']));
521 // Empty events in one where I'm not enrolled and one parent category
522 // (parent of a category where this is a course where the user is enrolled).
523 $paramevents = array('categoryids' => array($category2->id, $category->id));
524 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
525 $events = core_calendar_external::get_calendar_events($paramevents, $options);
526 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
527 $this->assertEquals(1, count($events['events']));
528 $this->assertEquals($catevent2->id, $events['events'][0]['id']);
529 $this->assertEquals(0, count($events['warnings']));
531 // Admin can see all category events.
532 $this->setAdminUser();
533 $paramevents = array('categoryids' => array($category->id, $category2->id, $category2b->id));
534 $options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
535 $events = core_calendar_external::get_calendar_events($paramevents, $options);
536 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
537 $this->assertEquals(2, count($events['events']));
538 $this->assertEquals(0, count($events['warnings']));
539 $this->assertEquals($catevent1->id, $events['events'][0]['id']);
540 $this->assertEquals($category->id, $events['events'][0]['categoryid']);
541 $this->assertEquals($catevent2->id, $events['events'][1]['id']);
542 $this->assertEquals($category2->id, $events['events'][1]['categoryid']);
546 * Test core_calendar_external::create_calendar_events
548 public function test_core_create_calendar_events() {
549 global $DB, $USER, $SITE;
551 $this->resetAfterTest(true);
552 $this->setAdminUser();
554 // Create a few stuff to test with.
555 $user = $this->getDataGenerator()->create_user();
556 $course = $this->getDataGenerator()->create_course();
557 $record = new stdClass();
558 $record->courseid = $course->id;
559 $group = $this->getDataGenerator()->create_group($record);
561 $prevcount = $DB->count_records('event');
563 // Let's create a few events.
564 $events = array (
565 array('name' => 'site', 'courseid' => $SITE->id, 'eventtype' => 'site'),
566 array('name' => 'course', 'courseid' => $course->id, 'eventtype' => 'course', 'repeats' => 2),
567 array('name' => 'group', 'courseid' => $course->id, 'groupid' => $group->id, 'eventtype' => 'group'),
568 array('name' => 'user')
570 $eventsret = core_calendar_external::create_calendar_events($events);
571 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
573 // Check to see if things were created properly.
574 $aftercount = $DB->count_records('event');
575 $this->assertEquals($prevcount + 5, $aftercount);
576 $this->assertEquals(5, count($eventsret['events']));
577 $this->assertEquals(0, count($eventsret['warnings']));
579 $sitecontext = context_system::instance();
580 $coursecontext = context_course::instance($course->id);
582 $this->setUser($user);
583 $prevcount = $aftercount;
584 $events = array (
585 array('name' => 'course', 'courseid' => $course->id, 'eventtype' => 'course', 'repeats' => 2),
586 array('name' => 'group', 'courseid' => $course->id, 'groupid' => $group->id, 'eventtype' => 'group'),
587 array('name' => 'user')
589 $role = $DB->get_record('role', array('shortname' => 'student'));
590 $this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
591 groups_add_member($group, $user);
592 $this->assignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id);
593 $this->assignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
594 $eventsret = core_calendar_external::create_calendar_events($events);
595 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
596 // Check to see if things were created properly.
597 $aftercount = $DB->count_records('event');
598 $this->assertEquals($prevcount + 4, $aftercount);
599 $this->assertEquals(4, count($eventsret['events']));
600 $this->assertEquals(0, count($eventsret['warnings']));
602 // Check to see nothing was created without proper permission.
603 $this->setGuestUser();
604 $prevcount = $DB->count_records('event');
605 $eventsret = core_calendar_external::create_calendar_events($events);
606 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
607 $aftercount = $DB->count_records('event');
608 $this->assertEquals($prevcount, $aftercount);
609 $this->assertEquals(0, count($eventsret['events']));
610 $this->assertEquals(3, count($eventsret['warnings']));
612 $this->setUser($user);
613 $this->unassignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id);
614 $this->unassignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
615 $prevcount = $DB->count_records('event');
616 $eventsret = core_calendar_external::create_calendar_events($events);
617 $eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
618 $aftercount = $DB->count_records('event');
619 $this->assertEquals($prevcount + 1, $aftercount); // User event.
620 $this->assertEquals(1, count($eventsret['events']));
621 $this->assertEquals(2, count($eventsret['warnings']));
625 * Requesting calendar events from a given time should return all events with a sort
626 * time at or after the requested time. All events prior to that time should not
627 * be return.
629 * If there are no events on or after the given time then an empty result set should
630 * be returned.
632 public function test_get_calendar_action_events_by_timesort_after_time() {
633 $user = $this->getDataGenerator()->create_user();
634 $course = $this->getDataGenerator()->create_course();
635 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
636 $moduleinstance = $generator->create_instance(['course' => $course->id]);
638 $this->getDataGenerator()->enrol_user($user->id, $course->id);
639 $this->resetAfterTest(true);
640 $this->setUser($user);
642 $params = [
643 'type' => CALENDAR_EVENT_TYPE_ACTION,
644 'modulename' => 'assign',
645 'instance' => $moduleinstance->id,
646 'courseid' => $course->id,
649 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1]));
650 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
651 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
652 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
653 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
654 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
655 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
656 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
658 $result = core_calendar_external::get_calendar_action_events_by_timesort(5);
659 $result = external_api::clean_returnvalue(
660 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
661 $result
663 $events = $result['events'];
665 $this->assertCount(4, $events);
666 $this->assertEquals('Event 5', $events[0]['name']);
667 $this->assertEquals('Event 6', $events[1]['name']);
668 $this->assertEquals('Event 7', $events[2]['name']);
669 $this->assertEquals('Event 8', $events[3]['name']);
670 $this->assertEquals($event5->id, $result['firstid']);
671 $this->assertEquals($event8->id, $result['lastid']);
673 $result = core_calendar_external::get_calendar_action_events_by_timesort(9);
674 $result = external_api::clean_returnvalue(
675 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
676 $result
679 $this->assertEmpty($result['events']);
680 $this->assertNull($result['firstid']);
681 $this->assertNull($result['lastid']);
685 * Requesting calendar events before a given time should return all events with a sort
686 * time at or before the requested time (inclusive). All events after that time
687 * should not be returned.
689 * If there are no events before the given time then an empty result set should be
690 * returned.
692 public function test_get_calendar_action_events_by_timesort_before_time() {
693 $user = $this->getDataGenerator()->create_user();
694 $course = $this->getDataGenerator()->create_course();
695 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
696 $moduleinstance = $generator->create_instance(['course' => $course->id]);
698 $this->getDataGenerator()->enrol_user($user->id, $course->id);
699 $this->resetAfterTest(true);
700 $this->setUser($user);
702 $params = [
703 'type' => CALENDAR_EVENT_TYPE_ACTION,
704 'modulename' => 'assign',
705 'instance' => $moduleinstance->id,
706 'courseid' => $course->id,
709 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
710 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
711 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
712 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
713 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
714 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
715 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
716 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 9]));
718 $result = core_calendar_external::get_calendar_action_events_by_timesort(null, 5);
719 $result = external_api::clean_returnvalue(
720 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
721 $result
723 $events = $result['events'];
725 $this->assertCount(4, $events);
726 $this->assertEquals('Event 1', $events[0]['name']);
727 $this->assertEquals('Event 2', $events[1]['name']);
728 $this->assertEquals('Event 3', $events[2]['name']);
729 $this->assertEquals('Event 4', $events[3]['name']);
730 $this->assertEquals($event1->id, $result['firstid']);
731 $this->assertEquals($event4->id, $result['lastid']);
733 $result = core_calendar_external::get_calendar_action_events_by_timesort(null, 1);
734 $result = external_api::clean_returnvalue(
735 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
736 $result
739 $this->assertEmpty($result['events']);
740 $this->assertNull($result['firstid']);
741 $this->assertNull($result['lastid']);
745 * Test retrieving event that was overridden for a user
747 public function test_get_calendar_events_override() {
748 $user = $this->getDataGenerator()->create_user();
749 $user2 = $this->getDataGenerator()->create_user();
750 $teacher = $this->getDataGenerator()->create_user();
751 $anotheruser = $this->getDataGenerator()->create_user();
752 $course = $this->getDataGenerator()->create_course();
753 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
754 $moduleinstance = $generator->create_instance(['course' => $course->id]);
756 $this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
757 $this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
758 $this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
759 $this->resetAfterTest(true);
760 $this->setAdminUser();
762 $params = [
763 'type' => CALENDAR_EVENT_TYPE_ACTION,
764 'modulename' => 'assign',
765 'instance' => $moduleinstance->id,
768 $now = time();
769 // Create two events - one for everybody in the course and one only for the first student.
770 $event1 = $this->create_calendar_event('Base event', 0, 'due', 0, $now + DAYSECS, $params + ['courseid' => $course->id]);
771 $event2 = $this->create_calendar_event('User event', $user->id, 'due', 0, $now + 2*DAYSECS, $params + ['courseid' => 0]);
773 // Retrieve course events for the second student - only one "Base event" is returned.
774 $this->setUser($user2);
775 $paramevents = array('courseids' => array($course->id));
776 $options = array ('siteevents' => true, 'userevents' => true);
777 $events = core_calendar_external::get_calendar_events($paramevents, $options);
778 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
779 $this->assertEquals(1, count($events['events']));
780 $this->assertEquals(0, count($events['warnings']));
781 $this->assertEquals('Base event', $events['events'][0]['name']);
783 // Retrieve events for the first student - both events are returned.
784 $this->setUser($user);
785 $events = core_calendar_external::get_calendar_events($paramevents, $options);
786 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
787 $this->assertEquals(2, count($events['events']));
788 $this->assertEquals(0, count($events['warnings']));
789 $this->assertEquals('Base event', $events['events'][0]['name']);
790 $this->assertEquals('User event', $events['events'][1]['name']);
792 // Retrieve events by id as a teacher, 'User event' should be returned since teacher has access to this course.
793 $this->setUser($teacher);
794 $paramevents = ['eventids' => [$event2->id]];
795 $events = core_calendar_external::get_calendar_events($paramevents, $options);
796 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
797 $this->assertEquals(1, count($events['events']));
798 $this->assertEquals(0, count($events['warnings']));
799 $this->assertEquals('User event', $events['events'][0]['name']);
801 // Retrieve events by id as another user, nothing should be returned.
802 $this->setUser($anotheruser);
803 $paramevents = ['eventids' => [$event2->id, $event1->id]];
804 $events = core_calendar_external::get_calendar_events($paramevents, $options);
805 $events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
806 $this->assertEquals(0, count($events['events']));
807 $this->assertEquals(0, count($events['warnings']));
811 * Requesting calendar events within a given time range should return all events with
812 * a sort time between the lower and upper time bound (inclusive).
814 * If there are no events in the given time range then an empty result set should be
815 * returned.
817 public function test_get_calendar_action_events_by_timesort_time_range() {
818 $user = $this->getDataGenerator()->create_user();
819 $course = $this->getDataGenerator()->create_course();
820 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
821 $moduleinstance = $generator->create_instance(['course' => $course->id]);
823 $this->getDataGenerator()->enrol_user($user->id, $course->id);
824 $this->resetAfterTest(true);
825 $this->setUser($user);
827 $params = [
828 'type' => CALENDAR_EVENT_TYPE_ACTION,
829 'modulename' => 'assign',
830 'instance' => $moduleinstance->id,
831 'courseid' => $course->id,
834 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1]));
835 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
836 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
837 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
838 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
839 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
840 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
841 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
843 $result = core_calendar_external::get_calendar_action_events_by_timesort(3, 6);
844 $result = external_api::clean_returnvalue(
845 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
846 $result
848 $events = $result['events'];
850 $this->assertCount(4, $events);
851 $this->assertEquals('Event 3', $events[0]['name']);
852 $this->assertEquals('Event 4', $events[1]['name']);
853 $this->assertEquals('Event 5', $events[2]['name']);
854 $this->assertEquals('Event 6', $events[3]['name']);
855 $this->assertEquals($event3->id, $result['firstid']);
856 $this->assertEquals($event6->id, $result['lastid']);
858 $result = core_calendar_external::get_calendar_action_events_by_timesort(10, 15);
859 $result = external_api::clean_returnvalue(
860 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
861 $result
864 $this->assertEmpty($result['events']);
865 $this->assertNull($result['firstid']);
866 $this->assertNull($result['lastid']);
870 * Requesting calendar events within a given time range and a limit and offset should return
871 * the number of events up to the given limit value that have a sort time between the lower
872 * and uppper time bound (inclusive) where the result set is shifted by the offset value.
874 * If there are no events in the given time range then an empty result set should be
875 * returned.
877 public function test_get_calendar_action_events_by_timesort_time_limit_offset() {
878 $user = $this->getDataGenerator()->create_user();
879 $course = $this->getDataGenerator()->create_course();
880 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
881 $moduleinstance = $generator->create_instance(['course' => $course->id]);
883 $this->getDataGenerator()->enrol_user($user->id, $course->id);
884 $this->resetAfterTest(true);
885 $this->setUser($user);
887 $params = [
888 'type' => CALENDAR_EVENT_TYPE_ACTION,
889 'modulename' => 'assign',
890 'instance' => $moduleinstance->id,
891 'courseid' => $course->id,
894 $event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1]));
895 $event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
896 $event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
897 $event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
898 $event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
899 $event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
900 $event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
901 $event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
903 $result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event3->id, 2);
904 $result = external_api::clean_returnvalue(
905 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
906 $result
908 $events = $result['events'];
910 $this->assertCount(2, $events);
911 $this->assertEquals('Event 4', $events[0]['name']);
912 $this->assertEquals('Event 5', $events[1]['name']);
913 $this->assertEquals($event4->id, $result['firstid']);
914 $this->assertEquals($event5->id, $result['lastid']);
916 $result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event5->id, 2);
917 $result = external_api::clean_returnvalue(
918 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
919 $result
921 $events = $result['events'];
923 $this->assertCount(2, $events);
924 $this->assertEquals('Event 6', $events[0]['name']);
925 $this->assertEquals('Event 7', $events[1]['name']);
926 $this->assertEquals($event6->id, $result['firstid']);
927 $this->assertEquals($event7->id, $result['lastid']);
929 $result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event7->id, 2);
930 $result = external_api::clean_returnvalue(
931 core_calendar_external::get_calendar_action_events_by_timesort_returns(),
932 $result
935 $this->assertEmpty($result['events']);
936 $this->assertNull($result['firstid']);
937 $this->assertNull($result['lastid']);
941 * Requesting calendar events from a given course and time should return all
942 * events with a sort time at or after the requested time. All events prior
943 * to that time should not be return.
945 * If there are no events on or after the given time then an empty result set should
946 * be returned.
948 public function test_get_calendar_action_events_by_course_after_time() {
949 $user = $this->getDataGenerator()->create_user();
950 $course1 = $this->getDataGenerator()->create_course();
951 $course2 = $this->getDataGenerator()->create_course();
952 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
953 $instance1 = $generator->create_instance(['course' => $course1->id]);
954 $instance2 = $generator->create_instance(['course' => $course2->id]);
955 $records = [];
957 $this->getDataGenerator()->enrol_user($user->id, $course1->id);
958 $this->getDataGenerator()->enrol_user($user->id, $course2->id);
959 $this->resetAfterTest(true);
960 $this->setUser($user);
962 for ($i = 1; $i < 19; $i++) {
963 $courseid = ($i < 9) ? $course1->id : $course2->id;
964 $instance = ($i < 9) ? $instance1->id : $instance2->id;
965 $records[] = $this->create_calendar_event(
966 sprintf('Event %d', $i),
967 $user->id,
968 'user',
972 'type' => CALENDAR_EVENT_TYPE_ACTION,
973 'courseid' => $courseid,
974 'timesort' => $i,
975 'modulename' => 'assign',
976 'instance' => $instance,
981 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 5);
982 $result = external_api::clean_returnvalue(
983 core_calendar_external::get_calendar_action_events_by_course_returns(),
984 $result
986 $result = $result['events'];
988 $this->assertCount(4, $result);
989 $this->assertEquals('Event 5', $result[0]['name']);
990 $this->assertEquals('Event 6', $result[1]['name']);
991 $this->assertEquals('Event 7', $result[2]['name']);
992 $this->assertEquals('Event 8', $result[3]['name']);
994 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 9);
995 $result = external_api::clean_returnvalue(
996 core_calendar_external::get_calendar_action_events_by_course_returns(),
997 $result
999 $result = $result['events'];
1001 $this->assertEmpty($result);
1005 * Requesting calendar events for a course and before a given time should return
1006 * all events with a sort time at or before the requested time (inclusive). All
1007 * events after that time should not be returned.
1009 * If there are no events before the given time then an empty result set should be
1010 * returned.
1012 public function test_get_calendar_action_events_by_course_before_time() {
1013 $user = $this->getDataGenerator()->create_user();
1014 $course1 = $this->getDataGenerator()->create_course();
1015 $course2 = $this->getDataGenerator()->create_course();
1016 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
1017 $instance1 = $generator->create_instance(['course' => $course1->id]);
1018 $instance2 = $generator->create_instance(['course' => $course2->id]);
1019 $records = [];
1021 $this->getDataGenerator()->enrol_user($user->id, $course1->id);
1022 $this->getDataGenerator()->enrol_user($user->id, $course2->id);
1023 $this->resetAfterTest(true);
1024 $this->setUser($user);
1026 for ($i = 1; $i < 19; $i++) {
1027 $courseid = ($i < 9) ? $course1->id : $course2->id;
1028 $instance = ($i < 9) ? $instance1->id : $instance2->id;
1029 $records[] = $this->create_calendar_event(
1030 sprintf('Event %d', $i),
1031 $user->id,
1032 'user',
1036 'type' => CALENDAR_EVENT_TYPE_ACTION,
1037 'courseid' => $courseid,
1038 'timesort' => $i + 1,
1039 'modulename' => 'assign',
1040 'instance' => $instance,
1045 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, null, 5);
1046 $result = external_api::clean_returnvalue(
1047 core_calendar_external::get_calendar_action_events_by_course_returns(),
1048 $result
1050 $result = $result['events'];
1052 $this->assertCount(4, $result);
1053 $this->assertEquals('Event 1', $result[0]['name']);
1054 $this->assertEquals('Event 2', $result[1]['name']);
1055 $this->assertEquals('Event 3', $result[2]['name']);
1056 $this->assertEquals('Event 4', $result[3]['name']);
1058 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, null, 1);
1059 $result = external_api::clean_returnvalue(
1060 core_calendar_external::get_calendar_action_events_by_course_returns(),
1061 $result
1063 $result = $result['events'];
1065 $this->assertEmpty($result);
1069 * Requesting calendar events for a course and within a given time range should
1070 * return all events with a sort time between the lower and upper time bound
1071 * (inclusive).
1073 * If there are no events in the given time range then an empty result set should be
1074 * returned.
1076 public function test_get_calendar_action_events_by_course_time_range() {
1077 $user = $this->getDataGenerator()->create_user();
1078 $course1 = $this->getDataGenerator()->create_course();
1079 $course2 = $this->getDataGenerator()->create_course();
1080 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
1081 $instance1 = $generator->create_instance(['course' => $course1->id]);
1082 $instance2 = $generator->create_instance(['course' => $course2->id]);
1083 $records = [];
1085 $this->getDataGenerator()->enrol_user($user->id, $course1->id);
1086 $this->getDataGenerator()->enrol_user($user->id, $course2->id);
1087 $this->resetAfterTest(true);
1088 $this->setUser($user);
1090 for ($i = 1; $i < 19; $i++) {
1091 $courseid = ($i < 9) ? $course1->id : $course2->id;
1092 $instance = ($i < 9) ? $instance1->id : $instance2->id;
1093 $records[] = $this->create_calendar_event(
1094 sprintf('Event %d', $i),
1095 $user->id,
1096 'user',
1100 'type' => CALENDAR_EVENT_TYPE_ACTION,
1101 'courseid' => $courseid,
1102 'timesort' => $i,
1103 'modulename' => 'assign',
1104 'instance' => $instance,
1109 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 3, 6);
1110 $result = external_api::clean_returnvalue(
1111 core_calendar_external::get_calendar_action_events_by_course_returns(),
1112 $result
1114 $result = $result['events'];
1116 $this->assertCount(4, $result);
1117 $this->assertEquals('Event 3', $result[0]['name']);
1118 $this->assertEquals('Event 4', $result[1]['name']);
1119 $this->assertEquals('Event 5', $result[2]['name']);
1120 $this->assertEquals('Event 6', $result[3]['name']);
1122 $result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 10, 15);
1123 $result = external_api::clean_returnvalue(
1124 core_calendar_external::get_calendar_action_events_by_course_returns(),
1125 $result
1127 $result = $result['events'];
1129 $this->assertEmpty($result);
1133 * Requesting calendar events for a course and within a given time range and a limit
1134 * and offset should return the number of events up to the given limit value that have
1135 * a sort time between the lower and uppper time bound (inclusive) where the result
1136 * set is shifted by the offset value.
1138 * If there are no events in the given time range then an empty result set should be
1139 * returned.
1141 public function test_get_calendar_action_events_by_course_time_limit_offset() {
1142 $user = $this->getDataGenerator()->create_user();
1143 $course1 = $this->getDataGenerator()->create_course();
1144 $course2 = $this->getDataGenerator()->create_course();
1145 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
1146 $instance1 = $generator->create_instance(['course' => $course1->id]);
1147 $instance2 = $generator->create_instance(['course' => $course2->id]);
1148 $records = [];
1150 $this->getDataGenerator()->enrol_user($user->id, $course1->id);
1151 $this->getDataGenerator()->enrol_user($user->id, $course2->id);
1152 $this->resetAfterTest(true);
1153 $this->setUser($user);
1155 for ($i = 1; $i < 19; $i++) {
1156 $courseid = ($i < 9) ? $course1->id : $course2->id;
1157 $instance = ($i < 9) ? $instance1->id : $instance2->id;
1158 $records[] = $this->create_calendar_event(
1159 sprintf('Event %d', $i),
1160 $user->id,
1161 'user',
1165 'type' => CALENDAR_EVENT_TYPE_ACTION,
1166 'courseid' => $courseid,
1167 'timesort' => $i,
1168 'modulename' => 'assign',
1169 'instance' => $instance,
1174 $result = core_calendar_external::get_calendar_action_events_by_course(
1175 $course1->id, 2, 7, $records[2]->id, 2);
1176 $result = external_api::clean_returnvalue(
1177 core_calendar_external::get_calendar_action_events_by_course_returns(),
1178 $result
1180 $result = $result['events'];
1182 $this->assertCount(2, $result);
1183 $this->assertEquals('Event 4', $result[0]['name']);
1184 $this->assertEquals('Event 5', $result[1]['name']);
1186 $result = core_calendar_external::get_calendar_action_events_by_course(
1187 $course1->id, 2, 7, $records[4]->id, 2);
1188 $result = external_api::clean_returnvalue(
1189 core_calendar_external::get_calendar_action_events_by_course_returns(),
1190 $result
1192 $result = $result['events'];
1194 $this->assertCount(2, $result);
1195 $this->assertEquals('Event 6', $result[0]['name']);
1196 $this->assertEquals('Event 7', $result[1]['name']);
1198 $result = core_calendar_external::get_calendar_action_events_by_course(
1199 $course1->id, 2, 7, $records[6]->id, 2);
1200 $result = external_api::clean_returnvalue(
1201 core_calendar_external::get_calendar_action_events_by_course_returns(),
1202 $result
1204 $result = $result['events'];
1206 $this->assertEmpty($result);
1210 * Test that get_action_events_by_courses will return a list of events for each
1211 * course you provided as long as the user is enrolled in the course.
1213 public function test_get_action_events_by_courses() {
1214 $user = $this->getDataGenerator()->create_user();
1215 $course1 = $this->getDataGenerator()->create_course();
1216 $course2 = $this->getDataGenerator()->create_course();
1217 $course3 = $this->getDataGenerator()->create_course();
1218 $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
1219 $instance1 = $generator->create_instance(['course' => $course1->id]);
1220 $instance2 = $generator->create_instance(['course' => $course2->id]);
1221 $instance3 = $generator->create_instance(['course' => $course3->id]);
1222 $records = [];
1223 $mapresult = function($result) {
1224 $groupedbycourse = [];
1225 foreach ($result['groupedbycourse'] as $group) {
1226 $events = $group['events'];
1227 $courseid = $group['courseid'];
1228 $groupedbycourse[$courseid] = $events;
1231 return $groupedbycourse;
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);
1239 for ($i = 1; $i < 10; $i++) {
1240 if ($i < 3) {
1241 $courseid = $course1->id;
1242 $instance = $instance1->id;
1243 } else if ($i < 6) {
1244 $courseid = $course2->id;
1245 $instance = $instance2->id;
1246 } else {
1247 $courseid = $course3->id;
1248 $instance = $instance3->id;
1251 $records[] = $this->create_calendar_event(
1252 sprintf('Event %d', $i),
1253 $user->id,
1254 'user',
1258 'type' => CALENDAR_EVENT_TYPE_ACTION,
1259 'courseid' => $courseid,
1260 'timesort' => $i,
1261 'modulename' => 'assign',
1262 'instance' => $instance,
1267 $result = core_calendar_external::get_calendar_action_events_by_courses([], 1);
1268 $result = external_api::clean_returnvalue(
1269 core_calendar_external::get_calendar_action_events_by_courses_returns(),
1270 $result
1272 $result = $result['groupedbycourse'];
1274 $this->assertEmpty($result);
1276 $result = core_calendar_external::get_calendar_action_events_by_courses([$course1->id], 3);
1277 $result = external_api::clean_returnvalue(
1278 core_calendar_external::get_calendar_action_events_by_courses_returns(),
1279 $result
1282 $groupedbycourse = $mapresult($result);
1284 $this->assertEmpty($groupedbycourse[$course1->id]);
1286 $result = core_calendar_external::get_calendar_action_events_by_courses([$course1->id], 1);
1287 $result = external_api::clean_returnvalue(
1288 core_calendar_external::get_calendar_action_events_by_courses_returns(),
1289 $result
1291 $groupedbycourse = $mapresult($result);
1293 $this->assertCount(2, $groupedbycourse[$course1->id]);
1294 $this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']);
1295 $this->assertEquals('Event 2', $groupedbycourse[$course1->id][1]['name']);
1297 $result = core_calendar_external::get_calendar_action_events_by_courses(
1298 [$course1->id, $course2->id], 1);
1299 $result = external_api::clean_returnvalue(
1300 core_calendar_external::get_calendar_action_events_by_courses_returns(),
1301 $result
1303 $groupedbycourse = $mapresult($result);
1305 $this->assertCount(2, $groupedbycourse[$course1->id]);
1306 $this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']);
1307 $this->assertEquals('Event 2', $groupedbycourse[$course1->id][1]['name']);
1308 $this->assertCount(3, $groupedbycourse[$course2->id]);
1309 $this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']);
1310 $this->assertEquals('Event 4', $groupedbycourse[$course2->id][1]['name']);
1311 $this->assertEquals('Event 5', $groupedbycourse[$course2->id][2]['name']);
1313 $result = core_calendar_external::get_calendar_action_events_by_courses(
1314 [$course1->id, $course2->id], 2, 4);
1315 $result = external_api::clean_returnvalue(
1316 core_calendar_external::get_calendar_action_events_by_courses_returns(),
1317 $result
1319 $groupedbycourse = $mapresult($result);
1321 $this->assertCount(2, $groupedbycourse);
1322 $this->assertCount(1, $groupedbycourse[$course1->id]);
1323 $this->assertEquals('Event 2', $groupedbycourse[$course1->id][0]['name']);
1324 $this->assertCount(2, $groupedbycourse[$course2->id]);
1325 $this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']);
1326 $this->assertEquals('Event 4', $groupedbycourse[$course2->id][1]['name']);
1328 $result = core_calendar_external::get_calendar_action_events_by_courses(
1329 [$course1->id, $course2->id], 1, null, 1);
1330 $result = external_api::clean_returnvalue(
1331 core_calendar_external::get_calendar_action_events_by_courses_returns(),
1332 $result
1334 $groupedbycourse = $mapresult($result);
1336 $this->assertCount(2, $groupedbycourse);
1337 $this->assertCount(1, $groupedbycourse[$course1->id]);
1338 $this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']);
1339 $this->assertCount(1, $groupedbycourse[$course2->id]);
1340 $this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']);
1344 * Test for deleting module events.
1346 public function test_delete_calendar_events_for_modules() {
1347 $this->resetAfterTest();
1348 $this->setAdminUser();
1349 $course = $this->getDataGenerator()->create_course();
1350 $nexttime = time() + DAYSECS;
1351 $this->getDataGenerator()->create_module('assign', ['course' => $course->id, 'duedate' => $nexttime]);
1352 $events = calendar_get_events(time(), $nexttime, true, true, true);
1353 $this->assertCount(1, $events);
1354 $params = [];
1355 foreach ($events as $event) {
1356 $params[] = [
1357 'eventid' => $event->id,
1358 'repeat' => false
1362 $this->expectException('moodle_exception');
1363 core_calendar_external::delete_calendar_events($params);
1367 * Updating the event start day should change the date value but leave
1368 * the time of day unchanged.
1370 public function test_update_event_start_day() {
1371 $generator = $this->getDataGenerator();
1372 $user = $generator->create_user();
1373 $roleid = $generator->create_role();
1374 $context = \context_system::instance();
1375 $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1376 $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1377 $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1379 $generator->role_assign($roleid, $user->id, $context->id);
1380 assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
1382 $this->setUser($user);
1383 $this->resetAfterTest(true);
1385 $event = $this->create_calendar_event(
1386 'Test event',
1387 $user->id,
1388 'user',
1390 null,
1392 'courseid' => 0,
1393 'timestart' => $originalstarttime->getTimestamp()
1397 $result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp());
1398 $result = external_api::clean_returnvalue(
1399 core_calendar_external::update_event_start_day_returns(),
1400 $result
1403 $this->assertEquals($expected->getTimestamp(), $result['event']['timestart']);
1407 * A user should not be able to edit an event that they don't have
1408 * capabilities for.
1410 public function test_update_event_start_day_no_permission() {
1411 $generator = $this->getDataGenerator();
1412 $user = $generator->create_user();
1413 $roleid = $generator->create_role();
1414 $context = \context_system::instance();
1415 $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1416 $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1417 $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1419 $generator->role_assign($roleid, $user->id, $context->id);
1420 assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
1422 $this->setUser($user);
1423 $this->resetAfterTest(true);
1425 $event = $this->create_calendar_event(
1426 'Test event',
1427 $user->id,
1428 'user',
1430 null,
1432 'courseid' => 0,
1433 'timestart' => $originalstarttime->getTimestamp()
1437 assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true);
1438 $this->expectException('moodle_exception');
1439 $result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp());
1440 $result = external_api::clean_returnvalue(
1441 core_calendar_external::update_event_start_day_returns(),
1442 $result
1447 * A user should not be able to update a module event.
1449 public function test_update_event_start_day_module_event() {
1450 $generator = $this->getDataGenerator();
1451 $user = $generator->create_user();
1452 $course = $generator->create_course();
1453 $plugingenerator = $generator->get_plugin_generator('mod_assign');
1454 $moduleinstance = $plugingenerator->create_instance(['course' => $course->id]);
1455 $roleid = $generator->create_role();
1456 $context = \context_course::instance($course->id);
1457 $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1458 $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1459 $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1461 $generator->role_assign($roleid, $user->id, $context->id);
1462 $generator->enrol_user($user->id, $course->id);
1464 $this->setUser($user);
1465 $this->resetAfterTest(true);
1467 $event = $this->create_calendar_event(
1468 'Test event',
1469 $user->id,
1470 'user',
1472 null,
1474 'modulename' => 'assign',
1475 'instance' => $moduleinstance->id,
1476 'courseid' => $course->id,
1477 'timestart' => $originalstarttime->getTimestamp()
1481 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
1482 $this->expectException('moodle_exception');
1483 $result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp());
1484 $result = external_api::clean_returnvalue(
1485 core_calendar_external::update_event_start_day_returns(),
1486 $result
1491 * Submit a request where the time duration until is earlier than the time
1492 * start in order to get a validation error from the server.
1494 public function test_submit_create_update_form_validation_error() {
1495 $user = $this->getDataGenerator()->create_user();
1496 $timestart = new DateTime();
1497 $interval = new DateInterval("P1D"); // One day.
1498 $timedurationuntil = new DateTime();
1499 $timedurationuntil->sub($interval);
1500 $formdata = [
1501 'id' => 0,
1502 'userid' => $user->id,
1503 'modulename' => '',
1504 'instance' => 0,
1505 'visible' => 1,
1506 'name' => 'Test',
1507 'timestart' => [
1508 'day' => $timestart->format('j'),
1509 'month' => $timestart->format('n'),
1510 'year' => $timestart->format('Y'),
1511 'hour' => $timestart->format('G'),
1512 'minute' => 0,
1514 'eventtype' => 'user',
1515 'description' => [
1516 'text' => '',
1517 'format' => 1,
1519 'duration' => 1,
1520 'timedurationuntil' => [
1521 'day' => $timedurationuntil->format('j'),
1522 'month' => $timedurationuntil->format('n'),
1523 'year' => $timedurationuntil->format('Y'),
1524 'hour' => $timedurationuntil->format('G'),
1525 'minute' => 0,
1529 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1531 $querystring = http_build_query($formdata, '', '&amp;');
1533 $this->resetAfterTest(true);
1534 $this->setUser($user);
1536 $result = external_api::clean_returnvalue(
1537 core_calendar_external::submit_create_update_form_returns(),
1538 core_calendar_external::submit_create_update_form($querystring)
1541 $this->assertTrue($result['validationerror']);
1545 * A user with the moodle/calendar:manageownentries capability at the
1546 * system context should be able to create a user event.
1548 public function test_submit_create_update_form_create_user_event() {
1549 $generator = $this->getDataGenerator();
1550 $user = $generator->create_user();
1551 $roleid = $generator->create_role();
1552 $context = \context_system::instance();
1553 $timestart = new DateTime();
1554 $interval = new DateInterval("P1D"); // One day.
1555 $timedurationuntil = new DateTime();
1556 $timedurationuntil->add($interval);
1557 $formdata = [
1558 'id' => 0,
1559 'userid' => $user->id,
1560 'modulename' => '',
1561 'instance' => 0,
1562 'visible' => 1,
1563 'name' => 'Test',
1564 'timestart' => [
1565 'day' => $timestart->format('j'),
1566 'month' => $timestart->format('n'),
1567 'year' => $timestart->format('Y'),
1568 'hour' => $timestart->format('G'),
1569 'minute' => 0,
1571 'eventtype' => 'user',
1572 'description' => [
1573 'text' => '',
1574 'format' => 1,
1575 'itemid' => 0
1577 'duration' => 1,
1578 'timedurationuntil' => [
1579 'day' => $timedurationuntil->format('j'),
1580 'month' => $timedurationuntil->format('n'),
1581 'year' => $timedurationuntil->format('Y'),
1582 'hour' => $timedurationuntil->format('G'),
1583 'minute' => 0,
1587 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1588 $querystring = http_build_query($formdata, '', '&');
1590 $generator->role_assign($roleid, $user->id, $context->id);
1591 assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
1593 $user->ignoresesskey = true;
1594 $this->resetAfterTest(true);
1595 $this->setUser($user);
1597 $result = external_api::clean_returnvalue(
1598 core_calendar_external::submit_create_update_form_returns(),
1599 core_calendar_external::submit_create_update_form($querystring)
1602 $event = $result['event'];
1603 $this->assertEquals($user->id, $event['userid']);
1604 $this->assertEquals($formdata['eventtype'], $event['eventtype']);
1605 $this->assertEquals($formdata['name'], $event['name']);
1609 * A user without the moodle/calendar:manageownentries capability at the
1610 * system context should not be able to create a user event.
1612 public function test_submit_create_update_form_create_user_event_no_permission() {
1613 $generator = $this->getDataGenerator();
1614 $user = $generator->create_user();
1615 $roleid = $generator->create_role();
1616 $context = \context_system::instance();
1617 $timestart = new DateTime();
1618 $interval = new DateInterval("P1D"); // One day.
1619 $timedurationuntil = new DateTime();
1620 $timedurationuntil->add($interval);
1621 $formdata = [
1622 'id' => 0,
1623 'userid' => $user->id,
1624 'modulename' => '',
1625 'instance' => 0,
1626 'visible' => 1,
1627 'name' => 'Test',
1628 'timestart' => [
1629 'day' => $timestart->format('j'),
1630 'month' => $timestart->format('n'),
1631 'year' => $timestart->format('Y'),
1632 'hour' => $timestart->format('G'),
1633 'minute' => 0,
1635 'eventtype' => 'user',
1636 'description' => [
1637 'text' => '',
1638 'format' => 1,
1640 'duration' => 1,
1641 'timedurationuntil' => [
1642 'day' => $timedurationuntil->format('j'),
1643 'month' => $timedurationuntil->format('n'),
1644 'year' => $timedurationuntil->format('Y'),
1645 'hour' => $timedurationuntil->format('G'),
1646 'minute' => 0,
1650 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1651 $querystring = http_build_query($formdata, '', '&');
1653 $generator->role_assign($roleid, $user->id, $context->id);
1654 assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true);
1656 $user->ignoresesskey = true;
1657 $this->resetAfterTest(true);
1658 $this->setUser($user);
1660 $this->expectException('moodle_exception');
1662 external_api::clean_returnvalue(
1663 core_calendar_external::submit_create_update_form_returns(),
1664 core_calendar_external::submit_create_update_form($querystring)
1669 * A user with the moodle/calendar:manageentries capability at the
1670 * site course context should be able to create a site event.
1672 public function test_submit_create_update_form_create_site_event() {
1673 $generator = $this->getDataGenerator();
1674 $user = $generator->create_user();
1675 $context = context_system::instance();
1676 $roleid = $generator->create_role();
1677 $timestart = new DateTime();
1678 $interval = new DateInterval("P1D"); // One day.
1679 $timedurationuntil = new DateTime();
1680 $timedurationuntil->add($interval);
1681 $formdata = [
1682 'id' => 0,
1683 'userid' => $user->id,
1684 'modulename' => '',
1685 'instance' => 0,
1686 'visible' => 1,
1687 'name' => 'Test',
1688 'timestart' => [
1689 'day' => $timestart->format('j'),
1690 'month' => $timestart->format('n'),
1691 'year' => $timestart->format('Y'),
1692 'hour' => $timestart->format('G'),
1693 'minute' => 0,
1695 'eventtype' => 'site',
1696 'description' => [
1697 'text' => '',
1698 'format' => 1,
1699 'itemid' => 0
1701 'duration' => 1,
1702 'timedurationuntil' => [
1703 'day' => $timedurationuntil->format('j'),
1704 'month' => $timedurationuntil->format('n'),
1705 'year' => $timedurationuntil->format('Y'),
1706 'hour' => $timedurationuntil->format('G'),
1707 'minute' => 0,
1711 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1712 $querystring = http_build_query($formdata, '', '&');
1714 $generator->role_assign($roleid, $user->id, $context->id);
1716 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
1718 $user->ignoresesskey = true;
1719 $this->resetAfterTest(true);
1720 $this->setUser($user);
1722 $result = external_api::clean_returnvalue(
1723 core_calendar_external::submit_create_update_form_returns(),
1724 core_calendar_external::submit_create_update_form($querystring)
1727 $event = $result['event'];
1728 $this->assertEquals($user->id, $event['userid']);
1729 $this->assertEquals($formdata['eventtype'], $event['eventtype']);
1730 $this->assertEquals($formdata['name'], $event['name']);
1734 * A user without the moodle/calendar:manageentries capability at the
1735 * site course context should not be able to create a site event.
1737 public function test_submit_create_update_form_create_site_event_no_permission() {
1738 $generator = $this->getDataGenerator();
1739 $user = $generator->create_user();
1740 $context = context_course::instance(SITEID);
1741 $roleid = $generator->create_role();
1742 $timestart = new DateTime();
1743 $interval = new DateInterval("P1D"); // One day.
1744 $timedurationuntil = new DateTime();
1745 $timedurationuntil->add($interval);
1746 $formdata = [
1747 'id' => 0,
1748 'userid' => $user->id,
1749 'modulename' => '',
1750 'instance' => 0,
1751 'visible' => 1,
1752 'name' => 'Test',
1753 'timestart' => [
1754 'day' => $timestart->format('j'),
1755 'month' => $timestart->format('n'),
1756 'year' => $timestart->format('Y'),
1757 'hour' => $timestart->format('G'),
1758 'minute' => 0,
1760 'eventtype' => 'site',
1761 'description' => [
1762 'text' => '',
1763 'format' => 1,
1765 'duration' => 1,
1766 'timedurationuntil' => [
1767 'day' => $timedurationuntil->format('j'),
1768 'month' => $timedurationuntil->format('n'),
1769 'year' => $timedurationuntil->format('Y'),
1770 'hour' => $timedurationuntil->format('G'),
1771 'minute' => 0,
1775 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1776 $querystring = http_build_query($formdata, '', '&');
1778 $generator->role_assign($roleid, $user->id, $context->id);
1780 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
1782 $user->ignoresesskey = true;
1783 $this->resetAfterTest(true);
1784 $this->setUser($user);
1786 $result = external_api::clean_returnvalue(
1787 core_calendar_external::submit_create_update_form_returns(),
1788 core_calendar_external::submit_create_update_form($querystring)
1791 $this->assertTrue($result['validationerror']);
1795 * A user that has the moodle/calendar:manageentries in a course that they
1796 * are enrolled in should be able to create a course event in that course.
1798 public function test_submit_create_update_form_create_course_event() {
1799 $generator = $this->getDataGenerator();
1800 $user = $generator->create_user();
1801 $course = $generator->create_course();
1802 $context = context_course::instance($course->id);
1803 $roleid = $generator->create_role();
1804 $timestart = new DateTime();
1805 $interval = new DateInterval("P1D"); // One day.
1806 $timedurationuntil = new DateTime();
1807 $timedurationuntil->add($interval);
1808 $formdata = [
1809 'id' => 0,
1810 'userid' => $user->id,
1811 'modulename' => '',
1812 'instance' => 0,
1813 'visible' => 1,
1814 'name' => 'Test',
1815 'timestart' => [
1816 'day' => $timestart->format('j'),
1817 'month' => $timestart->format('n'),
1818 'year' => $timestart->format('Y'),
1819 'hour' => $timestart->format('G'),
1820 'minute' => 0,
1822 'eventtype' => 'course',
1823 'courseid' => $course->id,
1824 'description' => [
1825 'text' => '',
1826 'format' => 1,
1827 'itemid' => 0,
1829 'duration' => 1,
1830 'timedurationuntil' => [
1831 'day' => $timedurationuntil->format('j'),
1832 'month' => $timedurationuntil->format('n'),
1833 'year' => $timedurationuntil->format('Y'),
1834 'hour' => $timedurationuntil->format('G'),
1835 'minute' => 0,
1839 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1840 $querystring = http_build_query($formdata, '', '&');
1842 $generator->enrol_user($user->id, $course->id, 'student');
1843 $generator->role_assign($roleid, $user->id, $context->id);
1845 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
1847 $user->ignoresesskey = true;
1848 $this->resetAfterTest(true);
1849 $this->setUser($user);
1851 $result = external_api::clean_returnvalue(
1852 core_calendar_external::submit_create_update_form_returns(),
1853 core_calendar_external::submit_create_update_form($querystring)
1856 $event = $result['event'];
1857 $this->assertEquals($user->id, $event['userid']);
1858 $this->assertEquals($formdata['eventtype'], $event['eventtype']);
1859 $this->assertEquals($formdata['name'], $event['name']);
1860 $this->assertEquals($formdata['courseid'], $event['course']['id']);
1864 * A user without the moodle/calendar:manageentries capability in a course
1865 * that they are enrolled in should not be able to create a course event in that course.
1867 public function test_submit_create_update_form_create_course_event_no_permission() {
1868 $generator = $this->getDataGenerator();
1869 $user = $generator->create_user();
1870 $course = $generator->create_course();
1871 $context = context_course::instance($course->id);
1872 $roleid = $generator->create_role();
1873 $timestart = new DateTime();
1874 $interval = new DateInterval("P1D"); // One day.
1875 $timedurationuntil = new DateTime();
1876 $timedurationuntil->add($interval);
1877 $formdata = [
1878 'id' => 0,
1879 'userid' => $user->id,
1880 'modulename' => '',
1881 'instance' => 0,
1882 'visible' => 1,
1883 'name' => 'Test',
1884 'timestart' => [
1885 'day' => $timestart->format('j'),
1886 'month' => $timestart->format('n'),
1887 'year' => $timestart->format('Y'),
1888 'hour' => $timestart->format('G'),
1889 'minute' => 0,
1891 'eventtype' => 'course',
1892 'courseid' => $course->id,
1893 'description' => [
1894 'text' => '',
1895 'format' => 1,
1897 'duration' => 1,
1898 'timedurationuntil' => [
1899 'day' => $timedurationuntil->format('j'),
1900 'month' => $timedurationuntil->format('n'),
1901 'year' => $timedurationuntil->format('Y'),
1902 'hour' => $timedurationuntil->format('G'),
1903 'minute' => 0,
1907 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1908 $querystring = http_build_query($formdata, '', '&');
1910 $generator->enrol_user($user->id, $course->id, 'student');
1911 $generator->role_assign($roleid, $user->id, $context->id);
1913 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
1915 $user->ignoresesskey = true;
1916 $this->resetAfterTest(true);
1917 $this->setUser($user);
1919 $result = external_api::clean_returnvalue(
1920 core_calendar_external::submit_create_update_form_returns(),
1921 core_calendar_external::submit_create_update_form($querystring)
1924 $this->assertTrue($result['validationerror']);
1928 * A user should not be able to create an event for a course that they are
1929 * not enrolled in.
1931 public function test_submit_create_update_form_create_course_event_not_enrolled() {
1932 $generator = $this->getDataGenerator();
1933 $user = $generator->create_user();
1934 $course = $generator->create_course();
1935 $course2 = $generator->create_course();
1936 $context = context_course::instance($course->id);
1937 $roleid = $generator->create_role();
1938 $timestart = new DateTime();
1939 $interval = new DateInterval("P1D"); // One day.
1940 $timedurationuntil = new DateTime();
1941 $timedurationuntil->add($interval);
1942 $formdata = [
1943 'id' => 0,
1944 'userid' => $user->id,
1945 'modulename' => '',
1946 'instance' => 0,
1947 'visible' => 1,
1948 'name' => 'Test',
1949 'timestart' => [
1950 'day' => $timestart->format('j'),
1951 'month' => $timestart->format('n'),
1952 'year' => $timestart->format('Y'),
1953 'hour' => $timestart->format('G'),
1954 'minute' => 0,
1956 'eventtype' => 'course',
1957 'courseid' => $course2->id, // Not enrolled.
1958 'description' => [
1959 'text' => '',
1960 'format' => 1,
1962 'duration' => 1,
1963 'timedurationuntil' => [
1964 'day' => $timedurationuntil->format('j'),
1965 'month' => $timedurationuntil->format('n'),
1966 'year' => $timedurationuntil->format('Y'),
1967 'hour' => $timedurationuntil->format('G'),
1968 'minute' => 0,
1972 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
1973 $querystring = http_build_query($formdata, '', '&');
1975 $generator->enrol_user($user->id, $course->id, 'student');
1976 $generator->role_assign($roleid, $user->id, $context->id);
1978 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
1980 $user->ignoresesskey = true;
1981 $this->resetAfterTest(true);
1982 $this->setUser($user);
1984 $this->expectException('moodle_exception');
1986 external_api::clean_returnvalue(
1987 core_calendar_external::submit_create_update_form_returns(),
1988 core_calendar_external::submit_create_update_form($querystring)
1993 * A user should be able to create an event for a group that they are a member of in
1994 * a course in which they are enrolled and have the moodle/calendar:manageentries capability.
1996 public function test_submit_create_update_form_create_group_event_group_member_manage_course() {
1997 $generator = $this->getDataGenerator();
1998 $user = $generator->create_user();
1999 $course = $generator->create_course();
2000 $group = $generator->create_group(array('courseid' => $course->id));
2001 $context = context_course::instance($course->id);
2002 $roleid = $generator->create_role();
2003 $timestart = new DateTime();
2004 $interval = new DateInterval("P1D"); // One day.
2005 $timedurationuntil = new DateTime();
2006 $timedurationuntil->add($interval);
2007 $formdata = [
2008 'id' => 0,
2009 'userid' => $user->id,
2010 'modulename' => '',
2011 'instance' => 0,
2012 'visible' => 1,
2013 'name' => 'Test',
2014 'timestart' => [
2015 'day' => $timestart->format('j'),
2016 'month' => $timestart->format('n'),
2017 'year' => $timestart->format('Y'),
2018 'hour' => $timestart->format('G'),
2019 'minute' => 0,
2021 'eventtype' => 'group',
2022 'groupid' => "{$course->id}-{$group->id}", // The form format.
2023 'groupcourseid' => $course->id,
2024 'description' => [
2025 'text' => '',
2026 'format' => 1,
2027 'itemid' => 0
2029 'duration' => 1,
2030 'timedurationuntil' => [
2031 'day' => $timedurationuntil->format('j'),
2032 'month' => $timedurationuntil->format('n'),
2033 'year' => $timedurationuntil->format('Y'),
2034 'hour' => $timedurationuntil->format('G'),
2035 'minute' => 0,
2039 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
2040 $querystring = http_build_query($formdata, '', '&');
2042 $generator->enrol_user($user->id, $course->id, 'student');
2043 $generator->role_assign($roleid, $user->id, $context->id);
2044 $generator->create_group_member(['groupid' => $group->id, 'userid' => $user->id]);
2046 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
2048 $user->ignoresesskey = true;
2049 $this->resetAfterTest(true);
2050 $this->setUser($user);
2052 $result = external_api::clean_returnvalue(
2053 core_calendar_external::submit_create_update_form_returns(),
2054 core_calendar_external::submit_create_update_form($querystring)
2057 $event = $result['event'];
2058 $this->assertEquals($user->id, $event['userid']);
2059 $this->assertEquals($formdata['eventtype'], $event['eventtype']);
2060 $this->assertEquals($formdata['name'], $event['name']);
2061 $this->assertEquals($group->id, $event['groupid']);
2065 * A user should be able to create an event for a group that they are a member of in
2066 * a course in which they are enrolled and have the moodle/calendar:managegroupentries capability.
2068 public function test_submit_create_update_form_create_group_event_group_member_manage_group_entries() {
2069 $generator = $this->getDataGenerator();
2070 $user = $generator->create_user();
2071 $course = $generator->create_course();
2072 $group = $generator->create_group(array('courseid' => $course->id));
2073 $context = context_course::instance($course->id);
2074 $roleid = $generator->create_role();
2075 $timestart = new DateTime();
2076 $interval = new DateInterval("P1D"); // One day.
2077 $timedurationuntil = new DateTime();
2078 $timedurationuntil->add($interval);
2079 $formdata = [
2080 'id' => 0,
2081 'userid' => $user->id,
2082 'modulename' => '',
2083 'instance' => 0,
2084 'visible' => 1,
2085 'name' => 'Test',
2086 'timestart' => [
2087 'day' => $timestart->format('j'),
2088 'month' => $timestart->format('n'),
2089 'year' => $timestart->format('Y'),
2090 'hour' => $timestart->format('G'),
2091 'minute' => 0,
2093 'eventtype' => 'group',
2094 'groupid' => "{$course->id}-{$group->id}", // The form format.
2095 'groupcourseid' => $course->id,
2096 'description' => [
2097 'text' => '',
2098 'format' => 1,
2099 'itemid' => 0
2101 'duration' => 1,
2102 'timedurationuntil' => [
2103 'day' => $timedurationuntil->format('j'),
2104 'month' => $timedurationuntil->format('n'),
2105 'year' => $timedurationuntil->format('Y'),
2106 'hour' => $timedurationuntil->format('G'),
2107 'minute' => 0,
2111 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
2112 $querystring = http_build_query($formdata, '', '&');
2114 $generator->enrol_user($user->id, $course->id, 'student');
2115 $generator->role_assign($roleid, $user->id, $context->id);
2116 $generator->create_group_member(['groupid' => $group->id, 'userid' => $user->id]);
2118 assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
2119 assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
2121 $user->ignoresesskey = true;
2122 $this->resetAfterTest(true);
2123 $this->setUser($user);
2125 $result = external_api::clean_returnvalue(
2126 core_calendar_external::submit_create_update_form_returns(),
2127 core_calendar_external::submit_create_update_form($querystring)
2130 $event = $result['event'];
2131 $this->assertEquals($user->id, $event['userid']);
2132 $this->assertEquals($formdata['eventtype'], $event['eventtype']);
2133 $this->assertEquals($formdata['name'], $event['name']);
2134 $this->assertEquals($group->id, $event['groupid']);
2138 * A user should be able to create an event for any group in a course in which
2139 * they are enrolled and have the moodle/site:accessallgroups capability.
2141 public function test_submit_create_update_form_create_group_event_access_all_groups() {
2142 $generator = $this->getDataGenerator();
2143 $user = $generator->create_user();
2144 $course = $generator->create_course();
2145 $group = $generator->create_group(array('courseid' => $course->id));
2146 $context = context_course::instance($course->id);
2147 $roleid = $generator->create_role();
2148 $timestart = new DateTime();
2149 $interval = new DateInterval("P1D"); // One day.
2150 $timedurationuntil = new DateTime();
2151 $timedurationuntil->add($interval);
2152 $formdata = [
2153 'id' => 0,
2154 'userid' => $user->id,
2155 'modulename' => '',
2156 'instance' => 0,
2157 'visible' => 1,
2158 'name' => 'Test',
2159 'timestart' => [
2160 'day' => $timestart->format('j'),
2161 'month' => $timestart->format('n'),
2162 'year' => $timestart->format('Y'),
2163 'hour' => $timestart->format('G'),
2164 'minute' => 0,
2166 'eventtype' => 'group',
2167 'groupid' => "{$course->id}-{$group->id}", // The form format.
2168 'groupcourseid' => $course->id,
2169 'description' => [
2170 'text' => '',
2171 'format' => 1,
2172 'itemid' => 0
2174 'duration' => 1,
2175 'timedurationuntil' => [
2176 'day' => $timedurationuntil->format('j'),
2177 'month' => $timedurationuntil->format('n'),
2178 'year' => $timedurationuntil->format('Y'),
2179 'hour' => $timedurationuntil->format('G'),
2180 'minute' => 0,
2184 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
2185 $querystring = http_build_query($formdata, '', '&');
2187 $generator->enrol_user($user->id, $course->id, 'student');
2188 $generator->role_assign($roleid, $user->id, $context->id);
2190 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
2191 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true);
2193 $user->ignoresesskey = true;
2194 $this->resetAfterTest(true);
2195 $this->setUser($user);
2197 $result = external_api::clean_returnvalue(
2198 core_calendar_external::submit_create_update_form_returns(),
2199 core_calendar_external::submit_create_update_form($querystring)
2202 $event = $result['event'];
2203 $this->assertEquals($user->id, $event['userid']);
2204 $this->assertEquals($formdata['eventtype'], $event['eventtype']);
2205 $this->assertEquals($formdata['name'], $event['name']);
2206 $this->assertEquals($group->id, $event['groupid']);
2210 * A user should not be able to create an event for any group that they are not a
2211 * member of in a course in which they are enrolled but don't have the
2212 * moodle/site:accessallgroups capability.
2214 public function test_submit_create_update_form_create_group_event_non_member_no_permission() {
2215 $generator = $this->getDataGenerator();
2216 $user = $generator->create_user();
2217 $course = $generator->create_course();
2218 $group = $generator->create_group(array('courseid' => $course->id));
2219 $context = context_course::instance($course->id);
2220 $roleid = $generator->create_role();
2221 $timestart = new DateTime();
2222 $interval = new DateInterval("P1D"); // One day.
2223 $timedurationuntil = new DateTime();
2224 $timedurationuntil->add($interval);
2225 $formdata = [
2226 'id' => 0,
2227 'userid' => $user->id,
2228 'modulename' => '',
2229 'instance' => 0,
2230 'visible' => 1,
2231 'name' => 'Test',
2232 'timestart' => [
2233 'day' => $timestart->format('j'),
2234 'month' => $timestart->format('n'),
2235 'year' => $timestart->format('Y'),
2236 'hour' => $timestart->format('G'),
2237 'minute' => 0,
2239 'eventtype' => 'group',
2240 'groupid' => "{$course->id}-{$group->id}", // The form format.
2241 'groupcourseid' => $course->id,
2242 'description' => [
2243 'text' => '',
2244 'format' => 1,
2246 'duration' => 1,
2247 'timedurationuntil' => [
2248 'day' => $timedurationuntil->format('j'),
2249 'month' => $timedurationuntil->format('n'),
2250 'year' => $timedurationuntil->format('Y'),
2251 'hour' => $timedurationuntil->format('G'),
2252 'minute' => 0,
2256 $formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
2257 $querystring = http_build_query($formdata, '', '&');
2259 $generator->enrol_user($user->id, $course->id, 'student');
2260 $generator->role_assign($roleid, $user->id, $context->id);
2262 assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
2263 assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true);
2265 $user->ignoresesskey = true;
2266 $this->resetAfterTest(true);
2267 $this->setUser($user);
2269 $result = external_api::clean_returnvalue(
2270 core_calendar_external::submit_create_update_form_returns(),
2271 core_calendar_external::submit_create_update_form($querystring)
2274 $this->assertTrue($result['validationerror']);
2278 * A user should not be able load the calendar monthly view for a course they cannot access.
2280 public function test_get_calendar_monthly_view_no_course_permission() {
2281 global $USER;
2282 $this->resetAfterTest(true);
2283 $this->setAdminUser();
2285 $generator = $this->getDataGenerator();
2286 $user1 = $generator->create_user();
2287 $user2 = $generator->create_user();
2288 $course = $generator->create_course();
2289 $generator->enrol_user($user1->id, $course->id, 'student');
2290 $name = 'Course Event (course' . $course->id . ')';
2291 $record = new stdClass();
2292 $record->courseid = $course->id;
2293 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
2295 $timestart = new DateTime();
2296 // Admin can load the course.
2297 $data = external_api::clean_returnvalue(
2298 core_calendar_external::get_calendar_monthly_view_returns(),
2299 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'),
2300 $course->id, null, false, true)
2302 $this->assertEquals($data['courseid'], $course->id);
2303 // User enrolled in the course can load the course calendar.
2304 $this->setUser($user1);
2305 $data = external_api::clean_returnvalue(
2306 core_calendar_external::get_calendar_monthly_view_returns(),
2307 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'),
2308 $course->id, null, false, true)
2310 $this->assertEquals($data['courseid'], $course->id);
2311 // User not enrolled in the course cannot load the course calendar.
2312 $this->setUser($user2);
2313 $this->expectException('require_login_exception');
2314 $data = external_api::clean_returnvalue(
2315 core_calendar_external::get_calendar_monthly_view_returns(),
2316 core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'),
2317 $course->id, null, false, false)
2322 * A user should not be able load the calendar day view for a course they cannot access.
2324 public function test_get_calendar_day_view_no_course_permission() {
2325 global $USER;
2326 $this->resetAfterTest(true);
2327 $this->setAdminUser();
2329 $generator = $this->getDataGenerator();
2330 $user1 = $generator->create_user();
2331 $user2 = $generator->create_user();
2332 $course = $generator->create_course();
2333 $generator->enrol_user($user1->id, $course->id, 'student');
2334 $name = 'Course Event (course' . $course->id . ')';
2335 $record = new stdClass();
2336 $record->courseid = $course->id;
2337 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
2339 $timestart = new DateTime();
2340 // Admin can load the course.
2341 $data = external_api::clean_returnvalue(
2342 core_calendar_external::get_calendar_day_view_returns(),
2343 core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'),
2344 $timestart->format('j'), $course->id, null)
2346 $this->assertEquals($data['courseid'], $course->id);
2347 // User enrolled in the course can load the course calendar.
2348 $this->setUser($user1);
2349 $data = external_api::clean_returnvalue(
2350 core_calendar_external::get_calendar_day_view_returns(),
2351 core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'),
2352 $timestart->format('j'), $course->id, null)
2354 $this->assertEquals($data['courseid'], $course->id);
2355 // User not enrolled in the course cannot load the course calendar.
2356 $this->setUser($user2);
2357 $this->expectException('require_login_exception');
2358 $data = external_api::clean_returnvalue(
2359 core_calendar_external::get_calendar_day_view_returns(),
2360 core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'),
2361 $timestart->format('j'), $course->id, null)
2366 * A user should not be able load the calendar upcoming view for a course they cannot access.
2368 public function test_get_calendar_upcoming_view_no_course_permission() {
2369 global $USER;
2370 $this->resetAfterTest(true);
2371 $this->setAdminUser();
2373 $generator = $this->getDataGenerator();
2374 $user1 = $generator->create_user();
2375 $user2 = $generator->create_user();
2376 $course = $generator->create_course();
2377 $generator->enrol_user($user1->id, $course->id, 'student');
2378 $name = 'Course Event (course' . $course->id . ')';
2379 $record = new stdClass();
2380 $record->courseid = $course->id;
2381 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
2383 // Admin can load the course.
2384 $data = external_api::clean_returnvalue(
2385 core_calendar_external::get_calendar_upcoming_view_returns(),
2386 core_calendar_external::get_calendar_upcoming_view($course->id, null)
2388 $this->assertEquals($data['courseid'], $course->id);
2389 // User enrolled in the course can load the course calendar.
2390 $this->setUser($user1);
2391 $data = external_api::clean_returnvalue(
2392 core_calendar_external::get_calendar_upcoming_view_returns(),
2393 core_calendar_external::get_calendar_upcoming_view($course->id, null)
2395 $this->assertEquals($data['courseid'], $course->id);
2396 // User not enrolled in the course cannot load the course calendar.
2397 $this->setUser($user2);
2398 $this->expectException('require_login_exception');
2399 $data = external_api::clean_returnvalue(
2400 core_calendar_external::get_calendar_upcoming_view_returns(),
2401 core_calendar_external::get_calendar_upcoming_view($course->id, null)
2406 * A user should not be able load the calendar event for a course they cannot access.
2408 public function test_get_calendar_event_by_id_no_course_permission() {
2409 global $USER;
2410 $this->resetAfterTest(true);
2411 $this->setAdminUser();
2413 $generator = $this->getDataGenerator();
2414 $user1 = $generator->create_user();
2415 $user2 = $generator->create_user();
2416 $course = $generator->create_course();
2417 $generator->enrol_user($user1->id, $course->id, 'student');
2418 $name = 'Course Event (course' . $course->id . ')';
2419 $record = new stdClass();
2420 $record->courseid = $course->id;
2421 $courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
2423 // Admin can load the course event.
2424 $data = external_api::clean_returnvalue(
2425 core_calendar_external::get_calendar_event_by_id_returns(),
2426 core_calendar_external::get_calendar_event_by_id($courseevent->id)
2428 $this->assertEquals($data['event']['id'], $courseevent->id);
2429 // User enrolled in the course can load the course event.
2430 $this->setUser($user1);
2431 $data = external_api::clean_returnvalue(
2432 core_calendar_external::get_calendar_event_by_id_returns(),
2433 core_calendar_external::get_calendar_event_by_id($courseevent->id)
2435 $this->assertEquals($data['event']['id'], $courseevent->id);
2436 // User not enrolled in the course cannot load the course event.
2437 $this->setUser($user2);
2438 $this->expectException('required_capability_exception');
2439 $data = external_api::clean_returnvalue(
2440 core_calendar_external::get_calendar_event_by_id_returns(),
2441 core_calendar_external::get_calendar_event_by_id($courseevent->id)
2446 * A user should not be able load the calendar events for a category they cannot see.
2448 public function test_get_calendar_events_hidden_category() {
2449 global $USER;
2450 $this->resetAfterTest(true);
2451 $this->setAdminUser();
2453 $generator = $this->getDataGenerator();
2454 $user1 = $generator->create_user();
2455 $category = $generator->create_category(['visible' => 0]);
2456 $name = 'Category Event (category: ' . $category->id . ')';
2457 $record = new stdClass();
2458 $record->categoryid = $category->id;
2459 $categoryevent = $this->create_calendar_event($name, $USER->id, 'category', 0, time(), $record);
2461 $events = [
2462 'eventids' => [$categoryevent->id]
2464 $options = [];
2465 // Admin can load the category event.
2466 $data = external_api::clean_returnvalue(
2467 core_calendar_external::get_calendar_events_returns(),
2468 core_calendar_external::get_calendar_events($events, $options)
2470 $this->assertEquals($data['events'][0]['id'], $categoryevent->id);
2471 // User with no special permission to see hidden categories will not see the event.
2472 $this->setUser($user1);
2473 $data = external_api::clean_returnvalue(
2474 core_calendar_external::get_calendar_events_returns(),
2475 core_calendar_external::get_calendar_events($events, $options)
2477 $this->assertCount(0, $data['events']);
2478 $this->assertEquals('nopermissions', $data['warnings'][0]['warningcode']);