You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2699 lines
117 KiB
2699 lines
117 KiB
<?php
|
|
// This file is part of Moodle - http://moodle.org/
|
|
//
|
|
// Moodle is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// Moodle is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
/**
|
|
* External calendar functions unit tests
|
|
*
|
|
* @package core_calendar
|
|
* @category external
|
|
* @copyright 2012 Ankit Agarwal
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
*/
|
|
|
|
defined('MOODLE_INTERNAL') || die();
|
|
|
|
global $CFG;
|
|
|
|
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
|
|
|
|
/**
|
|
* External course functions unit tests
|
|
*
|
|
* @package core_calendar
|
|
* @category external
|
|
* @copyright 2012 Ankit Agarwal
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
|
* @since Moodle 2.5
|
|
*/
|
|
class core_calendar_externallib_testcase extends externallib_advanced_testcase {
|
|
|
|
/**
|
|
* Tests set up
|
|
*/
|
|
protected function setUp() {
|
|
global $CFG;
|
|
require_once($CFG->dirroot . '/calendar/externallib.php');
|
|
}
|
|
|
|
/** Create calendar events or update them
|
|
* Set $prop->id, if you want to do an update instead of creating an new event
|
|
*
|
|
* @param string $name Event title
|
|
* @param int $userid User id
|
|
* @param string $type Event type
|
|
* @param int $repeats Number of repeated events to create
|
|
* @param int $timestart Time stamp of the event start
|
|
* @param mixed $prop List of event properties as array or object
|
|
* @return mixed Event object or false;
|
|
* @since Moodle 2.5
|
|
*/
|
|
|
|
public static function create_calendar_event($name, $userid = 0, $type = 'user', $repeats = 0, $timestart = null, $prop = null) {
|
|
global $CFG, $DB, $SITE;
|
|
|
|
require_once("$CFG->dirroot/calendar/lib.php");
|
|
if (!empty($prop)) {
|
|
if (is_array($prop)) {
|
|
$prop = (object)$prop;
|
|
}
|
|
} else {
|
|
$prop = new stdClass();
|
|
}
|
|
$prop->name = $name;
|
|
if (empty($prop->eventtype)) {
|
|
$prop->eventtype = $type;
|
|
}
|
|
if (empty($prop->repeats)) {
|
|
$prop->repeats = $repeats;
|
|
}
|
|
if (empty($prop->timestart)) {
|
|
$prop->timestart = time();
|
|
}
|
|
if (empty($prop->timeduration)) {
|
|
$prop->timeduration = 0;
|
|
}
|
|
if (empty($prop->timesort)) {
|
|
$prop->timesort = 0;
|
|
}
|
|
if (empty($prop->type)) {
|
|
$prop->type = CALENDAR_EVENT_TYPE_STANDARD;
|
|
}
|
|
if (empty($prop->repeats)) {
|
|
$prop->repeat = 0;
|
|
} else {
|
|
$prop->repeat = 1;
|
|
}
|
|
if (empty($prop->userid)) {
|
|
if (!empty($userid)) {
|
|
$prop->userid = $userid;
|
|
} else {
|
|
$prop->userid = 0;
|
|
}
|
|
}
|
|
if (!isset($prop->courseid)) {
|
|
$prop->courseid = $SITE->id;
|
|
}
|
|
|
|
// Determine event priority.
|
|
if ($prop->courseid == 0 && isset($prop->groupid) && $prop->groupid == 0 && !empty($prop->userid)) {
|
|
// User override event.
|
|
$prop->priority = CALENDAR_EVENT_USER_OVERRIDE_PRIORITY;
|
|
} else if ($prop->courseid != $SITE->id && !empty($prop->groupid)) {
|
|
// Group override event.
|
|
$priorityparams = ['courseid' => $prop->courseid, 'groupid' => $prop->groupid];
|
|
// Group override event with the highest priority.
|
|
$groupevents = $DB->get_records('event', $priorityparams, 'priority DESC', 'id, priority', 0, 1);
|
|
$priority = 1;
|
|
if (!empty($groupevents)) {
|
|
$event = reset($groupevents);
|
|
if (!empty($event->priority)) {
|
|
$priority = $event->priority + 1;
|
|
}
|
|
}
|
|
$prop->priority = $priority;
|
|
}
|
|
|
|
$event = new calendar_event($prop);
|
|
return $event->create($prop);
|
|
}
|
|
|
|
public function test_create_calendar_events () {
|
|
global $DB, $USER;
|
|
|
|
$this->setAdminUser();
|
|
$this->resetAfterTest();
|
|
$prevcount = count($DB->get_records("event"));
|
|
|
|
// Create a few events and do asserts.
|
|
$this->create_calendar_event('test', $USER->id);
|
|
$where = $DB->sql_compare_text('name') ." = ?";
|
|
$count = count($DB->get_records_select("event", $where, array('test')));
|
|
$this->assertEquals(1, $count);
|
|
$aftercount = count($DB->get_records("event"));
|
|
$this->assertEquals($prevcount + 1, $aftercount);
|
|
|
|
$this->create_calendar_event('user', $USER->id, 'user', 3);
|
|
$where = $DB->sql_compare_text('name') ." = ?";
|
|
$count = count($DB->get_records_select("event", $where, array('user')));
|
|
|
|
$this->assertEquals(3, $count);
|
|
$aftercount = count($DB->get_records("event"));
|
|
$this->assertEquals($prevcount + 4, $aftercount);
|
|
|
|
}
|
|
|
|
/**
|
|
* Test delete_calendar_events
|
|
*
|
|
* @expectedException moodle_exception
|
|
*/
|
|
public function test_delete_calendar_events() {
|
|
global $DB, $USER;
|
|
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
// Create a few stuff to test with.
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$group = $this->getDataGenerator()->create_group($record);
|
|
|
|
$notdeletedcount = $DB->count_records('event');
|
|
|
|
// Let's create a few events.
|
|
$siteevent = $this->create_calendar_event('site', $USER->id, 'site');
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record);
|
|
$userevent = $this->create_calendar_event('user', $USER->id);
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$record->groupid = $group->id;
|
|
$groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
|
|
|
|
// Now lets try to delete stuff with proper rights.
|
|
$events = array(
|
|
array('eventid' => $siteevent->id, 'repeat' => 0),
|
|
array('eventid' => $courseevent->id, 'repeat' => 1),
|
|
array('eventid' => $userevent->id, 'repeat' => 0),
|
|
array('eventid' => $groupevent->id, 'repeat' => 0)
|
|
);
|
|
core_calendar_external::delete_calendar_events($events);
|
|
|
|
// Check to see if things were deleted properly.
|
|
$deletedcount = $DB->count_records('event');
|
|
$this->assertEquals($notdeletedcount, $deletedcount);
|
|
|
|
// Let's create a few events.
|
|
$siteevent = $this->create_calendar_event('site', $USER->id, 'site');
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event('course', $USER->id, 'course', 3, time(), $record);
|
|
$userevent = $this->create_calendar_event('user', $USER->id);
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$record->groupid = $group->id;
|
|
$groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
|
|
|
|
$this->setuser($user);
|
|
$sitecontext = context_system::instance();
|
|
$coursecontext = context_course::instance($course->id);
|
|
$usercontext = context_user::instance($user->id);
|
|
$role = $DB->get_record('role', array('shortname' => 'student'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
|
|
// Remove all caps.
|
|
$this->unassignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id);
|
|
$this->unassignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id);
|
|
$this->unassignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
|
|
$this->unassignUserCapability('moodle/calendar:manageownentries', $usercontext->id, $role->id);
|
|
|
|
// Assign proper caps and attempt delete.
|
|
$this->assignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id);
|
|
$events = array(
|
|
array('eventid' => $siteevent->id, 'repeat' => 0),
|
|
);
|
|
core_calendar_external::delete_calendar_events($events);
|
|
$deletedcount = $DB->count_records('event');
|
|
$count = $notdeletedcount+5;
|
|
$this->assertEquals($count, $deletedcount);
|
|
|
|
$this->assignUserCapability('moodle/calendar:manageentries', $sitecontext->id, $role->id);
|
|
$events = array(
|
|
array('eventid' => $courseevent->id, 'repeat' => 0),
|
|
);
|
|
core_calendar_external::delete_calendar_events($events);
|
|
$deletedcount = $DB->count_records('event');
|
|
$count = $notdeletedcount+4;
|
|
$this->assertEquals($count, $deletedcount);
|
|
|
|
$this->assignUserCapability('moodle/calendar:manageownentries', $usercontext->id, $role->id);
|
|
$events = array(
|
|
array('eventid' => $userevent->id, 'repeat' => 0),
|
|
);
|
|
core_calendar_external::delete_calendar_events($events);
|
|
$deletedcount = $DB->count_records('event');
|
|
$count = $notdeletedcount+3;
|
|
$this->assertEquals($count, $deletedcount);
|
|
|
|
$this->assignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
|
|
$events = array(
|
|
array('eventid' => $groupevent->id, 'repeat' => 0),
|
|
);
|
|
core_calendar_external::delete_calendar_events($events);
|
|
$deletedcount = $DB->count_records('event');
|
|
$count = $notdeletedcount+2;
|
|
$this->assertEquals($count, $deletedcount);
|
|
|
|
$notdeletedcount = $deletedcount;
|
|
|
|
// Let us try deleting without caps.
|
|
|
|
$siteevent = $this->create_calendar_event('site', $USER->id, 'site');
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event('course', $USER->id, 'course', 3, time(), $record);
|
|
$userevent = $this->create_calendar_event('user', $USER->id);
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$record->groupid = $group->id;
|
|
$groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
|
|
|
|
$this->setGuestUser();
|
|
|
|
$events = array(
|
|
array('eventid' => $siteevent->id, 'repeat' => 0),
|
|
array('eventid' => $courseevent->id, 'repeat' => 0),
|
|
array('eventid' => $userevent->id, 'repeat' => 0),
|
|
array('eventid' => $groupevent->id, 'repeat' => 0)
|
|
);
|
|
core_calendar_external::delete_calendar_events($events);
|
|
}
|
|
|
|
/**
|
|
* Test get_calendar_events
|
|
*/
|
|
public function test_get_calendar_events() {
|
|
global $DB, $USER;
|
|
|
|
$this->resetAfterTest(true);
|
|
set_config('calendar_adminseesall', 1);
|
|
$this->setAdminUser();
|
|
|
|
// Create a few stuff to test with.
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$user2 = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
|
|
$category = $this->getDataGenerator()->create_category();
|
|
|
|
$category2 = $this->getDataGenerator()->create_category();
|
|
$category2b = $this->getDataGenerator()->create_category(['parent' => $category2->id]);
|
|
$course3 = $this->getDataGenerator()->create_course(['category' => $category2b->id]);
|
|
|
|
$role = $DB->get_record('role', array('shortname' => 'student'));
|
|
$this->getDataGenerator()->enrol_user($user2->id, $course3->id, $role->id);
|
|
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$group = $this->getDataGenerator()->create_group($record);
|
|
|
|
$beforecount = $DB->count_records('event');
|
|
|
|
// Let's create a few events.
|
|
$siteevent = $this->create_calendar_event('site', $USER->id, 'site');
|
|
|
|
// This event will have description with an inline fake image.
|
|
$draftidfile = file_get_unused_draft_itemid();
|
|
$usercontext = context_course::instance($course->id);
|
|
$filerecord = array(
|
|
'contextid' => $usercontext->id,
|
|
'component' => 'user',
|
|
'filearea' => 'draft',
|
|
'itemid' => $draftidfile,
|
|
'filepath' => '/',
|
|
'filename' => 'fakeimage.png',
|
|
);
|
|
$fs = get_file_storage();
|
|
$fs->create_file_from_string($filerecord, 'img contents');
|
|
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$record->groupid = 0;
|
|
$record->description = array(
|
|
'format' => FORMAT_HTML,
|
|
'text' => 'Text with img <img src="@@PLUGINFILE@@/fakeimage.png">',
|
|
'itemid' => $draftidfile
|
|
);
|
|
$courseevent = $this->create_calendar_event('course', $USER->id, 'course', 2, time(), $record);
|
|
|
|
$record = new stdClass();
|
|
$record->courseid = 0;
|
|
$record->groupid = 0;
|
|
$userevent = $this->create_calendar_event('user', $USER->id, 'user', 0, time(), $record);
|
|
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$record->groupid = $group->id;
|
|
$groupevent = $this->create_calendar_event('group', $USER->id, 'group', 0, time(), $record);
|
|
|
|
$paramevents = array ('eventids' => array($siteevent->id), 'courseids' => array($course->id),
|
|
'groupids' => array($group->id), 'categoryids' => array($category->id));
|
|
|
|
$options = array ('siteevents' => true, 'userevents' => true);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
|
|
// Check to see if we got all events.
|
|
$this->assertEquals(5, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
$options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + 7*WEEKSECS);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(5, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
// Expect the same URL in the description of two different events (because they are repeated).
|
|
$coursecontext = context_course::instance($course->id);
|
|
$expectedurl = "webservice/pluginfile.php/$coursecontext->id/calendar/event_description/$courseevent->id/fakeimage.png";
|
|
$withdescription = 0;
|
|
foreach ($events['events'] as $event) {
|
|
if (!empty($event['description'])) {
|
|
$withdescription++;
|
|
$this->assertContains($expectedurl, $event['description']);
|
|
}
|
|
}
|
|
$this->assertEquals(2, $withdescription);
|
|
|
|
// Let's play around with caps.
|
|
|
|
// Create user event for the user $user.
|
|
$record = new stdClass();
|
|
$record->courseid = 0;
|
|
$record->groupid = 0;
|
|
$this->create_calendar_event('user', $user->id, 'user', 0, time(), $record);
|
|
|
|
$this->setUser($user);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(2, count($events['events'])); // site, user.
|
|
$this->assertEquals(2, count($events['warnings'])); // course, group.
|
|
|
|
$role = $DB->get_record('role', array('shortname' => 'student'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(4, count($events['events'])); // site, user, both course events.
|
|
$this->assertEquals(1, count($events['warnings'])); // group.
|
|
|
|
$options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + HOURSECS);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(3, count($events['events'])); // site, user, one course event.
|
|
$this->assertEquals(1, count($events['warnings'])); // group.
|
|
|
|
groups_add_member($group, $user);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(4, count($events['events'])); // site, user, group, one course event.
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
$paramevents = array ('courseids' => array($course->id), 'groupids' => array($group->id));
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(4, count($events['events'])); // site, user, group, one course event.
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
$paramevents = array ('groupids' => array($group->id, 23));
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(3, count($events['events'])); // site, user, group.
|
|
$this->assertEquals(1, count($events['warnings']));
|
|
|
|
$paramevents = array ('courseids' => array(23));
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(2, count($events['events'])); // site, user.
|
|
$this->assertEquals(1, count($events['warnings']));
|
|
|
|
$paramevents = array ();
|
|
$options = array ('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7*WEEKSECS);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(0, count($events['events'])); // nothing returned.
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
$paramevents = array ('eventids' => array($siteevent->id, $groupevent->id));
|
|
$options = array ('siteevents' => false, 'userevents' => false, 'timeend' => time() + 7*WEEKSECS);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(2, count($events['events'])); // site, group.
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
$paramevents = array ('eventids' => array($siteevent->id));
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(1, count($events['events'])); // site.
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
// Try getting a course event by its id.
|
|
$paramevents = array ('eventids' => array($courseevent->id));
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(1, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
// Now, create an activity event.
|
|
$this->setAdminUser();
|
|
$nexttime = time() + DAYSECS;
|
|
$assign = $this->getDataGenerator()->create_module('assign', array('course' => $course->id, 'duedate' => $nexttime));
|
|
|
|
$this->setUser($user);
|
|
$paramevents = array ('courseids' => array($course->id));
|
|
$options = array ('siteevents' => true, 'userevents' => true, 'timeend' => time() + WEEKSECS);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
|
|
$this->assertCount(5, $events['events']);
|
|
|
|
// Hide the assignment.
|
|
set_coursemodule_visible($assign->cmid, 0);
|
|
// Empty all the caches that may be affected by this change.
|
|
accesslib_clear_all_caches_for_unit_testing();
|
|
course_modinfo::clear_instance_cache();
|
|
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
// Expect one less.
|
|
$this->assertCount(4, $events['events']);
|
|
|
|
// Create some category events.
|
|
$this->setAdminUser();
|
|
$record = new stdClass();
|
|
$record->courseid = 0;
|
|
$record->categoryid = $category->id;
|
|
$record->timestart = time() - DAYSECS;
|
|
$catevent1 = $this->create_calendar_event('category a', $USER->id, 'category', 0, time(), $record);
|
|
|
|
$record = new stdClass();
|
|
$record->courseid = 0;
|
|
$record->categoryid = $category2->id;
|
|
$record->timestart = time() + DAYSECS;
|
|
$catevent2 = $this->create_calendar_event('category b', $USER->id, 'category', 0, time(), $record);
|
|
|
|
// Now as student, make sure we get the events of the courses I am enrolled.
|
|
$this->setUser($user2);
|
|
$paramevents = array('categoryids' => array($category2b->id));
|
|
$options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
|
|
// Should be just one, since there's just one category event of the course I am enrolled (course3 - cat2b).
|
|
$this->assertEquals(1, count($events['events']));
|
|
$this->assertEquals($catevent2->id, $events['events'][0]['id']);
|
|
$this->assertEquals($category2->id, $events['events'][0]['categoryid']);
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
// Now get category events but by course (there aren't course events in the course).
|
|
$paramevents = array('courseids' => array($course3->id));
|
|
$options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(1, count($events['events']));
|
|
$this->assertEquals($catevent2->id, $events['events'][0]['id']);
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
// Empty events in one where I'm not enrolled and one parent category
|
|
// (parent of a category where this is a course where the user is enrolled).
|
|
$paramevents = array('categoryids' => array($category2->id, $category->id));
|
|
$options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(1, count($events['events']));
|
|
$this->assertEquals($catevent2->id, $events['events'][0]['id']);
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
|
|
// Admin can see all category events.
|
|
$this->setAdminUser();
|
|
$paramevents = array('categoryids' => array($category->id, $category2->id, $category2b->id));
|
|
$options = array('timeend' => time() + 7 * WEEKSECS, 'userevents' => false, 'siteevents' => false);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(2, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
$this->assertEquals($catevent1->id, $events['events'][0]['id']);
|
|
$this->assertEquals($category->id, $events['events'][0]['categoryid']);
|
|
$this->assertEquals($catevent2->id, $events['events'][1]['id']);
|
|
$this->assertEquals($category2->id, $events['events'][1]['categoryid']);
|
|
}
|
|
|
|
/**
|
|
* Test core_calendar_external::create_calendar_events
|
|
*/
|
|
public function test_core_create_calendar_events() {
|
|
global $DB, $USER, $SITE;
|
|
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
// Create a few stuff to test with.
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$group = $this->getDataGenerator()->create_group($record);
|
|
|
|
$prevcount = $DB->count_records('event');
|
|
|
|
// Let's create a few events.
|
|
$events = array (
|
|
array('name' => 'site', 'courseid' => $SITE->id, 'eventtype' => 'site'),
|
|
array('name' => 'course', 'courseid' => $course->id, 'eventtype' => 'course', 'repeats' => 2),
|
|
array('name' => 'group', 'courseid' => $course->id, 'groupid' => $group->id, 'eventtype' => 'group'),
|
|
array('name' => 'user')
|
|
);
|
|
$eventsret = core_calendar_external::create_calendar_events($events);
|
|
$eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
|
|
|
|
// Check to see if things were created properly.
|
|
$aftercount = $DB->count_records('event');
|
|
$this->assertEquals($prevcount + 5, $aftercount);
|
|
$this->assertEquals(5, count($eventsret['events']));
|
|
$this->assertEquals(0, count($eventsret['warnings']));
|
|
|
|
$sitecontext = context_system::instance();
|
|
$coursecontext = context_course::instance($course->id);
|
|
|
|
$this->setUser($user);
|
|
$prevcount = $aftercount;
|
|
$events = array (
|
|
array('name' => 'course', 'courseid' => $course->id, 'eventtype' => 'course', 'repeats' => 2),
|
|
array('name' => 'group', 'courseid' => $course->id, 'groupid' => $group->id, 'eventtype' => 'group'),
|
|
array('name' => 'user')
|
|
);
|
|
$role = $DB->get_record('role', array('shortname' => 'student'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
groups_add_member($group, $user);
|
|
$this->assignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id);
|
|
$this->assignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
|
|
$eventsret = core_calendar_external::create_calendar_events($events);
|
|
$eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
|
|
// Check to see if things were created properly.
|
|
$aftercount = $DB->count_records('event');
|
|
$this->assertEquals($prevcount + 4, $aftercount);
|
|
$this->assertEquals(4, count($eventsret['events']));
|
|
$this->assertEquals(0, count($eventsret['warnings']));
|
|
|
|
// Check to see nothing was created without proper permission.
|
|
$this->setGuestUser();
|
|
$prevcount = $DB->count_records('event');
|
|
$eventsret = core_calendar_external::create_calendar_events($events);
|
|
$eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
|
|
$aftercount = $DB->count_records('event');
|
|
$this->assertEquals($prevcount, $aftercount);
|
|
$this->assertEquals(0, count($eventsret['events']));
|
|
$this->assertEquals(3, count($eventsret['warnings']));
|
|
|
|
$this->setUser($user);
|
|
$this->unassignUserCapability('moodle/calendar:manageentries', $coursecontext->id, $role->id);
|
|
$this->unassignUserCapability('moodle/calendar:managegroupentries', $coursecontext->id, $role->id);
|
|
$prevcount = $DB->count_records('event');
|
|
$eventsret = core_calendar_external::create_calendar_events($events);
|
|
$eventsret = external_api::clean_returnvalue(core_calendar_external::create_calendar_events_returns(), $eventsret);
|
|
$aftercount = $DB->count_records('event');
|
|
$this->assertEquals($prevcount + 1, $aftercount); // User event.
|
|
$this->assertEquals(1, count($eventsret['events']));
|
|
$this->assertEquals(2, count($eventsret['warnings']));
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events from a given time should return all events with a sort
|
|
* time at or after the requested time. All events prior to that time should not
|
|
* be return.
|
|
*
|
|
* If there are no events on or after the given time then an empty result set should
|
|
* be returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_timesort_after_time() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$moduleinstance = $generator->create_instance(['course' => $course->id]);
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$params = [
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'modulename' => 'assign',
|
|
'instance' => $moduleinstance->id,
|
|
'courseid' => $course->id,
|
|
];
|
|
|
|
$event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1]));
|
|
$event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
|
|
$event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
|
|
$event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
|
|
$event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
|
|
$event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
|
|
$event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
|
|
$event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(5);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(4, $events);
|
|
$this->assertEquals('Event 5', $events[0]['name']);
|
|
$this->assertEquals('Event 6', $events[1]['name']);
|
|
$this->assertEquals('Event 7', $events[2]['name']);
|
|
$this->assertEquals('Event 8', $events[3]['name']);
|
|
$this->assertEquals($event5->id, $result['firstid']);
|
|
$this->assertEquals($event8->id, $result['lastid']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(9);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
|
|
$this->assertEmpty($result['events']);
|
|
$this->assertNull($result['firstid']);
|
|
$this->assertNull($result['lastid']);
|
|
|
|
// Requesting action events on behalf of another user.
|
|
$this->setAdminUser();
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(5, null, 0, 20, false, $user->id);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(4, $events);
|
|
$this->assertEquals('Event 5', $events[0]['name']);
|
|
$this->assertEquals('Event 6', $events[1]['name']);
|
|
$this->assertEquals('Event 7', $events[2]['name']);
|
|
$this->assertEquals('Event 8', $events[3]['name']);
|
|
$this->assertEquals($event5->id, $result['firstid']);
|
|
$this->assertEquals($event8->id, $result['lastid']);
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events before a given time should return all events with a sort
|
|
* time at or before the requested time (inclusive). All events after that time
|
|
* should not be returned.
|
|
*
|
|
* If there are no events before the given time then an empty result set should be
|
|
* returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_timesort_before_time() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$moduleinstance = $generator->create_instance(['course' => $course->id]);
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$params = [
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'modulename' => 'assign',
|
|
'instance' => $moduleinstance->id,
|
|
'courseid' => $course->id,
|
|
];
|
|
|
|
$event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
|
|
$event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
|
|
$event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
|
|
$event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
|
|
$event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
|
|
$event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
|
|
$event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
|
|
$event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 9]));
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(null, 5);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(4, $events);
|
|
$this->assertEquals('Event 1', $events[0]['name']);
|
|
$this->assertEquals('Event 2', $events[1]['name']);
|
|
$this->assertEquals('Event 3', $events[2]['name']);
|
|
$this->assertEquals('Event 4', $events[3]['name']);
|
|
$this->assertEquals($event1->id, $result['firstid']);
|
|
$this->assertEquals($event4->id, $result['lastid']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(null, 1);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
|
|
$this->assertEmpty($result['events']);
|
|
$this->assertNull($result['firstid']);
|
|
$this->assertNull($result['lastid']);
|
|
|
|
// Requesting action events on behalf of another user.
|
|
$this->setAdminUser();
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(null, 5, 0, 20, false, $user->id);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(4, $events);
|
|
$this->assertEquals('Event 1', $events[0]['name']);
|
|
$this->assertEquals('Event 2', $events[1]['name']);
|
|
$this->assertEquals('Event 3', $events[2]['name']);
|
|
$this->assertEquals('Event 4', $events[3]['name']);
|
|
$this->assertEquals($event1->id, $result['firstid']);
|
|
$this->assertEquals($event4->id, $result['lastid']);
|
|
}
|
|
|
|
/**
|
|
* Test retrieving event that was overridden for a user
|
|
*/
|
|
public function test_get_calendar_events_override() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$user2 = $this->getDataGenerator()->create_user();
|
|
$teacher = $this->getDataGenerator()->create_user();
|
|
$anotheruser = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$moduleinstance = $generator->create_instance(['course' => $course->id]);
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
|
|
$this->getDataGenerator()->enrol_user($user2->id, $course->id, 'student');
|
|
$this->getDataGenerator()->enrol_user($teacher->id, $course->id, 'editingteacher');
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$params = [
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'modulename' => 'assign',
|
|
'instance' => $moduleinstance->id,
|
|
];
|
|
|
|
$now = time();
|
|
// Create two events - one for everybody in the course and one only for the first student.
|
|
$event1 = $this->create_calendar_event('Base event', 0, 'due', 0, $now + DAYSECS, $params + ['courseid' => $course->id]);
|
|
$event2 = $this->create_calendar_event('User event', $user->id, 'due', 0, $now + 2*DAYSECS, $params + ['courseid' => 0]);
|
|
|
|
// Retrieve course events for the second student - only one "Base event" is returned.
|
|
$this->setUser($user2);
|
|
$paramevents = array('courseids' => array($course->id));
|
|
$options = array ('siteevents' => true, 'userevents' => true);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(1, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
$this->assertEquals('Base event', $events['events'][0]['name']);
|
|
|
|
// Retrieve events for the first student - both events are returned.
|
|
$this->setUser($user);
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(2, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
$this->assertEquals('Base event', $events['events'][0]['name']);
|
|
$this->assertEquals('User event', $events['events'][1]['name']);
|
|
|
|
// Retrieve events by id as a teacher, 'User event' should be returned since teacher has access to this course.
|
|
$this->setUser($teacher);
|
|
$paramevents = ['eventids' => [$event2->id]];
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(1, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
$this->assertEquals('User event', $events['events'][0]['name']);
|
|
|
|
// Retrieve events by id as another user, nothing should be returned.
|
|
$this->setUser($anotheruser);
|
|
$paramevents = ['eventids' => [$event2->id, $event1->id]];
|
|
$events = core_calendar_external::get_calendar_events($paramevents, $options);
|
|
$events = external_api::clean_returnvalue(core_calendar_external::get_calendar_events_returns(), $events);
|
|
$this->assertEquals(0, count($events['events']));
|
|
$this->assertEquals(0, count($events['warnings']));
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events within a given time range should return all events with
|
|
* a sort time between the lower and upper time bound (inclusive).
|
|
*
|
|
* If there are no events in the given time range then an empty result set should be
|
|
* returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_timesort_time_range() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$moduleinstance = $generator->create_instance(['course' => $course->id]);
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$params = [
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'modulename' => 'assign',
|
|
'instance' => $moduleinstance->id,
|
|
'courseid' => $course->id,
|
|
];
|
|
|
|
$event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1]));
|
|
$event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
|
|
$event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
|
|
$event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
|
|
$event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
|
|
$event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
|
|
$event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
|
|
$event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(3, 6);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(4, $events);
|
|
$this->assertEquals('Event 3', $events[0]['name']);
|
|
$this->assertEquals('Event 4', $events[1]['name']);
|
|
$this->assertEquals('Event 5', $events[2]['name']);
|
|
$this->assertEquals('Event 6', $events[3]['name']);
|
|
$this->assertEquals($event3->id, $result['firstid']);
|
|
$this->assertEquals($event6->id, $result['lastid']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(10, 15);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
|
|
$this->assertEmpty($result['events']);
|
|
$this->assertNull($result['firstid']);
|
|
$this->assertNull($result['lastid']);
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events within a given time range and a limit and offset should return
|
|
* the number of events up to the given limit value that have a sort time between the lower
|
|
* and uppper time bound (inclusive) where the result set is shifted by the offset value.
|
|
*
|
|
* If there are no events in the given time range then an empty result set should be
|
|
* returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_timesort_time_limit_offset() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$moduleinstance = $generator->create_instance(['course' => $course->id]);
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$params = [
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'modulename' => 'assign',
|
|
'instance' => $moduleinstance->id,
|
|
'courseid' => $course->id,
|
|
];
|
|
|
|
$event1 = $this->create_calendar_event('Event 1', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 1]));
|
|
$event2 = $this->create_calendar_event('Event 2', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 2]));
|
|
$event3 = $this->create_calendar_event('Event 3', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 3]));
|
|
$event4 = $this->create_calendar_event('Event 4', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 4]));
|
|
$event5 = $this->create_calendar_event('Event 5', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 5]));
|
|
$event6 = $this->create_calendar_event('Event 6', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 6]));
|
|
$event7 = $this->create_calendar_event('Event 7', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 7]));
|
|
$event8 = $this->create_calendar_event('Event 8', $user->id, 'user', 0, 1, array_merge($params, ['timesort' => 8]));
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event3->id, 2);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(2, $events);
|
|
$this->assertEquals('Event 4', $events[0]['name']);
|
|
$this->assertEquals('Event 5', $events[1]['name']);
|
|
$this->assertEquals($event4->id, $result['firstid']);
|
|
$this->assertEquals($event5->id, $result['lastid']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event5->id, 2);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
$events = $result['events'];
|
|
|
|
$this->assertCount(2, $events);
|
|
$this->assertEquals('Event 6', $events[0]['name']);
|
|
$this->assertEquals('Event 7', $events[1]['name']);
|
|
$this->assertEquals($event6->id, $result['firstid']);
|
|
$this->assertEquals($event7->id, $result['lastid']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(2, 7, $event7->id, 2);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_timesort_returns(),
|
|
$result
|
|
);
|
|
|
|
$this->assertEmpty($result['events']);
|
|
$this->assertNull($result['firstid']);
|
|
$this->assertNull($result['lastid']);
|
|
}
|
|
|
|
/**
|
|
* Check that it is possible to restrict the calendar events to events where the user is not suspended in the course.
|
|
*/
|
|
public function test_get_calendar_action_events_by_timesort_suspended_course() {
|
|
$this->resetAfterTest();
|
|
$user1 = $this->getDataGenerator()->create_user();
|
|
$user2 = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$this->setAdminUser();
|
|
$lesson = $this->getDataGenerator()->create_module('lesson', [
|
|
'name' => 'Lesson 1',
|
|
'course' => $course->id,
|
|
'available' => time(),
|
|
'deadline' => (time() + (60 * 60 * 24 * 5))
|
|
]
|
|
);
|
|
$this->getDataGenerator()->enrol_user($user1->id, $course->id, null, 'manual', 0, 0, ENROL_USER_SUSPENDED);
|
|
$this->getDataGenerator()->enrol_user($user2->id, $course->id);
|
|
|
|
$this->setUser($user1);
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true);
|
|
$this->assertEmpty($result->events);
|
|
$this->setUser($user2);
|
|
$result = core_calendar_external::get_calendar_action_events_by_timesort(0, null, 0, 20, true);
|
|
$this->assertCount(1, $result->events);
|
|
$this->assertEquals('Lesson 1 closes', $result->events[0]->name);
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events from a given course and time should return all
|
|
* events with a sort time at or after the requested time. All events prior
|
|
* to that time should not be return.
|
|
*
|
|
* If there are no events on or after the given time then an empty result set should
|
|
* be returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_course_after_time() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course1 = $this->getDataGenerator()->create_course();
|
|
$course2 = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$instance1 = $generator->create_instance(['course' => $course1->id]);
|
|
$instance2 = $generator->create_instance(['course' => $course2->id]);
|
|
$records = [];
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course1->id);
|
|
$this->getDataGenerator()->enrol_user($user->id, $course2->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
for ($i = 1; $i < 19; $i++) {
|
|
$courseid = ($i < 9) ? $course1->id : $course2->id;
|
|
$instance = ($i < 9) ? $instance1->id : $instance2->id;
|
|
$records[] = $this->create_calendar_event(
|
|
sprintf('Event %d', $i),
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
1,
|
|
[
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'courseid' => $courseid,
|
|
'timesort' => $i,
|
|
'modulename' => 'assign',
|
|
'instance' => $instance,
|
|
]
|
|
);
|
|
}
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 5);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertCount(4, $result);
|
|
$this->assertEquals('Event 5', $result[0]['name']);
|
|
$this->assertEquals('Event 6', $result[1]['name']);
|
|
$this->assertEquals('Event 7', $result[2]['name']);
|
|
$this->assertEquals('Event 8', $result[3]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 9);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events for a course and before a given time should return
|
|
* all events with a sort time at or before the requested time (inclusive). All
|
|
* events after that time should not be returned.
|
|
*
|
|
* If there are no events before the given time then an empty result set should be
|
|
* returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_course_before_time() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course1 = $this->getDataGenerator()->create_course();
|
|
$course2 = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$instance1 = $generator->create_instance(['course' => $course1->id]);
|
|
$instance2 = $generator->create_instance(['course' => $course2->id]);
|
|
$records = [];
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course1->id);
|
|
$this->getDataGenerator()->enrol_user($user->id, $course2->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
for ($i = 1; $i < 19; $i++) {
|
|
$courseid = ($i < 9) ? $course1->id : $course2->id;
|
|
$instance = ($i < 9) ? $instance1->id : $instance2->id;
|
|
$records[] = $this->create_calendar_event(
|
|
sprintf('Event %d', $i),
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
1,
|
|
[
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'courseid' => $courseid,
|
|
'timesort' => $i + 1,
|
|
'modulename' => 'assign',
|
|
'instance' => $instance,
|
|
]
|
|
);
|
|
}
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course($course1->id, null, 5);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertCount(4, $result);
|
|
$this->assertEquals('Event 1', $result[0]['name']);
|
|
$this->assertEquals('Event 2', $result[1]['name']);
|
|
$this->assertEquals('Event 3', $result[2]['name']);
|
|
$this->assertEquals('Event 4', $result[3]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course($course1->id, null, 1);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events for a course and within a given time range should
|
|
* return all events with a sort time between the lower and upper time bound
|
|
* (inclusive).
|
|
*
|
|
* If there are no events in the given time range then an empty result set should be
|
|
* returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_course_time_range() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course1 = $this->getDataGenerator()->create_course();
|
|
$course2 = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$instance1 = $generator->create_instance(['course' => $course1->id]);
|
|
$instance2 = $generator->create_instance(['course' => $course2->id]);
|
|
$records = [];
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course1->id);
|
|
$this->getDataGenerator()->enrol_user($user->id, $course2->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
for ($i = 1; $i < 19; $i++) {
|
|
$courseid = ($i < 9) ? $course1->id : $course2->id;
|
|
$instance = ($i < 9) ? $instance1->id : $instance2->id;
|
|
$records[] = $this->create_calendar_event(
|
|
sprintf('Event %d', $i),
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
1,
|
|
[
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'courseid' => $courseid,
|
|
'timesort' => $i,
|
|
'modulename' => 'assign',
|
|
'instance' => $instance,
|
|
]
|
|
);
|
|
}
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 3, 6);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertCount(4, $result);
|
|
$this->assertEquals('Event 3', $result[0]['name']);
|
|
$this->assertEquals('Event 4', $result[1]['name']);
|
|
$this->assertEquals('Event 5', $result[2]['name']);
|
|
$this->assertEquals('Event 6', $result[3]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course($course1->id, 10, 15);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Requesting calendar events for a course and within a given time range and a limit
|
|
* and offset should return the number of events up to the given limit value that have
|
|
* a sort time between the lower and uppper time bound (inclusive) where the result
|
|
* set is shifted by the offset value.
|
|
*
|
|
* If there are no events in the given time range then an empty result set should be
|
|
* returned.
|
|
*/
|
|
public function test_get_calendar_action_events_by_course_time_limit_offset() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course1 = $this->getDataGenerator()->create_course();
|
|
$course2 = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$instance1 = $generator->create_instance(['course' => $course1->id]);
|
|
$instance2 = $generator->create_instance(['course' => $course2->id]);
|
|
$records = [];
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course1->id);
|
|
$this->getDataGenerator()->enrol_user($user->id, $course2->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
for ($i = 1; $i < 19; $i++) {
|
|
$courseid = ($i < 9) ? $course1->id : $course2->id;
|
|
$instance = ($i < 9) ? $instance1->id : $instance2->id;
|
|
$records[] = $this->create_calendar_event(
|
|
sprintf('Event %d', $i),
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
1,
|
|
[
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'courseid' => $courseid,
|
|
'timesort' => $i,
|
|
'modulename' => 'assign',
|
|
'instance' => $instance,
|
|
]
|
|
);
|
|
}
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course(
|
|
$course1->id, 2, 7, $records[2]->id, 2);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertCount(2, $result);
|
|
$this->assertEquals('Event 4', $result[0]['name']);
|
|
$this->assertEquals('Event 5', $result[1]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course(
|
|
$course1->id, 2, 7, $records[4]->id, 2);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertCount(2, $result);
|
|
$this->assertEquals('Event 6', $result[0]['name']);
|
|
$this->assertEquals('Event 7', $result[1]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_course(
|
|
$course1->id, 2, 7, $records[6]->id, 2);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_course_returns(),
|
|
$result
|
|
);
|
|
$result = $result['events'];
|
|
|
|
$this->assertEmpty($result);
|
|
}
|
|
|
|
/**
|
|
* Test that get_action_events_by_courses will return a list of events for each
|
|
* course you provided as long as the user is enrolled in the course.
|
|
*/
|
|
public function test_get_action_events_by_courses() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course1 = $this->getDataGenerator()->create_course();
|
|
$course2 = $this->getDataGenerator()->create_course();
|
|
$course3 = $this->getDataGenerator()->create_course();
|
|
$generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
|
|
$instance1 = $generator->create_instance(['course' => $course1->id]);
|
|
$instance2 = $generator->create_instance(['course' => $course2->id]);
|
|
$instance3 = $generator->create_instance(['course' => $course3->id]);
|
|
$records = [];
|
|
$mapresult = function($result) {
|
|
$groupedbycourse = [];
|
|
foreach ($result['groupedbycourse'] as $group) {
|
|
$events = $group['events'];
|
|
$courseid = $group['courseid'];
|
|
$groupedbycourse[$courseid] = $events;
|
|
}
|
|
|
|
return $groupedbycourse;
|
|
};
|
|
|
|
$this->getDataGenerator()->enrol_user($user->id, $course1->id);
|
|
$this->getDataGenerator()->enrol_user($user->id, $course2->id);
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
for ($i = 1; $i < 10; $i++) {
|
|
if ($i < 3) {
|
|
$courseid = $course1->id;
|
|
$instance = $instance1->id;
|
|
} else if ($i < 6) {
|
|
$courseid = $course2->id;
|
|
$instance = $instance2->id;
|
|
} else {
|
|
$courseid = $course3->id;
|
|
$instance = $instance3->id;
|
|
}
|
|
|
|
$records[] = $this->create_calendar_event(
|
|
sprintf('Event %d', $i),
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
1,
|
|
[
|
|
'type' => CALENDAR_EVENT_TYPE_ACTION,
|
|
'courseid' => $courseid,
|
|
'timesort' => $i,
|
|
'modulename' => 'assign',
|
|
'instance' => $instance,
|
|
]
|
|
);
|
|
}
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_courses([], 1);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_courses_returns(),
|
|
$result
|
|
);
|
|
$result = $result['groupedbycourse'];
|
|
|
|
$this->assertEmpty($result);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_courses([$course1->id], 3);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_courses_returns(),
|
|
$result
|
|
);
|
|
|
|
$groupedbycourse = $mapresult($result);
|
|
|
|
$this->assertEmpty($groupedbycourse[$course1->id]);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_courses([$course1->id], 1);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_courses_returns(),
|
|
$result
|
|
);
|
|
$groupedbycourse = $mapresult($result);
|
|
|
|
$this->assertCount(2, $groupedbycourse[$course1->id]);
|
|
$this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']);
|
|
$this->assertEquals('Event 2', $groupedbycourse[$course1->id][1]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_courses(
|
|
[$course1->id, $course2->id], 1);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_courses_returns(),
|
|
$result
|
|
);
|
|
$groupedbycourse = $mapresult($result);
|
|
|
|
$this->assertCount(2, $groupedbycourse[$course1->id]);
|
|
$this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']);
|
|
$this->assertEquals('Event 2', $groupedbycourse[$course1->id][1]['name']);
|
|
$this->assertCount(3, $groupedbycourse[$course2->id]);
|
|
$this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']);
|
|
$this->assertEquals('Event 4', $groupedbycourse[$course2->id][1]['name']);
|
|
$this->assertEquals('Event 5', $groupedbycourse[$course2->id][2]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_courses(
|
|
[$course1->id, $course2->id], 2, 4);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_courses_returns(),
|
|
$result
|
|
);
|
|
$groupedbycourse = $mapresult($result);
|
|
|
|
$this->assertCount(2, $groupedbycourse);
|
|
$this->assertCount(1, $groupedbycourse[$course1->id]);
|
|
$this->assertEquals('Event 2', $groupedbycourse[$course1->id][0]['name']);
|
|
$this->assertCount(2, $groupedbycourse[$course2->id]);
|
|
$this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']);
|
|
$this->assertEquals('Event 4', $groupedbycourse[$course2->id][1]['name']);
|
|
|
|
$result = core_calendar_external::get_calendar_action_events_by_courses(
|
|
[$course1->id, $course2->id], 1, null, 1);
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_action_events_by_courses_returns(),
|
|
$result
|
|
);
|
|
$groupedbycourse = $mapresult($result);
|
|
|
|
$this->assertCount(2, $groupedbycourse);
|
|
$this->assertCount(1, $groupedbycourse[$course1->id]);
|
|
$this->assertEquals('Event 1', $groupedbycourse[$course1->id][0]['name']);
|
|
$this->assertCount(1, $groupedbycourse[$course2->id]);
|
|
$this->assertEquals('Event 3', $groupedbycourse[$course2->id][0]['name']);
|
|
}
|
|
|
|
/**
|
|
* Test for deleting module events.
|
|
*/
|
|
public function test_delete_calendar_events_for_modules() {
|
|
$this->resetAfterTest();
|
|
$this->setAdminUser();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$nexttime = time() + DAYSECS;
|
|
$this->getDataGenerator()->create_module('assign', ['course' => $course->id, 'duedate' => $nexttime]);
|
|
$events = calendar_get_events(time(), $nexttime, true, true, true);
|
|
$this->assertCount(1, $events);
|
|
$params = [];
|
|
foreach ($events as $event) {
|
|
$params[] = [
|
|
'eventid' => $event->id,
|
|
'repeat' => false
|
|
];
|
|
}
|
|
|
|
$this->expectException('moodle_exception');
|
|
core_calendar_external::delete_calendar_events($params);
|
|
}
|
|
|
|
/**
|
|
* Updating the event start day should change the date value but leave
|
|
* the time of day unchanged.
|
|
*/
|
|
public function test_update_event_start_day() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$roleid = $generator->create_role();
|
|
$context = \context_system::instance();
|
|
$originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
|
|
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
|
|
$expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$this->setUser($user);
|
|
$this->resetAfterTest(true);
|
|
|
|
$event = $this->create_calendar_event(
|
|
'Test event',
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
null,
|
|
[
|
|
'courseid' => 0,
|
|
'timestart' => $originalstarttime->getTimestamp()
|
|
]
|
|
);
|
|
|
|
$result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp());
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::update_event_start_day_returns(),
|
|
$result
|
|
);
|
|
|
|
$this->assertEquals($expected->getTimestamp(), $result['event']['timestart']);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able to edit an event that they don't have
|
|
* capabilities for.
|
|
*/
|
|
public function test_update_event_start_day_no_permission() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$roleid = $generator->create_role();
|
|
$context = \context_system::instance();
|
|
$originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
|
|
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
|
|
$expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$this->setUser($user);
|
|
$this->resetAfterTest(true);
|
|
|
|
$event = $this->create_calendar_event(
|
|
'Test event',
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
null,
|
|
[
|
|
'courseid' => 0,
|
|
'timestart' => $originalstarttime->getTimestamp()
|
|
]
|
|
);
|
|
|
|
assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true);
|
|
$this->expectException('moodle_exception');
|
|
$result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp());
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::update_event_start_day_returns(),
|
|
$result
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able to update a module event.
|
|
*/
|
|
public function test_update_event_start_day_module_event() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$plugingenerator = $generator->get_plugin_generator('mod_assign');
|
|
$moduleinstance = $plugingenerator->create_instance(['course' => $course->id]);
|
|
$roleid = $generator->create_role();
|
|
$context = \context_course::instance($course->id);
|
|
$originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
|
|
$newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
|
|
$expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
$generator->enrol_user($user->id, $course->id);
|
|
|
|
$this->setUser($user);
|
|
$this->resetAfterTest(true);
|
|
|
|
$event = $this->create_calendar_event(
|
|
'Test event',
|
|
$user->id,
|
|
'user',
|
|
0,
|
|
null,
|
|
[
|
|
'modulename' => 'assign',
|
|
'instance' => $moduleinstance->id,
|
|
'courseid' => $course->id,
|
|
'timestart' => $originalstarttime->getTimestamp()
|
|
]
|
|
);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
$this->expectException('moodle_exception');
|
|
$result = core_calendar_external::update_event_start_day($event->id, $newstartdate->getTimestamp());
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::update_event_start_day_returns(),
|
|
$result
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Submit a request where the time duration until is earlier than the time
|
|
* start in order to get a validation error from the server.
|
|
*/
|
|
public function test_submit_create_update_form_validation_error() {
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->sub($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'user',
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$this->assertTrue($result['validationerror']);
|
|
}
|
|
|
|
/**
|
|
* A user with the moodle/calendar:manageownentries capability at the
|
|
* system context should be able to create a user event.
|
|
*/
|
|
public function test_submit_create_update_form_create_user_event() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$roleid = $generator->create_role();
|
|
$context = \context_system::instance();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'user',
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
'itemid' => 0
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$event = $result['event'];
|
|
$this->assertEquals($user->id, $event['userid']);
|
|
$this->assertEquals($formdata['eventtype'], $event['eventtype']);
|
|
$this->assertEquals($formdata['name'], $event['name']);
|
|
}
|
|
|
|
/**
|
|
* A user without the moodle/calendar:manageownentries capability at the
|
|
* system context should not be able to create a user event.
|
|
*/
|
|
public function test_submit_create_update_form_create_user_event_no_permission() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$roleid = $generator->create_role();
|
|
$context = \context_system::instance();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'user',
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$this->expectException('moodle_exception');
|
|
|
|
external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A user with the moodle/calendar:manageentries capability at the
|
|
* site course context should be able to create a site event.
|
|
*/
|
|
public function test_submit_create_update_form_create_site_event() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$context = context_system::instance();
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'site',
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
'itemid' => 0
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$event = $result['event'];
|
|
$this->assertEquals($user->id, $event['userid']);
|
|
$this->assertEquals($formdata['eventtype'], $event['eventtype']);
|
|
$this->assertEquals($formdata['name'], $event['name']);
|
|
}
|
|
|
|
/**
|
|
* A user without the moodle/calendar:manageentries capability at the
|
|
* site course context should not be able to create a site event.
|
|
*/
|
|
public function test_submit_create_update_form_create_site_event_no_permission() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$context = context_course::instance(SITEID);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'site',
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$this->assertTrue($result['validationerror']);
|
|
}
|
|
|
|
/**
|
|
* A user that has the moodle/calendar:manageentries in a course that they
|
|
* are enrolled in should be able to create a course event in that course.
|
|
*/
|
|
public function test_submit_create_update_form_create_course_event() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'course',
|
|
'courseid' => $course->id,
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
'itemid' => 0,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$event = $result['event'];
|
|
$this->assertEquals($user->id, $event['userid']);
|
|
$this->assertEquals($formdata['eventtype'], $event['eventtype']);
|
|
$this->assertEquals($formdata['name'], $event['name']);
|
|
$this->assertEquals($formdata['courseid'], $event['course']['id']);
|
|
}
|
|
|
|
/**
|
|
* A user without the moodle/calendar:manageentries capability in a course
|
|
* that they are enrolled in should not be able to create a course event in that course.
|
|
*/
|
|
public function test_submit_create_update_form_create_course_event_no_permission() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'course',
|
|
'courseid' => $course->id,
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$this->assertTrue($result['validationerror']);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able to create an event for a course that they are
|
|
* not enrolled in.
|
|
*/
|
|
public function test_submit_create_update_form_create_course_event_not_enrolled() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$course2 = $generator->create_course();
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'course',
|
|
'courseid' => $course2->id, // Not enrolled.
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$this->assertTrue($result['validationerror']);
|
|
}
|
|
|
|
/**
|
|
* A user should be able to create an event for a group that they are a member of in
|
|
* a course in which they are enrolled and have the moodle/calendar:manageentries capability.
|
|
*/
|
|
public function test_submit_create_update_form_create_group_event_group_member_manage_course() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$group = $generator->create_group(array('courseid' => $course->id));
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'group',
|
|
'groupid' => $group->id,
|
|
'groupcourseid' => $course->id,
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
'itemid' => 0
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
$generator->create_group_member(['groupid' => $group->id, 'userid' => $user->id]);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$event = $result['event'];
|
|
$this->assertEquals($user->id, $event['userid']);
|
|
$this->assertEquals($formdata['eventtype'], $event['eventtype']);
|
|
$this->assertEquals($formdata['name'], $event['name']);
|
|
$this->assertEquals($group->id, $event['groupid']);
|
|
}
|
|
|
|
/**
|
|
* A user should be able to create an event for a group that they are a member of in
|
|
* a course in which they are enrolled and have the moodle/calendar:managegroupentries capability.
|
|
*/
|
|
public function test_submit_create_update_form_create_group_event_group_member_manage_group_entries() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$group = $generator->create_group(array('courseid' => $course->id));
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'group',
|
|
'groupid' => $group->id,
|
|
'groupcourseid' => $course->id,
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
'itemid' => 0
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
$generator->create_group_member(['groupid' => $group->id, 'userid' => $user->id]);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context, true);
|
|
assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$event = $result['event'];
|
|
$this->assertEquals($user->id, $event['userid']);
|
|
$this->assertEquals($formdata['eventtype'], $event['eventtype']);
|
|
$this->assertEquals($formdata['name'], $event['name']);
|
|
$this->assertEquals($group->id, $event['groupid']);
|
|
}
|
|
|
|
/**
|
|
* A user should be able to create an event for any group in a course in which
|
|
* they are enrolled and have the moodle/site:accessallgroups capability.
|
|
*/
|
|
public function test_submit_create_update_form_create_group_event_access_all_groups() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$group = $generator->create_group(array('courseid' => $course->id));
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'group',
|
|
'groupid' => $group->id,
|
|
'groupcourseid' => $course->id,
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
'itemid' => 0
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$event = $result['event'];
|
|
$this->assertEquals($user->id, $event['userid']);
|
|
$this->assertEquals($formdata['eventtype'], $event['eventtype']);
|
|
$this->assertEquals($formdata['name'], $event['name']);
|
|
$this->assertEquals($group->id, $event['groupid']);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able to create an event for any group that they are not a
|
|
* member of in a course in which they are enrolled but don't have the
|
|
* moodle/site:accessallgroups capability.
|
|
*/
|
|
public function test_submit_create_update_form_create_group_event_non_member_no_permission() {
|
|
$generator = $this->getDataGenerator();
|
|
$user = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$group = $generator->create_group(array('courseid' => $course->id));
|
|
$context = context_course::instance($course->id);
|
|
$roleid = $generator->create_role();
|
|
$timestart = new DateTime();
|
|
$interval = new DateInterval("P1D"); // One day.
|
|
$timedurationuntil = new DateTime();
|
|
$timedurationuntil->add($interval);
|
|
$formdata = [
|
|
'id' => 0,
|
|
'userid' => $user->id,
|
|
'modulename' => '',
|
|
'instance' => 0,
|
|
'visible' => 1,
|
|
'name' => 'Test',
|
|
'timestart' => [
|
|
'day' => $timestart->format('j'),
|
|
'month' => $timestart->format('n'),
|
|
'year' => $timestart->format('Y'),
|
|
'hour' => $timestart->format('G'),
|
|
'minute' => 0,
|
|
],
|
|
'eventtype' => 'group',
|
|
'groupid' => $group->id,
|
|
'groupcourseid' => $course->id,
|
|
'description' => [
|
|
'text' => '',
|
|
'format' => 1,
|
|
],
|
|
'location' => 'Test',
|
|
'duration' => 1,
|
|
'timedurationuntil' => [
|
|
'day' => $timedurationuntil->format('j'),
|
|
'month' => $timedurationuntil->format('n'),
|
|
'year' => $timedurationuntil->format('Y'),
|
|
'hour' => $timedurationuntil->format('G'),
|
|
'minute' => 0,
|
|
]
|
|
];
|
|
|
|
$formdata = \core_calendar\local\event\forms\create::mock_generate_submit_keys($formdata);
|
|
$querystring = http_build_query($formdata, '', '&');
|
|
|
|
$generator->enrol_user($user->id, $course->id, 'student');
|
|
$generator->role_assign($roleid, $user->id, $context->id);
|
|
|
|
assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
|
|
assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true);
|
|
|
|
$user->ignoresesskey = true;
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($user);
|
|
|
|
$result = external_api::clean_returnvalue(
|
|
core_calendar_external::submit_create_update_form_returns(),
|
|
core_calendar_external::submit_create_update_form($querystring)
|
|
);
|
|
|
|
$this->assertTrue($result['validationerror']);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able load the calendar monthly view for a course they cannot access.
|
|
*/
|
|
public function test_get_calendar_monthly_view_no_course_permission() {
|
|
global $USER;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$generator = $this->getDataGenerator();
|
|
$user1 = $generator->create_user();
|
|
$user2 = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$generator->enrol_user($user1->id, $course->id, 'student');
|
|
$name = 'Course Event (course' . $course->id . ')';
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
|
|
|
|
$timestart = new DateTime();
|
|
// Admin can load the course.
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_monthly_view_returns(),
|
|
core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'),
|
|
$course->id, null, false, true)
|
|
);
|
|
$this->assertEquals($data['courseid'], $course->id);
|
|
// User enrolled in the course can load the course calendar.
|
|
$this->setUser($user1);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_monthly_view_returns(),
|
|
core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'),
|
|
$course->id, null, false, true)
|
|
);
|
|
$this->assertEquals($data['courseid'], $course->id);
|
|
// User not enrolled in the course cannot load the course calendar.
|
|
$this->setUser($user2);
|
|
$this->expectException('require_login_exception');
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_monthly_view_returns(),
|
|
core_calendar_external::get_calendar_monthly_view($timestart->format('Y'), $timestart->format('n'),
|
|
$course->id, null, false, false)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able load the calendar day view for a course they cannot access.
|
|
*/
|
|
public function test_get_calendar_day_view_no_course_permission() {
|
|
global $USER;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$generator = $this->getDataGenerator();
|
|
$user1 = $generator->create_user();
|
|
$user2 = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$generator->enrol_user($user1->id, $course->id, 'student');
|
|
$name = 'Course Event (course' . $course->id . ')';
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
|
|
|
|
$timestart = new DateTime();
|
|
// Admin can load the course.
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_day_view_returns(),
|
|
core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'),
|
|
$timestart->format('j'), $course->id, null)
|
|
);
|
|
$this->assertEquals($data['courseid'], $course->id);
|
|
// User enrolled in the course can load the course calendar.
|
|
$this->setUser($user1);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_day_view_returns(),
|
|
core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'),
|
|
$timestart->format('j'), $course->id, null)
|
|
);
|
|
$this->assertEquals($data['courseid'], $course->id);
|
|
// User not enrolled in the course cannot load the course calendar.
|
|
$this->setUser($user2);
|
|
$this->expectException('require_login_exception');
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_day_view_returns(),
|
|
core_calendar_external::get_calendar_day_view($timestart->format('Y'), $timestart->format('n'),
|
|
$timestart->format('j'), $course->id, null)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able load the calendar upcoming view for a course they cannot access.
|
|
*/
|
|
public function test_get_calendar_upcoming_view_no_course_permission() {
|
|
global $USER;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$generator = $this->getDataGenerator();
|
|
$user1 = $generator->create_user();
|
|
$user2 = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$generator->enrol_user($user1->id, $course->id, 'student');
|
|
$name = 'Course Event (course' . $course->id . ')';
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
|
|
|
|
// Admin can load the course.
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_upcoming_view_returns(),
|
|
core_calendar_external::get_calendar_upcoming_view($course->id, null)
|
|
);
|
|
$this->assertEquals($data['courseid'], $course->id);
|
|
// User enrolled in the course can load the course calendar.
|
|
$this->setUser($user1);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_upcoming_view_returns(),
|
|
core_calendar_external::get_calendar_upcoming_view($course->id, null)
|
|
);
|
|
$this->assertEquals($data['courseid'], $course->id);
|
|
// User not enrolled in the course cannot load the course calendar.
|
|
$this->setUser($user2);
|
|
$this->expectException('require_login_exception');
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_upcoming_view_returns(),
|
|
core_calendar_external::get_calendar_upcoming_view($course->id, null)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able load the calendar event for a course they cannot access.
|
|
*/
|
|
public function test_get_calendar_event_by_id_no_course_permission() {
|
|
global $USER;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$generator = $this->getDataGenerator();
|
|
$user1 = $generator->create_user();
|
|
$user2 = $generator->create_user();
|
|
$course = $generator->create_course();
|
|
$generator->enrol_user($user1->id, $course->id, 'student');
|
|
$name = 'Course Event (course' . $course->id . ')';
|
|
$record = new stdClass();
|
|
$record->courseid = $course->id;
|
|
$courseevent = $this->create_calendar_event($name, $USER->id, 'course', 0, time(), $record);
|
|
|
|
// Admin can load the course event.
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_event_by_id_returns(),
|
|
core_calendar_external::get_calendar_event_by_id($courseevent->id)
|
|
);
|
|
$this->assertEquals($data['event']['id'], $courseevent->id);
|
|
// User enrolled in the course can load the course event.
|
|
$this->setUser($user1);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_event_by_id_returns(),
|
|
core_calendar_external::get_calendar_event_by_id($courseevent->id)
|
|
);
|
|
$this->assertEquals($data['event']['id'], $courseevent->id);
|
|
// User not enrolled in the course cannot load the course event.
|
|
$this->setUser($user2);
|
|
$this->expectException('required_capability_exception');
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_event_by_id_returns(),
|
|
core_calendar_external::get_calendar_event_by_id($courseevent->id)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* A user should not be able load the calendar events for a category they cannot see.
|
|
*/
|
|
public function test_get_calendar_events_hidden_category() {
|
|
global $USER;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$generator = $this->getDataGenerator();
|
|
$user1 = $generator->create_user();
|
|
$category = $generator->create_category(['visible' => 0]);
|
|
$name = 'Category Event (category: ' . $category->id . ')';
|
|
$record = new stdClass();
|
|
$record->categoryid = $category->id;
|
|
$categoryevent = $this->create_calendar_event($name, $USER->id, 'category', 0, time(), $record);
|
|
|
|
$events = [
|
|
'eventids' => [$categoryevent->id]
|
|
];
|
|
$options = [];
|
|
// Admin can load the category event.
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_events_returns(),
|
|
core_calendar_external::get_calendar_events($events, $options)
|
|
);
|
|
$this->assertEquals($data['events'][0]['id'], $categoryevent->id);
|
|
// User with no special permission to see hidden categories will not see the event.
|
|
$this->setUser($user1);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_events_returns(),
|
|
core_calendar_external::get_calendar_events($events, $options)
|
|
);
|
|
$this->assertCount(0, $data['events']);
|
|
$this->assertEquals('nopermissions', $data['warnings'][0]['warningcode']);
|
|
}
|
|
|
|
/**
|
|
* Test get_calendar_access_information for admins.
|
|
*/
|
|
public function test_get_calendar_access_information_for_admins() {
|
|
global $CFG;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
|
|
$CFG->calendar_adminseesall = 1;
|
|
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_access_information_returns(),
|
|
core_calendar_external::get_calendar_access_information()
|
|
);
|
|
$this->assertTrue($data['canmanageownentries']);
|
|
$this->assertTrue($data['canmanagegroupentries']);
|
|
$this->assertTrue($data['canmanageentries']);
|
|
}
|
|
|
|
/**
|
|
* Test get_calendar_access_information for authenticated users.
|
|
*/
|
|
public function test_get_calendar_access_information_for_authenticated_users() {
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($this->getDataGenerator()->create_user());
|
|
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_access_information_returns(),
|
|
core_calendar_external::get_calendar_access_information()
|
|
);
|
|
$this->assertTrue($data['canmanageownentries']);
|
|
$this->assertFalse($data['canmanagegroupentries']);
|
|
$this->assertFalse($data['canmanageentries']);
|
|
}
|
|
|
|
/**
|
|
* Test get_calendar_access_information for student users.
|
|
*/
|
|
public function test_get_calendar_access_information_for_student_users() {
|
|
global $DB;
|
|
$this->resetAfterTest(true);
|
|
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$role = $DB->get_record('role', array('shortname' => 'student'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
|
|
$this->setUser($user);
|
|
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_access_information_returns(),
|
|
core_calendar_external::get_calendar_access_information($course->id)
|
|
);
|
|
$this->assertTrue($data['canmanageownentries']);
|
|
$this->assertFalse($data['canmanagegroupentries']);
|
|
$this->assertFalse($data['canmanageentries']);
|
|
}
|
|
|
|
/**
|
|
* Test get_calendar_access_information for teacher users.
|
|
*/
|
|
public function test_get_calendar_access_information_for_teacher_users() {
|
|
global $DB;
|
|
$this->resetAfterTest(true);
|
|
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course(['groupmode' => 1]);
|
|
$role = $DB->get_record('role', array('shortname' => 'editingteacher'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
$this->getDataGenerator()->create_group(['courseid' => $course->id]);
|
|
|
|
$this->setUser($user);
|
|
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_calendar_access_information_returns(),
|
|
core_calendar_external::get_calendar_access_information($course->id)
|
|
);
|
|
$this->assertTrue($data['canmanageownentries']);
|
|
$this->assertTrue($data['canmanagegroupentries']);
|
|
$this->assertTrue($data['canmanageentries']);
|
|
}
|
|
|
|
/**
|
|
* Test get_allowed_event_types for admins.
|
|
*/
|
|
public function test_get_allowed_event_types_for_admins() {
|
|
global $CFG;
|
|
$this->resetAfterTest(true);
|
|
$this->setAdminUser();
|
|
$CFG->calendar_adminseesall = 1;
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_allowed_event_types_returns(),
|
|
core_calendar_external::get_allowed_event_types()
|
|
);
|
|
$this->assertEquals(['user', 'site', 'course', 'category'], $data['allowedeventtypes']);
|
|
}
|
|
/**
|
|
* Test get_allowed_event_types for authenticated users.
|
|
*/
|
|
public function test_get_allowed_event_types_for_authenticated_users() {
|
|
$this->resetAfterTest(true);
|
|
$this->setUser($this->getDataGenerator()->create_user());
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_allowed_event_types_returns(),
|
|
core_calendar_external::get_allowed_event_types()
|
|
);
|
|
$this->assertEquals(['user'], $data['allowedeventtypes']);
|
|
}
|
|
/**
|
|
* Test get_allowed_event_types for student users.
|
|
*/
|
|
public function test_get_allowed_event_types_for_student_users() {
|
|
global $DB;
|
|
$this->resetAfterTest(true);
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course();
|
|
$role = $DB->get_record('role', array('shortname' => 'student'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
$this->setUser($user);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_allowed_event_types_returns(),
|
|
core_calendar_external::get_allowed_event_types($course->id)
|
|
);
|
|
$this->assertEquals(['user'], $data['allowedeventtypes']);
|
|
}
|
|
/**
|
|
* Test get_allowed_event_types for teacher users.
|
|
*/
|
|
public function test_get_allowed_event_types_for_teacher_users() {
|
|
global $DB;
|
|
$this->resetAfterTest(true);
|
|
$user = $this->getDataGenerator()->create_user();
|
|
$course = $this->getDataGenerator()->create_course(['groupmode' => 1]);
|
|
$role = $DB->get_record('role', array('shortname' => 'editingteacher'));
|
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, $role->id);
|
|
$this->getDataGenerator()->create_group(['courseid' => $course->id]);
|
|
$this->setUser($user);
|
|
$data = external_api::clean_returnvalue(
|
|
core_calendar_external::get_allowed_event_types_returns(),
|
|
core_calendar_external::get_allowed_event_types($course->id)
|
|
);
|
|
$this->assertEquals(['user', 'course', 'group'], $data['allowedeventtypes']);
|
|
}
|
|
}
|
|
|