MDL-33509 forms: Change button type in url resource editing page
[moodle.git] / calendar / tests / local_api_test.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Contains the class containing unit tests for the calendar local API.
19  *
20  * @package    core_calendar
21  * @copyright  2017 Mark Nelson <markn@moodle.com>
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 defined('MOODLE_INTERNAL') || die();
27 require_once(__DIR__ . '/helpers.php');
29 use \core_calendar\local\event\container;
31 /**
32  * Class contaning unit tests for the calendar local API.
33  *
34  * @package    core_calendar
35  * @copyright  2017 Mark Nelson <markn@moodle.com>
36  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37  */
38 class core_calendar_local_api_testcase extends advanced_testcase {
40     /**
41      * Tests set up
42      */
43     protected function setUp() {
44         $this->resetAfterTest();
45     }
47     /**
48      * Create a feedback activity instance and a calendar event for
49      * that instance.
50      *
51      * @param array $feedbackproperties Properties to set on the feedback activity
52      * @param array $eventproperties Properties to set on the calendar event
53      * @return array The feedback activity and the calendar event
54      */
55     protected function create_feedback_activity_and_event(array $feedbackproperties = [], array $eventproperties = []) {
56         $generator = $this->getDataGenerator();
57         $course = $generator->create_course();
58         $mapper = container::get_event_mapper();
59         $feedbackgenerator = $generator->get_plugin_generator('mod_feedback');
60         $feedback = $feedbackgenerator->create_instance(array_merge(
61             ['course' => $course->id],
62             $feedbackproperties
63         ));
65         $event = create_event(array_merge(
66             [
67                 'courseid' => $course->id,
68                 'modulename' => 'feedback',
69                 'instance' => $feedback->id
70             ],
71              $eventproperties
72         ));
73         $event = $mapper->from_legacy_event_to_event($event);
75         return [$feedback, $event];
76     }
78     /**
79      * Requesting calendar events from a given time should return all events with a sort
80      * time at or after the requested time. All events prior to that time should not
81      * be return.
82      *
83      * If there are no events on or after the given time then an empty result set should
84      * be returned.
85      */
86     public function test_get_calendar_action_events_by_timesort_after_time() {
87         $user = $this->getDataGenerator()->create_user();
88         $course = $this->getDataGenerator()->create_course();
89         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
90         $moduleinstance = $generator->create_instance(['course' => $course->id]);
92         $this->getDataGenerator()->enrol_user($user->id, $course->id);
93         $this->resetAfterTest(true);
94         $this->setAdminUser();
96         $params = [
97             'type' => CALENDAR_EVENT_TYPE_ACTION,
98             'courseid' => $course->id,
99             'modulename' => 'assign',
100             'instance' => $moduleinstance->id,
101             'userid' => $user->id,
102             'eventtype' => 'user',
103             'repeats' => 0,
104             'timestart' => 1,
105         ];
107         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
108         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
109         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
110         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
111         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
112         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
113         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
114         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
116         $this->setUser($user);
117         $result = \core_calendar\local\api::get_action_events_by_timesort(5);
119         $this->assertCount(4, $result);
120         $this->assertEquals('Event 5', $result[0]->get_name());
121         $this->assertEquals('Event 6', $result[1]->get_name());
122         $this->assertEquals('Event 7', $result[2]->get_name());
123         $this->assertEquals('Event 8', $result[3]->get_name());
125         $result = \core_calendar\local\api::get_action_events_by_timesort(9);
127         $this->assertEmpty($result);
128     }
130     /**
131      * Requesting calendar events before a given time should return all events with a sort
132      * time at or before the requested time (inclusive). All events after that time
133      * should not be returned.
134      *
135      * If there are no events before the given time then an empty result set should be
136      * returned.
137      */
138     public function test_get_calendar_action_events_by_timesort_before_time() {
139         $user = $this->getDataGenerator()->create_user();
140         $course = $this->getDataGenerator()->create_course();
141         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
142         $moduleinstance = $generator->create_instance(['course' => $course->id]);
144         $this->getDataGenerator()->enrol_user($user->id, $course->id);
145         $this->resetAfterTest(true);
146         $this->setAdminUser();
148         $params = [
149             'type' => CALENDAR_EVENT_TYPE_ACTION,
150             'courseid' => $course->id,
151             'modulename' => 'assign',
152             'instance' => $moduleinstance->id,
153             'userid' => 1,
154             'eventtype' => 'user',
155             'repeats' => 0,
156             'timestart' => 1,
157         ];
159         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 2]));
160         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 3]));
161         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 4]));
162         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 5]));
163         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 6]));
164         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 7]));
165         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 8]));
166         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 9]));
168         $this->setUser($user);
169         $result = \core_calendar\local\api::get_action_events_by_timesort(null, 5);
171         $this->assertCount(4, $result);
172         $this->assertEquals('Event 1', $result[0]->get_name());
173         $this->assertEquals('Event 2', $result[1]->get_name());
174         $this->assertEquals('Event 3', $result[2]->get_name());
175         $this->assertEquals('Event 4', $result[3]->get_name());
177         $result = \core_calendar\local\api::get_action_events_by_timesort(null, 1);
179         $this->assertEmpty($result);
180     }
182     /**
183      * Requesting calendar events within a given time range should return all events with
184      * a sort time between the lower and upper time bound (inclusive).
185      *
186      * If there are no events in the given time range then an empty result set should be
187      * returned.
188      */
189     public function test_get_calendar_action_events_by_timesort_time_range() {
190         $user = $this->getDataGenerator()->create_user();
191         $course = $this->getDataGenerator()->create_course();
192         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
193         $moduleinstance = $generator->create_instance(['course' => $course->id]);
195         $this->getDataGenerator()->enrol_user($user->id, $course->id);
196         $this->resetAfterTest(true);
197         $this->setAdminUser();
199         $params = [
200             'type' => CALENDAR_EVENT_TYPE_ACTION,
201             'courseid' => $course->id,
202             'modulename' => 'assign',
203             'instance' => $moduleinstance->id,
204             'userid' => 1,
205             'eventtype' => 'user',
206             'repeats' => 0,
207             'timestart' => 1,
208         ];
210         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
211         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
212         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
213         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
214         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
215         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
216         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
217         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
219         $this->setUser($user);
220         $result = \core_calendar\local\api::get_action_events_by_timesort(3, 6);
222         $this->assertCount(4, $result);
223         $this->assertEquals('Event 3', $result[0]->get_name());
224         $this->assertEquals('Event 4', $result[1]->get_name());
225         $this->assertEquals('Event 5', $result[2]->get_name());
226         $this->assertEquals('Event 6', $result[3]->get_name());
228         $result = \core_calendar\local\api::get_action_events_by_timesort(10, 15);
230         $this->assertEmpty($result);
231     }
233     /**
234      * Requesting calendar events within a given time range and a limit and offset should return
235      * the number of events up to the given limit value that have a sort time between the lower
236      * and uppper time bound (inclusive) where the result set is shifted by the offset value.
237      *
238      * If there are no events in the given time range then an empty result set should be
239      * returned.
240      */
241     public function test_get_calendar_action_events_by_timesort_time_limit_offset() {
242         $user = $this->getDataGenerator()->create_user();
243         $course = $this->getDataGenerator()->create_course();
244         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
245         $moduleinstance = $generator->create_instance(['course' => $course->id]);
247         $this->getDataGenerator()->enrol_user($user->id, $course->id);
248         $this->resetAfterTest(true);
249         $this->setAdminUser();
251         $params = [
252             'type' => CALENDAR_EVENT_TYPE_ACTION,
253             'courseid' => $course->id,
254             'modulename' => 'assign',
255             'instance' => $moduleinstance->id,
256             'userid' => 1,
257             'eventtype' => 'user',
258             'repeats' => 0,
259             'timestart' => 1,
260         ];
262         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
263         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
264         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
265         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
266         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
267         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
268         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
269         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
271         $this->setUser($user);
272         $result = \core_calendar\local\api::get_action_events_by_timesort(2, 7, $event3->id, 2);
274         $this->assertCount(2, $result);
275         $this->assertEquals('Event 4', $result[0]->get_name());
276         $this->assertEquals('Event 5', $result[1]->get_name());
278         $result = \core_calendar\local\api::get_action_events_by_timesort(2, 7, $event5->id, 2);
280         $this->assertCount(2, $result);
281         $this->assertEquals('Event 6', $result[0]->get_name());
282         $this->assertEquals('Event 7', $result[1]->get_name());
284         $result = \core_calendar\local\api::get_action_events_by_timesort(2, 7, $event7->id, 2);
286         $this->assertEmpty($result);
287     }
289     /**
290      * Requesting calendar events from a given course and time should return all
291      * events with a sort time at or after the requested time. All events prior
292      * to that time should not be return.
293      *
294      * If there are no events on or after the given time then an empty result set should
295      * be returned.
296      */
297     public function test_get_calendar_action_events_by_course_after_time() {
298         $user = $this->getDataGenerator()->create_user();
299         $course1 = $this->getDataGenerator()->create_course();
300         $course2 = $this->getDataGenerator()->create_course();
301         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
302         $moduleinstance1 = $generator->create_instance(['course' => $course1->id]);
303         $moduleinstance2 = $generator->create_instance(['course' => $course2->id]);
305         $this->getDataGenerator()->enrol_user($user->id, $course1->id);
306         $this->getDataGenerator()->enrol_user($user->id, $course2->id);
307         $this->resetAfterTest(true);
308         $this->setUser($user);
310         $params = [
311             'type' => CALENDAR_EVENT_TYPE_ACTION,
312             'modulename' => 'assign',
313             'instance' => $moduleinstance1->id,
314             'userid' => $user->id,
315             'courseid' => $course1->id,
316             'eventtype' => 'user',
317             'repeats' => 0,
318             'timestart' => 1,
319         ];
321         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
322         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
323         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
324         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
325         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
326         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
327         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
328         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
330         $params['courseid'] = $course2->id;
331         $params['instance'] = $moduleinstance2->id;
332         $event9 = create_event(array_merge($params, ['name' => 'Event 9', 'timesort' => 1]));
333         $event10 = create_event(array_merge($params, ['name' => 'Event 10', 'timesort' => 2]));
334         $event11 = create_event(array_merge($params, ['name' => 'Event 11', 'timesort' => 3]));
335         $event12 = create_event(array_merge($params, ['name' => 'Event 12', 'timesort' => 4]));
336         $event13 = create_event(array_merge($params, ['name' => 'Event 13', 'timesort' => 5]));
337         $event14 = create_event(array_merge($params, ['name' => 'Event 14', 'timesort' => 6]));
338         $event15 = create_event(array_merge($params, ['name' => 'Event 15', 'timesort' => 7]));
339         $event16 = create_event(array_merge($params, ['name' => 'Event 16', 'timesort' => 8]));
341         $result = \core_calendar\local\api::get_action_events_by_course($course1, 5);
343         $this->assertCount(4, $result);
344         $this->assertEquals('Event 5', $result[0]->get_name());
345         $this->assertEquals('Event 6', $result[1]->get_name());
346         $this->assertEquals('Event 7', $result[2]->get_name());
347         $this->assertEquals('Event 8', $result[3]->get_name());
349         $result = \core_calendar\local\api::get_action_events_by_course($course1, 9);
351         $this->assertEmpty($result);
352     }
354     /**
355      * Requesting calendar events for a course and before a given time should return
356      * all events with a sort time at or before the requested time (inclusive). All
357      * events after that time should not be returned.
358      *
359      * If there are no events before the given time then an empty result set should be
360      * returned.
361      */
362     public function test_get_calendar_action_events_by_course_before_time() {
363         $user = $this->getDataGenerator()->create_user();
364         $course1 = $this->getDataGenerator()->create_course();
365         $course2 = $this->getDataGenerator()->create_course();
366         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
367         $moduleinstance1 = $generator->create_instance(['course' => $course1->id]);
368         $moduleinstance2 = $generator->create_instance(['course' => $course2->id]);
370         $this->getDataGenerator()->enrol_user($user->id, $course1->id);
371         $this->getDataGenerator()->enrol_user($user->id, $course2->id);
372         $this->resetAfterTest(true);
373         $this->setUser($user);
375         $params = [
376             'type' => CALENDAR_EVENT_TYPE_ACTION,
377             'modulename' => 'assign',
378             'instance' => $moduleinstance1->id,
379             'userid' => $user->id,
380             'courseid' => $course1->id,
381             'eventtype' => 'user',
382             'repeats' => 0,
383             'timestart' => 1,
384         ];
386         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 2]));
387         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 3]));
388         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 4]));
389         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 5]));
390         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 6]));
391         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 7]));
392         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 8]));
393         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 9]));
395         $params['courseid'] = $course2->id;
396         $params['instance'] = $moduleinstance2->id;
397         $event9 = create_event(array_merge($params, ['name' => 'Event 9', 'timesort' => 2]));
398         $event10 = create_event(array_merge($params, ['name' => 'Event 10', 'timesort' => 3]));
399         $event11 = create_event(array_merge($params, ['name' => 'Event 11', 'timesort' => 4]));
400         $event12 = create_event(array_merge($params, ['name' => 'Event 12', 'timesort' => 5]));
401         $event13 = create_event(array_merge($params, ['name' => 'Event 13', 'timesort' => 6]));
402         $event14 = create_event(array_merge($params, ['name' => 'Event 14', 'timesort' => 7]));
403         $event15 = create_event(array_merge($params, ['name' => 'Event 15', 'timesort' => 8]));
404         $event16 = create_event(array_merge($params, ['name' => 'Event 16', 'timesort' => 9]));
406         $result = \core_calendar\local\api::get_action_events_by_course($course1, null, 5);
408         $this->assertCount(4, $result);
409         $this->assertEquals('Event 1', $result[0]->get_name());
410         $this->assertEquals('Event 2', $result[1]->get_name());
411         $this->assertEquals('Event 3', $result[2]->get_name());
412         $this->assertEquals('Event 4', $result[3]->get_name());
414         $result = \core_calendar\local\api::get_action_events_by_course($course1, null, 1);
416         $this->assertEmpty($result);
417     }
419     /**
420      * Requesting calendar events for a course and within a given time range should
421      * return all events with a sort time between the lower and upper time bound
422      * (inclusive).
423      *
424      * If there are no events in the given time range then an empty result set should be
425      * returned.
426      */
427     public function test_get_calendar_action_events_by_course_time_range() {
428         $user = $this->getDataGenerator()->create_user();
429         $course1 = $this->getDataGenerator()->create_course();
430         $course2 = $this->getDataGenerator()->create_course();
431         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
432         $moduleinstance1 = $generator->create_instance(['course' => $course1->id]);
433         $moduleinstance2 = $generator->create_instance(['course' => $course2->id]);
435         $this->getDataGenerator()->enrol_user($user->id, $course1->id);
436         $this->getDataGenerator()->enrol_user($user->id, $course2->id);
437         $this->resetAfterTest(true);
438         $this->setUser($user);
440         $params = [
441             'type' => CALENDAR_EVENT_TYPE_ACTION,
442             'modulename' => 'assign',
443             'instance' => $moduleinstance1->id,
444             'userid' => $user->id,
445             'courseid' => $course1->id,
446             'eventtype' => 'user',
447             'repeats' => 0,
448             'timestart' => 1,
449         ];
451         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
452         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
453         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
454         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
455         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
456         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
457         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
458         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
460         $params['courseid'] = $course2->id;
461         $params['instance'] = $moduleinstance2->id;
462         $event9 = create_event(array_merge($params, ['name' => 'Event 9', 'timesort' => 1]));
463         $event10 = create_event(array_merge($params, ['name' => 'Event 10', 'timesort' => 2]));
464         $event11 = create_event(array_merge($params, ['name' => 'Event 11', 'timesort' => 3]));
465         $event12 = create_event(array_merge($params, ['name' => 'Event 12', 'timesort' => 4]));
466         $event13 = create_event(array_merge($params, ['name' => 'Event 13', 'timesort' => 5]));
467         $event14 = create_event(array_merge($params, ['name' => 'Event 14', 'timesort' => 6]));
468         $event15 = create_event(array_merge($params, ['name' => 'Event 15', 'timesort' => 7]));
469         $event16 = create_event(array_merge($params, ['name' => 'Event 16', 'timesort' => 8]));
471         $result = \core_calendar\local\api::get_action_events_by_course($course1, 3, 6);
473         $this->assertCount(4, $result);
474         $this->assertEquals('Event 3', $result[0]->get_name());
475         $this->assertEquals('Event 4', $result[1]->get_name());
476         $this->assertEquals('Event 5', $result[2]->get_name());
477         $this->assertEquals('Event 6', $result[3]->get_name());
479         $result = \core_calendar\local\api::get_action_events_by_course($course1, 10, 15);
481         $this->assertEmpty($result);
482     }
484     /**
485      * Requesting calendar events for a course and within a given time range and a limit
486      * and offset should return the number of events up to the given limit value that have
487      * a sort time between the lower and uppper time bound (inclusive) where the result
488      * set is shifted by the offset value.
489      *
490      * If there are no events in the given time range then an empty result set should be
491      * returned.
492      */
493     public function test_get_calendar_action_events_by_course_time_limit_offset() {
494         $user = $this->getDataGenerator()->create_user();
495         $course1 = $this->getDataGenerator()->create_course();
496         $course2 = $this->getDataGenerator()->create_course();
497         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
498         $moduleinstance1 = $generator->create_instance(['course' => $course1->id]);
499         $moduleinstance2 = $generator->create_instance(['course' => $course2->id]);
501         $this->getDataGenerator()->enrol_user($user->id, $course1->id);
502         $this->getDataGenerator()->enrol_user($user->id, $course2->id);
503         $this->resetAfterTest(true);
504         $this->setUser($user);
506         $params = [
507             'type' => CALENDAR_EVENT_TYPE_ACTION,
508             'modulename' => 'assign',
509             'instance' => $moduleinstance1->id,
510             'userid' => $user->id,
511             'courseid' => $course1->id,
512             'eventtype' => 'user',
513             'repeats' => 0,
514             'timestart' => 1,
515         ];
517         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
518         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
519         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
520         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
521         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
522         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
523         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
524         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
526         $params['courseid'] = $course2->id;
527         $params['instance'] = $moduleinstance2->id;
528         $event9 = create_event(array_merge($params, ['name' => 'Event 9', 'timesort' => 1]));
529         $event10 = create_event(array_merge($params, ['name' => 'Event 10', 'timesort' => 2]));
530         $event11 = create_event(array_merge($params, ['name' => 'Event 11', 'timesort' => 3]));
531         $event12 = create_event(array_merge($params, ['name' => 'Event 12', 'timesort' => 4]));
532         $event13 = create_event(array_merge($params, ['name' => 'Event 13', 'timesort' => 5]));
533         $event14 = create_event(array_merge($params, ['name' => 'Event 14', 'timesort' => 6]));
534         $event15 = create_event(array_merge($params, ['name' => 'Event 15', 'timesort' => 7]));
535         $event16 = create_event(array_merge($params, ['name' => 'Event 16', 'timesort' => 8]));
537         $result = \core_calendar\local\api::get_action_events_by_course($course1, 2, 7, $event3->id, 2);
539         $this->assertCount(2, $result);
540         $this->assertEquals('Event 4', $result[0]->get_name());
541         $this->assertEquals('Event 5', $result[1]->get_name());
543         $result = \core_calendar\local\api::get_action_events_by_course($course1, 2, 7, $event5->id, 2);
545         $this->assertCount(2, $result);
546         $this->assertEquals('Event 6', $result[0]->get_name());
547         $this->assertEquals('Event 7', $result[1]->get_name());
549         $result = \core_calendar\local\api::get_action_events_by_course($course1, 2, 7, $event7->id, 2);
551         $this->assertEmpty($result);
552     }
554     /**
555      * Test that get_action_events_by_courses will return a list of events for each
556      * course you provided as long as the user is enrolled in the course.
557      */
558     public function test_get_action_events_by_courses() {
559         $user = $this->getDataGenerator()->create_user();
560         $course1 = $this->getDataGenerator()->create_course();
561         $course2 = $this->getDataGenerator()->create_course();
562         $course3 = $this->getDataGenerator()->create_course();
563         $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
564         $moduleinstance1 = $generator->create_instance(['course' => $course1->id]);
565         $moduleinstance2 = $generator->create_instance(['course' => $course2->id]);
566         $moduleinstance3 = $generator->create_instance(['course' => $course3->id]);
568         $this->getDataGenerator()->enrol_user($user->id, $course1->id);
569         $this->getDataGenerator()->enrol_user($user->id, $course2->id);
570         $this->getDataGenerator()->enrol_user($user->id, $course3->id);
571         $this->resetAfterTest(true);
572         $this->setUser($user);
574         $params = [
575             'type' => CALENDAR_EVENT_TYPE_ACTION,
576             'modulename' => 'assign',
577             'instance' => $moduleinstance1->id,
578             'userid' => $user->id,
579             'courseid' => $course1->id,
580             'eventtype' => 'user',
581             'repeats' => 0,
582             'timestart' => 1,
583         ];
585         $event1 = create_event(array_merge($params, ['name' => 'Event 1', 'timesort' => 1]));
586         $event2 = create_event(array_merge($params, ['name' => 'Event 2', 'timesort' => 2]));
588         $params['courseid'] = $course2->id;
589         $params['instance'] = $moduleinstance2->id;
590         $event3 = create_event(array_merge($params, ['name' => 'Event 3', 'timesort' => 3]));
591         $event4 = create_event(array_merge($params, ['name' => 'Event 4', 'timesort' => 4]));
592         $event5 = create_event(array_merge($params, ['name' => 'Event 5', 'timesort' => 5]));
594         $params['courseid'] = $course3->id;
595         $params['instance'] = $moduleinstance3->id;
596         $event6 = create_event(array_merge($params, ['name' => 'Event 6', 'timesort' => 6]));
597         $event7 = create_event(array_merge($params, ['name' => 'Event 7', 'timesort' => 7]));
598         $event8 = create_event(array_merge($params, ['name' => 'Event 8', 'timesort' => 8]));
599         $event9 = create_event(array_merge($params, ['name' => 'Event 9', 'timesort' => 9]));
601         $result = \core_calendar\local\api::get_action_events_by_courses([], 1);
603         $this->assertEmpty($result);
605         $result = \core_calendar\local\api::get_action_events_by_courses([$course1], 3);
607         $this->assertEmpty($result[$course1->id]);
609         $result = \core_calendar\local\api::get_action_events_by_courses([$course1], 1);
611         $this->assertCount(2, $result[$course1->id]);
612         $this->assertEquals('Event 1', $result[$course1->id][0]->get_name());
613         $this->assertEquals('Event 2', $result[$course1->id][1]->get_name());
615         $result = \core_calendar\local\api::get_action_events_by_courses([$course1, $course2], 1);
617         $this->assertCount(2, $result[$course1->id]);
618         $this->assertEquals('Event 1', $result[$course1->id][0]->get_name());
619         $this->assertEquals('Event 2', $result[$course1->id][1]->get_name());
620         $this->assertCount(3, $result[$course2->id]);
621         $this->assertEquals('Event 3', $result[$course2->id][0]->get_name());
622         $this->assertEquals('Event 4', $result[$course2->id][1]->get_name());
623         $this->assertEquals('Event 5', $result[$course2->id][2]->get_name());
625         $result = \core_calendar\local\api::get_action_events_by_courses([$course1, $course2], 2, 4);
627         $this->assertCount(1, $result[$course1->id]);
628         $this->assertEquals('Event 2', $result[$course1->id][0]->get_name());
629         $this->assertCount(2, $result[$course2->id]);
630         $this->assertEquals('Event 3', $result[$course2->id][0]->get_name());
631         $this->assertEquals('Event 4', $result[$course2->id][1]->get_name());
633         $result = \core_calendar\local\api::get_action_events_by_courses([$course1, $course2, $course3], 1, null, 1);
635         $this->assertCount(1, $result[$course1->id]);
636         $this->assertEquals('Event 1', $result[$course1->id][0]->get_name());
637         $this->assertCount(1, $result[$course2->id]);
638         $this->assertEquals('Event 3', $result[$course2->id][0]->get_name());
639         $this->assertCount(1, $result[$course3->id]);
640         $this->assertEquals('Event 6', $result[$course3->id][0]->get_name());
641     }
643     /**
644      * Test that the get_legacy_events() function only returns activity events that are enabled.
645      */
646     public function test_get_legacy_events_with_disabled_module() {
647         global $DB;
649         $this->setAdminUser();
651         $course = $this->getDataGenerator()->create_course();
653         $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
654         $assigninstance = $assigngenerator->create_instance(['course' => $course->id]);
656         $lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
657         $lessoninstance = $lessongenerator->create_instance(['course' => $course->id]);
658         $student = $this->getDataGenerator()->create_user();
659         $this->getDataGenerator()->enrol_user($student->id, $course->id, 'student');
660         $this->setUser($student);
661         $events = [
662             [
663                 'name' => 'Start of assignment',
664                 'description' => '',
665                 'format' => 1,
666                 'courseid' => $course->id,
667                 'groupid' => 0,
668                 'userid' => 2,
669                 'modulename' => 'assign',
670                 'instance' => $assigninstance->id,
671                 'eventtype' => 'due',
672                 'timestart' => time(),
673                 'timeduration' => 86400,
674                 'visible' => 1
675             ], [
676                 'name' => 'Start of lesson',
677                 'description' => '',
678                 'format' => 1,
679                 'courseid' => $course->id,
680                 'groupid' => 0,
681                 'userid' => 2,
682                 'modulename' => 'lesson',
683                 'instance' => $lessoninstance->id,
684                 'eventtype' => 'end',
685                 'timestart' => time(),
686                 'timeduration' => 86400,
687                 'visible' => 1
688             ]
689         ];
690         foreach ($events as $event) {
691             calendar_event::create($event, false);
692         }
693         $timestart = time() - 60;
694         $timeend = time() + 60;
696         // Get all events.
697         $events = calendar_get_legacy_events($timestart, $timeend, true, 0, true);
698         $this->assertCount(2, $events);
700         // Disable the lesson module.
701         $modulerecord = $DB->get_record('modules', ['name' => 'lesson']);
702         $modulerecord->visible = 0;
703         $DB->update_record('modules', $modulerecord);
705         // Check that we only return the assign event.
706         $events = calendar_get_legacy_events($timestart, $timeend, true, 0, true);
707         $this->assertCount(1, $events);
708         $event = reset($events);
709         $this->assertEquals('assign', $event->modulename);
710     }
712     /**
713      * Test for \core_calendar\local\api::get_legacy_events() when there are user and group overrides.
714      */
715     public function test_get_legacy_events_with_overrides() {
716         $generator = $this->getDataGenerator();
718         $course = $generator->create_course();
720         $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
721         if (!isset($params['course'])) {
722             $params['course'] = $course->id;
723         }
725         $instance = $plugingenerator->create_instance($params);
727         // Create users.
728         $useroverridestudent = $generator->create_user();
729         $group1student = $generator->create_user();
730         $group2student = $generator->create_user();
731         $group12student = $generator->create_user();
732         $nogroupstudent = $generator->create_user();
734         // Enrol users.
735         $generator->enrol_user($useroverridestudent->id, $course->id, 'student');
736         $generator->enrol_user($group1student->id, $course->id, 'student');
737         $generator->enrol_user($group2student->id, $course->id, 'student');
738         $generator->enrol_user($group12student->id, $course->id, 'student');
739         $generator->enrol_user($nogroupstudent->id, $course->id, 'student');
741         // Create groups.
742         $group1 = $generator->create_group(['courseid' => $course->id]);
743         $group2 = $generator->create_group(['courseid' => $course->id]);
745         // Add members to groups.
746         $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group1student->id]);
747         $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group2student->id]);
748         $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group12student->id]);
749         $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group12student->id]);
750         $now = time();
752         // Events with the same module name, instance and event type.
753         $events = [
754             [
755                 'name' => 'Assignment 1 due date',
756                 'description' => '',
757                 'format' => 0,
758                 'courseid' => $course->id,
759                 'groupid' => 0,
760                 'userid' => 2,
761                 'modulename' => 'assign',
762                 'instance' => $instance->id,
763                 'eventtype' => 'due',
764                 'timestart' => $now,
765                 'timeduration' => 0,
766                 'visible' => 1
767             ], [
768                 'name' => 'Assignment 1 due date - User override',
769                 'description' => '',
770                 'format' => 1,
771                 'courseid' => 0,
772                 'groupid' => 0,
773                 'userid' => $useroverridestudent->id,
774                 'modulename' => 'assign',
775                 'instance' => $instance->id,
776                 'eventtype' => 'due',
777                 'timestart' => $now + 86400,
778                 'timeduration' => 0,
779                 'visible' => 1,
780                 'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY
781             ], [
782                 'name' => 'Assignment 1 due date - Group A override',
783                 'description' => '',
784                 'format' => 1,
785                 'courseid' => $course->id,
786                 'groupid' => $group1->id,
787                 'userid' => 2,
788                 'modulename' => 'assign',
789                 'instance' => $instance->id,
790                 'eventtype' => 'due',
791                 'timestart' => $now + (2 * 86400),
792                 'timeduration' => 0,
793                 'visible' => 1,
794                 'priority' => 1,
795             ], [
796                 'name' => 'Assignment 1 due date - Group B override',
797                 'description' => '',
798                 'format' => 1,
799                 'courseid' => $course->id,
800                 'groupid' => $group2->id,
801                 'userid' => 2,
802                 'modulename' => 'assign',
803                 'instance' => $instance->id,
804                 'eventtype' => 'due',
805                 'timestart' => $now + (3 * 86400),
806                 'timeduration' => 0,
807                 'visible' => 1,
808                 'priority' => 2,
809             ],
810         ];
812         foreach ($events as $event) {
813             calendar_event::create($event, false);
814         }
816         $timestart = $now - 100;
817         $timeend = $now + (3 * 86400);
818         $groups = [$group1->id, $group2->id];
820         // Get user override events.
821         $this->setUser($useroverridestudent);
822         $events = calendar_get_legacy_events($timestart, $timeend, $useroverridestudent->id, $groups, $course->id);
823         $this->assertCount(1, $events);
824         $event = reset($events);
825         $this->assertEquals('Assignment 1 due date - User override', $event->name);
827         // Get event for user with override but with the timestart and timeend parameters only covering the original event.
828         $events = calendar_get_legacy_events($timestart, $now, $useroverridestudent->id, $groups, $course->id);
829         $this->assertCount(0, $events);
831         // Get events for user that does not belong to any group and has no user override events.
832         $this->setUser($nogroupstudent);
833         $events = calendar_get_legacy_events($timestart, $timeend, $nogroupstudent->id, $groups, $course->id);
834         $this->assertCount(1, $events);
835         $event = reset($events);
836         $this->assertEquals('Assignment 1 due date', $event->name);
838         // Get events for user that belongs to groups A and B and has no user override events.
839         $this->setUser($group12student);
840         $events = calendar_get_legacy_events($timestart, $timeend, $group12student->id, $groups, $course->id);
841         $this->assertCount(1, $events);
842         $event = reset($events);
843         $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
845         // Get events for user that belongs to group A and has no user override events.
846         $this->setUser($group1student);
847         $events = calendar_get_legacy_events($timestart, $timeend, $group1student->id, $groups, $course->id);
848         $this->assertCount(1, $events);
849         $event = reset($events);
850         $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
852         // Add repeating events.
853         $repeatingevents = [
854             [
855                 'name' => 'Repeating site event',
856                 'description' => '',
857                 'format' => 1,
858                 'courseid' => SITEID,
859                 'groupid' => 0,
860                 'userid' => 2,
861                 'repeatid' => $event->id,
862                 'modulename' => '0',
863                 'instance' => 0,
864                 'eventtype' => 'site',
865                 'timestart' => $now + 86400,
866                 'timeduration' => 0,
867                 'visible' => 1,
868             ],
869             [
870                 'name' => 'Repeating site event',
871                 'description' => '',
872                 'format' => 1,
873                 'courseid' => SITEID,
874                 'groupid' => 0,
875                 'userid' => 2,
876                 'repeatid' => $event->id,
877                 'modulename' => '0',
878                 'instance' => 0,
879                 'eventtype' => 'site',
880                 'timestart' => $now + (2 * 86400),
881                 'timeduration' => 0,
882                 'visible' => 1,
883             ],
884         ];
886         foreach ($repeatingevents as $event) {
887             calendar_event::create($event, false);
888         }
890         // Make sure repeating events are not filtered out.
891         $events = calendar_get_legacy_events($timestart, $timeend, true, true, true);
892         $this->assertCount(3, $events);
893     }
895     /**
896      * Setting the start date on the calendar event should update the date
897      * of the event but should leave the time of day unchanged.
898      */
899     public function test_update_event_start_day_updates_date() {
900         $generator = $this->getDataGenerator();
901         $user = $generator->create_user();
902         $roleid = $generator->create_role();
903         $context = \context_system::instance();
904         $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
905         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
906         $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
907         $mapper = container::get_event_mapper();
909         $generator->role_assign($roleid, $user->id, $context->id);
910         assign_capability('moodle/calendar:manageownentries', CAP_ALLOW, $roleid, $context, true);
912         $this->setUser($user);
913         $this->resetAfterTest(true);
915         $event = create_event([
916             'name' => 'Test event',
917             'userid' => $user->id,
918             'eventtype' => 'user',
919             'repeats' => 0,
920             'timestart' => $originalstarttime->getTimestamp(),
921         ]);
922         $event = $mapper->from_legacy_event_to_event($event);
924         $newEvent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
925         $actual = $newEvent->get_times()->get_start_time();
927         $this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
928     }
930     /**
931      * A user should not be able to update the start date of the event
932      * that they don't have the capabilities to modify.
933      */
934     public function test_update_event_start_day_no_permission() {
935         $generator = $this->getDataGenerator();
936         $user = $generator->create_user();
937         $roleid = $generator->create_role();
938         $context = \context_system::instance();
939         $originalstarttime = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
940         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
941         $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
942         $mapper = container::get_event_mapper();
944         $generator->role_assign($roleid, $user->id, $context->id);
946         $this->setUser($user);
947         $this->resetAfterTest(true);
949         $event = create_event([
950             'name' => 'Test event',
951             'userid' => $user->id,
952             'eventtype' => 'user',
953             'repeats' => 0,
954             'timestart' => $originalstarttime->getTimestamp(),
955         ]);
956         $event = $mapper->from_legacy_event_to_event($event);
958         assign_capability('moodle/calendar:manageownentries', CAP_PROHIBIT, $roleid, $context, true);
959         $this->expectException('moodle_exception');
960         $newEvent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
961     }
963     /**
964      * Updating the start day of an event with no maximum cutoff should
965      * update the corresponding activity property.
966      *
967      * Note: This test uses the feedback activity because it requires
968      * module callbacks to be in place to test.
969      */
970     public function test_update_event_start_day_activity_event_no_max() {
971         global $CFG, $DB;
972         require_once($CFG->dirroot . '/mod/feedback/lib.php');
974         $this->resetAfterTest(true);
975         $this->setAdminUser();
976         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
977         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
978         $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
979         list($feedback, $event) = $this->create_feedback_activity_and_event(
980             [
981                 'timeopen' => $timeopen->getTimestamp(),
982                 'timeclose' => 0
983             ],
984             [
985                 'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
986                 'timestart' => $timeopen->getTimestamp()
987             ]
988         );
989         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
990         $actual = $newevent->get_times()->get_start_time();
991         $feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
993         $this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
994         $this->assertEquals($expected->getTimestamp(), $feedback->timeopen);
995     }
997     /**
998      * Updating the start day of an event belonging to an activity to a value
999      * less than the maximum cutoff should update the corresponding activity
1000      * property.
1001      *
1002      * Note: This test uses the feedback activity because it requires
1003      * module callbacks to be in place to test.
1004      */
1005     public function test_update_event_start_day_activity_event_less_than_max() {
1006         global $CFG, $DB;
1007         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1009         $this->resetAfterTest(true);
1010         $this->setAdminUser();
1011         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1012         $timeclose = new DateTimeImmutable('2019-01-1T15:00:00+08:00');
1013         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1014         $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1015         list($feedback, $event) = $this->create_feedback_activity_and_event(
1016             [
1017                 'timeopen' => $timeopen->getTimestamp(),
1018                 'timeclose' => $timeclose->getTimestamp()
1019             ],
1020             [
1021                 'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
1022                 'timestart' => $timeopen->getTimestamp()
1023             ]
1024         );
1026         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1027         $actual = $newevent->get_times()->get_start_time();
1028         $feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
1030         $this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
1031         $this->assertEquals($expected->getTimestamp(), $feedback->timeopen);
1032     }
1034     /**
1035      * Updating the start day of an event belonging to an activity to a value
1036      * equal to the maximum cutoff should update the corresponding activity
1037      * property.
1038      *
1039      * Note: This test uses the feedback activity because it requires
1040      * module callbacks to be in place to test.
1041      */
1042     public function test_update_event_start_day_activity_event_equal_to_max() {
1043         global $CFG, $DB;
1044         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1046         $this->resetAfterTest(true);
1047         $this->setAdminUser();
1048         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1049         $timeclose = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1050         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1051         list($feedback, $event) = $this->create_feedback_activity_and_event(
1052             [
1053                 'timeopen' => $timeopen->getTimestamp(),
1054                 'timeclose' => $timeclose->getTimestamp(),
1055             ],
1056             [
1057                 'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
1058                 'timestart' => $timeopen->getTimestamp()
1059             ]
1060         );
1062         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1063         $actual = $newevent->get_times()->get_start_time();
1064         $feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
1066         $this->assertEquals($timeclose->getTimestamp(), $actual->getTimestamp());
1067         $this->assertEquals($timeclose->getTimestamp(), $feedback->timeopen);
1068     }
1070     /**
1071      * Updating the start day of an event belonging to an activity to a value
1072      * after the maximum cutoff should not update the corresponding activity
1073      * property. Instead it should throw an exception.
1074      *
1075      * Note: This test uses the feedback activity because it requires
1076      * module callbacks to be in place to test.
1077      */
1078     public function test_update_event_start_day_activity_event_after_max() {
1079         global $CFG, $DB;
1080         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1082         $this->resetAfterTest(true);
1083         $this->setAdminUser();
1084         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1085         $timeclose = new DateTimeImmutable('2017-02-2T15:00:00+08:00');
1086         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1087         list($feedback, $event) = $this->create_feedback_activity_and_event(
1088             [
1089                 'timeopen' => $timeopen->getTimestamp(),
1090                 'timeclose' => $timeclose->getTimestamp(),
1091             ],
1092             [
1093                 'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
1094                 'timestart' => $timeopen->getTimestamp()
1095             ]
1096         );
1098         $this->expectException('moodle_exception');
1099         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1100     }
1102     /**
1103      * Updating the start day of an event with no minimum cutoff should
1104      * update the corresponding activity property.
1105      *
1106      * Note: This test uses the feedback activity because it requires
1107      * module callbacks to be in place to test.
1108      */
1109     public function test_update_event_start_day_activity_event_no_min() {
1110         global $CFG, $DB;
1111         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1113         $this->resetAfterTest(true);
1114         $this->setAdminUser();
1115         $timeclose = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1116         $newstartdate = new DateTimeImmutable('2016-02-2T10:00:00+08:00');
1117         $expected = new DateTimeImmutable('2016-02-2T15:00:00+08:00');
1118         list($feedback, $event) = $this->create_feedback_activity_and_event(
1119             [
1120                 'timeopen' => 0,
1121                 'timeclose' => $timeclose->getTimestamp()
1122             ],
1123             [
1124                 'eventtype' => FEEDBACK_EVENT_TYPE_OPEN,
1125                 'timestart' => $timeclose->getTimestamp()
1126             ]
1127         );
1129         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1130         $actual = $newevent->get_times()->get_start_time();
1131         $feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
1133         $this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
1134         $this->assertEquals($expected->getTimestamp(), $feedback->timeopen);
1135     }
1137     /**
1138      * Updating the start day of an event belonging to an activity to a value
1139      * greater than the minimum cutoff should update the corresponding activity
1140      * property.
1141      *
1142      * Note: This test uses the feedback activity because it requires
1143      * module callbacks to be in place to test.
1144      */
1145     public function test_update_event_start_day_activity_event_greater_than_min() {
1146         global $CFG, $DB;
1147         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1149         $this->resetAfterTest(true);
1150         $this->setAdminUser();
1151         $timeopen = new DateTimeImmutable('2016-01-1T15:00:00+08:00');
1152         $timeclose = new DateTimeImmutable('2019-01-1T15:00:00+08:00');
1153         $newstartdate = new DateTimeImmutable('2018-02-2T10:00:00+08:00');
1154         $expected = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1155         list($feedback, $event) = $this->create_feedback_activity_and_event(
1156             [
1157                 'timeopen' => $timeopen->getTimestamp(),
1158                 'timeclose' => $timeclose->getTimestamp()
1159             ],
1160             [
1161                 'eventtype' => FEEDBACK_EVENT_TYPE_CLOSE,
1162                 'timestart' => $timeclose->getTimestamp()
1163             ]
1164         );
1166         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1167         $actual = $newevent->get_times()->get_start_time();
1168         $feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
1170         $this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
1171         $this->assertEquals($expected->getTimestamp(), $feedback->timeclose);
1172     }
1174     /**
1175      * Updating the start day of an event belonging to an activity to a value
1176      * equal to the minimum cutoff should update the corresponding activity
1177      * property.
1178      *
1179      * Note: This test uses the feedback activity because it requires
1180      * module callbacks to be in place to test.
1181      */
1182     public function test_update_event_start_day_activity_event_equal_to_min() {
1183         global $CFG, $DB;
1184         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1186         $this->resetAfterTest(true);
1187         $this->setAdminUser();
1188         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1189         $timeclose = new DateTimeImmutable('2018-02-2T15:00:00+08:00');
1190         $newstartdate = new DateTimeImmutable('2017-01-1T10:00:00+08:00');
1191         $expected = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1192         list($feedback, $event) = $this->create_feedback_activity_and_event(
1193             [
1194                 'timeopen' => $timeopen->getTimestamp(),
1195                 'timeclose' => $timeclose->getTimestamp(),
1196             ],
1197             [
1198                 'eventtype' => FEEDBACK_EVENT_TYPE_CLOSE,
1199                 'timestart' => $timeclose->getTimestamp()
1200             ]
1201         );
1203         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1204         $actual = $newevent->get_times()->get_start_time();
1205         $feedback = $DB->get_record('feedback', ['id' => $feedback->id]);
1207         $this->assertEquals($expected->getTimestamp(), $actual->getTimestamp());
1208         $this->assertEquals($expected->getTimestamp(), $feedback->timeclose);
1209     }
1211     /**
1212      * Updating the start day of an event belonging to an activity to a value
1213      * before the minimum cutoff should not update the corresponding activity
1214      * property. Instead it should throw an exception.
1215      *
1216      * Note: This test uses the feedback activity because it requires
1217      * module callbacks to be in place to test.
1218      */
1219     public function test_update_event_start_day_activity_event_before_min() {
1220         global $CFG, $DB;
1221         require_once($CFG->dirroot . '/mod/feedback/lib.php');
1223         $this->resetAfterTest(true);
1224         $this->setAdminUser();
1225         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1226         $timeclose = new DateTimeImmutable('2017-02-2T15:00:00+08:00');
1227         $newstartdate = new DateTimeImmutable('2016-02-2T10:00:00+08:00');
1228         list($feedback, $event) = $this->create_feedback_activity_and_event(
1229             [
1230                 'timeopen' => $timeopen->getTimestamp(),
1231                 'timeclose' => $timeclose->getTimestamp(),
1232             ],
1233             [
1234                 'eventtype' => FEEDBACK_EVENT_TYPE_CLOSE,
1235                 'timestart' => $timeclose->getTimestamp()
1236             ]
1237         );
1239         $this->expectException('moodle_exception');
1240         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1241     }
1243     /**
1244      * Updating the start day of an overridden event belonging to an activity
1245      * should result in an exception. This is to prevent the drag and drop
1246      * of override events.
1247      *
1248      * Note: This test uses the quiz activity because it requires
1249      * module callbacks to be in place and override event support to test.
1250      */
1251     public function test_update_event_start_day_activity_event_override() {
1252         global $CFG, $DB;
1253         require_once($CFG->dirroot . '/calendar/lib.php');
1254         require_once($CFG->dirroot . '/mod/quiz/lib.php');
1256         $this->resetAfterTest(true);
1257         $this->setAdminUser();
1258         $mapper = container::get_event_mapper();
1259         $timeopen = new DateTimeImmutable('2017-01-1T15:00:00+08:00');
1260         $newstartdate = new DateTimeImmutable('2016-02-2T10:00:00+08:00');
1261         $generator = $this->getDataGenerator();
1262         $user = $generator->create_user();
1263         $course = $generator->create_course();
1264         $quizgenerator = $generator->get_plugin_generator('mod_quiz');
1265         $quiz = $quizgenerator->create_instance([
1266             'course' => $course->id,
1267             'timeopen' => $timeopen->getTimestamp(),
1268         ]);
1269         $event = create_event([
1270             'courseid' => $course->id,
1271             'userid' => $user->id,
1272             'modulename' => 'quiz',
1273             'instance' => $quiz->id,
1274             'eventtype' => QUIZ_EVENT_TYPE_OPEN,
1275             'timestart' => $timeopen->getTimestamp()
1276         ]);
1277         $event = $mapper->from_legacy_event_to_event($event);
1278         $record = (object) [
1279             'quiz' => $quiz->id,
1280             'userid' => $user->id
1281         ];
1283         $DB->insert_record('quiz_overrides', $record);
1285         $this->expectException('moodle_exception');
1286         $newevent = \core_calendar\local\api::update_event_start_day($event, $newstartdate);
1287     }