Proyectos de Subversion Moodle

Rev

Ir a la última revisión | | 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
/**
20
 * Class contaning unit tests for the calendar lib.
21
 *
22
 * @package    core_calendar
23
 * @copyright  2017 Mark Nelson <markn@moodle.com>
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
class lib_test extends \advanced_testcase {
27
 
28
    /**
29
     * Load required test libraries
30
     */
31
    public static function setUpBeforeClass(): void {
32
        global $CFG;
33
 
34
        require_once("{$CFG->dirroot}/calendar/tests/helpers.php");
35
    }
36
 
37
    /**
38
     * Tests set up
39
     */
40
    protected function setUp(): void {
41
        $this->resetAfterTest();
42
    }
43
 
44
    /**
45
     * Test that the get_events() function only returns activity events that are enabled.
46
     */
47
    public function test_get_events_with_disabled_module() {
48
        global $DB;
49
        $this->setAdminUser();
50
        $generator = $this->getDataGenerator();
51
        $course = $generator->create_course();
52
        $assigngenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
53
        $assigninstance = $assigngenerator->create_instance(['course' => $course->id]);
54
        $lessongenerator = $this->getDataGenerator()->get_plugin_generator('mod_lesson');
55
        $lessoninstance = $lessongenerator->create_instance(['course' => $course->id]);
56
        $student = $generator->create_user();
57
        $generator->enrol_user($student->id, $course->id, 'student');
58
        $this->setUser($student);
59
        $events = [
60
            [
61
                'name' => 'Start of assignment',
62
                'description' => '',
63
                'location' => 'Test',
64
                'format' => 1,
65
                'courseid' => $course->id,
66
                'groupid' => 0,
67
                'userid' => 2,
68
                'modulename' => 'assign',
69
                'instance' => $assigninstance->id,
70
                'eventtype' => 'due',
71
                'timestart' => time(),
72
                'timeduration' => 86400,
73
                'visible' => 1
74
            ], [
75
                'name' => 'Start of lesson',
76
                'description' => '',
77
                'location' => 'Test',
78
                'format' => 1,
79
                'courseid' => $course->id,
80
                'groupid' => 0,
81
                'userid' => 2,
82
                'modulename' => 'lesson',
83
                'instance' => $lessoninstance->id,
84
                'eventtype' => 'end',
85
                'timestart' => time(),
86
                'timeduration' => 86400,
87
                'visible' => 1
88
            ]
89
        ];
90
        foreach ($events as $event) {
91
            \calendar_event::create($event, false);
92
        }
93
        $timestart = time() - 60;
94
        $timeend = time() + 60;
95
        // Get all events.
96
        $events = calendar_get_events($timestart, $timeend, true, 0, true);
97
        $this->assertCount(2, $events);
98
        // Disable the lesson module.
99
        $modulerecord = $DB->get_record('modules', ['name' => 'lesson']);
100
        $modulerecord->visible = 0;
101
        $DB->update_record('modules', $modulerecord);
102
        // Check that we only return the assign event.
103
        $events = calendar_get_events($timestart, $timeend, true, 0, true);
104
        $this->assertCount(1, $events);
105
        $event = reset($events);
106
        $this->assertEquals('assign', $event->modulename);
107
    }
108
 
109
    public function test_get_course_cached() {
110
        // Setup some test courses.
111
        $course1 = $this->getDataGenerator()->create_course();
112
        $course2 = $this->getDataGenerator()->create_course();
113
        $course3 = $this->getDataGenerator()->create_course();
114
 
115
        // Load courses into cache.
116
        $coursecache = null;
117
        calendar_get_course_cached($coursecache, $course1->id);
118
        calendar_get_course_cached($coursecache, $course2->id);
119
        calendar_get_course_cached($coursecache, $course3->id);
120
 
121
        // Verify the cache.
122
        $this->assertArrayHasKey($course1->id, $coursecache);
123
        $cachedcourse1 = $coursecache[$course1->id];
124
        $this->assertEquals($course1->id, $cachedcourse1->id);
125
        $this->assertEquals($course1->shortname, $cachedcourse1->shortname);
126
        $this->assertEquals($course1->fullname, $cachedcourse1->fullname);
127
 
128
        $this->assertArrayHasKey($course2->id, $coursecache);
129
        $cachedcourse2 = $coursecache[$course2->id];
130
        $this->assertEquals($course2->id, $cachedcourse2->id);
131
        $this->assertEquals($course2->shortname, $cachedcourse2->shortname);
132
        $this->assertEquals($course2->fullname, $cachedcourse2->fullname);
133
 
134
        $this->assertArrayHasKey($course3->id, $coursecache);
135
        $cachedcourse3 = $coursecache[$course3->id];
136
        $this->assertEquals($course3->id, $cachedcourse3->id);
137
        $this->assertEquals($course3->shortname, $cachedcourse3->shortname);
138
        $this->assertEquals($course3->fullname, $cachedcourse3->fullname);
139
    }
140
 
141
    /**
142
     * Test the update_subscription() function.
143
     */
144
    public function test_update_subscription() {
145
        $this->resetAfterTest(true);
146
 
147
        $subscription = new \stdClass();
148
        $subscription->eventtype = 'site';
149
        $subscription->name = 'test';
150
        $id = calendar_add_subscription($subscription);
151
 
152
        $subscription = calendar_get_subscription($id);
153
        $subscription->name = 'awesome';
154
        calendar_update_subscription($subscription);
155
        $sub = calendar_get_subscription($id);
156
        $this->assertEquals($subscription->name, $sub->name);
157
 
158
        $subscription = calendar_get_subscription($id);
159
        $subscription->name = 'awesome2';
160
        $subscription->pollinterval = 604800;
161
        calendar_update_subscription($subscription);
162
        $sub = calendar_get_subscription($id);
163
        $this->assertEquals($subscription->name, $sub->name);
164
        $this->assertEquals($subscription->pollinterval, $sub->pollinterval);
165
 
166
        $subscription = new \stdClass();
167
        $subscription->name = 'awesome4';
168
        $this->expectException('coding_exception');
169
        calendar_update_subscription($subscription);
170
    }
171
 
172
    public function test_add_subscription() {
173
        global $DB, $CFG;
174
 
175
        require_once($CFG->dirroot . '/lib/bennu/bennu.inc.php');
176
 
177
        $this->resetAfterTest(true);
178
 
179
        // Test for Microsoft Outlook 2010.
180
        $subscription = new \stdClass();
181
        $subscription->name = 'Microsoft Outlook 2010';
182
        $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
183
        $subscription->eventtype = 'site';
184
        $id = calendar_add_subscription($subscription);
185
 
186
        $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/ms_outlook_2010.ics');
187
        $ical = new \iCalendar();
188
        $ical->unserialize($calendar);
189
        $this->assertEquals($ical->parser_errors, array());
190
 
191
        $sub = calendar_get_subscription($id);
192
        calendar_import_events_from_ical($ical, $sub->id);
193
        $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
194
        $this->assertEquals($count, 1);
195
 
196
        // Test for OSX Yosemite.
197
        $subscription = new \stdClass();
198
        $subscription->name = 'OSX Yosemite';
199
        $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
200
        $subscription->eventtype = 'site';
201
        $id = calendar_add_subscription($subscription);
202
 
203
        $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/osx_yosemite.ics');
204
        $ical = new \iCalendar();
205
        $ical->unserialize($calendar);
206
        $this->assertEquals($ical->parser_errors, array());
207
 
208
        $sub = calendar_get_subscription($id);
209
        calendar_import_events_from_ical($ical, $sub->id);
210
        $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
211
        $this->assertEquals($count, 1);
212
 
213
        // Test for Google Gmail.
214
        $subscription = new \stdClass();
215
        $subscription->name = 'Google Gmail';
216
        $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
217
        $subscription->eventtype = 'site';
218
        $id = calendar_add_subscription($subscription);
219
 
220
        $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/google_gmail.ics');
221
        $ical = new \iCalendar();
222
        $ical->unserialize($calendar);
223
        $this->assertEquals($ical->parser_errors, array());
224
 
225
        $sub = calendar_get_subscription($id);
226
        calendar_import_events_from_ical($ical, $sub->id);
227
        $count = $DB->count_records('event', array('subscriptionid' => $sub->id));
228
        $this->assertEquals($count, 1);
229
 
230
        // Test for ICS file with repeated events.
231
        $subscription = new \stdClass();
232
        $subscription->name = 'Repeated events';
233
        $subscription->importfrom = CALENDAR_IMPORT_FROM_FILE;
234
        $subscription->eventtype = 'site';
235
        $id = calendar_add_subscription($subscription);
236
        $calendar = file_get_contents($CFG->dirroot . '/lib/tests/fixtures/repeated_events.ics');
237
        $ical = new \iCalendar();
238
        $ical->unserialize($calendar);
239
        $this->assertEquals($ical->parser_errors, []);
240
 
241
        $sub = calendar_get_subscription($id);
242
        $output = calendar_import_events_from_ical($ical, $sub->id);
243
        $this->assertArrayHasKey('eventsimported', $output);
244
        $this->assertArrayHasKey('eventsskipped', $output);
245
        $this->assertArrayHasKey('eventsupdated', $output);
246
        $this->assertArrayHasKey('eventsdeleted', $output);
247
        $this->assertEquals(1, $output['eventsimported']);
248
        $this->assertEquals(0, $output['eventsskipped']);
249
        $this->assertEquals(0, $output['eventsupdated']);
250
        $this->assertEquals(0, $output['eventsdeleted']);
251
    }
252
 
253
    /**
254
     * Test for calendar_get_legacy_events() when there are user and group overrides.
255
     */
256
    public function test_get_legacy_events_with_overrides() {
257
        $generator = $this->getDataGenerator();
258
 
259
        $course = $generator->create_course();
260
 
261
        $plugingenerator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
262
        if (!isset($params['course'])) {
263
            $params['course'] = $course->id;
264
        }
265
 
266
        $instance = $plugingenerator->create_instance($params);
267
 
268
        // Create users.
269
        $useroverridestudent = $generator->create_user();
270
        $group1student = $generator->create_user();
271
        $group2student = $generator->create_user();
272
        $group12student = $generator->create_user();
273
        $nogroupstudent = $generator->create_user();
274
 
275
        // Enrol users.
276
        $generator->enrol_user($useroverridestudent->id, $course->id, 'student');
277
        $generator->enrol_user($group1student->id, $course->id, 'student');
278
        $generator->enrol_user($group2student->id, $course->id, 'student');
279
        $generator->enrol_user($group12student->id, $course->id, 'student');
280
        $generator->enrol_user($nogroupstudent->id, $course->id, 'student');
281
 
282
        // Create groups.
283
        $group1 = $generator->create_group(['courseid' => $course->id]);
284
        $group2 = $generator->create_group(['courseid' => $course->id]);
285
 
286
        // Add members to groups.
287
        $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group1student->id]);
288
        $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group2student->id]);
289
        $generator->create_group_member(['groupid' => $group1->id, 'userid' => $group12student->id]);
290
        $generator->create_group_member(['groupid' => $group2->id, 'userid' => $group12student->id]);
291
        $now = time();
292
 
293
        // Events with the same module name, instance and event type.
294
        $events = [
295
            [
296
                'name' => 'Assignment 1 due date',
297
                'description' => '',
298
                'location' => 'Test',
299
                'format' => 0,
300
                'courseid' => $course->id,
301
                'groupid' => 0,
302
                'userid' => 2,
303
                'modulename' => 'assign',
304
                'instance' => $instance->id,
305
                'eventtype' => 'due',
306
                'timestart' => $now,
307
                'timeduration' => 0,
308
                'visible' => 1
309
            ], [
310
                'name' => 'Assignment 1 due date - User override',
311
                'description' => '',
312
                'location' => 'Test',
313
                'format' => 1,
314
                'courseid' => 0,
315
                'groupid' => 0,
316
                'userid' => $useroverridestudent->id,
317
                'modulename' => 'assign',
318
                'instance' => $instance->id,
319
                'eventtype' => 'due',
320
                'timestart' => $now + 86400,
321
                'timeduration' => 0,
322
                'visible' => 1,
323
                'priority' => CALENDAR_EVENT_USER_OVERRIDE_PRIORITY
324
            ], [
325
                'name' => 'Assignment 1 due date - Group A override',
326
                'description' => '',
327
                'location' => 'Test',
328
                'format' => 1,
329
                'courseid' => $course->id,
330
                'groupid' => $group1->id,
331
                'userid' => 2,
332
                'modulename' => 'assign',
333
                'instance' => $instance->id,
334
                'eventtype' => 'due',
335
                'timestart' => $now + (2 * 86400),
336
                'timeduration' => 0,
337
                'visible' => 1,
338
                'priority' => 1,
339
            ], [
340
                'name' => 'Assignment 1 due date - Group B override',
341
                'description' => '',
342
                'location' => 'Test',
343
                'format' => 1,
344
                'courseid' => $course->id,
345
                'groupid' => $group2->id,
346
                'userid' => 2,
347
                'modulename' => 'assign',
348
                'instance' => $instance->id,
349
                'eventtype' => 'due',
350
                'timestart' => $now + (3 * 86400),
351
                'timeduration' => 0,
352
                'visible' => 1,
353
                'priority' => 2,
354
            ],
355
        ];
356
 
357
        foreach ($events as $event) {
358
            \calendar_event::create($event, false);
359
        }
360
 
361
        $timestart = $now - 100;
362
        $timeend = $now + (3 * 86400);
363
        $groups = [$group1->id, $group2->id];
364
 
365
        // Get user override events.
366
        $this->setUser($useroverridestudent);
367
        $events = calendar_get_legacy_events($timestart, $timeend, $useroverridestudent->id, $groups, $course->id);
368
        $this->assertCount(1, $events);
369
        $event = reset($events);
370
        $this->assertEquals('Assignment 1 due date - User override', $event->name);
371
 
372
        // Get event for user with override but with the timestart and timeend parameters only covering the original event.
373
        $events = calendar_get_legacy_events($timestart, $now, $useroverridestudent->id, $groups, $course->id);
374
        $this->assertCount(0, $events);
375
 
376
        // Get events for user that does not belong to any group and has no user override events.
377
        $this->setUser($nogroupstudent);
378
        $events = calendar_get_legacy_events($timestart, $timeend, $nogroupstudent->id, $groups, $course->id);
379
        $this->assertCount(1, $events);
380
        $event = reset($events);
381
        $this->assertEquals('Assignment 1 due date', $event->name);
382
 
383
        // Get events for user that belongs to groups A and B and has no user override events.
384
        $this->setUser($group12student);
385
        $events = calendar_get_legacy_events($timestart, $timeend, $group12student->id, $groups, $course->id);
386
        $this->assertCount(1, $events);
387
        $event = reset($events);
388
        $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
389
 
390
        // Get events for user that belongs to group A and has no user override events.
391
        $this->setUser($group1student);
392
        $events = calendar_get_legacy_events($timestart, $timeend, $group1student->id, $groups, $course->id);
393
        $this->assertCount(1, $events);
394
        $event = reset($events);
395
        $this->assertEquals('Assignment 1 due date - Group A override', $event->name);
396
 
397
        // Add repeating events.
398
        $repeatingevents = [
399
            [
400
                'name' => 'Repeating site event',
401
                'description' => '',
402
                'location' => 'Test',
403
                'format' => 1,
404
                'courseid' => SITEID,
405
                'groupid' => 0,
406
                'userid' => 2,
407
                'repeatid' => $event->id,
408
                'modulename' => '0',
409
                'instance' => 0,
410
                'eventtype' => 'site',
411
                'timestart' => $now + 86400,
412
                'timeduration' => 0,
413
                'visible' => 1,
414
            ],
415
            [
416
                'name' => 'Repeating site event',
417
                'description' => '',
418
                'location' => 'Test',
419
                'format' => 1,
420
                'courseid' => SITEID,
421
                'groupid' => 0,
422
                'userid' => 2,
423
                'repeatid' => $event->id,
424
                'modulename' => '0',
425
                'instance' => 0,
426
                'eventtype' => 'site',
427
                'timestart' => $now + (2 * 86400),
428
                'timeduration' => 0,
429
                'visible' => 1,
430
            ],
431
        ];
432
 
433
        foreach ($repeatingevents as $event) {
434
            \calendar_event::create($event, false);
435
        }
436
 
437
        // Make sure repeating events are not filtered out.
438
        $events = calendar_get_legacy_events($timestart, $timeend, true, true, true);
439
        $this->assertCount(3, $events);
440
    }
441
 
442
    public function test_calendar_get_default_courses() {
443
        global $USER, $CFG;
444
 
445
        $this->resetAfterTest(true);
446
 
447
        $generator = $this->getDataGenerator();
448
        $user = $generator->create_user();
449
        $course1 = $generator->create_course();
450
        $course2 = $generator->create_course();
451
        $course3 = $generator->create_course();
452
        $context = \context_course::instance($course1->id);
453
 
454
        $this->setAdminUser();
455
        $admin = clone $USER;
456
 
457
        $teacher = $generator->create_user();
458
        $generator->enrol_user($teacher->id, $course1->id, 'teacher');
459
        $generator->enrol_user($admin->id, $course1->id, 'teacher');
460
 
461
        $CFG->calendar_adminseesall = false;
462
 
463
        $courses = calendar_get_default_courses();
464
        // Only enrolled in one course.
465
        $this->assertCount(1, $courses);
466
        $courses = calendar_get_default_courses($course2->id);
467
        // Enrolled course + current course.
468
        $this->assertCount(2, $courses);
469
        $CFG->calendar_adminseesall = true;
470
        $courses = calendar_get_default_courses();
471
        // All courses + SITE.
472
        $this->assertCount(4, $courses);
473
        $courses = calendar_get_default_courses($course2->id);
474
        // All courses + SITE.
475
        $this->assertCount(4, $courses);
476
 
477
        $this->setUser($teacher);
478
 
479
        $CFG->calendar_adminseesall = false;
480
 
481
        $courses = calendar_get_default_courses();
482
        // Only enrolled in one course.
483
        $this->assertCount(1, $courses);
484
        $courses = calendar_get_default_courses($course2->id);
485
        // Enrolled course only (ignore current).
486
        $this->assertCount(1, $courses);
487
        // This setting should not affect teachers.
488
        $CFG->calendar_adminseesall = true;
489
        $courses = calendar_get_default_courses();
490
        // Only enrolled in one course.
491
        $this->assertCount(1, $courses);
492
        $courses = calendar_get_default_courses($course2->id);
493
        // Enrolled course only (ignore current).
494
        $this->assertCount(1, $courses);
495
 
496
        // Now, log out and test again.
497
        $this->setUser();
498
 
499
        $CFG->calendar_adminseesall = false;
500
 
501
        $courses = calendar_get_default_courses(null, '*', false, $teacher->id);
502
        // Only enrolled in one course.
503
        $this->assertCount(1, $courses);
504
        $courses = calendar_get_default_courses($course2->id, '*', false, $teacher->id);
505
        // Enrolled course only (ignore current).
506
        $this->assertCount(1, $courses);
507
        // This setting should not affect teachers.
508
        $CFG->calendar_adminseesall = true;
509
        $courses = calendar_get_default_courses(null, '*', false, $teacher->id);
510
        // Only enrolled in one course.
511
        $this->assertCount(1, $courses);
512
        $courses = calendar_get_default_courses($course2->id, '*', false, $teacher->id);
513
        // Enrolled course only (ignore current).
514
        $this->assertCount(1, $courses);
515
 
516
    }
517
 
518
    /**
519
     * Confirm that the skip events flag causes the calendar_get_view function
520
     * to avoid querying for the calendar events.
521
     */
522
    public function test_calendar_get_view_skip_events() {
523
        $this->resetAfterTest(true);
524
        $this->setAdminUser();
525
 
526
        $generator = $this->getDataGenerator();
527
        $user = $generator->create_user();
528
        $skipnavigation = true;
529
        $skipevents = true;
530
        $event = create_event([
531
            'eventtype' => 'user',
532
            'userid' => $user->id
533
        ]);
534
 
535
        $this->setUser($user);
536
        $calendar = \calendar_information::create(time() - 10, SITEID, null);
537
 
538
        list($data, $template) = calendar_get_view($calendar, 'day', $skipnavigation, $skipevents);
539
        $this->assertEmpty($data->events);
540
 
541
        $skipevents = false;
542
        list($data, $template) = calendar_get_view($calendar, 'day', $skipnavigation, $skipevents);
543
 
544
        $this->assertEquals($event->id, $data->events[0]->id);
545
    }
546
 
547
    public function test_calendar_get_allowed_event_types_course() {
548
        $generator = $this->getDataGenerator();
549
        $user = $generator->create_user();
550
        $course1 = $generator->create_course(); // Has capability.
551
        $course2 = $generator->create_course(); // Doesn't have capability.
552
        $course3 = $generator->create_course(); // Not enrolled.
553
        $context1 = \context_course::instance($course1->id);
554
        $context2 = \context_course::instance($course2->id);
555
        $context3 = \context_course::instance($course3->id);
556
        $roleid = $generator->create_role();
557
        $contexts = [$context1, $context2, $context3];
558
        $enrolledcourses = [$course1, $course2];
559
 
560
        foreach ($enrolledcourses as $course) {
561
            $generator->enrol_user($user->id, $course->id, 'student');
562
        }
563
 
564
        foreach ($contexts as $context) {
565
            $generator->role_assign($roleid, $user->id, $context->id);
566
        }
567
 
568
        $this->setUser($user);
569
 
570
        // In general for all courses, they don't have the ability to add course events yet.
571
        $types = calendar_get_allowed_event_types();
572
        $this->assertFalse($types['course']);
573
 
574
        assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context1, true);
575
        assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context2, true);
576
 
577
        // The user only has the correct capability in course 1 so that is the only
578
        // one that should be in the results.
579
        $types = calendar_get_allowed_event_types($course1->id);
580
        $this->assertTrue($types['course']);
581
 
582
        // If calling function without specified course,  there is still a course where they have it.
583
        $types = calendar_get_allowed_event_types();
584
        $this->assertTrue($types['course']);
585
 
586
        assign_capability('moodle/calendar:manageentries', CAP_PROHIBIT, $roleid, $context1, true);
587
 
588
        // The user only now has the correct capability in both course 1 and 2 so we
589
        // expect both to be in the results.
590
        $types = calendar_get_allowed_event_types($course3->id);
591
        $this->assertFalse($types['course']);
592
 
593
        // They now do not have permission in any course.
594
        $types = calendar_get_allowed_event_types();
595
        $this->assertFalse($types['course']);
596
    }
597
 
598
    public function test_calendar_get_allowed_event_types_group_no_acces_to_diff_groups() {
599
        $generator = $this->getDataGenerator();
600
        $user = $generator->create_user();
601
        $course = $generator->create_course();
602
        $context = \context_course::instance($course->id);
603
        $roleid = $generator->create_role();
604
 
605
        $generator->enrol_user($user->id, $course->id, 'student');
606
        $generator->role_assign($roleid, $user->id, $context->id);
607
 
608
        $this->setUser($user);
609
 
610
        assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
611
        assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true);
612
 
613
        // The user has the correct capability in the course but they aren't a member
614
        // of any of the groups and don't have the accessallgroups capability.
615
        $types = calendar_get_allowed_event_types($course->id);
616
        $this->assertTrue($types['course']);
617
        $this->assertFalse($types['group']);
618
 
619
        // Same result applies when not providing a specific course as they are only on one course.
620
        $types = calendar_get_allowed_event_types();
621
        $this->assertTrue($types['course']);
622
        $this->assertFalse($types['group']);
623
    }
624
 
625
    public function test_calendar_get_allowed_event_types_group_no_groups() {
626
        $generator = $this->getDataGenerator();
627
        $user = $generator->create_user();
628
        $course = $generator->create_course();
629
        $context = \context_course::instance($course->id);
630
        $roleid = $generator->create_role();
631
        $generator->enrol_user($user->id, $course->id, 'student');
632
        $generator->role_assign($roleid, $user->id, $context->id);
633
        $this->setUser($user);
634
        assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
635
        // The user has the correct capability in the course but there are
636
        // no groups so we shouldn't see a group type.
637
        $types = calendar_get_allowed_event_types($course->id);
638
        $this->assertTrue($types['course']);
639
        $this->assertFalse($types['group']);
640
 
641
        // Same result applies when not providing a specific course as they are only on one course.
642
        $types = calendar_get_allowed_event_types();
643
        $this->assertTrue($types['course']);
644
        $this->assertFalse($types['group']);
645
    }
646
 
647
    public function test_calendar_get_allowed_event_types_group_access_all_groups() {
648
        $generator = $this->getDataGenerator();
649
        $user = $generator->create_user();
650
        $course1 = $generator->create_course();
651
        $course2 = $generator->create_course();
652
        $generator->create_group(array('courseid' => $course1->id));
653
        $generator->create_group(array('courseid' => $course2->id));
654
        $context1 = \context_course::instance($course1->id);
655
        $context2 = \context_course::instance($course2->id);
656
        $roleid = $generator->create_role();
657
        $generator->enrol_user($user->id, $course1->id, 'student');
658
        $generator->enrol_user($user->id, $course2->id, 'student');
659
        $generator->role_assign($roleid, $user->id, $context1->id);
660
        $generator->role_assign($roleid, $user->id, $context2->id);
661
        $this->setUser($user);
662
        assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context1, true);
663
        assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context2, true);
664
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context1, true);
665
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context2, true);
666
        // The user has the correct capability in the course and has
667
        // the accessallgroups capability.
668
        $types = calendar_get_allowed_event_types($course1->id);
669
        $this->assertTrue($types['group']);
670
 
671
        // Same result applies when not providing a specific course as they are only on one course.
672
        $types = calendar_get_allowed_event_types();
673
        $this->assertTrue($types['group']);
674
    }
675
 
676
    public function test_calendar_get_allowed_event_types_group_no_access_all_groups() {
677
        $generator = $this->getDataGenerator();
678
        $user = $generator->create_user();
679
        $course = $generator->create_course();
680
        $context = \context_course::instance($course->id);
681
        $group1 = $generator->create_group(array('courseid' => $course->id));
682
        $group2 = $generator->create_group(array('courseid' => $course->id));
683
        $roleid = $generator->create_role();
684
        $generator->enrol_user($user->id, $course->id, 'student');
685
        $generator->role_assign($roleid, $user->id, $context->id);
686
        $generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user->id));
687
        $generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user->id));
688
        $this->setUser($user);
689
        assign_capability('moodle/site:accessallgroups', CAP_PROHIBIT, $roleid, $context, true);
690
        // The user has the correct capability in the course but can't access
691
        // groups that they are not a member of.
692
        $types = calendar_get_allowed_event_types($course->id);
693
        $this->assertFalse($types['group']);
694
 
695
        // Same result applies when not providing a specific course as they are only on one course.
696
        $types = calendar_get_allowed_event_types();
697
        $this->assertFalse($types['group']);
698
 
699
        assign_capability('moodle/calendar:manageentries', CAP_ALLOW, $roleid, $context, true);
700
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true);
701
        $types = calendar_get_allowed_event_types($course->id);
702
        $this->assertTrue($types['group']);
703
 
704
        // Same result applies when not providing a specific course as they are only on one course.
705
        $types = calendar_get_allowed_event_types();
706
        $this->assertTrue($types['group']);
707
    }
708
 
709
    public function test_calendar_get_allowed_event_types_group_cap_no_groups() {
710
        $generator = $this->getDataGenerator();
711
        $user = $generator->create_user();
712
        $course = $generator->create_course();
713
        $context = \context_course::instance($course->id);
714
        $roleid = $generator->create_role();
715
        $group = $generator->create_group(['courseid' => $course->id]);
716
        $generator->enrol_user($user->id, $course->id, 'student');
717
        $generator->role_assign($roleid, $user->id, $context->id);
718
        assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
719
 
720
        $this->setUser($user);
721
        $types = calendar_get_allowed_event_types($course->id);
722
        $this->assertFalse($types['course']);
723
        $this->assertFalse($types['group']);
724
 
725
        // Check without specifying a course (same result as user only has one course).
726
        $types = calendar_get_allowed_event_types();
727
        $this->assertFalse($types['course']);
728
        $this->assertFalse($types['group']);
729
    }
730
 
731
    public function test_calendar_get_allowed_event_types_group_cap_has_group() {
732
        $generator = $this->getDataGenerator();
733
        $user = $generator->create_user();
734
        $course = $generator->create_course();
735
        $context = \context_course::instance($course->id);
736
        $roleid = $generator->create_role();
737
        $group = $generator->create_group(['courseid' => $course->id]);
738
        $generator->enrol_user($user->id, $course->id, 'student');
739
        $generator->role_assign($roleid, $user->id, $context->id);
740
        groups_add_member($group, $user);
741
        assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
742
 
743
        $this->setUser($user);
744
        $types = calendar_get_allowed_event_types($course->id);
745
        $this->assertFalse($types['course']);
746
        $this->assertTrue($types['group']);
747
 
748
        // Check without specifying a course (same result as user only has one course).
749
        $types = calendar_get_allowed_event_types();
750
        $this->assertFalse($types['course']);
751
        $this->assertTrue($types['group']);
752
    }
753
 
754
    public function test_calendar_get_allowed_event_types_group_cap_access_all_groups() {
755
        $generator = $this->getDataGenerator();
756
        $user = $generator->create_user();
757
        $course = $generator->create_course();
758
        $context = \context_course::instance($course->id);
759
        $roleid = $generator->create_role();
760
        $group = $generator->create_group(['courseid' => $course->id]);
761
        $generator->enrol_user($user->id, $course->id, 'student');
762
        $generator->role_assign($roleid, $user->id, $context->id);
763
        assign_capability('moodle/calendar:managegroupentries', CAP_ALLOW, $roleid, $context, true);
764
        assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, $context, true);
765
 
766
        $this->setUser($user);
767
        $types = calendar_get_allowed_event_types($course->id);
768
        $this->assertFalse($types['course']);
769
        $this->assertTrue($types['group']);
770
 
771
        // Check without specifying a course (same result as user only has one course).
772
        $types = calendar_get_allowed_event_types();
773
        $this->assertFalse($types['course']);
774
        $this->assertTrue($types['group']);
775
    }
776
 
777
    /**
778
     * This is a setup helper function that create some users, courses, groups and group memberships.
779
     * This is useful to prepare the environment for testing the calendar_set_filters function.
780
     *
781
     * @return array An array of ($users, $courses, $coursegroups)
782
     */
783
    protected function setup_test_calendar_set_filters() {
784
        $generator = $this->getDataGenerator();
785
 
786
        // Create some users.
787
        $users = [];
788
        $users[] = $generator->create_user();
789
        $users[] = $generator->create_user();
790
        $users[] = $generator->create_user();
791
 
792
        // Create some courses.
793
        $courses = [];
794
        $courses[] = $generator->create_course();
795
        $courses[] = $generator->create_course();
796
        $courses[] = $generator->create_course();
797
        $courses[] = $generator->create_course();
798
 
799
        // Create some groups.
800
        $coursegroups = [];
801
        $coursegroups[$courses[0]->id] = [];
802
        $coursegroups[$courses[0]->id][] = $generator->create_group(['courseid' => $courses[0]->id]);
803
        $coursegroups[$courses[0]->id][] = $generator->create_group(['courseid' => $courses[0]->id]);
804
        $coursegroups[$courses[2]->id] = [];
805
        $coursegroups[$courses[2]->id][] = $generator->create_group(['courseid' => $courses[2]->id]);
806
        $coursegroups[$courses[2]->id][] = $generator->create_group(['courseid' => $courses[2]->id]);
807
        $coursegroups[$courses[3]->id] = [];
808
        $coursegroups[$courses[3]->id][] = $generator->create_group(['courseid' => $courses[3]->id]);
809
        $coursegroups[$courses[3]->id][] = $generator->create_group(['courseid' => $courses[3]->id]);
810
 
811
        // Create some enrolments and group memberships.
812
        $generator->enrol_user($users[0]->id, $courses[0]->id, 'student');
813
        $generator->create_group_member(['groupid' => $coursegroups[$courses[0]->id][0]->id, 'userid' => $users[0]->id]);
814
        $generator->enrol_user($users[1]->id, $courses[0]->id, 'student');
815
        $generator->create_group_member(['groupid' => $coursegroups[$courses[0]->id][1]->id, 'userid' => $users[1]->id]);
816
        $generator->enrol_user($users[0]->id, $courses[1]->id, 'student');
817
        $generator->enrol_user($users[0]->id, $courses[2]->id, 'student');
818
 
819
        return array($users, $courses, $coursegroups);
820
    }
821
 
822
    /**
823
     * This function tests calendar_set_filters for the case when user is not logged in.
824
     */
825
    public function test_calendar_set_filters_not_logged_in() {
826
        $this->resetAfterTest();
827
 
828
        list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
829
 
830
        $defaultcourses = calendar_get_default_courses(null, '*', false, $users[0]->id);
831
        list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses);
832
 
833
        $this->assertEqualsCanonicalizing(
834
                [$courses[0]->id, $courses[1]->id, $courses[2]->id, SITEID],
835
                array_values($courseids));
836
        $this->assertFalse($groupids);
837
        $this->assertFalse($userid);
838
    }
839
 
840
    /**
841
     * This function tests calendar_set_filters for the case when no one is logged in, but a user id is provided.
842
     */
843
    public function test_calendar_set_filters_not_logged_in_with_user() {
844
        $this->resetAfterTest();
845
 
846
        list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
847
 
848
        $defaultcourses = calendar_get_default_courses(null, '*', false, $users[1]->id);
849
        list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false, $users[1]);
850
 
851
        $this->assertEquals(array($courses[0]->id, SITEID), array_values($courseids));
852
        $this->assertEquals(array($coursegroups[$courses[0]->id][1]->id), $groupids);
853
        $this->assertEquals($users[1]->id, $userid);
854
 
855
        $defaultcourses = calendar_get_default_courses(null, '*', false, $users[0]->id);
856
        list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false, $users[0]);
857
 
858
        $this->assertEqualsCanonicalizing(
859
                [$courses[0]->id, $courses[1]->id, $courses[2]->id, SITEID],
860
                array_values($courseids));
861
        $this->assertEquals(array($coursegroups[$courses[0]->id][0]->id), $groupids);
862
        $this->assertEquals($users[0]->id, $userid);
863
 
864
    }
865
 
866
    /**
867
     * This function tests calendar_set_filters for the case when user is logged in, but no user id is provided.
868
     */
869
    public function test_calendar_set_filters_logged_in_no_user() {
870
        $this->resetAfterTest();
871
 
872
        list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
873
 
874
        $this->setUser($users[0]);
875
        $defaultcourses = calendar_get_default_courses(null, '*', false, $users[0]->id);
876
        list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false);
877
        $this->assertEqualsCanonicalizing([$courses[0]->id, $courses[1]->id, $courses[2]->id, SITEID], array_values($courseids));
878
        $this->assertEquals(array($coursegroups[$courses[0]->id][0]->id), $groupids);
879
        $this->assertEquals($users[0]->id, $userid);
880
    }
881
 
882
    /**
883
     * This function tests calendar_set_filters for the case when a user is logged in, but another user id is provided.
884
     */
885
    public function test_calendar_set_filters_logged_in_another_user() {
886
        $this->resetAfterTest();
887
 
888
        list($users, $courses, $coursegroups) = $this->setup_test_calendar_set_filters();
889
 
890
        $this->setUser($users[0]);
891
        $defaultcourses = calendar_get_default_courses(null, '*', false, $users[1]->id);
892
        list($courseids, $groupids, $userid) = calendar_set_filters($defaultcourses, false, $users[1]);
893
 
894
        $this->assertEquals(array($courses[0]->id, SITEID), array_values($courseids));
895
        $this->assertEquals(array($coursegroups[$courses[0]->id][1]->id), $groupids);
896
        $this->assertEquals($users[1]->id, $userid);
897
    }
898
 
899
    /**
900
     *  Test for calendar_view_event_allowed for course event types.
901
     */
902
    public function test_calendar_view_event_allowed_course_event() {
903
        global $USER;
904
 
905
        $this->setAdminUser();
906
 
907
        $generator = $this->getDataGenerator();
908
 
909
        // A student in a course.
910
        $student = $generator->create_user();
911
        // Some user not enrolled in any course.
912
        $someuser = $generator->create_user();
913
 
914
        // A course with manual enrolments.
915
        $manualcourse = $generator->create_course();
916
 
917
        // Enrol the student to the manual enrolment course.
918
        $generator->enrol_user($student->id, $manualcourse->id);
919
 
920
        // A course that allows guest access.
921
        $guestcourse = $generator->create_course(
922
            (object)[
923
                'shortname' => 'guestcourse',
924
                'enrol_guest_status_0' => ENROL_INSTANCE_ENABLED,
925
                'enrol_guest_password_0' => ''
926
            ]);
927
 
928
        $manualevent = (object)[
929
            'name' => 'Manual course event',
930
            'description' => '',
931
            'format' => 1,
932
            'categoryid' => 0,
933
            'courseid' => $manualcourse->id,
934
            'groupid' => 0,
935
            'userid' => $USER->id,
936
            'modulename' => 0,
937
            'instance' => 0,
938
            'eventtype' => 'course',
939
            'timestart' => time(),
940
            'timeduration' => 86400,
941
            'visible' => 1
942
        ];
943
        $caleventmanual = \calendar_event::create($manualevent, false);
944
 
945
        // Create a course event for the course with guest access.
946
        $guestevent = clone $manualevent;
947
        $guestevent->name = 'Guest course event';
948
        $guestevent->courseid = $guestcourse->id;
949
        $caleventguest = \calendar_event::create($guestevent, false);
950
 
951
        // Viewing as admin.
952
        $this->assertTrue(calendar_view_event_allowed($caleventmanual));
953
        $this->assertTrue(calendar_view_event_allowed($caleventguest));
954
 
955
        // Viewing as someone enrolled in a course.
956
        $this->setUser($student);
957
        $this->assertTrue(calendar_view_event_allowed($caleventmanual));
958
 
959
        // Viewing as someone not enrolled in any course.
960
        $this->setUser($someuser);
961
        // Viewing as someone not enrolled in a course without guest access on.
962
        $this->assertFalse(calendar_view_event_allowed($caleventmanual));
963
        // Viewing as someone not enrolled in a course with guest access on.
964
        $this->assertTrue(calendar_view_event_allowed($caleventguest));
965
    }
966
 
967
    /**
968
     *  Test for calendar_get_export_token for current user.
969
     */
970
    public function test_calendar_get_export_token_for_current_user() {
971
        global $USER, $DB, $CFG;
972
 
973
        $this->setAdminUser();
974
 
975
        // Get my token.
976
        $authtoken = calendar_get_export_token($USER);
977
        $expected = sha1($USER->id . $DB->get_field('user', 'password', ['id' => $USER->id]) . $CFG->calendar_exportsalt);
978
 
979
        $this->assertEquals($expected, $authtoken);
980
    }
981
 
982
    /**
983
     *  Test for calendar_get_export_token for another user.
984
     */
985
    public function test_calendar_get_export_token_for_another_user() {
986
        global $CFG;
987
 
988
        // Get any user token.
989
        $generator = $this->getDataGenerator();
990
        $user = $generator->create_user();
991
 
992
        // Get other user token.
993
        $authtoken = calendar_get_export_token($user);
994
        $expected = sha1($user->id . $user->password . $CFG->calendar_exportsalt);
995
 
996
        $this->assertEquals($expected, $authtoken);
997
    }
998
 
999
    /**
1000
     *  Test calendar_can_manage_user_event for different users.
1001
     *
1002
     * @covers ::calendar_can_manage_user_event
1003
     */
1004
    public function test_calendar_can_manage_user_event() {
1005
        global $DB, $USER;
1006
        $generator = $this->getDataGenerator();
1007
        $sitecontext = \context_system::instance();
1008
        $this->resetAfterTest();
1009
        $this->setAdminUser();
1010
        $user1 = $generator->create_user();
1011
        $user2 = $generator->create_user();
1012
        $adminevent = create_event([
1013
            'eventtype' => 'user',
1014
            'userid' => $USER->id,
1015
        ]);
1016
 
1017
        $this->setUser($user1);
1018
        $user1event = create_event([
1019
            'name' => 'user1 event',
1020
            'eventtype' => 'user',
1021
            'userid' => $user1->id,
1022
        ]);
1023
        $this->setUser($user2);
1024
        $user2event = create_event([
1025
            'name' => 'user2 event',
1026
            'eventtype' => 'user',
1027
            'userid' => $user2->id,
1028
        ]);
1029
        $this->setUser($user1);
1030
        $result = calendar_can_manage_user_event($user1event);
1031
        $this->assertEquals(true, $result);
1032
        $result = calendar_can_manage_user_event($user2event);
1033
        $this->assertEquals(false, $result);
1034
 
1035
        $sitemanager = $generator->create_user();
1036
 
1037
        $managerroleid = $DB->get_field('role', 'id', ['shortname' => 'manager']);
1038
        role_assign($managerroleid, $sitemanager->id, $sitecontext->id);
1039
 
1040
        $this->setUser($sitemanager);
1041
 
1042
        $result = calendar_can_manage_user_event($user1event);
1043
        $this->assertEquals(true, $result);
1044
        $result = calendar_can_manage_user_event($adminevent);
1045
        $this->assertEquals(false, $result);
1046
    }
1047
 
1048
    /**
1049
     * Data provider for {@see test_calendar_format_event_location}
1050
     *
1051
     * @return array[]
1052
     */
1053
    public function calendar_format_event_location_provider(): array {
1054
        return [
1055
            'Empty' => ['', ''],
1056
            'Text' => ['Barcelona', 'Barcelona'],
1057
            'Link (http)' => ['http://example.com', '<a title=".*" href="http://example.com">http://example.com</a>'],
1058
            'Link (https)' => ['https://example.com', '<a title=".*" href="https://example.com">https://example.com</a>'],
1059
        ];
1060
    }
1061
 
1062
    /**
1063
     * Test formatting event location
1064
     *
1065
     * @param string $location
1066
     * @param string $expectedpattern
1067
     *
1068
     * @covers ::calendar_format_event_location
1069
     * @dataProvider calendar_format_event_location_provider
1070
     */
1071
    public function test_calendar_format_event_location(string $location, string $expectedpattern): void {
1072
        $this->resetAfterTest();
1073
        $this->setAdminUser();
1074
 
1075
        $event = create_event(['location' => $location]);
1076
        $this->assertMatchesRegularExpression("|^({$expectedpattern})$|", calendar_format_event_location($event));
1077
    }
1078
}