Proyectos de Subversion Moodle

Rev

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