Proyectos de Subversion Moodle

Rev

Rev 11 | | Comparar con el anterior | Ultima modificación | Ver Log |

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