weekly release 4.5dev
[moodle.git] / lib / tests / grouplib_test.php
blobb76bf7f9e38cbda0638b7264b7fa28ceb3be5f10
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.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 namespace core;
19 use core_group\visibility;
21 /**
22 * Unit tests for lib/grouplib.php
24 * @package core
25 * @copyright 2007 onwards Martin Dougiamas (http://dougiamas.com)
26 * @author Andrew Nicols
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 class grouplib_test extends \advanced_testcase {
31 public function test_groups_get_group_by_idnumber(): void {
32 $this->resetAfterTest(true);
34 $generator = $this->getDataGenerator();
36 // Create a course category and course.
37 $cat = $generator->create_category(array('parent' => 0));
38 $course = $generator->create_course(array('category' => $cat->id));
40 $idnumber1 = 'idnumber1';
41 $idnumber2 = 'idnumber2';
44 * Test with an empty and a null idnumber.
46 // An empty idnumber should always return a false value.
47 $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
48 $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
50 // Even when a group exists which also has an empty idnumber.
51 $generator->create_group(array('courseid' => $course->id));
52 $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
53 $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
56 * Test with a valid idnumber.
58 // There is no matching idnumber at present.
59 $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber1));
61 // We should now have a valid group returned by the idnumber search.
62 $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber1));
63 $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber1));
65 // An empty idnumber should still return false.
66 $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
67 $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
70 * Test with another idnumber.
72 // There is no matching idnumber at present.
73 $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber2));
75 // We should now have a valid group returned by the idnumber search.
76 $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber2));
77 $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber2));
80 * Group idnumbers are unique within a course so test that we don't
81 * retrieve groups for the first course.
84 // Create a second course.
85 $course = $generator->create_course(array('category' => $cat->id));
87 // An empty idnumber should always return a false value.
88 $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
89 $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
91 // Our existing idnumbers shouldn't be returned here as we're in a different course.
92 $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber1));
93 $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber2));
95 // We should be able to reuse the idnumbers again since this is a different course.
96 $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber1));
97 $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber1));
99 $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber2));
100 $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber2));
103 public function test_groups_get_grouping_by_idnumber(): void {
104 $this->resetAfterTest(true);
106 $generator = $this->getDataGenerator();
108 // Create a course category and course.
109 $cat = $generator->create_category(array('parent' => 0));
110 $course = $generator->create_course(array('category' => $cat->id));
112 $idnumber1 = 'idnumber1';
113 $idnumber2 = 'idnumber2';
116 * Test with an empty and a null idnumber.
118 // An empty idnumber should always return a false value.
119 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
120 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
122 // Even when a grouping exists which also has an empty idnumber.
123 $generator->create_grouping(array('courseid' => $course->id));
124 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
125 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
128 * Test with a valid idnumber
130 // There is no matching idnumber at present.
131 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber1));
133 // We should now have a valid group returned by the idnumber search.
134 $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber1));
135 $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber1));
137 // An empty idnumber should still return false.
138 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
139 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
142 * Test with another idnumber.
144 // There is no matching idnumber at present.
145 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber2));
147 // We should now have a valid grouping returned by the idnumber search.
148 $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber2));
149 $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber2));
152 * Grouping idnumbers are unique within a course so test that we don't
153 * retrieve groupings for the first course.
156 // Create a second course.
157 $course = $generator->create_course(array('category' => $cat->id));
159 // An empty idnumber should always return a false value.
160 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
161 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
163 // Our existing idnumbers shouldn't be returned here as we're in a different course.
164 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber1));
165 $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber2));
167 // We should be able to reuse the idnumbers again since this is a different course.
168 $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber1));
169 $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber1));
171 $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber2));
172 $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber2));
175 public function test_groups_get_members_ids_sql(): void {
176 global $DB;
178 $this->resetAfterTest(true);
180 $generator = $this->getDataGenerator();
182 $course = $generator->create_course();
183 $coursecontext = \context_course::instance($course->id);
184 $student1 = $generator->create_user();
185 $student2 = $generator->create_user();
186 $plugin = enrol_get_plugin('manual');
187 $role = $DB->get_record('role', array('shortname' => 'student'));
188 $group = $generator->create_group(array('courseid' => $course->id));
189 $instance = $DB->get_record('enrol', array(
190 'courseid' => $course->id,
191 'enrol' => 'manual',
194 $this->assertNotEquals($instance, false);
196 // Enrol users in the course.
197 $plugin->enrol_user($instance, $student1->id, $role->id);
198 $plugin->enrol_user($instance, $student2->id, $role->id);
200 list($sql, $params) = groups_get_members_ids_sql($group->id);
202 // Test an empty group.
203 $users = $DB->get_records_sql($sql, $params);
204 $this->assertFalse(array_key_exists($student1->id, $users));
206 // Test with a group member.
207 groups_add_member($group->id, $student1->id);
208 $users = $DB->get_records_sql($sql, $params);
209 $this->assertTrue(array_key_exists($student1->id, $users));
212 public function test_groups_get_members_ids_sql_multiple_groups(): void {
213 global $DB;
215 $this->resetAfterTest(true);
217 $generator = $this->getDataGenerator();
219 $course = $generator->create_course();
220 $student1 = $generator->create_user();
221 $student2 = $generator->create_user();
222 $plugin = enrol_get_plugin('manual');
223 $role = $DB->get_record('role', array('shortname' => 'student'));
224 $group1 = $generator->create_group(array('courseid' => $course->id));
225 $group2 = $generator->create_group(array('courseid' => $course->id));
226 $groupids = [
227 $group1->id,
228 $group2->id,
230 $instance = $DB->get_record('enrol', array(
231 'courseid' => $course->id,
232 'enrol' => 'manual',
235 $this->assertNotEquals($instance, false);
237 // Enrol users in the course.
238 $plugin->enrol_user($instance, $student1->id, $role->id);
239 $plugin->enrol_user($instance, $student2->id, $role->id);
241 list($sql, $params) = groups_get_members_ids_sql($groupids);
243 // Test an empty group.
244 $users = $DB->get_records_sql($sql, $params);
245 $this->assertFalse(array_key_exists($student1->id, $users));
247 // Test with a member of one of the two group.
248 groups_add_member($group1->id, $student1->id);
249 $users = $DB->get_records_sql($sql, $params);
250 $this->assertTrue(array_key_exists($student1->id, $users));
252 // Test with members of two groups.
253 groups_add_member($group2->id, $student2->id);
254 $users = $DB->get_records_sql($sql, $params);
255 $this->assertTrue(array_key_exists($student1->id, $users));
256 $this->assertTrue(array_key_exists($student2->id, $users));
259 public function test_groups_get_members_ids_sql_multiple_groups_join_types(): void {
260 global $DB;
262 $this->resetAfterTest(true);
264 $generator = $this->getDataGenerator();
266 $course = $generator->create_course();
267 $student1 = $generator->create_user();
268 $student2 = $generator->create_user();
269 $student3 = $generator->create_user();
270 $student4 = $generator->create_user();
271 $student5 = $generator->create_user();
272 $student6 = $generator->create_user();
273 $plugin = enrol_get_plugin('manual');
274 $role = $DB->get_record('role', array('shortname' => 'student'));
275 $group1 = $generator->create_group(array('courseid' => $course->id));
276 $group2 = $generator->create_group(array('courseid' => $course->id));
277 $group3 = $generator->create_group(array('courseid' => $course->id));
278 // Only groups 1 and 2 specified in SQL (group 3 helps cover the None case).
279 $groupids = [
280 $group1->id,
281 $group2->id,
283 $instance = $DB->get_record('enrol', array(
284 'courseid' => $course->id,
285 'enrol' => 'manual',
288 $this->assertNotEquals($instance, false);
290 // Enrol users in the course.
291 $plugin->enrol_user($instance, $student1->id, $role->id);
292 $plugin->enrol_user($instance, $student2->id, $role->id);
293 $plugin->enrol_user($instance, $student3->id, $role->id);
294 $plugin->enrol_user($instance, $student4->id, $role->id);
295 $plugin->enrol_user($instance, $student5->id, $role->id);
296 $plugin->enrol_user($instance, $student6->id, $role->id);
298 // Generate SQL with the different groups join types for members of group1 and group2.
299 list($sqlany, $paramsany) = groups_get_members_ids_sql($groupids, null, GROUPS_JOIN_ANY);
300 list($sqlall, $paramsall) = groups_get_members_ids_sql($groupids, null, GROUPS_JOIN_ALL);
301 list($sqlnone, $paramsnone) = groups_get_members_ids_sql($groupids, null, GROUPS_JOIN_NONE);
303 // Any - Test empty groups, no matches.
304 $users = $DB->get_records_sql($sqlany, $paramsany);
305 $this->assertFalse(array_key_exists($student1->id, $users));
306 $this->assertFalse(array_key_exists($student2->id, $users));
307 $this->assertFalse(array_key_exists($student3->id, $users));
308 $this->assertFalse(array_key_exists($student4->id, $users));
309 $this->assertFalse(array_key_exists($student5->id, $users));
310 $this->assertFalse(array_key_exists($student6->id, $users));
312 // All - Test empty groups, no matches.
313 $users = $DB->get_records_sql($sqlall, $paramsall);
314 $this->assertFalse(array_key_exists($student1->id, $users));
315 $this->assertFalse(array_key_exists($student2->id, $users));
316 $this->assertFalse(array_key_exists($student3->id, $users));
317 $this->assertFalse(array_key_exists($student4->id, $users));
318 $this->assertFalse(array_key_exists($student5->id, $users));
319 $this->assertFalse(array_key_exists($student6->id, $users));
321 // None - Test empty groups, all match.
322 $users = $DB->get_records_sql($sqlnone, $paramsnone);
323 $this->assertTrue(array_key_exists($student1->id, $users));
324 $this->assertTrue(array_key_exists($student2->id, $users));
325 $this->assertTrue(array_key_exists($student3->id, $users));
326 $this->assertTrue(array_key_exists($student4->id, $users));
327 $this->assertTrue(array_key_exists($student5->id, $users));
328 $this->assertTrue(array_key_exists($student6->id, $users));
330 // Assign various group member combinations.
331 groups_add_member($group1->id, $student1->id);
332 groups_add_member($group1->id, $student2->id);
333 groups_add_member($group1->id, $student3->id);
334 groups_add_member($group2->id, $student2->id);
335 groups_add_member($group2->id, $student3->id);
336 groups_add_member($group2->id, $student4->id);
337 groups_add_member($group3->id, $student5->id);
339 // Any - Test students in one or both of groups 1 and 2 matched.
340 $users = $DB->get_records_sql($sqlany, $paramsany);
341 $this->assertTrue(array_key_exists($student1->id, $users));
342 $this->assertTrue(array_key_exists($student2->id, $users));
343 $this->assertTrue(array_key_exists($student3->id, $users));
344 $this->assertTrue(array_key_exists($student4->id, $users));
345 $this->assertFalse(array_key_exists($student5->id, $users));
346 $this->assertFalse(array_key_exists($student6->id, $users));
348 // All - Test only students in both groups 1 and 2 matched.
349 $users = $DB->get_records_sql($sqlall, $paramsall);
350 $this->assertTrue(array_key_exists($student2->id, $users));
351 $this->assertTrue(array_key_exists($student3->id, $users));
352 $this->assertFalse(array_key_exists($student1->id, $users));
353 $this->assertFalse(array_key_exists($student4->id, $users));
354 $this->assertFalse(array_key_exists($student5->id, $users));
355 $this->assertFalse(array_key_exists($student6->id, $users));
357 // None - Test only students not in group 1 or 2 matched.
358 $users = $DB->get_records_sql($sqlnone, $paramsnone);
359 $this->assertTrue(array_key_exists($student5->id, $users));
360 $this->assertTrue(array_key_exists($student6->id, $users));
361 $this->assertFalse(array_key_exists($student1->id, $users));
362 $this->assertFalse(array_key_exists($student2->id, $users));
363 $this->assertFalse(array_key_exists($student3->id, $users));
364 $this->assertFalse(array_key_exists($student4->id, $users));
367 public function test_groups_get_members_ids_sql_valid_context(): void {
368 global $DB;
370 $this->resetAfterTest(true);
372 $generator = $this->getDataGenerator();
374 $course = $generator->create_course();
375 $coursecontext = \context_course::instance($course->id);
376 $student1 = $generator->create_user();
377 $student2 = $generator->create_user();
378 $plugin = enrol_get_plugin('manual');
379 $role = $DB->get_record('role', array('shortname' => 'student'));
380 $group = $generator->create_group(array('courseid' => $course->id));
381 $instance = $DB->get_record('enrol', array(
382 'courseid' => $course->id,
383 'enrol' => 'manual',
386 $this->assertNotEquals($instance, false);
388 // Enrol users in the course.
389 $plugin->enrol_user($instance, $student1->id, $role->id);
390 $plugin->enrol_user($instance, $student2->id, $role->id);
392 // Add student1 to the group.
393 groups_add_member($group->id, $student1->id);
395 // Test with members at any group and with a valid $context.
396 list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP, $coursecontext);
397 $users = $DB->get_records_sql($sql, $params);
398 $this->assertFalse(array_key_exists($student1->id, $users));
399 $this->assertTrue(array_key_exists($student2->id, $users));
402 public function test_groups_get_members_ids_sql_empty_context(): void {
403 global $DB;
405 $this->resetAfterTest(true);
407 $generator = $this->getDataGenerator();
409 $course = $generator->create_course();
410 $coursecontext = \context_course::instance($course->id);
411 $student1 = $generator->create_user();
412 $student2 = $generator->create_user();
413 $plugin = enrol_get_plugin('manual');
414 $role = $DB->get_record('role', array('shortname' => 'student'));
415 $group = $generator->create_group(array('courseid' => $course->id));
416 $instance = $DB->get_record('enrol', array(
417 'courseid' => $course->id,
418 'enrol' => 'manual',
421 $this->assertNotEquals($instance, false);
423 // Enrol users in the course.
424 $plugin->enrol_user($instance, $student1->id, $role->id);
425 $plugin->enrol_user($instance, $student2->id, $role->id);
427 // Add student1 to the group.
428 groups_add_member($group->id, $student1->id);
430 // Test with members at any group and without the $context.
431 $this->expectException('coding_exception');
432 list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP);
435 public function test_groups_get_members_ids_sql_invalid_context(): void {
436 global $DB;
438 $this->resetAfterTest(true);
440 $generator = $this->getDataGenerator();
442 $course = $generator->create_course();
443 $coursecontext = \context_course::instance($course->id);
444 $student1 = $generator->create_user();
445 $student2 = $generator->create_user();
446 $plugin = enrol_get_plugin('manual');
447 $role = $DB->get_record('role', array('shortname' => 'student'));
448 $group = $generator->create_group(array('courseid' => $course->id));
449 $instance = $DB->get_record('enrol', array(
450 'courseid' => $course->id,
451 'enrol' => 'manual',
454 $this->assertNotEquals($instance, false);
456 // Enrol users in the course.
457 $plugin->enrol_user($instance, $student1->id, $role->id);
458 $plugin->enrol_user($instance, $student2->id, $role->id);
460 // Add student1 to the group.
461 groups_add_member($group->id, $student1->id);
463 // Test with members at any group and with an invalid $context.
464 $syscontext = \context_system::instance();
465 $this->expectException('coding_exception');
466 list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP, $syscontext);
470 * Test retrieving users with concatenated group names from a course
472 public function test_groups_get_names_concat_sql(): void {
473 global $DB;
475 $this->resetAfterTest();
477 // Create a course containing two groups.
478 $course = $this->getDataGenerator()->create_course();
479 $group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
480 $group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
482 // Create first user, add them to group 1 and group 2.
483 $user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
484 $this->getDataGenerator()->create_group_member(['userid' => $user1->id, 'groupid' => $group1->id]);
485 $this->getDataGenerator()->create_group_member(['userid' => $user1->id, 'groupid' => $group2->id]);
487 // Create second user, add them to group 1 only.
488 $user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
489 $this->getDataGenerator()->create_group_member(['userid' => $user2->id, 'groupid' => $group1->id]);
491 // Call our method, and assertion.
492 [$sql, $params] = groups_get_names_concat_sql($course->id);
493 $records = $DB->get_records_sql($sql, $params);
495 $this->assertEqualsCanonicalizing([
496 (object) [
497 'userid' => $user1->id,
498 'groupnames' => "{$group1->name}, {$group2->name}",
500 (object) [
501 'userid' => $user2->id,
502 'groupnames' => $group1->name,
504 ], $records);
507 public function test_groups_get_group_by_name(): void {
508 $this->resetAfterTest(true);
510 $generator = $this->getDataGenerator();
512 // Create a course category and course.
513 $cat = $generator->create_category(array('parent' => 0));
514 $course = $generator->create_course(array('category' => $cat->id));
516 $name1 = 'Name 1';
517 $name2 = 'Name 2';
519 // Test with an empty and a null idnumber.
520 $this->assertFalse(groups_get_group_by_name($course->id, ''));
521 $this->assertFalse(groups_get_group_by_name($course->id, null));
523 // Even when a group exists.
524 $generator->create_group(array('courseid' => $course->id));
525 $this->assertFalse(groups_get_group_by_name($course->id, ''));
526 $this->assertFalse(groups_get_group_by_name($course->id, null));
528 // Test with a valid name, but one that doesn't exist yet.
529 $this->assertFalse(groups_get_group_by_name($course->id, $name1));
530 $this->assertFalse(groups_get_group_by_name($course->id, $name2));
532 // We should now have a valid group returned by the name search.
533 $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => $name1));
534 $this->assertEquals($group1->id, groups_get_group_by_name($course->id, $name1));
535 $this->assertFalse(groups_get_group_by_name($course->id, $name2));
537 // We should now have a two valid groups returned by the name search.
538 $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => $name2));
539 $this->assertEquals($group1->id, groups_get_group_by_name($course->id, $name1));
540 $this->assertEquals($group2->id, groups_get_group_by_name($course->id, $name2));
542 // Delete a group.
543 $this->assertTrue(groups_delete_group($group1));
544 $this->assertFalse(groups_get_group_by_name($course->id, $name1));
545 $this->assertEquals($group2->id, groups_get_group_by_name($course->id, $name2));
548 * Group idnumbers are unique within a course so test that we don't
549 * retrieve groups for the first course.
552 // Create a second course.
553 $course = $generator->create_course(array('category' => $cat->id));
555 // An empty name should always return a false value.
556 $this->assertFalse(groups_get_group_by_name($course->id, ''));
557 $this->assertFalse(groups_get_group_by_name($course->id, null));
559 // Our existing names shouldn't be returned here as we're in a different course.
560 $this->assertFalse(groups_get_group_by_name($course->id, $name1));
561 $this->assertFalse(groups_get_group_by_name($course->id, $name2));
563 // We should be able to reuse the idnumbers again since this is a different course.
564 $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => $name1));
565 $this->assertEquals($group1->id, groups_get_group_by_name($course->id, $name1));
567 $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => $name2));
568 $this->assertEquals($group2->id, groups_get_group_by_name($course->id, $name2));
571 public function test_groups_get_grouping(): void {
572 $this->resetAfterTest(true);
574 $generator = $this->getDataGenerator();
576 // Create a course category and course.
577 $cat = $generator->create_category(array('parent' => 0));
578 $course = $generator->create_course(array('category' => $cat->id));
580 $name1 = 'Grouping 1';
581 $name2 = 'Grouping 2';
583 // Test with an empty and a null idnumber.
584 $this->assertFalse(groups_get_grouping_by_name($course->id, ''));
585 $this->assertFalse(groups_get_grouping_by_name($course->id, null));
587 // Even when a group exists.
588 $generator->create_group(array('courseid' => $course->id));
589 $this->assertFalse(groups_get_grouping_by_name($course->id, ''));
590 $this->assertFalse(groups_get_grouping_by_name($course->id, null));
592 // Test with a valid name, but one that doesn't exist yet.
593 $this->assertFalse(groups_get_grouping_by_name($course->id, $name1));
594 $this->assertFalse(groups_get_grouping_by_name($course->id, $name2));
596 // We should now have a valid group returned by the name search.
597 $group1 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name1));
598 $this->assertEquals($group1->id, groups_get_grouping_by_name($course->id, $name1));
599 $this->assertFalse(groups_get_grouping_by_name($course->id, $name2));
601 // We should now have a two valid groups returned by the name search.
602 $group2 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name2));
603 $this->assertEquals($group1->id, groups_get_grouping_by_name($course->id, $name1));
604 $this->assertEquals($group2->id, groups_get_grouping_by_name($course->id, $name2));
606 // Delete a group.
607 $this->assertTrue(groups_delete_grouping($group1));
608 $this->assertFalse(groups_get_grouping_by_name($course->id, $name1));
609 $this->assertEquals($group2->id, groups_get_grouping_by_name($course->id, $name2));
612 * Group idnumbers are unique within a course so test that we don't
613 * retrieve groups for the first course.
616 // Create a second course.
617 $course = $generator->create_course(array('category' => $cat->id));
619 // An empty name should always return a false value.
620 $this->assertFalse(groups_get_grouping_by_name($course->id, ''));
621 $this->assertFalse(groups_get_grouping_by_name($course->id, null));
623 // Our existing names shouldn't be returned here as we're in a different course.
624 $this->assertFalse(groups_get_grouping_by_name($course->id, $name1));
625 $this->assertFalse(groups_get_grouping_by_name($course->id, $name2));
627 // We should be able to reuse the idnumbers again since this is a different course.
628 $group1 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name1));
629 $this->assertEquals($group1->id, groups_get_grouping_by_name($course->id, $name1));
631 $group2 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name2));
632 $this->assertEquals($group2->id, groups_get_grouping_by_name($course->id, $name2));
635 public function test_groups_get_course_data(): void {
636 $this->resetAfterTest(true);
638 $generator = $this->getDataGenerator();
640 // Create a course category and course.
641 $cat = $generator->create_category(array('parent' => 0));
642 $course = $generator->create_course(array('category' => $cat->id));
643 $grouping1 = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 1'));
644 $grouping2 = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 2'));
645 $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
646 $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
647 $group3 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 3'));
648 $group4 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 4'));
650 // Assign the groups to groupings.
651 $this->assertTrue(groups_assign_grouping($grouping1->id, $group1->id));
652 $this->assertTrue(groups_assign_grouping($grouping1->id, $group2->id));
653 $this->assertTrue(groups_assign_grouping($grouping2->id, $group3->id));
654 $this->assertTrue(groups_assign_grouping($grouping2->id, $group4->id));
656 // Get the data.
657 $data = groups_get_course_data($course->id);
658 $this->assertInstanceOf('stdClass', $data);
659 $this->assertObjectHasProperty('groups', $data);
660 $this->assertObjectHasProperty('groupings', $data);
661 $this->assertObjectHasProperty('mappings', $data);
663 // Test we have the expected items returns.
664 $this->assertCount(4, $data->groups);
665 $this->assertCount(2, $data->groupings);
666 $this->assertCount(4, $data->mappings);
668 // Check we have the expected groups.
669 $this->assertArrayHasKey($group1->id, $data->groups);
670 $this->assertArrayHasKey($group2->id, $data->groups);
671 $this->assertArrayHasKey($group3->id, $data->groups);
672 $this->assertArrayHasKey($group4->id, $data->groups);
674 // Test a group-id is mapped correctly.
675 $this->assertSame($group3->name, $data->groups[$group3->id]->name);
677 // Check we have the expected number of groupings.
678 $this->assertArrayHasKey($grouping1->id, $data->groupings);
679 $this->assertArrayHasKey($grouping2->id, $data->groupings);
681 // Test a grouping-id is mapped correctly.
682 $this->assertEquals($grouping2->name, $data->groupings[$grouping2->id]->name);
684 // Test that all of the mappings are correct.
685 $grouping1maps = 0;
686 $grouping2maps = 0;
687 $group1maps = 0;
688 $group2maps = 0;
689 $group3maps = 0;
690 $group4maps = 0;
691 foreach ($data->mappings as $mapping) {
692 if ($mapping->groupingid === $grouping1->id) {
693 $grouping1maps++;
694 $this->assertContainsEquals($mapping->groupid, array($group1->id, $group2->id));
695 } else if ($mapping->groupingid === $grouping2->id) {
696 $grouping2maps++;
697 $this->assertContainsEquals($mapping->groupid, array($group3->id, $group4->id));
698 } else {
699 $this->fail('Unexpected groupingid');
701 switch ($mapping->groupid) {
702 case $group1->id : $group1maps++; break;
703 case $group2->id : $group2maps++; break;
704 case $group3->id : $group3maps++; break;
705 case $group4->id : $group4maps++; break;
708 $this->assertEquals(2, $grouping1maps);
709 $this->assertEquals(2, $grouping2maps);
710 $this->assertEquals(1, $group1maps);
711 $this->assertEquals(1, $group2maps);
712 $this->assertEquals(1, $group3maps);
713 $this->assertEquals(1, $group4maps);
715 // Test the groups_get_all_groups which uses this functionality.
716 $groups = groups_get_all_groups($course->id);
717 $this->assertCount(4, $groups);
718 $this->assertArrayHasKey($group1->id, $groups);
719 $this->assertArrayHasKey($group2->id, $groups);
720 $this->assertArrayHasKey($group3->id, $groups);
721 $this->assertArrayHasKey($group4->id, $groups);
723 $groups = groups_get_all_groups($course->id, null, $grouping1->id);
724 $this->assertCount(2, $groups);
725 $this->assertArrayHasKey($group1->id, $groups);
726 $this->assertArrayHasKey($group2->id, $groups);
727 $this->assertArrayNotHasKey($group3->id, $groups);
728 $this->assertArrayNotHasKey($group4->id, $groups);
730 $groups = groups_get_all_groups($course->id, null, $grouping2->id);
731 $this->assertCount(2, $groups);
732 $this->assertArrayNotHasKey($group1->id, $groups);
733 $this->assertArrayNotHasKey($group2->id, $groups);
734 $this->assertArrayHasKey($group3->id, $groups);
735 $this->assertArrayHasKey($group4->id, $groups);
737 // Test this function using an alternate column for the result index
738 $groups = groups_get_all_groups($course->id, null, $grouping2->id, 'g.name, g.id');
739 $this->assertCount(2, $groups);
740 $this->assertArrayNotHasKey($group3->id, $groups);
741 $this->assertArrayHasKey($group3->name, $groups);
742 $this->assertEquals($group3->id, $groups[$group3->name]->id);
746 * Tests for groups_group_visible.
748 public function test_groups_group_visible(): void {
749 global $CFG, $DB;
751 $generator = $this->getDataGenerator();
752 $this->resetAfterTest();
753 $this->setAdminUser();
755 // Create a course category, course and groups.
756 $cat = $generator->create_category(array('parent' => 0));
757 $course = $generator->create_course(array('category' => $cat->id));
758 $coursecontext = \context_course::instance($course->id);
759 $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
760 $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
761 $group3 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 3'));
762 $group4 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 4'));
764 // Create cm.
765 $assign = $generator->create_module("assign", array('course' => $course->id));
766 $cm = get_coursemodule_from_instance("assign", $assign->id);
768 // Create users.
769 $user1 = $generator->create_user();
770 $user2 = $generator->create_user();
771 $user3 = $generator->create_user();
773 // Enrol users into the course.
774 $generator->enrol_user($user1->id, $course->id);
775 $generator->enrol_user($user2->id, $course->id);
777 // Assign groups.
778 groups_add_member($group1, $user2);
780 // Give capability at course level to the user to access all groups.
781 $role = $DB->get_field("role", "id", array("shortname" => "manager"));
782 $generator->enrol_user($user3->id, $course->id, $role);
783 // Make sure the user has the capability.
784 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role, $coursecontext->id);
786 // No groups , not forced.
787 $result = groups_group_visible($group1->id, $course, null, $user1->id);
788 $this->assertTrue($result);
789 $result = groups_group_visible(0, $course, null, $user1->id);
790 $this->assertTrue($result); // Requesting all groups.
792 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
793 $this->assertTrue($result); // Cm with no groups.
795 $cm->groupmode = SEPARATEGROUPS;
796 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
797 $this->assertFalse($result); // Cm with separate groups.
798 $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
799 $this->assertTrue($result); // Cm with separate groups.
801 $cm->groupmode = VISIBLEGROUPS;
802 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
803 $this->assertTrue($result); // Cm with visible groups.
805 // No groups, forced.
806 $course->groupmode = NOGROUPS;
807 $course->groupmodeforce = true;
808 update_course($course);
809 $result = groups_group_visible($group1->id, $course, null, $user1->id);
810 $this->assertTrue($result);
811 $result = groups_group_visible(0, $course, null, $user1->id);
812 $this->assertTrue($result); // Requesting all groups.
814 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
815 $this->assertTrue($result); // Cm with no groups.
817 $cm->groupmode = SEPARATEGROUPS;
818 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
819 $this->assertTrue($result); // Cm with separate groups.
820 $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
821 $this->assertTrue($result); // Cm with separate groups.
823 $cm->groupmode = SEPARATEGROUPS;
824 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
825 $this->assertTrue($result); // Cm with visible groups.
827 // Visible groups, forced.
828 $course->groupmode = VISIBLEGROUPS;
829 $course->groupmodeforce = true;
830 update_course($course);
831 $result = groups_group_visible($group1->id, $course, null, $user1->id);
832 $this->assertTrue($result);
833 $result = groups_group_visible(0, $course, null, $user1->id);
834 $this->assertTrue($result); // Requesting all groups.
836 $cm->groupmode = NOGROUPS;
837 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
838 $this->assertTrue($result); // Cm with no groups.
840 $cm->groupmode = SEPARATEGROUPS;
841 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
842 $this->assertTrue($result); // Cm with separate groups.
843 $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
844 $this->assertTrue($result); // Cm with separate groups.
846 $cm->groupmode = VISIBLEGROUPS;
847 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
848 $this->assertTrue($result); // Cm with visible groups.
850 // Visible groups, not forced.
851 $course->groupmode = VISIBLEGROUPS;
852 $course->groupmodeforce = false;
853 update_course($course);
854 $result = groups_group_visible($group1->id, $course, null, $user1->id);
855 $this->assertTrue($result);
856 $result = groups_group_visible(0, $course, null, $user1->id);
857 $this->assertTrue($result); // Requesting all groups.
859 $cm->groupmode = NOGROUPS;
860 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
861 $this->assertTrue($result); // Cm with no groups.
863 $cm->groupmode = SEPARATEGROUPS;
864 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
865 $this->assertFalse($result); // Cm with separate groups.
866 $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
867 $this->assertTrue($result); // Cm with separate groups.
869 $cm->groupmode = VISIBLEGROUPS;
870 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
871 $this->assertTrue($result); // Cm with visible groups.
873 // Separate groups, forced.
874 $course->groupmode = SEPARATEGROUPS;
875 $course->groupmodeforce = true;
876 update_course($course);
877 $result = groups_group_visible($group1->id, $course, null, $user1->id);
878 $this->assertFalse($result);
879 $result = groups_group_visible($group1->id, $course, null, $user2->id);
880 $this->assertTrue($result);
881 $result = groups_group_visible(0, $course, null, $user2->id);
882 $this->assertFalse($result); // Requesting all groups.
883 $result = groups_group_visible(0, $course, null, $user3->id);
884 $this->assertTrue($result); // Requesting all groups.
885 $result = groups_group_visible($group1->id, $course, null, $user3->id);
886 $this->assertTrue($result); // Make sure user with access to all groups can see any group.
888 $cm->groupmode = NOGROUPS;
889 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
890 $this->assertFalse($result); // Cm with no groups.
892 $cm->groupmode = SEPARATEGROUPS;
893 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
894 $this->assertFalse($result); // Cm with separate groups.
895 $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
896 $this->assertTrue($result); // Cm with separate groups.
897 $result = groups_group_visible($group1->id, $course, $cm, $user3->id);
898 $this->assertTrue($result); // Make sure user with access to all groups can see any group.
900 $cm->groupmode = VISIBLEGROUPS;
901 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
902 $this->assertFalse($result); // Cm with visible groups.
904 // Separate groups, not forced.
905 $course->groupmode = SEPARATEGROUPS;
906 $course->groupmodeforce = false;
907 update_course($course);
908 $result = groups_group_visible($group1->id, $course, null, $user1->id);
909 $this->assertFalse($result);
910 $result = groups_group_visible($group1->id, $course, null, $user2->id);
911 $this->assertTrue($result);
912 $result = groups_group_visible(0, $course, null, $user2->id);
913 $this->assertFalse($result); // Requesting all groups.
914 $result = groups_group_visible(0, $course, null, $user3->id);
915 $this->assertTrue($result); // Requesting all groups.
917 $cm->groupmode = NOGROUPS;
918 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
919 $this->assertTrue($result); // Cm with no groups.
921 $cm->groupmode = SEPARATEGROUPS;
922 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
923 $this->assertFalse($result); // Cm with separate groups.
924 $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
925 $this->assertTrue($result); // Cm with separate groups.
927 $cm->groupmode = VISIBLEGROUPS;
928 $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
929 $this->assertTrue($result); // Cm with visible groups.
932 function test_groups_get_groupmode(): void {
933 global $DB;
934 $generator = $this->getDataGenerator();
935 $this->resetAfterTest();
936 $this->setAdminUser();
938 // Create a course with no groups forcing.
939 $course1 = $generator->create_course();
941 // Create cm1 with no groups, cm1 with visible groups, cm2 with separate groups and cm3 with visible groups.
942 $assign1 = $generator->create_module("assign", array('course' => $course1->id));
943 $assign2 = $generator->create_module("assign", array('course' => $course1->id),
944 array('groupmode' => SEPARATEGROUPS));
945 $assign3 = $generator->create_module("assign", array('course' => $course1->id),
946 array('groupmode' => VISIBLEGROUPS));
948 // Request data for tests.
949 $cm1 = get_coursemodule_from_instance("assign", $assign1->id);
950 $cm2 = get_coursemodule_from_instance("assign", $assign2->id);
951 $cm3 = get_coursemodule_from_instance("assign", $assign3->id);
952 $modinfo = get_fast_modinfo($course1->id);
954 // Assert that any method of getting activity groupmode returns the correct result.
955 $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1));
956 $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1, $course1));
957 $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm1->id]));
958 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2));
959 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2, $course1));
960 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm2->id]));
961 $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3));
962 $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3, $course1));
963 $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm3->id]));
965 // Update the course set the groupmode SEPARATEGROUPS but not forced.
966 update_course((object)array('id' => $course1->id, 'groupmode' => SEPARATEGROUPS));
967 // Re-request the data from DB.
968 $course1 = $DB->get_record('course', array('id' => $course1->id));
969 $modinfo = get_fast_modinfo($course1->id);
971 // Existing activities are not changed.
972 $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1));
973 $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1, $course1));
974 $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm1->id]));
975 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2));
976 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2, $course1));
977 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm2->id]));
978 $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3));
979 $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3, $course1));
980 $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm3->id]));
982 // Update the course set the groupmode SEPARATEGROUPS and forced.
983 update_course((object)array('id' => $course1->id, 'groupmode' => SEPARATEGROUPS, 'groupmodeforce' => true));
984 // Re-request the data from DB.
985 $course1 = $DB->get_record('course', array('id' => $course1->id));
986 $modinfo = get_fast_modinfo($course1->id);
988 // Make sure all activities have separate groups mode now.
989 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm1));
990 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm1, $course1));
991 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm1->id]));
992 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2));
993 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2, $course1));
994 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm2->id]));
995 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm3));
996 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm3, $course1));
997 $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm3->id]));
1001 * Tests for groups_allgroups_course_menu() .
1003 public function test_groups_allgroups_course_menu(): void {
1004 global $SESSION;
1006 $this->resetAfterTest();
1008 // Generate data.
1009 $course = $this->getDataGenerator()->create_course();
1010 $record = new \stdClass();
1011 $record->courseid = $course->id;
1012 $group1 = $this->getDataGenerator()->create_group($record);
1013 $group2 = $this->getDataGenerator()->create_group($record);
1014 $user = $this->getDataGenerator()->create_user();
1015 $this->getDataGenerator()->enrol_user($user->id, $course->id);
1016 $this->setUser($user);
1018 $html = groups_allgroups_course_menu($course, 'someurl.php');
1019 // Since user is not a part of this group and doesn't have accessallgroups permission,
1020 // the html should be empty.
1021 $this->assertEmpty($html);
1023 groups_add_member($group1->id, $user);
1024 // Now user can access one of the group. We can't assert an exact match here because of random ids generated by yui. So do
1025 // partial match to see if all groups are listed or not.
1026 $html = groups_allgroups_course_menu($course, 'someurl.php');
1027 $this->assertStringContainsString(format_string($group1->name), $html);
1028 $this->assertStringNotContainsString(format_string($group2->name), $html);
1030 $this->setAdminUser();
1032 // Now user can access everything.
1033 $html = groups_allgroups_course_menu($course, 'someurl.php');
1034 $this->assertStringContainsString(format_string($group1->name), $html);
1035 $this->assertStringContainsString(format_string($group2->name), $html);
1037 // Make sure separate groups mode, doesn't change anything.
1038 $course->groupmode = SEPARATEGROUPS;
1039 update_course($course);
1040 $html = groups_allgroups_course_menu($course, 'someurl.php');
1041 $this->assertStringContainsString(format_string($group1->name), $html);
1042 $this->assertStringContainsString(format_string($group2->name), $html);
1044 // Make sure Visible groups mode, doesn't change anything.
1045 $course->groupmode = VISIBLEGROUPS;
1046 update_course($course);
1047 $html = groups_allgroups_course_menu($course, 'someurl.php');
1048 $this->assertStringContainsString(format_string($group1->name), $html);
1049 $this->assertStringContainsString(format_string($group2->name), $html);
1051 // Let us test activegroup changes now.
1052 $this->setUser($user);
1053 $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid] = 5;
1054 groups_allgroups_course_menu($course, 'someurl.php', false); // Do not update session.
1055 $this->assertSame(5, $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid]);
1056 groups_allgroups_course_menu($course, 'someurl.php', true, $group1->id); // Update session.
1057 $this->assertSame($group1->id, $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid]);
1058 // Try to update session with an invalid groupid. It should not accept the invalid id.
1059 groups_allgroups_course_menu($course, 'someurl.php', true, 256);
1060 $this->assertEquals($group1->id, $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid]);
1064 * This unit test checks that groups_get_all_groups returns groups in
1065 * alphabetical order even if they are in a grouping.
1067 public function test_groups_ordering(): void {
1068 $generator = $this->getDataGenerator();
1069 $this->resetAfterTest();
1071 // Create a course category and course.
1072 $cat = $generator->create_category(array('parent' => 0));
1073 $course = $generator->create_course(array('category' => $cat->id));
1074 $grouping = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping'));
1076 // Create groups in reverse order.
1077 $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
1078 $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
1080 // Assign the groups to the grouping in reverse order.
1081 $this->assertTrue(groups_assign_grouping($grouping->id, $group2->id));
1082 $this->assertTrue(groups_assign_grouping($grouping->id, $group1->id));
1084 // Get all groups and check they are alphabetical.
1085 $groups = array_values(groups_get_all_groups($course->id, 0));
1086 $this->assertEquals('Group 1', $groups[0]->name);
1087 $this->assertEquals('Group 2', $groups[1]->name);
1089 // Now check the same is true when accessed by grouping.
1090 $groups = array_values(groups_get_all_groups($course->id, 0, $grouping->id));
1091 $this->assertEquals('Group 1', $groups[0]->name);
1092 $this->assertEquals('Group 2', $groups[1]->name);
1096 * Tests for groups_get_all_groups when grouping is set and we want members as well.
1098 public function test_groups_get_all_groups_in_grouping_with_members(): void {
1099 $generator = $this->getDataGenerator();
1100 $this->resetAfterTest();
1102 // Create courses.
1103 $course1 = $generator->create_course();
1104 $course2 = $generator->create_course();
1106 // Create users.
1107 $c1user1 = $generator->create_user();
1108 $c12user1 = $generator->create_user();
1109 $c12user2 = $generator->create_user();
1111 // Enrol users.
1112 $generator->enrol_user($c1user1->id, $course1->id);
1113 $generator->enrol_user($c12user1->id, $course1->id);
1114 $generator->enrol_user($c12user1->id, $course2->id);
1115 $generator->enrol_user($c12user2->id, $course1->id);
1116 $generator->enrol_user($c12user2->id, $course2->id);
1118 // Create groupings and groups for course1.
1119 $c1grouping1 = $generator->create_grouping(array('courseid' => $course1->id));
1120 $c1grouping2 = $generator->create_grouping(array('courseid' => $course1->id));
1121 $c1group1 = $generator->create_group(array('courseid' => $course1->id));
1122 $c1group2 = $generator->create_group(array('courseid' => $course1->id));
1123 $c1group3 = $generator->create_group(array('courseid' => $course1->id));
1124 groups_assign_grouping($c1grouping1->id, $c1group1->id);
1125 groups_assign_grouping($c1grouping1->id, $c1group2->id);
1126 groups_assign_grouping($c1grouping2->id, $c1group3->id);
1128 // Create groupings and groups for course2.
1129 $c2grouping1 = $generator->create_grouping(array('courseid' => $course2->id));
1130 $c2group1 = $generator->create_group(array('courseid' => $course1->id));
1131 groups_assign_grouping($c2grouping1->id, $c2group1->id);
1133 // Assign users to groups.
1134 $generator->create_group_member(array('groupid' => $c1group1->id, 'userid' => $c1user1->id));
1135 $generator->create_group_member(array('groupid' => $c1group1->id, 'userid' => $c12user1->id));
1136 $generator->create_group_member(array('groupid' => $c1group2->id, 'userid' => $c12user2->id));
1137 $generator->create_group_member(array('groupid' => $c2group1->id, 'userid' => $c12user2->id));
1139 // Test without userid.
1140 $groups = groups_get_all_groups($course1->id, null, $c1grouping1->id, 'g.*', true);
1142 $this->assertEqualsCanonicalizing(
1143 [$c1group1->id, $c1group2->id],
1144 array_keys($groups)
1146 $this->assertEquals(
1147 [$c1user1->id => $c1user1->id, $c12user1->id => $c12user1->id],
1148 $groups[$c1group1->id]->members
1150 $this->assertEquals(
1151 [$c12user2->id => $c12user2->id],
1152 $groups[$c1group2->id]->members
1155 // Test with userid.
1156 $groups = groups_get_all_groups($course1->id, $c1user1->id, $c1grouping1->id, 'g.*', true);
1158 $this->assertEquals([$c1group1->id], array_keys($groups));
1159 $this->assertEqualsCanonicalizing(
1160 [$c1user1->id, $c12user1->id],
1161 $groups[$c1group1->id]->members
1166 * Tests for groups_get_user_groups() method.
1168 public function test_groups_get_user_groups(): void {
1169 $this->resetAfterTest(true);
1170 $generator = $this->getDataGenerator();
1172 // Create courses.
1173 $course1 = $generator->create_course();
1174 $course2 = $generator->create_course();
1176 // Create users.
1177 $user1 = $generator->create_user();
1178 $user2 = $generator->create_user();
1179 $user3 = $generator->create_user();
1181 // Enrol users.
1182 $generator->enrol_user($user1->id, $course1->id);
1183 $generator->enrol_user($user1->id, $course2->id);
1184 $generator->enrol_user($user2->id, $course2->id);
1185 $generator->enrol_user($user3->id, $course2->id);
1187 // Create groups.
1188 $group1 = $generator->create_group(array('courseid' => $course1->id));
1189 $group2 = $generator->create_group(array('courseid' => $course2->id));
1190 $group3 = $generator->create_group(array('courseid' => $course2->id));
1192 // Assign users to groups.
1193 $this->assertTrue($generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)));
1194 $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)));
1196 // Get user groups.
1197 $usergroups1 = groups_get_user_groups($course1->id, $user1->id);
1198 $usergroups2 = groups_get_user_groups($course2->id, $user2->id);;
1200 // Assert return data.
1201 $this->assertEquals($group1->id, $usergroups1[0][0]);
1202 $this->assertEquals($group2->id, $usergroups2[0][0]);
1204 // Now, test with groupings.
1205 $grouping1 = $generator->create_grouping(array('courseid' => $course1->id));
1206 $grouping2 = $generator->create_grouping(array('courseid' => $course2->id));
1208 // Assign the groups to grouping.
1209 groups_assign_grouping($grouping1->id, $group1->id);
1210 groups_assign_grouping($grouping2->id, $group2->id);
1211 groups_assign_grouping($grouping2->id, $group3->id);
1213 // Test with grouping.
1214 $usergroups1 = groups_get_user_groups($course1->id, $user1->id);
1215 $usergroups2 = groups_get_user_groups($course2->id, $user2->id);
1216 $this->assertArrayHasKey($grouping1->id, $usergroups1);
1217 $this->assertArrayHasKey($grouping2->id, $usergroups2);
1219 // Test user without a group.
1220 $usergroups1 = groups_get_user_groups($course2->id, $user3->id);
1221 $this->assertCount(0, $usergroups1[0]);
1223 // Test with userid = 0.
1224 $usergroups1 = groups_get_user_groups($course1->id, 0);
1225 $usergroups2 = groups_get_user_groups($course2->id, 0);
1226 $this->assertCount(0, $usergroups1[0]);
1227 $this->assertCount(0, $usergroups2[0]);
1229 // Test with courseid = 0.
1230 $usergroups1 = groups_get_user_groups(0, $user1->id);
1231 $usergroups2 = groups_get_user_groups(0, $user2->id);
1232 $this->assertCount(0, $usergroups1[0]);
1233 $this->assertCount(0, $usergroups2[0]);
1237 * Create dummy groups array for use in menu tests
1238 * @param int $number
1239 * @return array
1241 protected function make_group_list($number) {
1242 $testgroups = array();
1243 for ($a = 0; $a < $number; $a++) {
1244 $grp = new \stdClass();
1245 $grp->id = 100 + $a;
1246 $grp->name = 'test group ' . $grp->id;
1247 $testgroups[$grp->id] = $grp;
1249 return $testgroups;
1252 public function test_groups_sort_menu_options_empty(): void {
1253 $this->assertEquals(array(), groups_sort_menu_options(array(), array()));
1256 public function test_groups_sort_menu_options_allowed_goups_only(): void {
1257 $this->assertEquals(array(
1258 100 => 'test group 100',
1259 101 => 'test group 101',
1260 ), groups_sort_menu_options($this->make_group_list(2), array()));
1263 public function test_groups_sort_menu_options_user_goups_only(): void {
1264 $this->assertEquals(array(
1265 100 => 'test group 100',
1266 101 => 'test group 101',
1267 ), groups_sort_menu_options(array(), $this->make_group_list(2)));
1270 public function test_groups_sort_menu_options_user_both(): void {
1271 $this->assertEquals(array(
1272 1 => array(get_string('mygroups', 'group') => array(
1273 100 => 'test group 100',
1274 101 => 'test group 101',
1276 2 => array(get_string('othergroups', 'group') => array(
1277 102 => 'test group 102',
1278 103 => 'test group 103',
1280 ), groups_sort_menu_options($this->make_group_list(4), $this->make_group_list(2)));
1283 public function test_groups_sort_menu_options_user_both_many_groups(): void {
1284 $this->assertEquals(array(
1285 1 => array(get_string('mygroups', 'group') => array(
1286 100 => 'test group 100',
1287 101 => 'test group 101',
1289 2 => array (get_string('othergroups', 'group') => array(
1290 102 => 'test group 102',
1291 103 => 'test group 103',
1292 104 => 'test group 104',
1293 105 => 'test group 105',
1294 106 => 'test group 106',
1295 107 => 'test group 107',
1296 108 => 'test group 108',
1297 109 => 'test group 109',
1298 110 => 'test group 110',
1299 111 => 'test group 111',
1300 112 => 'test group 112',
1302 ), groups_sort_menu_options($this->make_group_list(13), $this->make_group_list(2)));
1306 * Tests for groups_user_groups_visible.
1308 public function test_groups_user_groups_visible(): void {
1309 global $DB;
1311 $generator = $this->getDataGenerator();
1312 $this->resetAfterTest();
1313 $this->setAdminUser();
1315 // Create a course category, course and groups.
1316 $cat = $generator->create_category(array('parent' => 0));
1317 $course = $generator->create_course(array('category' => $cat->id));
1318 $coursecontext = \context_course::instance($course->id);
1319 $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
1320 $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
1321 $group3 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 3'));
1322 $group4 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 4'));
1324 // Create cm.
1325 $assign = $generator->create_module("assign", array('course' => $course->id));
1326 $cm = get_coursemodule_from_instance("assign", $assign->id);
1328 // Create users.
1329 $user1 = $generator->create_user(); // Normal user.
1330 $user2 = $generator->create_user(); // Normal user.
1331 $user3 = $generator->create_user(); // Teacher, access all groups.
1332 $user4 = $generator->create_user(); // Normal user.
1334 // Enrol users into the course.
1335 $generator->enrol_user($user1->id, $course->id);
1336 $generator->enrol_user($user2->id, $course->id);
1337 $generator->enrol_user($user4->id, $course->id);
1339 // Assign groups.
1340 // User1 and User4 share groups.
1341 groups_add_member($group1, $user1);
1342 groups_add_member($group2, $user2);
1343 groups_add_member($group1, $user4);
1345 // Give capability at course level to the user to access all groups.
1346 $role = $DB->get_field("role", "id", array("shortname" => "manager"));
1347 $generator->enrol_user($user3->id, $course->id, $role);
1348 // Make sure the user has the capability.
1349 assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role, $coursecontext->id);
1351 // Normal users in different groups.
1352 $this->setUser($user1);
1354 // No groups , not forced.
1355 $result = groups_user_groups_visible($course, $user2->id);
1356 $this->assertTrue($result);
1358 $cm->groupmode = NOGROUPS;
1359 $result = groups_user_groups_visible($course, $user2->id, $cm);
1360 $this->assertTrue($result); // Cm with no groups.
1362 $cm->groupmode = SEPARATEGROUPS;
1363 $result = groups_user_groups_visible($course, $user2->id, $cm);
1364 $this->assertFalse($result); // Cm with separate groups.
1366 $cm->groupmode = VISIBLEGROUPS;
1367 $result = groups_user_groups_visible($course, $user2->id, $cm);
1368 $this->assertTrue($result); // Cm with visible groups.
1370 // No groups, forced.
1371 $course->groupmode = NOGROUPS;
1372 $course->groupmodeforce = true;
1373 update_course($course);
1374 $result = groups_user_groups_visible($course, $user2->id);
1375 $this->assertTrue($result);
1377 $cm->groupmode = NOGROUPS;
1378 $result = groups_user_groups_visible($course, $user2->id, $cm);
1379 $this->assertTrue($result); // Cm with no groups.
1381 $cm->groupmode = SEPARATEGROUPS;
1382 $result = groups_user_groups_visible($course, $user2->id, $cm);
1383 $this->assertTrue($result); // Cm with separate groups.
1385 $cm->groupmode = SEPARATEGROUPS;
1386 $result = groups_user_groups_visible($course, $user2->id);
1387 $this->assertTrue($result); // Cm with visible groups.
1389 // Visible groups, forced.
1390 $course->groupmode = VISIBLEGROUPS;
1391 $course->groupmodeforce = true;
1392 update_course($course);
1393 $result = groups_user_groups_visible($course, $user2->id);
1394 $this->assertTrue($result);
1396 $cm->groupmode = NOGROUPS;
1397 $result = groups_user_groups_visible($course, $user2->id, $cm);
1398 $this->assertTrue($result); // Cm with no groups.
1400 $cm->groupmode = SEPARATEGROUPS;
1401 $result = groups_user_groups_visible($course, $user2->id, $cm);
1402 $this->assertTrue($result); // Cm with separate groups.
1404 $cm->groupmode = VISIBLEGROUPS;
1405 $result = groups_user_groups_visible($course, $user2->id, $cm);
1406 $this->assertTrue($result); // Cm with visible groups.
1408 // Visible groups, not forced.
1409 $course->groupmode = VISIBLEGROUPS;
1410 $course->groupmodeforce = false;
1411 update_course($course);
1412 $result = groups_user_groups_visible($course, $user2->id);
1413 $this->assertTrue($result);
1415 $cm->groupmode = NOGROUPS;
1416 $result = groups_user_groups_visible($course, $user2->id, $cm);
1417 $this->assertTrue($result); // Cm with no groups.
1419 $cm->groupmode = SEPARATEGROUPS;
1420 $result = groups_user_groups_visible($course, $user2->id, $cm);
1421 $this->assertFalse($result); // Cm with separate groups.
1423 $cm->groupmode = VISIBLEGROUPS;
1424 $result = groups_user_groups_visible($course, $user2->id, $cm);
1425 $this->assertTrue($result); // Cm with visible groups.
1427 // Separate groups, forced.
1428 $course->groupmode = SEPARATEGROUPS;
1429 $course->groupmodeforce = true;
1430 update_course($course);
1431 $result = groups_user_groups_visible($course, $user2->id);
1432 $this->assertFalse($result);
1434 $result = groups_user_groups_visible($course, $user3->id);
1435 $this->assertFalse($result); // Requesting all groups.
1437 $cm->groupmode = NOGROUPS;
1438 $result = groups_user_groups_visible($course, $user2->id, $cm);
1439 $this->assertFalse($result); // Cm with no groups.
1441 $cm->groupmode = SEPARATEGROUPS;
1442 $result = groups_user_groups_visible($course, $user2->id, $cm);
1443 $this->assertFalse($result); // Cm with separate groups.
1445 $result = groups_user_groups_visible($course, $user3->id, $cm);
1446 $this->assertTrue($result);
1448 $cm->groupmode = VISIBLEGROUPS;
1449 $result = groups_user_groups_visible($course, $user2->id, $cm);
1450 $this->assertFalse($result); // Cm with visible groups.
1452 // Separate groups, not forced.
1453 $course->groupmode = SEPARATEGROUPS;
1454 $course->groupmodeforce = false;
1455 update_course($course);
1456 $result = groups_user_groups_visible($course, $user2->id);
1457 $this->assertFalse($result);
1459 $result = groups_user_groups_visible($course, $user3->id);
1460 $this->assertFalse($result); // Requesting all groups.
1462 $cm->groupmode = NOGROUPS;
1463 $result = groups_user_groups_visible($course, $user2->id, $cm);
1464 $this->assertTrue($result); // Cm with no groups.
1466 $cm->groupmode = SEPARATEGROUPS;
1467 $result = groups_user_groups_visible($course, $user2->id, $cm);
1468 $this->assertFalse($result); // Cm with separate groups.
1470 $cm->groupmode = VISIBLEGROUPS;
1471 $result = groups_user_groups_visible($course, $user2->id, $cm);
1472 $this->assertTrue($result); // Cm with visible groups.
1474 // Users sharing groups.
1476 // No groups , not forced.
1477 $course->groupmode = NOGROUPS;
1478 $course->groupmodeforce = false;
1479 update_course($course);
1481 $result = groups_user_groups_visible($course, $user4->id);
1482 $this->assertTrue($result);
1484 $cm->groupmode = NOGROUPS;
1485 $result = groups_user_groups_visible($course, $user4->id, $cm);
1486 $this->assertTrue($result); // Cm with no groups.
1488 $cm->groupmode = SEPARATEGROUPS;
1489 $result = groups_user_groups_visible($course, $user4->id, $cm);
1490 $this->assertTrue($result); // Cm with separate groups.
1492 $cm->groupmode = VISIBLEGROUPS;
1493 $result = groups_user_groups_visible($course, $user4->id, $cm);
1494 $this->assertTrue($result); // Cm with visible groups.
1496 // No groups, forced.
1497 $course->groupmode = NOGROUPS;
1498 $course->groupmodeforce = true;
1499 update_course($course);
1500 $result = groups_user_groups_visible($course, $user4->id);
1501 $this->assertTrue($result);
1503 $cm->groupmode = NOGROUPS;
1504 $result = groups_user_groups_visible($course, $user4->id, $cm);
1505 $this->assertTrue($result); // Cm with no groups.
1507 $cm->groupmode = SEPARATEGROUPS;
1508 $result = groups_user_groups_visible($course, $user4->id, $cm);
1509 $this->assertTrue($result); // Cm with separate groups.
1511 $cm->groupmode = SEPARATEGROUPS;
1512 $result = groups_user_groups_visible($course, $user4->id, $cm);
1513 $this->assertTrue($result); // Cm with visible groups.
1515 // Visible groups, forced.
1516 $course->groupmode = VISIBLEGROUPS;
1517 $course->groupmodeforce = true;
1518 update_course($course);
1519 $result = groups_user_groups_visible($course, $user4->id);
1520 $this->assertTrue($result);
1522 $cm->groupmode = NOGROUPS;
1523 $result = groups_user_groups_visible($course, $user4->id, $cm);
1524 $this->assertTrue($result); // Cm with no groups.
1526 $cm->groupmode = SEPARATEGROUPS;
1527 $result = groups_user_groups_visible($course, $user4->id, $cm);
1528 $this->assertTrue($result); // Cm with separate groups.
1530 $cm->groupmode = VISIBLEGROUPS;
1531 $result = groups_user_groups_visible($course, $user4->id, $cm);
1532 $this->assertTrue($result); // Cm with visible groups.
1534 // Visible groups, not forced.
1535 $course->groupmode = VISIBLEGROUPS;
1536 $course->groupmodeforce = false;
1537 update_course($course);
1538 $result = groups_user_groups_visible($course, $user4->id);
1539 $this->assertTrue($result);
1541 $cm->groupmode = NOGROUPS;
1542 $result = groups_user_groups_visible($course, $user4->id, $cm);
1543 $this->assertTrue($result); // Cm with no groups.
1545 $cm->groupmode = SEPARATEGROUPS;
1546 $result = groups_user_groups_visible($course, $user4->id, $cm);
1547 $this->assertTrue($result); // Cm with separate groups.
1549 $cm->groupmode = VISIBLEGROUPS;
1550 $result = groups_user_groups_visible($course, $user4->id, $cm);
1551 $this->assertTrue($result); // Cm with visible groups.
1553 // Separate groups, forced.
1554 $course->groupmode = SEPARATEGROUPS;
1555 $course->groupmodeforce = true;
1556 update_course($course);
1557 $result = groups_user_groups_visible($course, $user4->id);
1558 $this->assertTrue($result);
1560 $result = groups_user_groups_visible($course, $user3->id);
1561 $this->assertFalse($result); // Requesting all groups.
1563 $cm->groupmode = NOGROUPS;
1564 $result = groups_user_groups_visible($course, $user4->id, $cm);
1565 $this->assertTrue($result); // Cm with no groups.
1567 $cm->groupmode = SEPARATEGROUPS;
1568 $result = groups_user_groups_visible($course, $user4->id, $cm);
1569 $this->assertTrue($result); // Cm with separate groups.
1571 $result = groups_user_groups_visible($course, $user3->id, $cm);
1572 $this->assertTrue($result);
1574 $cm->groupmode = VISIBLEGROUPS;
1575 $result = groups_user_groups_visible($course, $user4->id, $cm);
1576 $this->assertTrue($result); // Cm with visible groups.
1578 // Separate groups, not forced.
1579 $course->groupmode = SEPARATEGROUPS;
1580 $course->groupmodeforce = false;
1581 update_course($course);
1582 $result = groups_user_groups_visible($course, $user4->id);
1583 $this->assertTrue($result);
1585 $result = groups_user_groups_visible($course, $user3->id);
1586 $this->assertFalse($result); // Requesting all groups.
1588 $cm->groupmode = NOGROUPS;
1589 $result = groups_user_groups_visible($course, $user4->id, $cm);
1590 $this->assertTrue($result); // Cm with no groups.
1592 $cm->groupmode = SEPARATEGROUPS;
1593 $result = groups_user_groups_visible($course, $user4->id, $cm);
1594 $this->assertTrue($result); // Cm with separate groups.
1596 $cm->groupmode = VISIBLEGROUPS;
1597 $result = groups_user_groups_visible($course, $user4->id, $cm);
1598 $this->assertTrue($result); // Cm with visible groups.
1600 // For teacher with access all groups.
1602 // No groups , not forced.
1603 $course->groupmode = NOGROUPS;
1604 $course->groupmodeforce = false;
1605 update_course($course);
1607 $this->setUser($user3);
1609 $result = groups_user_groups_visible($course, $user1->id);
1610 $this->assertTrue($result);
1611 $result = groups_user_groups_visible($course, $user1->id);
1612 $this->assertTrue($result); // Requesting all groups.
1614 $cm->groupmode = NOGROUPS;
1615 $result = groups_user_groups_visible($course, $user1->id, $cm);
1616 $this->assertTrue($result); // Cm with no groups.
1618 $cm->groupmode = SEPARATEGROUPS;
1619 $result = groups_user_groups_visible($course, $user1->id, $cm);
1620 $this->assertTrue($result); // Cm with separate groups.
1621 $result = groups_user_groups_visible($course, $user2->id, $cm);
1622 $this->assertTrue($result); // Cm with separate groups.
1624 $cm->groupmode = VISIBLEGROUPS;
1625 $result = groups_user_groups_visible($course, $user1->id, $cm);
1626 $this->assertTrue($result); // Cm with visible groups.
1628 // No groups, forced.
1629 $course->groupmode = NOGROUPS;
1630 $course->groupmodeforce = true;
1631 update_course($course);
1632 $result = groups_user_groups_visible($course, $user1->id);
1633 $this->assertTrue($result);
1634 $result = groups_user_groups_visible($course, $user1->id);
1635 $this->assertTrue($result); // Requesting all groups.
1637 $cm->groupmode = NOGROUPS;
1638 $result = groups_user_groups_visible($course, $user1->id, $cm);
1639 $this->assertTrue($result); // Cm with no groups.
1641 $cm->groupmode = SEPARATEGROUPS;
1642 $result = groups_user_groups_visible($course, $user1->id, $cm);
1643 $this->assertTrue($result); // Cm with separate groups.
1644 $result = groups_user_groups_visible($course, $user2->id, $cm);
1645 $this->assertTrue($result); // Cm with separate groups.
1647 $cm->groupmode = SEPARATEGROUPS;
1648 $result = groups_user_groups_visible($course, $user1->id, $cm);
1649 $this->assertTrue($result); // Cm with visible groups.
1651 // Visible groups, forced.
1652 $course->groupmode = VISIBLEGROUPS;
1653 $course->groupmodeforce = true;
1654 update_course($course);
1655 $result = groups_user_groups_visible($course, $user1->id);
1656 $this->assertTrue($result);
1657 $result = groups_user_groups_visible($course, $user1->id);
1658 $this->assertTrue($result); // Requesting all groups.
1660 $cm->groupmode = NOGROUPS;
1661 $result = groups_user_groups_visible($course, $user1->id, $cm);
1662 $this->assertTrue($result); // Cm with no groups.
1664 $cm->groupmode = SEPARATEGROUPS;
1665 $result = groups_user_groups_visible($course, $user1->id, $cm);
1666 $this->assertTrue($result); // Cm with separate groups.
1667 $result = groups_user_groups_visible($course, $user2->id, $cm);
1668 $this->assertTrue($result); // Cm with separate groups.
1670 $cm->groupmode = VISIBLEGROUPS;
1671 $result = groups_user_groups_visible($course, $user1->id, $cm);
1672 $this->assertTrue($result); // Cm with visible groups.
1674 // Visible groups, not forced.
1675 $course->groupmode = VISIBLEGROUPS;
1676 $course->groupmodeforce = false;
1677 update_course($course);
1678 $result = groups_user_groups_visible($course, $user1->id);
1679 $this->assertTrue($result);
1680 $result = groups_user_groups_visible($course, $user1->id);
1681 $this->assertTrue($result); // Requesting all groups.
1683 $cm->groupmode = NOGROUPS;
1684 $result = groups_user_groups_visible($course, $user1->id, $cm);
1685 $this->assertTrue($result); // Cm with no groups.
1687 $cm->groupmode = SEPARATEGROUPS;
1688 $result = groups_user_groups_visible($course, $user1->id, $cm);
1689 $this->assertTrue($result); // Cm with separate groups.
1690 $result = groups_user_groups_visible($course, $user2->id, $cm);
1691 $this->assertTrue($result); // Cm with separate groups.
1693 $cm->groupmode = VISIBLEGROUPS;
1694 $result = groups_user_groups_visible($course, $user1->id, $cm);
1695 $this->assertTrue($result); // Cm with visible groups.
1697 // Separate groups, forced.
1698 $course->groupmode = SEPARATEGROUPS;
1699 $course->groupmodeforce = true;
1700 update_course($course);
1701 $result = groups_user_groups_visible($course, $user1->id);
1702 $this->assertTrue($result);
1703 $result = groups_user_groups_visible($course, $user2->id);
1704 $this->assertTrue($result);
1705 $result = groups_user_groups_visible($course, $user2->id);
1706 $this->assertTrue($result); // Requesting all groups.
1707 $result = groups_user_groups_visible($course, $user3->id);
1708 $this->assertTrue($result); // Requesting all groups.
1709 $result = groups_user_groups_visible($course, $user3->id);
1710 $this->assertTrue($result);
1712 $cm->groupmode = NOGROUPS;
1713 $result = groups_user_groups_visible($course, $user1->id, $cm);
1714 $this->assertTrue($result); // Cm with no groups.
1716 $cm->groupmode = SEPARATEGROUPS;
1717 $result = groups_user_groups_visible($course, $user1->id, $cm);
1718 $this->assertTrue($result); // Cm with separate groups.
1719 $result = groups_user_groups_visible($course, $user2->id, $cm);
1720 $this->assertTrue($result); // Cm with separate groups.
1721 $result = groups_user_groups_visible($course, $user3->id, $cm);
1722 $this->assertTrue($result);
1724 $cm->groupmode = VISIBLEGROUPS;
1725 $result = groups_user_groups_visible($course, $user1->id, $cm);
1726 $this->assertTrue($result); // Cm with visible groups.
1728 // Separate groups, not forced.
1729 $course->groupmode = SEPARATEGROUPS;
1730 $course->groupmodeforce = false;
1731 update_course($course);
1732 $result = groups_user_groups_visible($course, $user1->id);
1733 $this->assertTrue($result);
1734 $result = groups_user_groups_visible($course, $user2->id);
1735 $this->assertTrue($result);
1736 $result = groups_user_groups_visible($course, $user2->id);
1737 $this->assertTrue($result); // Requesting all groups.
1738 $result = groups_user_groups_visible($course, $user3->id);
1739 $this->assertTrue($result); // Requesting all groups.
1741 $cm->groupmode = NOGROUPS;
1742 $result = groups_user_groups_visible($course, $user1->id, $cm);
1743 $this->assertTrue($result); // Cm with no groups.
1745 $cm->groupmode = SEPARATEGROUPS;
1746 $result = groups_user_groups_visible($course, $user1->id, $cm);
1747 $this->assertTrue($result); // Cm with separate groups.
1748 $result = groups_user_groups_visible($course, $user2->id, $cm);
1749 $this->assertTrue($result); // Cm with separate groups.
1751 $cm->groupmode = VISIBLEGROUPS;
1752 $result = groups_user_groups_visible($course, $user1->id, $cm);
1753 $this->assertTrue($result); // Cm with visible groups.
1757 * Tests for groups_get_groups_members() method.
1759 * @covers ::groups_get_groups_members
1761 public function test_groups_get_groups_members(): void {
1762 $this->resetAfterTest(true);
1763 $generator = $this->getDataGenerator();
1765 // Create courses.
1766 $course1 = $generator->create_course();
1767 $course2 = $generator->create_course();
1769 // Create users.
1770 $user1 = $generator->create_user();
1771 $user2 = $generator->create_user();
1772 $user3 = $generator->create_user();
1774 // Enrol users.
1775 $generator->enrol_user($user1->id, $course1->id);
1776 $generator->enrol_user($user1->id, $course2->id);
1777 $generator->enrol_user($user2->id, $course2->id);
1778 $generator->enrol_user($user3->id, $course2->id);
1780 // Create groups.
1781 $group1 = $generator->create_group(array('courseid' => $course1->id));
1782 $group2 = $generator->create_group(array('courseid' => $course2->id));
1783 $group3 = $generator->create_group(array('courseid' => $course2->id));
1785 // Assign users to groups.
1786 $this->assertTrue($generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)));
1787 $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id)));
1788 $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)));
1790 // Test get_groups_members (with extra field and ordering).
1791 $members = groups_get_groups_members([$group1->id, $group2->id], ['lastaccess'], 'u.id ASC');
1792 $this->assertCount(2, $members);
1793 $this->assertEquals([$user1->id, $user2->id], array_keys($members));
1794 $this->assertTrue(isset($members[$user1->id]->lastaccess));
1795 $this->assertTrue(isset($members[$user2->id]->lastaccess));
1797 // Group with just one.
1798 $members = groups_get_groups_members([$group1->id]);
1799 $this->assertCount(1, $members);
1800 $this->assertEquals($user1->id, $members[$user1->id]->id);
1802 // Test the info matches group membership for the entire course.
1803 $groups = groups_get_all_groups($course1->id, 0, 0, 'g.*', true);
1804 $group1withmembers = array_pop($groups);
1806 // Compare the sorted keys of both arrays (should be list of user ids).
1807 $members = array_keys($members);
1808 sort($members);
1809 $group1members = array_keys($group1withmembers->members);
1810 sort($group1members);
1811 $this->assertEquals($members, $group1members);
1813 // Group with just one plus empty group.
1814 $members = groups_get_groups_members([$group1->id, $group3->id]);
1815 $this->assertCount(1, $members);
1816 $this->assertEquals($user1->id, $members[$user1->id]->id);
1818 // Empty group.
1819 $members = groups_get_groups_members([$group3->id]);
1820 $this->assertCount(0, $members);
1822 // Our second group.
1823 $members = groups_get_groups_members([$group2->id]);
1824 $this->assertEqualsCanonicalizing([$user1->id, $user2->id], array_column($members, 'id'));
1826 // Test the info matches group membership for the entire course.
1827 $groups = groups_get_all_groups($course2->id, 0, 0, 'g.*', true);
1828 $group2withmembers = $groups[$group2->id];
1830 // Compare the sorted keys of both arrays (should be list of user ids).
1831 $members = array_keys($members);
1832 sort($members);
1833 $group2members = array_keys($group2withmembers->members);
1834 sort($group2members);
1835 $this->assertEquals($members, $group2members);
1840 * Tests for groups_get_activity_shared_group_members() method.
1842 public function test_groups_get_activity_shared_group_members(): void {
1843 $this->resetAfterTest(true);
1844 $generator = $this->getDataGenerator();
1846 // Create courses.
1847 $course = $generator->create_course();
1849 // Create cm.
1850 $assign = $generator->create_module("assign", array('course' => $course->id));
1851 $cm = get_coursemodule_from_instance("assign", $assign->id);
1853 // Create users.
1854 $user1 = $generator->create_user();
1855 $user2 = $generator->create_user();
1856 $user3 = $generator->create_user();
1857 $user4 = $generator->create_user();
1859 // Enrol users.
1860 $generator->enrol_user($user1->id, $course->id);
1861 $generator->enrol_user($user2->id, $course->id);
1862 $generator->enrol_user($user3->id, $course->id);
1863 $generator->enrol_user($user4->id, $course->id);
1865 // Create groups.
1866 $group1 = $generator->create_group(array('courseid' => $course->id));
1867 $group2 = $generator->create_group(array('courseid' => $course->id));
1868 $group3 = $generator->create_group(array('courseid' => $course->id));
1870 // Assign users to groups.
1871 $generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1872 $generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
1873 $generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1874 $generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user3->id));
1876 // Retrieve users sharing groups with user1.
1877 $members = groups_get_activity_shared_group_members($cm, $user1->id);
1878 $this->assertCount(2, $members);
1879 $this->assertEqualsCanonicalizing([$user1->id, $user2->id], array_keys($members));
1881 // Retrieve users sharing groups with user2.
1882 $members = groups_get_activity_shared_group_members($cm, $user2->id);
1883 $this->assertCount(2, $members);
1884 $this->assertEqualsCanonicalizing([$user1->id, $user2->id], array_keys($members));
1886 // Retrieve users sharing groups with user3.
1887 $members = groups_get_activity_shared_group_members($cm, $user3->id);
1888 $this->assertCount(1, $members);
1889 $this->assertEquals($user3->id, $members[$user3->id]->id);
1891 // Retrieve users sharing groups with user without groups (user4).
1892 $members = groups_get_activity_shared_group_members($cm, $user4->id);
1893 $this->assertCount(0, $members);
1895 // Now, create a different activity using groupings.
1896 $grouping = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 1'));
1897 // Skip group 2.
1898 groups_assign_grouping($grouping->id, $group1->id);
1899 groups_assign_grouping($grouping->id, $group3->id);
1901 $assign = $generator->create_module("assign", array('course' => $course->id, 'groupingid' => $grouping->id));
1902 $cm = get_coursemodule_from_instance("assign", $assign->id);
1904 // Since the activity is forced to groupings (groups 1 and 3), I don't see members of group 2.
1905 $members = groups_get_activity_shared_group_members($cm, $user1->id);
1906 $this->assertCount(1, $members);
1907 $this->assertEquals($user1->id, $members[$user1->id]->id);
1909 // Add user1 to group 3 (in the grouping).
1910 $generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user1->id));
1911 $members = groups_get_activity_shared_group_members($cm, $user1->id);
1912 $this->assertCount(2, $members); // Now I see members of group 3.
1913 $this->assertEqualsCanonicalizing([$user1->id, $user3->id], array_keys($members));
1917 * Generate a set of groups with different visibility levels and users to assign to them.
1919 * @return array
1921 protected function create_groups_with_visibilty(): array {
1922 $this->resetAfterTest(true);
1923 $generator = $this->getDataGenerator();
1925 // Create courses.
1926 $course = $generator->create_course();
1928 // Create users.
1929 $users = [
1930 1 => $generator->create_user(),
1931 2 => $generator->create_user(),
1932 3 => $generator->create_user(),
1933 4 => $generator->create_user(),
1934 5 => $generator->create_user(),
1937 // Enrol users.
1938 $generator->enrol_user($users[1]->id, $course->id);
1939 $generator->enrol_user($users[2]->id, $course->id);
1940 $generator->enrol_user($users[3]->id, $course->id);
1941 $generator->enrol_user($users[4]->id, $course->id);
1942 $generator->enrol_user($users[5]->id, $course->id, 'editingteacher');
1944 // Create groups.
1945 $groups = [
1946 'all' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_ALL]),
1947 'members' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_MEMBERS]),
1948 'own' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_OWN]),
1949 'none' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_NONE]),
1952 return [
1953 $users,
1954 $groups,
1955 $course,
1960 * Tests getting groups and group members based on visibility settings.
1962 * This also covers the groupdata cache, since calls without $withmembers = true use the cache.
1964 * @covers \groups_get_all_groups()
1966 public function test_get_all_groups_with_visibility(): void {
1967 list($users, $groups, $course) = $this->create_groups_with_visibilty();
1969 // Assign users to groups.
1970 $generator = $this->getDataGenerator();
1971 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[1]->id]);
1972 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[1]->id]);
1973 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[2]->id]);
1974 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[1]->id]);
1975 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[3]->id]);
1976 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[4]->id]);
1978 $this->setUser($users[1]);
1979 $groups1 = groups_get_all_groups($course->id);
1980 // User1 is in groups all, members and own, and can see them.
1981 $this->assertArrayHasKey($groups['all']->id, $groups1);
1982 $this->assertArrayHasKey($groups['members']->id, $groups1);
1983 $this->assertArrayHasKey($groups['own']->id, $groups1);
1984 $this->assertArrayNotHasKey($groups['none']->id, $groups1);
1985 // User1 can see members of groups all and members, but only themselves in group own.
1986 $groupsmembers1 = groups_get_all_groups($course->id, 0, 0, 'g.*', true);
1987 $this->assertArrayHasKey($users[1]->id, $groupsmembers1[$groups['all']->id]->members);
1988 $this->assertArrayHasKey($users[1]->id, $groupsmembers1[$groups['members']->id]->members);
1989 $this->assertArrayHasKey($users[2]->id, $groupsmembers1[$groups['members']->id]->members);
1990 $this->assertArrayHasKey($users[1]->id, $groupsmembers1[$groups['own']->id]->members);
1991 $this->assertArrayNotHasKey($users[3]->id, $groupsmembers1[$groups['own']->id]->members);
1993 $this->setUser($users[2]);
1994 $groups2 = groups_get_all_groups($course->id);
1995 // User2 is in group members, and can see group all as well.
1996 $this->assertArrayHasKey($groups['all']->id, $groups2);
1997 $this->assertArrayHasKey($groups['members']->id, $groups2);
1998 $this->assertArrayNotHasKey($groups['own']->id, $groups2);
1999 $this->assertArrayNotHasKey($groups['none']->id, $groups2);
2000 // User2 can see members of groups all and members.
2001 $groupsmembers2 = groups_get_all_groups($course->id, 0, 0, 'g.*', true);
2002 $this->assertArrayHasKey($users[1]->id, $groupsmembers2[$groups['all']->id]->members);
2003 $this->assertArrayHasKey($users[1]->id, $groupsmembers2[$groups['members']->id]->members);
2004 $this->assertArrayHasKey($users[2]->id, $groupsmembers2[$groups['members']->id]->members);
2006 $this->setUser($users[3]);
2007 $groups3 = groups_get_all_groups($course->id);
2008 // User3 is in group own, and can see group all as well.
2009 $this->assertArrayHasKey($groups['all']->id, $groups3);
2010 $this->assertArrayNotHasKey($groups['members']->id, $groups3);
2011 $this->assertArrayHasKey($groups['own']->id, $groups3);
2012 $this->assertArrayNotHasKey($groups['none']->id, $groups3);
2013 $groupsmembers3 = groups_get_all_groups($course->id, 0, 0, 'g.*', true);
2014 // User3 can see members of group all, but only themselves in group own.
2015 $this->assertArrayHasKey($users[1]->id, $groupsmembers3[$groups['all']->id]->members);
2016 $this->assertArrayHasKey($users[3]->id, $groupsmembers3[$groups['own']->id]->members);
2017 $this->assertArrayNotHasKey($users[1]->id, $groupsmembers3[$groups['own']->id]->members);
2019 $this->setUser($users[4]);
2020 $groups4 = groups_get_all_groups($course->id);
2021 // User4 can see group all and its members. They are in group none but cannot see it.
2022 $this->assertArrayHasKey($groups['all']->id, $groups4);
2023 $this->assertArrayNotHasKey($groups['members']->id, $groups4);
2024 $this->assertArrayNotHasKey($groups['own']->id, $groups4);
2025 $this->assertArrayNotHasKey($groups['none']->id, $groups4);
2026 // User4 can see members of group all.
2027 $groupsmembers4 = groups_get_all_groups($course->id, 0, 0, 'g.*', true);
2028 $this->assertArrayHasKey($users[1]->id, $groupsmembers4[$groups['all']->id]->members);
2030 $this->setUser($users[5]);
2031 $groups5 = groups_get_all_groups($course->id);
2032 // User5 is has viewallgroups, so can see all groups.
2033 $this->assertArrayHasKey($groups['all']->id, $groups5);
2034 $this->assertArrayHasKey($groups['members']->id, $groups5);
2035 $this->assertArrayHasKey($groups['own']->id, $groups5);
2036 $this->assertArrayHasKey($groups['none']->id, $groups5);
2037 // User5 is has viewallgroups, so can see all members.
2038 $groupsmembers5 = groups_get_all_groups($course->id, 0, 0, 'g.*', true);
2039 $this->assertArrayHasKey($users[1]->id, $groupsmembers5[$groups['all']->id]->members);
2040 $this->assertArrayHasKey($users[1]->id, $groupsmembers5[$groups['members']->id]->members);
2041 $this->assertArrayHasKey($users[2]->id, $groupsmembers5[$groups['members']->id]->members);
2042 $this->assertArrayHasKey($users[1]->id, $groupsmembers5[$groups['own']->id]->members);
2043 $this->assertArrayHasKey($users[3]->id, $groupsmembers5[$groups['own']->id]->members);
2044 $this->assertArrayHasKey($users[4]->id, $groupsmembers5[$groups['none']->id]->members);
2049 * Tests getting groups the current user is a member of, with visibility settings applied.
2051 * @covers \groups_get_my_groups()
2053 public function test_get_my_groups_with_visibility(): void {
2054 list($users, $groups) = $this->create_groups_with_visibilty();
2056 // Assign users to groups.
2057 $generator = $this->getDataGenerator();
2058 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[1]->id]);
2059 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[1]->id]);
2060 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[1]->id]);
2061 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[1]->id]);
2062 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[5]->id]);
2063 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[5]->id]);
2064 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[5]->id]);
2065 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[5]->id]);
2067 $generator->role_assign('editingteacher', $users[5]->id, \context_system::instance());
2069 // User can see all groups they are in, except group with visibility::NONE.
2070 $this->setUser($users[1]);
2071 $groups1 = groups_get_my_groups();
2072 $this->assertCount(3, $groups1);
2073 $groupids1 = array_map(function($groupmember) {
2074 return $groupmember->groupid;
2075 }, $groups1);
2076 sort($groupids1);
2077 $this->assertEquals([$groups['all']->id, $groups['members']->id, $groups['own']->id], $groupids1);
2079 $this->setUser($users[5]);
2080 $groups2 = groups_get_my_groups();
2081 $this->assertCount(4, $groups2);
2082 $groupids2 = array_map(function($groupmember) {
2083 return $groupmember->groupid;
2084 }, $groups2);
2085 sort($groupids2);
2086 $this->assertEquals([$groups['all']->id, $groups['members']->id, $groups['own']->id, $groups['none']->id], $groupids2);
2090 * Tests getting groups a user is a member of, with visibility settings applied.
2092 * @covers \groups_get_user_groups()
2094 public function test_get_user_groups_with_visibility(): void {
2095 list($users, $groups, $course) = $this->create_groups_with_visibilty();
2097 // Assign users to groups.
2098 $generator = $this->getDataGenerator();
2099 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[1]->id]);
2100 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[1]->id]);
2101 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[2]->id]);
2102 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[1]->id]);
2103 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[3]->id]);
2104 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[4]->id]);
2105 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[1]->id]);
2107 // Run as unprivileged user.
2108 $this->setUser($users[1]);
2109 // Own groups - should see all groups except group with visibility::NONE.
2110 $usergroups1 = groups_get_user_groups($course->id, $users[1]->id);
2111 $this->assertEquals([$groups['all']->id, $groups['members']->id, $groups['own']->id], $usergroups1[0]);
2112 // Own groups including hidden - should see all groups.
2113 $usergroups1hidden = groups_get_user_groups($course->id, $users[1]->id, true);
2114 $this->assertEquals(
2115 [$groups['all']->id, $groups['members']->id, $groups['own']->id, $groups['none']->id],
2116 $usergroups1hidden[0]
2118 // Fellow member of a group with visiblity::MEMBERS. Should see that group.
2119 $usergroups2 = groups_get_user_groups($course->id, $users[2]->id);
2120 $this->assertEquals([$groups['members']->id], $usergroups2[0]);
2121 // Fellow member of a group with visiblity::OWN. Should not see that group.
2122 $usergroups3 = groups_get_user_groups($course->id, $users[3]->id);
2123 $this->assertEmpty($usergroups3[0]);
2124 // Fellow member of a group with visiblity::NONE. Should not see that group.
2125 $usergroups4 = groups_get_user_groups($course->id, $users[4]->id);
2126 $this->assertEmpty($usergroups4[0]);
2127 // Fellow member of a group with visiblity::NONE including hidden. Should see that group.
2128 $usergroups4hidden = groups_get_user_groups($course->id, $users[4]->id, true);
2129 $this->assertEquals([$groups['none']->id], $usergroups4hidden[0]);
2131 // Run as a user with viewhiddengroups. Should see all group memberships for each member.
2132 $this->setUser($users[5]);
2133 $usergroups1 = groups_get_user_groups($course->id, $users[1]->id);
2134 $this->assertEquals([$groups['all']->id, $groups['members']->id, $groups['own']->id, $groups['none']->id], $usergroups1[0]);
2135 // Fellow member of a group with visiblity::MEMBERS. Should see that group.
2136 $usergroups2 = groups_get_user_groups($course->id, $users[2]->id);
2137 $this->assertEquals([$groups['members']->id], $usergroups2[0]);
2138 // Fellow member of a group with visiblity::OWN. Should not see that group.
2139 $usergroups3 = groups_get_user_groups($course->id, $users[3]->id);
2140 $this->assertEquals([$groups['own']->id], $usergroups3[0]);
2141 // Fellow member of a group with visiblity::NONE. Should not see that group.
2142 $usergroups4 = groups_get_user_groups($course->id, $users[4]->id);
2143 $this->assertEquals([$groups['none']->id], $usergroups4[0]);
2148 * Test groups_is_member() using groups with different visibility settings.
2150 * @covers \groups_is_member()
2152 public function test_groups_is_member_with_visibility(): void {
2153 list($users, $groups) = $this->create_groups_with_visibilty();
2155 // Assign users to groups.
2156 $generator = $this->getDataGenerator();
2157 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[1]->id]);
2158 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[1]->id]);
2159 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[2]->id]);
2160 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[1]->id]);
2161 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[3]->id]);
2162 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[4]->id]);
2163 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[1]->id]);
2165 // Run as unprivileged user.
2166 $this->setUser($users[1]);
2167 $this->assertTrue(groups_is_member($groups['all']->id, $users[1]->id)); // All can see members.
2168 $this->assertTrue(groups_is_member($groups['members']->id, $users[1]->id)); // Can see members.
2169 $this->assertTrue(groups_is_member($groups['own']->id, $users[1]->id)); // Can see own membership.
2170 $this->assertFalse(groups_is_member($groups['none']->id, $users[1]->id)); // Cannot see group.
2172 $this->assertFalse(groups_is_member($groups['all']->id, $users[2]->id)); // Not a member.
2173 $this->assertTrue(groups_is_member($groups['members']->id, $users[2]->id)); // Can see other members.
2174 $this->assertFalse(groups_is_member($groups['own']->id, $users[3]->id)); // Can only see own membership, not others.
2175 $this->assertFalse(groups_is_member($groups['none']->id, $users[4]->id)); // Cannot see group.
2177 // Run as a user not in group 1 or 2.
2178 $this->setUser($users[3]);
2179 $this->assertTrue(groups_is_member($groups['all']->id, $users[1]->id)); // All can see members.
2180 $this->assertFalse(groups_is_member($groups['members']->id, $users[2]->id)); // Cannot see members of the group.
2182 // Run as a user with viewhiddengroups. Should be able to see memberships that exist in any group.
2183 $this->setUser($users[5]);
2184 $this->assertTrue(groups_is_member($groups['all']->id, $users[1]->id));
2185 $this->assertTrue(groups_is_member($groups['members']->id, $users[1]->id));
2186 $this->assertTrue(groups_is_member($groups['own']->id, $users[1]->id));
2187 $this->assertTrue(groups_is_member($groups['none']->id, $users[1]->id));
2189 $this->assertFalse(groups_is_member($groups['all']->id, $users[2]->id)); // Not a member.
2190 $this->assertTrue(groups_is_member($groups['members']->id, $users[2]->id));
2191 $this->assertTrue(groups_is_member($groups['own']->id, $users[3]->id));
2192 $this->assertTrue(groups_is_member($groups['none']->id, $users[4]->id));
2196 * Test groups_get_members
2198 * @covers ::groups_get_members
2200 public function test_groups_get_members(): void {
2201 $this->resetAfterTest();
2203 $course = $this->getDataGenerator()->create_course();
2204 $userone = $this->getDataGenerator()->create_and_enrol($course);
2205 $usertwo = $this->getDataGenerator()->create_and_enrol($course);
2207 $group = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
2208 $this->getDataGenerator()->create_group_member(['groupid' => $group->id, 'userid' => $userone->id]);
2209 $this->getDataGenerator()->create_group_member(['groupid' => $group->id, 'userid' => $usertwo->id]);
2211 $users = groups_get_members($group->id);
2212 $this->assertEqualsCanonicalizing([$userone->id, $usertwo->id], array_column($users, 'id'));
2214 // Test invalid group.
2215 $users = groups_get_members(-1);
2216 $this->assertEmpty($users);
2220 * Test groups_get_members() using groups with different visibility settings.
2222 * @covers ::groups_get_members
2224 public function test_groups_get_members_with_visibility(): void {
2225 list($users, $groups) = $this->create_groups_with_visibilty();
2227 // Assign users to groups.
2228 $generator = $this->getDataGenerator();
2229 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[1]->id]);
2230 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[1]->id]);
2231 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[2]->id]);
2232 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[1]->id]);
2233 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[3]->id]);
2234 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[4]->id]);
2235 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[1]->id]);
2237 // Run as unprivileged user.
2238 $this->setUser($users[1]);
2239 $this->assertEquals([$users[1]->id],
2240 array_keys(groups_get_members($groups['all']->id, 'u.id', 'u.id'))); // All can see members.
2241 $this->assertEquals([$users[1]->id, $users[2]->id],
2242 array_keys(groups_get_members($groups['members']->id, 'u.id', 'u.id'))); // Can see members.
2243 $this->assertEquals([$users[1]->id],
2244 array_keys(groups_get_members($groups['own']->id, 'u.id', 'u.id'))); // Can see own membership.
2245 $this->assertEquals([], array_keys(groups_get_members($groups['none']->id, 'u.id', 'u.id'))); // Cannot see group.
2247 // Run as a user not in group 1 or 2.
2248 $this->setUser($users[3]);
2249 $this->assertEquals([$users[1]->id],
2250 array_keys(groups_get_members($groups['all']->id, 'u.id', 'u.id'))); // All can see members.
2251 $this->assertEquals([], array_keys(groups_get_members($groups['members']->id, 'u.id', 'u.id'))); // Cannot see members.
2253 // Run as a user with viewhiddengroups. Should be able to see memberships that exist in any group.
2254 $this->setUser($users[5]);
2255 $this->assertEquals([$users[1]->id], array_keys(groups_get_members($groups['all']->id, 'u.id', 'u.id')));
2256 $this->assertEquals([$users[1]->id, $users[2]->id],
2257 array_keys(groups_get_members($groups['members']->id, 'u.id', 'u.id')));
2258 $this->assertEquals([$users[1]->id, $users[3]->id],
2259 array_keys(groups_get_members($groups['own']->id, 'u.id', 'u.id')));
2260 $this->assertEquals([$users[1]->id, $users[4]->id],
2261 array_keys(groups_get_members($groups['none']->id, 'u.id', 'u.id')));
2265 * Test groups_get_groups_members() using groups with different visibility settings.
2267 * @covers \groups_get_groups_members()
2269 public function test_groups_get_groups_members_with_visibility(): void {
2270 list($users, $groups) = $this->create_groups_with_visibilty();
2272 // Assign users to groups.
2273 $generator = $this->getDataGenerator();
2274 $generator->create_group_member(['groupid' => $groups['all']->id, 'userid' => $users[1]->id]);
2275 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[1]->id]);
2276 $generator->create_group_member(['groupid' => $groups['members']->id, 'userid' => $users[2]->id]);
2277 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[1]->id]);
2278 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $users[3]->id]);
2279 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[4]->id]);
2280 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $users[1]->id]);
2282 $groupids = [$groups['all']->id, $groups['members']->id, $groups['own']->id, $groups['none']->id];
2284 $this->setUser($users[1]);
2285 // Can see self in group1/3, other users in group2.
2286 $this->assertEquals([$users[1]->id, $users[2]->id], array_keys(groups_get_groups_members($groupids, null, 'id ASC')));
2288 $this->setUser($users[2]);
2289 // Can see self in group2, user1 from group1/2.
2290 $this->assertEquals([$users[1]->id, $users[2]->id], array_keys(groups_get_groups_members($groupids, null, 'id ASC')));
2292 $this->setUser($users[3]);
2293 // Can see self in group3, user1 from group1.
2294 $this->assertEquals([$users[1]->id, $users[3]->id], array_keys(groups_get_groups_members($groupids, null, 'id ASC')));
2296 $this->setUser($users[4]);
2297 // Can see user1 from group1, cannot see self in group4.
2298 $this->assertEquals([$users[1]->id], array_keys(groups_get_groups_members($groupids, null, 'id ASC')));
2300 $this->setUser($users[5]);
2301 // Can see all users from all groups.
2302 $this->assertEquals([$users[1]->id, $users[2]->id, $users[3]->id, $users[4]->id],
2303 array_keys(groups_get_groups_members($groupids, null, 'id ASC')));
2307 * Only groups with participation == true should be returned for an activity.
2309 * @covers \groups_get_activity_allowed_groups()
2310 * @return void
2311 * @throws \coding_exception
2313 public function test_groups_get_activity_allowed_groups(): void {
2314 $this->resetAfterTest(true);
2315 $generator = $this->getDataGenerator();
2317 // Create courses.
2318 $course = $generator->create_course();
2320 // Create user.
2321 $user = $generator->create_user();
2323 // Enrol user.
2324 $generator->enrol_user($user->id, $course->id);
2326 // Create groups.
2327 $groups = [
2328 'all-p' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_ALL]),
2329 'members-p' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_MEMBERS]),
2330 'all-n' => $generator->create_group([
2331 'courseid' => $course->id,
2332 'visibility' => GROUPS_VISIBILITY_ALL,
2333 'participation' => false
2335 'members-n' => $generator->create_group([
2336 'courseid' => $course->id,
2337 'visibility' => GROUPS_VISIBILITY_MEMBERS,
2338 'participation' => false
2340 'own' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_OWN]),
2341 'none' => $generator->create_group(['courseid' => $course->id, 'visibility' => GROUPS_VISIBILITY_NONE]),
2343 // Add user to all groups.
2344 $generator->create_group_member(['groupid' => $groups['all-p']->id, 'userid' => $user->id]);
2345 $generator->create_group_member(['groupid' => $groups['members-p']->id, 'userid' => $user->id]);
2346 $generator->create_group_member(['groupid' => $groups['all-n']->id, 'userid' => $user->id]);
2347 $generator->create_group_member(['groupid' => $groups['members-n']->id, 'userid' => $user->id]);
2348 $generator->create_group_member(['groupid' => $groups['own']->id, 'userid' => $user->id]);
2349 $generator->create_group_member(['groupid' => $groups['none']->id, 'userid' => $user->id]);
2351 $module = $generator->create_module('forum', ['course' => $course->id]);
2352 $cm = get_fast_modinfo($course)->get_cm($module->cmid);
2354 $activitygroups = groups_get_activity_allowed_groups($cm, $user->id);
2356 $this->assertContains((int)$groups['all-p']->id, array_keys($activitygroups));
2357 $this->assertContains((int)$groups['members-p']->id, array_keys($activitygroups));
2358 $this->assertNotContains((int)$groups['all-n']->id, array_keys($activitygroups));
2359 $this->assertNotContains((int)$groups['members-n']->id, array_keys($activitygroups));
2360 $this->assertNotContains((int)$groups['own']->id, array_keys($activitygroups));
2361 $this->assertNotContains((int)$groups['none']->id, array_keys($activitygroups));