Proyectos de Subversion Moodle

Rev

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

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
namespace core_communication;
18
 
19
use communication_matrix\matrix_test_helper_trait;
20
use core_communication\task\add_members_to_room_task;
21
use core_communication\task\create_and_configure_room_task;
22
use core_communication\task\delete_room_task;
23
use core_communication\task\update_room_membership_task;
24
use core_communication\task\update_room_task;
25
use core_communication\processor as communication_processor;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
require_once(__DIR__ . '/../provider/matrix/tests/matrix_test_helper_trait.php');
30
require_once(__DIR__ . '/communication_test_helper_trait.php');
31
 
32
/**
33
 * Test communication hook listeners.
34
 *
35
 * @package    core_communication
36
 * @copyright  2023 Safat Shahin <safat.shahin@moodle.com>
37
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
38
 * @covers     \core_communication\hook_listener
39
 */
1441 ariadna 40
final class hook_listener_test extends \advanced_testcase {
1 efrain 41
 
42
    use communication_test_helper_trait;
43
    use matrix_test_helper_trait;
44
 
45
    public function setUp(): void {
46
        parent::setUp();
47
        $this->resetAfterTest();
48
        $this->setup_communication_configs();
49
        $this->initialise_mock_server();
50
    }
51
 
52
    /**
53
     * Test create_group_communication.
54
     */
55
    public function test_create_update_delete_group_communication(): void {
56
        global $DB;
57
 
58
        $course = $this->get_course(
59
            roomname: 'Test room name',
60
            extrafields: ['groupmode' => SEPARATEGROUPS],
61
        );
62
        $coursecontext = \context_course::instance(courseid: $course->id);
63
        $user1 = $this->getDataGenerator()->create_user();
64
        $user2 = $this->getDataGenerator()->create_user();
65
 
66
        // Enrol user1 as teacher.
67
        $teacherrole = $DB->get_record(
68
            table: 'role',
69
            conditions: ['shortname' => 'manager'],
70
        );
71
        $this->getDataGenerator()->enrol_user(
72
            userid: $user1->id,
73
            courseid: $course->id,
74
        );
75
        role_assign(
76
            roleid: $teacherrole->id,
77
            userid: $user1->id,
78
            contextid: $coursecontext->id,
79
        );
80
 
81
        // Enrol user2 as student.
82
        $studentrole = $DB->get_record('role', ['shortname' => 'student']);
83
        $this->getDataGenerator()->enrol_user(
84
            userid: $user2->id,
85
            courseid: $course->id,
86
        );
87
        role_assign(
88
            roleid: $studentrole->id,
89
            userid: $user2->id,
90
            contextid: $coursecontext->id,
91
        );
92
 
93
        $group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
94
        $context = \context_course::instance($course->id);
95
 
96
        $groupcommunication = helper::load_by_group(
97
            groupid: $group->id,
98
            context: $context,
99
        );
100
        $this->assertInstanceOf(
101
            expected: communication_processor::class,
102
            actual: $groupcommunication->get_processor(),
103
        );
104
 
105
        $this->assertEquals(
106
            expected: $group->id,
107
            actual: $groupcommunication->get_processor()->get_instance_id(),
108
        );
109
 
110
        // Task to create room should be added.
111
        $adhoctask = \core\task\manager::get_adhoc_tasks(create_and_configure_room_task::class);
112
        $this->assertCount(1, $adhoctask);
113
 
114
        // Task to add members to room should not be there as the room is yet to be created.
115
        $adhoctask = \core\task\manager::get_adhoc_tasks(add_members_to_room_task::class);
116
        $this->assertCount(0, $adhoctask);
117
 
118
        // Only users with access to all groups should be added to the room at this point.
119
        $groupcommunicationusers = $groupcommunication->get_processor()->get_all_userids_for_instance();
120
        $this->assertEquals(
121
            expected: [$user1->id],
122
            actual: $groupcommunicationusers,
123
        );
124
 
125
        // Now delete all the ad-hoc tasks.
126
        $DB->delete_records('task_adhoc');
127
 
128
        // Now cann the update group but don't change the group name.
129
        groups_update_group($group);
130
 
131
        // No task should be added as nothing changed.
132
        $adhoctask = \core\task\manager::get_adhoc_tasks(update_room_task::class);
133
        $this->assertCount(0, $adhoctask);
134
 
135
        // Now change the group name.
136
        $group->name = 'Changed group name';
137
        groups_update_group($group);
138
 
139
        // Now one task should be there to update the group room name.
140
        $adhoctask = \core\task\manager::get_adhoc_tasks(update_room_task::class);
141
        $this->assertCount(1, $adhoctask);
142
 
143
        $groupcommunication->reload();
144
        $this->assertEquals(
145
            expected: 'Changed group name (Test room name)',
146
            actual: $groupcommunication->get_processor()->get_room_name(),
147
        );
148
 
149
        // Now delete the group.
150
        groups_delete_group($group->id);
151
 
152
        $adhoctask = \core\task\manager::get_adhoc_tasks(delete_room_task::class);
153
        $this->assertCount(1, $adhoctask);
154
    }
155
 
156
    /**
11 efrain 157
     * Test inactive users are not included when being mapped to a new communication instance.
158
     */
159
    public function test_inactive_users_are_not_mapped_to_new_communication(): void {
160
        // Create a course without a communication provider set.
161
        $course = $this->getDataGenerator()->create_course();
162
 
163
        // Enrol some users that are both active and inactive (suspended).
164
        $user1 = $this->getDataGenerator()->create_user();
165
        $user2 = $this->getDataGenerator()->create_user();
166
        $user3 = $this->getDataGenerator()->create_user();
167
        $user4 = $this->getDataGenerator()->create_user();
168
 
169
        $this->getDataGenerator()->enrol_user(
170
            userid: $user1->id,
171
            courseid: $course->id,
172
            roleidorshortname: 'teacher',
173
        );
174
 
175
        $this->getDataGenerator()->enrol_user(
176
            userid: $user2->id,
177
            courseid: $course->id,
178
            roleidorshortname: 'student',
179
        );
180
 
181
        $this->getDataGenerator()->enrol_user(
182
            userid: $user3->id,
183
            courseid: $course->id,
184
            roleidorshortname: 'teacher',
185
            status: ENROL_USER_SUSPENDED,
186
        );
187
 
188
        $this->getDataGenerator()->enrol_user(
189
            userid: $user4->id,
190
            courseid: $course->id,
191
            roleidorshortname: 'student',
192
            status: ENROL_USER_SUSPENDED,
193
        );
194
 
195
        // Set Matrix as the communication provider and update.
196
        $course->selectedcommunication = 'communication_matrix';
197
        $course->communication_matrixroomname = 'testroom';
198
        update_course($course);
199
 
200
        helper::update_course_communication_instance(
201
            course: $course,
202
            changesincoursecat: false,
203
        );
204
 
205
        // Load the communication instance and check that only the 2 active users are returned.
206
        $communication = helper::load_by_course(
207
            courseid: $course->id,
208
            context: \context_course::instance($course->id),
209
        );
210
 
211
        $userids = $communication->get_processor()->get_all_userids_for_instance();
212
 
213
        $this->assertEquals(
214
            expected: 2,
215
            actual: count($userids),
216
        );
217
 
218
        $this->assertContains(
219
            needle: $user1->id,
220
            haystack: $userids,
221
        );
222
 
223
        $this->assertContains(
224
            needle: $user2->id,
225
            haystack: $userids,
226
        );
227
    }
228
 
229
    /**
230
     * Test inactive users are not included when being mapped to a new communication instance using groups.
231
     */
232
    public function test_inactive_users_are_not_mapped_to_new_group_communication(): void {
233
        // Create a course without a communication provider set.
234
        $course = $this->getDataGenerator()->create_course(
235
            options: ['groupmode' => SEPARATEGROUPS],
236
        );
237
 
238
        // Enrol some users that are both active and inactive (suspended).
239
        $user1 = $this->getDataGenerator()->create_user();
240
        $user2 = $this->getDataGenerator()->create_user();
241
        $user3 = $this->getDataGenerator()->create_user();
242
        $user4 = $this->getDataGenerator()->create_user();
243
 
244
        $this->getDataGenerator()->enrol_user(
245
            userid: $user1->id,
246
            courseid: $course->id,
247
            roleidorshortname: 'teacher',
248
        );
249
 
250
        $this->getDataGenerator()->enrol_user(
251
            userid: $user2->id,
252
            courseid: $course->id,
253
            roleidorshortname: 'student',
254
        );
255
 
256
        $this->getDataGenerator()->enrol_user(
257
            userid: $user3->id,
258
            courseid: $course->id,
259
            roleidorshortname: 'teacher',
260
            status: ENROL_USER_SUSPENDED,
261
        );
262
 
263
        $this->getDataGenerator()->enrol_user(
264
            userid: $user4->id,
265
            courseid: $course->id,
266
            roleidorshortname: 'student',
267
            status: ENROL_USER_SUSPENDED,
268
        );
269
 
270
        // Create a group and add all users to it.
271
        $group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
272
        groups_add_member(
273
            grouporid: $group,
274
            userorid: $user1,
275
        );
276
        groups_add_member(
277
            grouporid: $group,
278
            userorid: $user2,
279
        );
280
        groups_add_member(
281
            grouporid: $group,
282
            userorid: $user3,
283
        );
284
        groups_add_member(
285
            grouporid: $group,
286
            userorid: $user4,
287
        );
288
 
289
        // Set Matrix as the communication provider and update.
290
        $course->selectedcommunication = 'communication_matrix';
291
        $course->communication_matrixroomname = 'testroom';
292
        update_course($course);
293
 
294
        helper::update_group_communication_instances_for_course(
295
            course: $course,
296
            provider: 'communication_matrix',
297
        );
298
 
299
        // Load the communication instance and check that only the 2 active users are returned.
300
        $communication = helper::load_by_group(
301
            groupid: $group->id,
302
            context: \context_course::instance($course->id),
303
        );
304
 
305
        $userids = $communication->get_processor()->get_all_userids_for_instance();
306
 
307
        $this->assertEquals(
308
            expected: 2,
309
            actual: count($userids),
310
        );
311
 
312
        $this->assertContains(
313
            needle: $user1->id,
314
            haystack: $userids,
315
        );
316
 
317
        $this->assertContains(
318
            needle: $user2->id,
319
            haystack: $userids,
320
        );
321
    }
322
 
323
    /**
1 efrain 324
     * Test add_members_to_group_room.
325
     */
326
    public function test_add_members_to_group_room(): void {
327
        global $DB;
328
 
329
        $course = $this->get_course(
330
            extrafields: ['groupmode' => SEPARATEGROUPS],
331
        );
332
        $coursecontext = \context_course::instance(courseid: $course->id);
333
        $user1 = $this->getDataGenerator()->create_user();
334
        $user2 = $this->getDataGenerator()->create_user();
335
 
336
        // Enrol user1 as teacher.
337
        $teacherrole = $DB->get_record(
338
            table: 'role',
339
            conditions: ['shortname' => 'manager'],
340
        );
341
        $this->getDataGenerator()->enrol_user(
342
            userid: $user1->id,
343
            courseid: $course->id,
344
        );
345
        role_assign(
346
            roleid: $teacherrole->id,
347
            userid: $user1->id,
348
            contextid: $coursecontext->id,
349
        );
350
 
351
        // Enrol user2 as student.
352
        $studentrole = $DB->get_record('role', ['shortname' => 'student']);
353
        $this->getDataGenerator()->enrol_user(
354
            userid: $user2->id,
355
            courseid: $course->id,
356
        );
357
        role_assign(
358
            roleid: $studentrole->id,
359
            userid: $user2->id,
360
            contextid: $coursecontext->id,
361
        );
362
 
363
        $group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
364
 
365
        // Now check if the teacher is added to the group room as the teacher has access to all groups.
366
        $context = \context_course::instance($course->id);
367
        $groupcommunication = helper::load_by_group(
368
            groupid: $group->id,
369
            context: $context,
370
        );
371
 
372
        // Now the communication instance should not have the student added yet.
373
        $this->assertNotContains(
374
            needle: $user2->id,
375
            haystack: $groupcommunication->get_processor()->get_all_userids_for_instance(),
376
        );
377
 
378
        groups_add_member(
379
            grouporid: $group,
380
            userorid: $user2,
381
        );
382
 
383
        // Now it should have the student.
384
        $this->assertContains(
385
            needle: $user2->id,
386
            haystack: $groupcommunication->get_processor()->get_all_userids_for_instance(),
387
        );
388
    }
389
 
390
    /**
391
     * Test if the course instances are created properly for course default provider.
392
     */
393
    public function test_course_default_provider(): void {
394
        $defaultprovider = 'communication_matrix';
395
        // Set the default communication for course.
396
        set_config(
397
            name: 'coursecommunicationprovider',
398
            value: $defaultprovider,
399
            plugin: 'moodlecourse',
400
        );
401
 
402
        // Test that the default communication is created for course mode.
403
        $course = $this->get_course();
404
        $coursecontext = \context_course::instance(courseid: $course->id);
405
        $coursecommunication = helper::load_by_course(
406
            courseid: $course->id,
407
            context: $coursecontext,
408
        );
409
        $this->assertEquals(
410
            expected: $defaultprovider,
411
            actual: $coursecommunication->get_provider(),
412
        );
413
        $this->assertEquals(
414
            expected: 'core_course',
415
            actual: $coursecommunication->get_processor()->get_component(),
416
        );
417
        $this->assertEquals(
418
            expected: $course->id,
419
            actual: $coursecommunication->get_processor()->get_instance_id(),
420
        );
421
    }
422
 
423
    /**
424
     * Test update_course_communication.
425
     */
426
    public function test_update_course_communication(): void {
427
        global $DB;
428
 
429
        // Set up the data with course, group, user etc.
430
        $user = $this->getDataGenerator()->create_user();
431
        $course = $this->get_course();
432
        $group = $this->getDataGenerator()->create_group(record: ['courseid' => $course->id]);
433
        $coursecontext = \context_course::instance(courseid: $course->id);
434
        $teacherrole = $DB->get_record(
435
            table: 'role',
436
            conditions: ['shortname' => 'teacher'],
437
        );
438
        $this->getDataGenerator()->enrol_user(
439
            userid: $user->id,
440
            courseid: $course->id,
441
        );
442
        role_assign(
443
            roleid: $teacherrole->id,
444
            userid: $user->id,
445
            contextid: $coursecontext->id,
446
        );
447
        groups_add_member(
448
            grouporid: $group->id,
449
            userorid: $user->id,
450
        );
451
 
452
        // Now test that there is communication instances for the course and the user added for that instance.
453
        $coursecommunication = helper::load_by_course(
454
            courseid: $course->id,
455
            context: $coursecontext,
456
        );
457
        $this->assertInstanceOf(
458
            expected: communication_processor::class,
459
            actual: $coursecommunication->get_processor(),
460
        );
461
 
462
        // Check the user is added for course communication instance.
463
        $courseusers = $coursecommunication->get_processor()->get_all_userids_for_instance();
464
        $courseusers = reset($courseusers);
465
        $this->assertEquals(
466
            expected: $user->id,
467
            actual: $courseusers,
468
        );
469
 
470
        // Group should not have any instance yet.
471
        $groupcommunication = helper::load_by_group(
472
            groupid: $group->id,
473
            context: $coursecontext,
474
        );
475
        $this->assertNull(actual: $groupcommunication->get_processor());
476
 
477
        // Now update the course.
478
        $course->groupmode = SEPARATEGROUPS;
479
        $course->selectedcommunication = 'communication_matrix';
480
        update_course(data: $course);
481
 
482
        // Now there should be a group communication instance.
483
        $groupcommunication->reload();
484
        $this->assertInstanceOf(
485
            expected: communication_processor::class,
486
            actual: $groupcommunication->get_processor(),
487
        );
488
 
489
        // The course communication instance must be active.
490
        $coursecommunication->reload();
491
        $this->assertInstanceOf(
492
            expected: communication_processor::class,
493
            actual: $coursecommunication->get_processor(),
494
        );
495
 
496
        // All the course instance users must be marked as deleted.
497
        $coursecommunication->reload();
498
        $courseusers = $coursecommunication->get_processor()->get_all_delete_flagged_userids();
499
        $courseusers = reset($courseusers);
500
        $this->assertEquals(
501
            expected: $user->id,
502
            actual: $courseusers,
503
        );
504
 
505
        // Group instance should have the user.
506
        $groupusers = $groupcommunication->get_processor()->get_all_userids_for_instance();
507
        $groupusers = reset($groupusers);
508
        $this->assertEquals(
509
            expected: $user->id,
510
            actual: $groupusers,
511
        );
512
 
513
        // Now disable the communication instance for the course.
514
        $course->selectedcommunication = communication_processor::PROVIDER_NONE;
515
        update_course(data: $course);
516
 
517
        // Now both course and group instance should be disabled.
518
        $coursecommunication->reload();
519
        $this->assertNull(actual: $coursecommunication->get_processor());
520
 
521
        $groupcommunication->reload();
522
        $this->assertNull(actual: $groupcommunication->get_processor());
523
    }
524
 
525
    /**
526
     * Test create_course_communication_instance.
527
     */
528
    public function test_create_course_communication_instance(): void {
529
        $course = $this->get_course();
530
        $coursecontext = \context_course::instance(courseid: $course->id);
531
        $coursecommunication = helper::load_by_course(
532
            courseid: $course->id,
533
            context: $coursecontext,
534
        );
535
 
536
        $processor = $coursecommunication->get_processor();
537
        $this->assertEquals(
538
            expected: 'communication_matrix',
539
            actual: $processor->get_provider(),
540
        );
541
        $this->assertEquals(
542
            expected: 'Sampleroom',
543
            actual: $processor->get_room_name(),
544
        );
545
    }
546
 
547
    /**
548
     * Test delete_course_communication.
549
     */
550
    public function test_delete_course_communication(): void {
551
        $course = $this->get_course();
552
        delete_course(
553
            courseorid: $course,
554
            showfeedback: false,
555
        );
556
 
557
        $adhoctask = \core\task\manager::get_adhoc_tasks(delete_room_task::class);
558
        $this->assertCount(1, $adhoctask);
559
    }
560
 
561
    /**
562
     * Test update of room membership when user changes occur.
563
     */
564
    public function test_update_user_room_memberships(): void {
565
        global $DB;
566
 
567
        $user = $this->getDataGenerator()->create_user();
568
        $course = $this->get_course();
569
        $coursecontext = \context_course::instance($course->id);
570
        $teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
571
        $this->getDataGenerator()->enrol_user($user->id, $course->id);
572
        role_assign($teacherrole->id, $user->id, $coursecontext->id);
573
 
574
        $coursecommunication = helper::load_by_course($course->id, $coursecontext);
575
        $courseusers = $coursecommunication->get_processor()->get_all_userids_for_instance();
576
        $courseusers = reset($courseusers);
577
        $this->assertEquals($user->id, $courseusers);
578
 
579
        $user->suspended = 1;
580
        user_update_user($user, false);
581
 
582
        $coursecommunication->reload();
583
        $courseusers = $coursecommunication->get_processor()->get_all_delete_flagged_userids();
584
        $courseusers = reset($courseusers);
585
        $this->assertEquals($user->id, $courseusers);
586
    }
587
 
588
    /**
589
     * Test deletion of user room memberships when a user is deleted.
590
     */
591
    public function test_delete_user_room_memberships(): void {
592
        global $DB;
593
 
594
        $user = $this->getDataGenerator()->create_user();
595
        $course = $this->get_course();
596
        $coursecontext = \context_course::instance($course->id);
597
        $teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
598
        $this->getDataGenerator()->enrol_user($user->id, $course->id);
599
        role_assign($teacherrole->id, $user->id, $coursecontext->id);
600
 
601
        delete_user($user);
602
        $coursecommunication = helper::load_by_course($course->id, $coursecontext);
603
        $courseusers = $coursecommunication->get_processor()->get_all_userids_for_instance();
604
        $this->assertEmpty($courseusers);
605
    }
606
 
607
    /**
608
     * Test user room membership updates with role changes in a course.
609
     */
610
    public function test_update_user_membership_for_role_changes(): void {
611
        global $DB;
612
 
613
        $user = $this->getDataGenerator()->create_user();
614
        $course = $this->get_course();
615
        $coursecontext = \context_course::instance($course->id);
616
        $teacherrole = $DB->get_record('role', ['shortname' => 'teacher']);
617
        $this->getDataGenerator()->enrol_user($user->id, $course->id);
618
 
619
        $adhoctask = \core\task\manager::get_adhoc_tasks(update_room_membership_task::class);
620
        $this->assertCount(1, $adhoctask);
621
 
622
        role_assign($teacherrole->id, $user->id, $coursecontext->id);
623
 
624
        $adhoctask = \core\task\manager::get_adhoc_tasks(update_room_membership_task::class);
625
        $this->assertCount(2, $adhoctask);
626
    }
627
}
628