Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 38 and 311] [Versions 39 and 311]

   1  <?php
   2  // This file is part of Moodle - http://moodle.org/
   3  //
   4  // Moodle is free software: you can redistribute it and/or modify
   5  // it under the terms of the GNU General Public License as published by
   6  // the Free Software Foundation, either version 3 of the License, or
   7  // (at your option) any later version.
   8  //
   9  // Moodle is distributed in the hope that it will be useful,
  10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  // GNU General Public License for more details.
  13  //
  14  // You should have received a copy of the GNU General Public License
  15  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  16  
  17  namespace core;
  18  
  19  /**
  20   * Unit tests for lib/grouplib.php
  21   *
  22   * @package    core
  23   * @copyright  2007 onwards Martin Dougiamas (http://dougiamas.com)
  24   * @author     Andrew Nicols
  25   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  class grouplib_test extends \advanced_testcase {
  28  
  29      public function test_groups_get_group_by_idnumber() {
  30          $this->resetAfterTest(true);
  31  
  32          $generator = $this->getDataGenerator();
  33  
  34          // Create a course category and course.
  35          $cat = $generator->create_category(array('parent' => 0));
  36          $course = $generator->create_course(array('category' => $cat->id));
  37  
  38          $idnumber1 = 'idnumber1';
  39          $idnumber2 = 'idnumber2';
  40  
  41          /*
  42           * Test with an empty and a null idnumber.
  43           */
  44          // An empty idnumber should always return a false value.
  45          $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
  46          $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
  47  
  48          // Even when a group exists which also has an empty idnumber.
  49          $generator->create_group(array('courseid' => $course->id));
  50          $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
  51          $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
  52  
  53          /*
  54           * Test with a valid idnumber.
  55           */
  56          // There is no matching idnumber at present.
  57          $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber1));
  58  
  59          // We should now have a valid group returned by the idnumber search.
  60          $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber1));
  61          $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber1));
  62  
  63          // An empty idnumber should still return false.
  64          $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
  65          $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
  66  
  67          /*
  68           * Test with another idnumber.
  69           */
  70          // There is no matching idnumber at present.
  71          $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber2));
  72  
  73          // We should now have a valid group returned by the idnumber search.
  74          $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber2));
  75          $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber2));
  76  
  77          /*
  78           * Group idnumbers are unique within a course so test that we don't
  79           * retrieve groups for the first course.
  80           */
  81  
  82          // Create a second course.
  83          $course = $generator->create_course(array('category' => $cat->id));
  84  
  85          // An empty idnumber should always return a false value.
  86          $this->assertFalse(groups_get_group_by_idnumber($course->id, ''));
  87          $this->assertFalse(groups_get_group_by_idnumber($course->id, null));
  88  
  89          // Our existing idnumbers shouldn't be returned here as we're in a different course.
  90          $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber1));
  91          $this->assertFalse(groups_get_group_by_idnumber($course->id, $idnumber2));
  92  
  93          // We should be able to reuse the idnumbers again since this is a different course.
  94          $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber1));
  95          $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber1));
  96  
  97          $group = $generator->create_group(array('courseid' => $course->id, 'idnumber' => $idnumber2));
  98          $this->assertEquals($group, groups_get_group_by_idnumber($course->id, $idnumber2));
  99      }
 100  
 101      public function test_groups_get_grouping_by_idnumber() {
 102          $this->resetAfterTest(true);
 103  
 104          $generator = $this->getDataGenerator();
 105  
 106          // Create a course category and course.
 107          $cat = $generator->create_category(array('parent' => 0));
 108          $course = $generator->create_course(array('category' => $cat->id));
 109  
 110          $idnumber1 = 'idnumber1';
 111          $idnumber2 = 'idnumber2';
 112  
 113          /*
 114           * Test with an empty and a null idnumber.
 115           */
 116          // An empty idnumber should always return a false value.
 117          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
 118          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
 119  
 120          // Even when a grouping exists which also has an empty idnumber.
 121          $generator->create_grouping(array('courseid' => $course->id));
 122          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
 123          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
 124  
 125          /*
 126           * Test with a valid idnumber
 127           */
 128          // There is no matching idnumber at present.
 129          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber1));
 130  
 131          // We should now have a valid group returned by the idnumber search.
 132          $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber1));
 133          $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber1));
 134  
 135          // An empty idnumber should still return false.
 136          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
 137          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
 138  
 139          /*
 140           * Test with another idnumber.
 141           */
 142          // There is no matching idnumber at present.
 143          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber2));
 144  
 145          // We should now have a valid grouping returned by the idnumber search.
 146          $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber2));
 147          $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber2));
 148  
 149          /*
 150           * Grouping idnumbers are unique within a course so test that we don't
 151           * retrieve groupings for the first course.
 152           */
 153  
 154          // Create a second course.
 155          $course = $generator->create_course(array('category' => $cat->id));
 156  
 157          // An empty idnumber should always return a false value.
 158          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, ''));
 159          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, null));
 160  
 161          // Our existing idnumbers shouldn't be returned here as we're in a different course.
 162          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber1));
 163          $this->assertFalse(groups_get_grouping_by_idnumber($course->id, $idnumber2));
 164  
 165          // We should be able to reuse the idnumbers again since this is a different course.
 166          $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber1));
 167          $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber1));
 168  
 169          $grouping = $generator->create_grouping(array('courseid' => $course->id, 'idnumber' => $idnumber2));
 170          $this->assertEquals($grouping, groups_get_grouping_by_idnumber($course->id, $idnumber2));
 171      }
 172  
 173      public function test_groups_get_members_ids_sql() {
 174          global $DB;
 175  
 176          $this->resetAfterTest(true);
 177  
 178          $generator = $this->getDataGenerator();
 179  
 180          $course = $generator->create_course();
 181          $coursecontext = \context_course::instance($course->id);
 182          $student1 = $generator->create_user();
 183          $student2 = $generator->create_user();
 184          $plugin = enrol_get_plugin('manual');
 185          $role = $DB->get_record('role', array('shortname' => 'student'));
 186          $group = $generator->create_group(array('courseid' => $course->id));
 187          $instance = $DB->get_record('enrol', array(
 188                  'courseid' => $course->id,
 189                  'enrol' => 'manual',
 190          ));
 191  
 192          $this->assertNotEquals($instance, false);
 193  
 194          // Enrol users in the course.
 195          $plugin->enrol_user($instance, $student1->id, $role->id);
 196          $plugin->enrol_user($instance, $student2->id, $role->id);
 197  
 198          list($sql, $params) = groups_get_members_ids_sql($group->id);
 199  
 200          // Test an empty group.
 201          $users = $DB->get_records_sql($sql, $params);
 202          $this->assertFalse(array_key_exists($student1->id, $users));
 203  
 204          // Test with a group member.
 205          groups_add_member($group->id, $student1->id);
 206          $users = $DB->get_records_sql($sql, $params);
 207          $this->assertTrue(array_key_exists($student1->id, $users));
 208      }
 209  
 210      public function test_groups_get_members_ids_sql_multiple_groups() {
 211          global $DB;
 212  
 213          $this->resetAfterTest(true);
 214  
 215          $generator = $this->getDataGenerator();
 216  
 217          $course = $generator->create_course();
 218          $student1 = $generator->create_user();
 219          $student2 = $generator->create_user();
 220          $plugin = enrol_get_plugin('manual');
 221          $role = $DB->get_record('role', array('shortname' => 'student'));
 222          $group1 = $generator->create_group(array('courseid' => $course->id));
 223          $group2 = $generator->create_group(array('courseid' => $course->id));
 224          $groupids = [
 225              $group1->id,
 226              $group2->id,
 227          ];
 228          $instance = $DB->get_record('enrol', array(
 229                  'courseid' => $course->id,
 230                  'enrol' => 'manual',
 231          ));
 232  
 233          $this->assertNotEquals($instance, false);
 234  
 235          // Enrol users in the course.
 236          $plugin->enrol_user($instance, $student1->id, $role->id);
 237          $plugin->enrol_user($instance, $student2->id, $role->id);
 238  
 239          list($sql, $params) = groups_get_members_ids_sql($groupids);
 240  
 241          // Test an empty group.
 242          $users = $DB->get_records_sql($sql, $params);
 243          $this->assertFalse(array_key_exists($student1->id, $users));
 244  
 245          // Test with a member of one of the two group.
 246          groups_add_member($group1->id, $student1->id);
 247          $users = $DB->get_records_sql($sql, $params);
 248          $this->assertTrue(array_key_exists($student1->id, $users));
 249  
 250          // Test with members of two groups.
 251          groups_add_member($group2->id, $student2->id);
 252          $users = $DB->get_records_sql($sql, $params);
 253          $this->assertTrue(array_key_exists($student1->id, $users));
 254          $this->assertTrue(array_key_exists($student2->id, $users));
 255      }
 256  
 257      public function test_groups_get_members_ids_sql_multiple_groups_join_types() {
 258          global $DB;
 259  
 260          $this->resetAfterTest(true);
 261  
 262          $generator = $this->getDataGenerator();
 263  
 264          $course = $generator->create_course();
 265          $student1 = $generator->create_user();
 266          $student2 = $generator->create_user();
 267          $student3 = $generator->create_user();
 268          $student4 = $generator->create_user();
 269          $student5 = $generator->create_user();
 270          $student6 = $generator->create_user();
 271          $plugin = enrol_get_plugin('manual');
 272          $role = $DB->get_record('role', array('shortname' => 'student'));
 273          $group1 = $generator->create_group(array('courseid' => $course->id));
 274          $group2 = $generator->create_group(array('courseid' => $course->id));
 275          $group3 = $generator->create_group(array('courseid' => $course->id));
 276          // Only groups 1 and 2 specified in SQL (group 3 helps cover the None case).
 277          $groupids = [
 278              $group1->id,
 279              $group2->id,
 280          ];
 281          $instance = $DB->get_record('enrol', array(
 282                  'courseid' => $course->id,
 283                  'enrol' => 'manual',
 284          ));
 285  
 286          $this->assertNotEquals($instance, false);
 287  
 288          // Enrol users in the course.
 289          $plugin->enrol_user($instance, $student1->id, $role->id);
 290          $plugin->enrol_user($instance, $student2->id, $role->id);
 291          $plugin->enrol_user($instance, $student3->id, $role->id);
 292          $plugin->enrol_user($instance, $student4->id, $role->id);
 293          $plugin->enrol_user($instance, $student5->id, $role->id);
 294          $plugin->enrol_user($instance, $student6->id, $role->id);
 295  
 296          // Generate SQL with the different groups join types for members of group1 and group2.
 297          list($sqlany, $paramsany) = groups_get_members_ids_sql($groupids, null, GROUPS_JOIN_ANY);
 298          list($sqlall, $paramsall) = groups_get_members_ids_sql($groupids, null, GROUPS_JOIN_ALL);
 299          list($sqlnone, $paramsnone) = groups_get_members_ids_sql($groupids, null, GROUPS_JOIN_NONE);
 300  
 301          // Any - Test empty groups, no matches.
 302          $users = $DB->get_records_sql($sqlany, $paramsany);
 303          $this->assertFalse(array_key_exists($student1->id, $users));
 304          $this->assertFalse(array_key_exists($student2->id, $users));
 305          $this->assertFalse(array_key_exists($student3->id, $users));
 306          $this->assertFalse(array_key_exists($student4->id, $users));
 307          $this->assertFalse(array_key_exists($student5->id, $users));
 308          $this->assertFalse(array_key_exists($student6->id, $users));
 309  
 310          // All - Test empty groups, no matches.
 311          $users = $DB->get_records_sql($sqlall, $paramsall);
 312          $this->assertFalse(array_key_exists($student1->id, $users));
 313          $this->assertFalse(array_key_exists($student2->id, $users));
 314          $this->assertFalse(array_key_exists($student3->id, $users));
 315          $this->assertFalse(array_key_exists($student4->id, $users));
 316          $this->assertFalse(array_key_exists($student5->id, $users));
 317          $this->assertFalse(array_key_exists($student6->id, $users));
 318  
 319          // None - Test empty groups, all match.
 320          $users = $DB->get_records_sql($sqlnone, $paramsnone);
 321          $this->assertTrue(array_key_exists($student1->id, $users));
 322          $this->assertTrue(array_key_exists($student2->id, $users));
 323          $this->assertTrue(array_key_exists($student3->id, $users));
 324          $this->assertTrue(array_key_exists($student4->id, $users));
 325          $this->assertTrue(array_key_exists($student5->id, $users));
 326          $this->assertTrue(array_key_exists($student6->id, $users));
 327  
 328          // Assign various group member combinations.
 329          groups_add_member($group1->id, $student1->id);
 330          groups_add_member($group1->id, $student2->id);
 331          groups_add_member($group1->id, $student3->id);
 332          groups_add_member($group2->id, $student2->id);
 333          groups_add_member($group2->id, $student3->id);
 334          groups_add_member($group2->id, $student4->id);
 335          groups_add_member($group3->id, $student5->id);
 336  
 337          // Any - Test students in one or both of groups 1 and 2 matched.
 338          $users = $DB->get_records_sql($sqlany, $paramsany);
 339          $this->assertTrue(array_key_exists($student1->id, $users));
 340          $this->assertTrue(array_key_exists($student2->id, $users));
 341          $this->assertTrue(array_key_exists($student3->id, $users));
 342          $this->assertTrue(array_key_exists($student4->id, $users));
 343          $this->assertFalse(array_key_exists($student5->id, $users));
 344          $this->assertFalse(array_key_exists($student6->id, $users));
 345  
 346          // All - Test only students in both groups 1 and 2 matched.
 347          $users = $DB->get_records_sql($sqlall, $paramsall);
 348          $this->assertTrue(array_key_exists($student2->id, $users));
 349          $this->assertTrue(array_key_exists($student3->id, $users));
 350          $this->assertFalse(array_key_exists($student1->id, $users));
 351          $this->assertFalse(array_key_exists($student4->id, $users));
 352          $this->assertFalse(array_key_exists($student5->id, $users));
 353          $this->assertFalse(array_key_exists($student6->id, $users));
 354  
 355          // None - Test only students not in group 1 or 2 matched.
 356          $users = $DB->get_records_sql($sqlnone, $paramsnone);
 357          $this->assertTrue(array_key_exists($student5->id, $users));
 358          $this->assertTrue(array_key_exists($student6->id, $users));
 359          $this->assertFalse(array_key_exists($student1->id, $users));
 360          $this->assertFalse(array_key_exists($student2->id, $users));
 361          $this->assertFalse(array_key_exists($student3->id, $users));
 362          $this->assertFalse(array_key_exists($student4->id, $users));
 363      }
 364  
 365      public function test_groups_get_members_ids_sql_valid_context() {
 366          global $DB;
 367  
 368          $this->resetAfterTest(true);
 369  
 370          $generator = $this->getDataGenerator();
 371  
 372          $course = $generator->create_course();
 373          $coursecontext = \context_course::instance($course->id);
 374          $student1 = $generator->create_user();
 375          $student2 = $generator->create_user();
 376          $plugin = enrol_get_plugin('manual');
 377          $role = $DB->get_record('role', array('shortname' => 'student'));
 378          $group = $generator->create_group(array('courseid' => $course->id));
 379          $instance = $DB->get_record('enrol', array(
 380                  'courseid' => $course->id,
 381                  'enrol' => 'manual',
 382          ));
 383  
 384          $this->assertNotEquals($instance, false);
 385  
 386          // Enrol users in the course.
 387          $plugin->enrol_user($instance, $student1->id, $role->id);
 388          $plugin->enrol_user($instance, $student2->id, $role->id);
 389  
 390          // Add student1 to the group.
 391          groups_add_member($group->id, $student1->id);
 392  
 393          // Test with members at any group and with a valid $context.
 394          list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP, $coursecontext);
 395          $users = $DB->get_records_sql($sql, $params);
 396          $this->assertFalse(array_key_exists($student1->id, $users));
 397          $this->assertTrue(array_key_exists($student2->id, $users));
 398      }
 399  
 400      public function test_groups_get_members_ids_sql_empty_context() {
 401          global $DB;
 402  
 403          $this->resetAfterTest(true);
 404  
 405          $generator = $this->getDataGenerator();
 406  
 407          $course = $generator->create_course();
 408          $coursecontext = \context_course::instance($course->id);
 409          $student1 = $generator->create_user();
 410          $student2 = $generator->create_user();
 411          $plugin = enrol_get_plugin('manual');
 412          $role = $DB->get_record('role', array('shortname' => 'student'));
 413          $group = $generator->create_group(array('courseid' => $course->id));
 414          $instance = $DB->get_record('enrol', array(
 415                  'courseid' => $course->id,
 416                  'enrol' => 'manual',
 417          ));
 418  
 419          $this->assertNotEquals($instance, false);
 420  
 421          // Enrol users in the course.
 422          $plugin->enrol_user($instance, $student1->id, $role->id);
 423          $plugin->enrol_user($instance, $student2->id, $role->id);
 424  
 425          // Add student1 to the group.
 426          groups_add_member($group->id, $student1->id);
 427  
 428          // Test with members at any group and without the $context.
 429          $this->expectException('coding_exception');
 430          list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP);
 431      }
 432  
 433      public function test_groups_get_members_ids_sql_invalid_context() {
 434          global $DB;
 435  
 436          $this->resetAfterTest(true);
 437  
 438          $generator = $this->getDataGenerator();
 439  
 440          $course = $generator->create_course();
 441          $coursecontext = \context_course::instance($course->id);
 442          $student1 = $generator->create_user();
 443          $student2 = $generator->create_user();
 444          $plugin = enrol_get_plugin('manual');
 445          $role = $DB->get_record('role', array('shortname' => 'student'));
 446          $group = $generator->create_group(array('courseid' => $course->id));
 447          $instance = $DB->get_record('enrol', array(
 448                  'courseid' => $course->id,
 449                  'enrol' => 'manual',
 450          ));
 451  
 452          $this->assertNotEquals($instance, false);
 453  
 454          // Enrol users in the course.
 455          $plugin->enrol_user($instance, $student1->id, $role->id);
 456          $plugin->enrol_user($instance, $student2->id, $role->id);
 457  
 458          // Add student1 to the group.
 459          groups_add_member($group->id, $student1->id);
 460  
 461          // Test with members at any group and with an invalid $context.
 462          $syscontext = \context_system::instance();
 463          $this->expectException('coding_exception');
 464          list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP, $syscontext);
 465      }
 466  
 467      public function test_groups_get_group_by_name() {
 468          $this->resetAfterTest(true);
 469  
 470          $generator = $this->getDataGenerator();
 471  
 472          // Create a course category and course.
 473          $cat = $generator->create_category(array('parent' => 0));
 474          $course = $generator->create_course(array('category' => $cat->id));
 475  
 476          $name1 = 'Name 1';
 477          $name2 = 'Name 2';
 478  
 479          // Test with an empty and a null idnumber.
 480          $this->assertFalse(groups_get_group_by_name($course->id, ''));
 481          $this->assertFalse(groups_get_group_by_name($course->id, null));
 482  
 483          // Even when a group exists.
 484          $generator->create_group(array('courseid' => $course->id));
 485          $this->assertFalse(groups_get_group_by_name($course->id, ''));
 486          $this->assertFalse(groups_get_group_by_name($course->id, null));
 487  
 488          // Test with a valid name, but one that doesn't exist yet.
 489          $this->assertFalse(groups_get_group_by_name($course->id, $name1));
 490          $this->assertFalse(groups_get_group_by_name($course->id, $name2));
 491  
 492          // We should now have a valid group returned by the name search.
 493          $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => $name1));
 494          $this->assertEquals($group1->id, groups_get_group_by_name($course->id, $name1));
 495          $this->assertFalse(groups_get_group_by_name($course->id, $name2));
 496  
 497          // We should now have a two valid groups returned by the name search.
 498          $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => $name2));
 499          $this->assertEquals($group1->id, groups_get_group_by_name($course->id, $name1));
 500          $this->assertEquals($group2->id, groups_get_group_by_name($course->id, $name2));
 501  
 502          // Delete a group.
 503          $this->assertTrue(groups_delete_group($group1));
 504          $this->assertFalse(groups_get_group_by_name($course->id, $name1));
 505          $this->assertEquals($group2->id, groups_get_group_by_name($course->id, $name2));
 506  
 507          /*
 508           * Group idnumbers are unique within a course so test that we don't
 509           * retrieve groups for the first course.
 510           */
 511  
 512          // Create a second course.
 513          $course = $generator->create_course(array('category' => $cat->id));
 514  
 515          // An empty name should always return a false value.
 516          $this->assertFalse(groups_get_group_by_name($course->id, ''));
 517          $this->assertFalse(groups_get_group_by_name($course->id, null));
 518  
 519          // Our existing names shouldn't be returned here as we're in a different course.
 520          $this->assertFalse(groups_get_group_by_name($course->id, $name1));
 521          $this->assertFalse(groups_get_group_by_name($course->id, $name2));
 522  
 523          // We should be able to reuse the idnumbers again since this is a different course.
 524          $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => $name1));
 525          $this->assertEquals($group1->id, groups_get_group_by_name($course->id, $name1));
 526  
 527          $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => $name2));
 528          $this->assertEquals($group2->id, groups_get_group_by_name($course->id, $name2));
 529      }
 530  
 531      public function test_groups_get_grouping() {
 532          $this->resetAfterTest(true);
 533  
 534          $generator = $this->getDataGenerator();
 535  
 536          // Create a course category and course.
 537          $cat = $generator->create_category(array('parent' => 0));
 538          $course = $generator->create_course(array('category' => $cat->id));
 539  
 540          $name1 = 'Grouping 1';
 541          $name2 = 'Grouping 2';
 542  
 543          // Test with an empty and a null idnumber.
 544          $this->assertFalse(groups_get_grouping_by_name($course->id, ''));
 545          $this->assertFalse(groups_get_grouping_by_name($course->id, null));
 546  
 547          // Even when a group exists.
 548          $generator->create_group(array('courseid' => $course->id));
 549          $this->assertFalse(groups_get_grouping_by_name($course->id, ''));
 550          $this->assertFalse(groups_get_grouping_by_name($course->id, null));
 551  
 552          // Test with a valid name, but one that doesn't exist yet.
 553          $this->assertFalse(groups_get_grouping_by_name($course->id, $name1));
 554          $this->assertFalse(groups_get_grouping_by_name($course->id, $name2));
 555  
 556          // We should now have a valid group returned by the name search.
 557          $group1 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name1));
 558          $this->assertEquals($group1->id, groups_get_grouping_by_name($course->id, $name1));
 559          $this->assertFalse(groups_get_grouping_by_name($course->id, $name2));
 560  
 561          // We should now have a two valid groups returned by the name search.
 562          $group2 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name2));
 563          $this->assertEquals($group1->id, groups_get_grouping_by_name($course->id, $name1));
 564          $this->assertEquals($group2->id, groups_get_grouping_by_name($course->id, $name2));
 565  
 566          // Delete a group.
 567          $this->assertTrue(groups_delete_grouping($group1));
 568          $this->assertFalse(groups_get_grouping_by_name($course->id, $name1));
 569          $this->assertEquals($group2->id, groups_get_grouping_by_name($course->id, $name2));
 570  
 571          /*
 572           * Group idnumbers are unique within a course so test that we don't
 573           * retrieve groups for the first course.
 574           */
 575  
 576          // Create a second course.
 577          $course = $generator->create_course(array('category' => $cat->id));
 578  
 579          // An empty name should always return a false value.
 580          $this->assertFalse(groups_get_grouping_by_name($course->id, ''));
 581          $this->assertFalse(groups_get_grouping_by_name($course->id, null));
 582  
 583          // Our existing names shouldn't be returned here as we're in a different course.
 584          $this->assertFalse(groups_get_grouping_by_name($course->id, $name1));
 585          $this->assertFalse(groups_get_grouping_by_name($course->id, $name2));
 586  
 587          // We should be able to reuse the idnumbers again since this is a different course.
 588          $group1 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name1));
 589          $this->assertEquals($group1->id, groups_get_grouping_by_name($course->id, $name1));
 590  
 591          $group2 = $generator->create_grouping(array('courseid' => $course->id, 'name' => $name2));
 592          $this->assertEquals($group2->id, groups_get_grouping_by_name($course->id, $name2));
 593      }
 594  
 595      public function test_groups_get_course_data() {
 596          $this->resetAfterTest(true);
 597  
 598          $generator = $this->getDataGenerator();
 599  
 600          // Create a course category and course.
 601          $cat = $generator->create_category(array('parent' => 0));
 602          $course = $generator->create_course(array('category' => $cat->id));
 603          $grouping1 = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 1'));
 604          $grouping2 = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 2'));
 605          $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
 606          $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
 607          $group3 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 3'));
 608          $group4 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 4'));
 609  
 610          // Assign the groups to groupings.
 611          $this->assertTrue(groups_assign_grouping($grouping1->id, $group1->id));
 612          $this->assertTrue(groups_assign_grouping($grouping1->id, $group2->id));
 613          $this->assertTrue(groups_assign_grouping($grouping2->id, $group3->id));
 614          $this->assertTrue(groups_assign_grouping($grouping2->id, $group4->id));
 615  
 616          // Get the data.
 617          $data = groups_get_course_data($course->id);
 618          $this->assertInstanceOf('stdClass', $data);
 619          $this->assertObjectHasAttribute('groups', $data);
 620          $this->assertObjectHasAttribute('groupings', $data);
 621          $this->assertObjectHasAttribute('mappings', $data);
 622  
 623          // Test we have the expected items returns.
 624          $this->assertCount(4, $data->groups);
 625          $this->assertCount(2, $data->groupings);
 626          $this->assertCount(4, $data->mappings);
 627  
 628          // Check we have the expected groups.
 629          $this->assertArrayHasKey($group1->id, $data->groups);
 630          $this->assertArrayHasKey($group2->id, $data->groups);
 631          $this->assertArrayHasKey($group3->id, $data->groups);
 632          $this->assertArrayHasKey($group4->id, $data->groups);
 633  
 634          // Test a group-id is mapped correctly.
 635          $this->assertSame($group3->name, $data->groups[$group3->id]->name);
 636  
 637          // Check we have the expected number of groupings.
 638          $this->assertArrayHasKey($grouping1->id, $data->groupings);
 639          $this->assertArrayHasKey($grouping2->id, $data->groupings);
 640  
 641          // Test a grouping-id is mapped correctly.
 642          $this->assertEquals($grouping2->name, $data->groupings[$grouping2->id]->name);
 643  
 644          // Test that all of the mappings are correct.
 645          $grouping1maps = 0;
 646          $grouping2maps = 0;
 647          $group1maps = 0;
 648          $group2maps = 0;
 649          $group3maps = 0;
 650          $group4maps = 0;
 651          foreach ($data->mappings as $mapping) {
 652              if ($mapping->groupingid === $grouping1->id) {
 653                  $grouping1maps++;
 654                  $this->assertContainsEquals($mapping->groupid, array($group1->id, $group2->id));
 655              } else if ($mapping->groupingid === $grouping2->id) {
 656                  $grouping2maps++;
 657                  $this->assertContainsEquals($mapping->groupid, array($group3->id, $group4->id));
 658              } else {
 659                  $this->fail('Unexpected groupingid');
 660              }
 661              switch ($mapping->groupid) {
 662                  case $group1->id : $group1maps++; break;
 663                  case $group2->id : $group2maps++; break;
 664                  case $group3->id : $group3maps++; break;
 665                  case $group4->id : $group4maps++; break;
 666              }
 667          }
 668          $this->assertEquals(2, $grouping1maps);
 669          $this->assertEquals(2, $grouping2maps);
 670          $this->assertEquals(1, $group1maps);
 671          $this->assertEquals(1, $group2maps);
 672          $this->assertEquals(1, $group3maps);
 673          $this->assertEquals(1, $group4maps);
 674  
 675          // Test the groups_get_all_groups which uses this functionality.
 676          $groups  = groups_get_all_groups($course->id);
 677          $this->assertCount(4, $groups);
 678          $this->assertArrayHasKey($group1->id, $groups);
 679          $this->assertArrayHasKey($group2->id, $groups);
 680          $this->assertArrayHasKey($group3->id, $groups);
 681          $this->assertArrayHasKey($group4->id, $groups);
 682  
 683          $groups  = groups_get_all_groups($course->id, null, $grouping1->id);
 684          $this->assertCount(2, $groups);
 685          $this->assertArrayHasKey($group1->id, $groups);
 686          $this->assertArrayHasKey($group2->id, $groups);
 687          $this->assertArrayNotHasKey($group3->id, $groups);
 688          $this->assertArrayNotHasKey($group4->id, $groups);
 689  
 690          $groups  = groups_get_all_groups($course->id, null, $grouping2->id);
 691          $this->assertCount(2, $groups);
 692          $this->assertArrayNotHasKey($group1->id, $groups);
 693          $this->assertArrayNotHasKey($group2->id, $groups);
 694          $this->assertArrayHasKey($group3->id, $groups);
 695          $this->assertArrayHasKey($group4->id, $groups);
 696  
 697          // Test this function using an alternate column for the result index
 698          $groups  = groups_get_all_groups($course->id, null, $grouping2->id, 'g.name, g.id');
 699          $this->assertCount(2, $groups);
 700          $this->assertArrayNotHasKey($group3->id, $groups);
 701          $this->assertArrayHasKey($group3->name, $groups);
 702          $this->assertEquals($group3->id, $groups[$group3->name]->id);
 703      }
 704  
 705      /**
 706       * Tests for groups_group_visible.
 707       */
 708      public function test_groups_group_visible() {
 709          global $CFG, $DB;
 710  
 711          $generator = $this->getDataGenerator();
 712          $this->resetAfterTest();
 713          $this->setAdminUser();
 714  
 715          // Create a course category, course and groups.
 716          $cat = $generator->create_category(array('parent' => 0));
 717          $course = $generator->create_course(array('category' => $cat->id));
 718          $coursecontext = \context_course::instance($course->id);
 719          $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
 720          $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
 721          $group3 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 3'));
 722          $group4 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 4'));
 723  
 724          // Create cm.
 725          $assign = $generator->create_module("assign", array('course' => $course->id));
 726          $cm = get_coursemodule_from_instance("assign", $assign->id);
 727  
 728          // Create users.
 729          $user1 = $generator->create_user();
 730          $user2 = $generator->create_user();
 731          $user3 = $generator->create_user();
 732  
 733          // Enrol users into the course.
 734          $generator->enrol_user($user1->id, $course->id);
 735          $generator->enrol_user($user2->id, $course->id);
 736  
 737          // Assign groups.
 738          groups_add_member($group1, $user2);
 739  
 740          // Give capability at course level to the user to access all groups.
 741          $role = $DB->get_field("role", "id", array("shortname" => "manager"));
 742          $generator->enrol_user($user3->id, $course->id, $role);
 743          // Make sure the user has the capability.
 744          assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role, $coursecontext->id);
 745  
 746          // No groups , not forced.
 747          $result = groups_group_visible($group1->id, $course, null, $user1->id);
 748          $this->assertTrue($result);
 749          $result = groups_group_visible(0, $course, null, $user1->id);
 750          $this->assertTrue($result); // Requesting all groups.
 751  
 752          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 753          $this->assertTrue($result); // Cm with no groups.
 754  
 755          $cm->groupmode = SEPARATEGROUPS;
 756          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 757          $this->assertFalse($result); // Cm with separate groups.
 758          $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
 759          $this->assertTrue($result); // Cm with separate groups.
 760  
 761          $cm->groupmode = VISIBLEGROUPS;
 762          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 763          $this->assertTrue($result); // Cm with visible groups.
 764  
 765          // No groups, forced.
 766          $course->groupmode = NOGROUPS;
 767          $course->groupmodeforce = true;
 768          update_course($course);
 769          $result = groups_group_visible($group1->id, $course, null, $user1->id);
 770          $this->assertTrue($result);
 771          $result = groups_group_visible(0, $course, null, $user1->id);
 772          $this->assertTrue($result); // Requesting all groups.
 773  
 774          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 775          $this->assertTrue($result); // Cm with no groups.
 776  
 777          $cm->groupmode = SEPARATEGROUPS;
 778          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 779          $this->assertTrue($result); // Cm with separate groups.
 780          $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
 781          $this->assertTrue($result); // Cm with separate groups.
 782  
 783          $cm->groupmode = SEPARATEGROUPS;
 784          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 785          $this->assertTrue($result); // Cm with visible groups.
 786  
 787          // Visible groups, forced.
 788          $course->groupmode = VISIBLEGROUPS;
 789          $course->groupmodeforce = true;
 790          update_course($course);
 791          $result = groups_group_visible($group1->id, $course, null, $user1->id);
 792          $this->assertTrue($result);
 793          $result = groups_group_visible(0, $course, null, $user1->id);
 794          $this->assertTrue($result); // Requesting all groups.
 795  
 796          $cm->groupmode = NOGROUPS;
 797          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 798          $this->assertTrue($result); // Cm with no groups.
 799  
 800          $cm->groupmode = SEPARATEGROUPS;
 801          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 802          $this->assertTrue($result); // Cm with separate groups.
 803          $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
 804          $this->assertTrue($result); // Cm with separate groups.
 805  
 806          $cm->groupmode = VISIBLEGROUPS;
 807          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 808          $this->assertTrue($result); // Cm with visible groups.
 809  
 810          // Visible groups, not forced.
 811          $course->groupmode = VISIBLEGROUPS;
 812          $course->groupmodeforce = false;
 813          update_course($course);
 814          $result = groups_group_visible($group1->id, $course, null, $user1->id);
 815          $this->assertTrue($result);
 816          $result = groups_group_visible(0, $course, null, $user1->id);
 817          $this->assertTrue($result); // Requesting all groups.
 818  
 819          $cm->groupmode = NOGROUPS;
 820          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 821          $this->assertTrue($result); // Cm with no groups.
 822  
 823          $cm->groupmode = SEPARATEGROUPS;
 824          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 825          $this->assertFalse($result); // Cm with separate groups.
 826          $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
 827          $this->assertTrue($result); // Cm with separate groups.
 828  
 829          $cm->groupmode = VISIBLEGROUPS;
 830          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 831          $this->assertTrue($result); // Cm with visible groups.
 832  
 833          // Separate groups, forced.
 834          $course->groupmode = SEPARATEGROUPS;
 835          $course->groupmodeforce = true;
 836          update_course($course);
 837          $result = groups_group_visible($group1->id, $course, null, $user1->id);
 838          $this->assertFalse($result);
 839          $result = groups_group_visible($group1->id, $course, null, $user2->id);
 840          $this->assertTrue($result);
 841          $result = groups_group_visible(0, $course, null, $user2->id);
 842          $this->assertFalse($result); // Requesting all groups.
 843          $result = groups_group_visible(0, $course, null, $user3->id);
 844          $this->assertTrue($result); // Requesting all groups.
 845          $result = groups_group_visible($group1->id, $course, null, $user3->id);
 846          $this->assertTrue($result); // Make sure user with access to all groups can see any group.
 847  
 848          $cm->groupmode = NOGROUPS;
 849          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 850          $this->assertFalse($result); // Cm with no groups.
 851  
 852          $cm->groupmode = SEPARATEGROUPS;
 853          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 854          $this->assertFalse($result); // Cm with separate groups.
 855          $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
 856          $this->assertTrue($result); // Cm with separate groups.
 857          $result = groups_group_visible($group1->id, $course, $cm, $user3->id);
 858          $this->assertTrue($result); // Make sure user with access to all groups can see any group.
 859  
 860          $cm->groupmode = VISIBLEGROUPS;
 861          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 862          $this->assertFalse($result); // Cm with visible groups.
 863  
 864          // Separate groups, not forced.
 865          $course->groupmode = SEPARATEGROUPS;
 866          $course->groupmodeforce = false;
 867          update_course($course);
 868          $result = groups_group_visible($group1->id, $course, null, $user1->id);
 869          $this->assertFalse($result);
 870          $result = groups_group_visible($group1->id, $course, null, $user2->id);
 871          $this->assertTrue($result);
 872          $result = groups_group_visible(0, $course, null, $user2->id);
 873          $this->assertFalse($result); // Requesting all groups.
 874          $result = groups_group_visible(0, $course, null, $user3->id);
 875          $this->assertTrue($result); // Requesting all groups.
 876  
 877          $cm->groupmode = NOGROUPS;
 878          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 879          $this->assertTrue($result); // Cm with no groups.
 880  
 881          $cm->groupmode = SEPARATEGROUPS;
 882          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 883          $this->assertFalse($result); // Cm with separate groups.
 884          $result = groups_group_visible($group1->id, $course, $cm, $user2->id);
 885          $this->assertTrue($result); // Cm with separate groups.
 886  
 887          $cm->groupmode = VISIBLEGROUPS;
 888          $result = groups_group_visible($group1->id, $course, $cm, $user1->id);
 889          $this->assertTrue($result); // Cm with visible groups.
 890      }
 891  
 892      function test_groups_get_groupmode() {
 893          global $DB;
 894          $generator = $this->getDataGenerator();
 895          $this->resetAfterTest();
 896          $this->setAdminUser();
 897  
 898          // Create a course with no groups forcing.
 899          $course1 = $generator->create_course();
 900  
 901          // Create cm1 with no groups, cm1 with visible groups, cm2 with separate groups and cm3 with visible groups.
 902          $assign1 = $generator->create_module("assign", array('course' => $course1->id));
 903          $assign2 = $generator->create_module("assign", array('course' => $course1->id),
 904                  array('groupmode' => SEPARATEGROUPS));
 905          $assign3 = $generator->create_module("assign", array('course' => $course1->id),
 906                  array('groupmode' => VISIBLEGROUPS));
 907  
 908          // Request data for tests.
 909          $cm1 = get_coursemodule_from_instance("assign", $assign1->id);
 910          $cm2 = get_coursemodule_from_instance("assign", $assign2->id);
 911          $cm3 = get_coursemodule_from_instance("assign", $assign3->id);
 912          $modinfo = get_fast_modinfo($course1->id);
 913  
 914          // Assert that any method of getting activity groupmode returns the correct result.
 915          $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1));
 916          $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1, $course1));
 917          $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm1->id]));
 918          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2));
 919          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2, $course1));
 920          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm2->id]));
 921          $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3));
 922          $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3, $course1));
 923          $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm3->id]));
 924  
 925          // Update the course set the groupmode SEPARATEGROUPS but not forced.
 926          update_course((object)array('id' => $course1->id, 'groupmode' => SEPARATEGROUPS));
 927          // Re-request the data from DB.
 928          $course1 = $DB->get_record('course', array('id' => $course1->id));
 929          $modinfo = get_fast_modinfo($course1->id);
 930  
 931          // Existing activities are not changed.
 932          $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1));
 933          $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($cm1, $course1));
 934          $this->assertEquals(NOGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm1->id]));
 935          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2));
 936          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2, $course1));
 937          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm2->id]));
 938          $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3));
 939          $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($cm3, $course1));
 940          $this->assertEquals(VISIBLEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm3->id]));
 941  
 942          // Update the course set the groupmode SEPARATEGROUPS and forced.
 943          update_course((object)array('id' => $course1->id, 'groupmode' => SEPARATEGROUPS, 'groupmodeforce' => true));
 944          // Re-request the data from DB.
 945          $course1 = $DB->get_record('course', array('id' => $course1->id));
 946          $modinfo = get_fast_modinfo($course1->id);
 947  
 948          // Make sure all activities have separate groups mode now.
 949          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm1));
 950          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm1, $course1));
 951          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm1->id]));
 952          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2));
 953          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm2, $course1));
 954          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm2->id]));
 955          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm3));
 956          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($cm3, $course1));
 957          $this->assertEquals(SEPARATEGROUPS, groups_get_activity_groupmode($modinfo->cms[$cm3->id]));
 958      }
 959  
 960      /**
 961       * Tests for groups_allgroups_course_menu() .
 962       */
 963      public function test_groups_allgroups_course_menu() {
 964          global $SESSION;
 965  
 966          $this->resetAfterTest();
 967  
 968          // Generate data.
 969          $course = $this->getDataGenerator()->create_course();
 970          $record = new \stdClass();
 971          $record->courseid = $course->id;
 972          $group1 = $this->getDataGenerator()->create_group($record);
 973          $group2 = $this->getDataGenerator()->create_group($record);
 974          $user = $this->getDataGenerator()->create_user();
 975          $this->getDataGenerator()->enrol_user($user->id, $course->id);
 976          $this->setUser($user);
 977  
 978          $html = groups_allgroups_course_menu($course, 'someurl.php');
 979          // Since user is not a part of this group and doesn't have accessallgroups permission,
 980          // the html should be empty.
 981          $this->assertEmpty($html);
 982  
 983          groups_add_member($group1->id, $user);
 984          // 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
 985          // partial match to see if all groups are listed or not.
 986          $html = groups_allgroups_course_menu($course, 'someurl.php');
 987          $this->assertStringContainsString(format_string($group1->name), $html);
 988          $this->assertStringNotContainsString(format_string($group2->name), $html);
 989  
 990          $this->setAdminUser();
 991  
 992          // Now user can access everything.
 993          $html = groups_allgroups_course_menu($course, 'someurl.php');
 994          $this->assertStringContainsString(format_string($group1->name), $html);
 995          $this->assertStringContainsString(format_string($group2->name), $html);
 996  
 997          // Make sure separate groups mode, doesn't change anything.
 998          $course->groupmode = SEPARATEGROUPS;
 999          update_course($course);
1000          $html = groups_allgroups_course_menu($course, 'someurl.php');
1001          $this->assertStringContainsString(format_string($group1->name), $html);
1002          $this->assertStringContainsString(format_string($group2->name), $html);
1003  
1004          // Make sure Visible groups mode, doesn't change anything.
1005          $course->groupmode = VISIBLEGROUPS;
1006          update_course($course);
1007          $html = groups_allgroups_course_menu($course, 'someurl.php');
1008          $this->assertStringContainsString(format_string($group1->name), $html);
1009          $this->assertStringContainsString(format_string($group2->name), $html);
1010  
1011          // Let us test activegroup changes now.
1012          $this->setUser($user);
1013          $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid] = 5;
1014          groups_allgroups_course_menu($course, 'someurl.php', false); // Do not update session.
1015          $this->assertSame(5, $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid]);
1016          groups_allgroups_course_menu($course, 'someurl.php', true, $group1->id); // Update session.
1017          $this->assertSame($group1->id, $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid]);
1018          // Try to update session with an invalid groupid. It should not accept the invalid id.
1019          groups_allgroups_course_menu($course, 'someurl.php', true, 256);
1020          $this->assertEquals($group1->id, $SESSION->activegroup[$course->id][VISIBLEGROUPS][$course->defaultgroupingid]);
1021      }
1022  
1023      /**
1024       * This unit test checks that groups_get_all_groups returns groups in
1025       * alphabetical order even if they are in a grouping.
1026       */
1027      public function test_groups_ordering() {
1028          $generator = $this->getDataGenerator();
1029          $this->resetAfterTest();
1030  
1031          // Create a course category and course.
1032          $cat = $generator->create_category(array('parent' => 0));
1033          $course = $generator->create_course(array('category' => $cat->id));
1034          $grouping = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping'));
1035  
1036          // Create groups in reverse order.
1037          $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
1038          $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
1039  
1040          // Assign the groups to the grouping in reverse order.
1041          $this->assertTrue(groups_assign_grouping($grouping->id, $group2->id));
1042          $this->assertTrue(groups_assign_grouping($grouping->id, $group1->id));
1043  
1044          // Get all groups and check they are alphabetical.
1045          $groups = array_values(groups_get_all_groups($course->id, 0));
1046          $this->assertEquals('Group 1', $groups[0]->name);
1047          $this->assertEquals('Group 2', $groups[1]->name);
1048  
1049          // Now check the same is true when accessed by grouping.
1050          $groups = array_values(groups_get_all_groups($course->id, 0, $grouping->id));
1051          $this->assertEquals('Group 1', $groups[0]->name);
1052          $this->assertEquals('Group 2', $groups[1]->name);
1053      }
1054  
1055      /**
1056       * Tests for groups_get_all_groups when grouping is set and we want members as well.
1057       */
1058      public function test_groups_get_all_groups_in_grouping_with_members() {
1059          $generator = $this->getDataGenerator();
1060          $this->resetAfterTest();
1061  
1062          // Create courses.
1063          $course1 = $generator->create_course();
1064          $course2 = $generator->create_course();
1065  
1066          // Create users.
1067          $c1user1 = $generator->create_user();
1068          $c12user1 = $generator->create_user();
1069          $c12user2 = $generator->create_user();
1070  
1071          // Enrol users.
1072          $generator->enrol_user($c1user1->id, $course1->id);
1073          $generator->enrol_user($c12user1->id, $course1->id);
1074          $generator->enrol_user($c12user1->id, $course2->id);
1075          $generator->enrol_user($c12user2->id, $course1->id);
1076          $generator->enrol_user($c12user2->id, $course2->id);
1077  
1078          // Create groupings and groups for course1.
1079          $c1grouping1 = $generator->create_grouping(array('courseid' => $course1->id));
1080          $c1grouping2 = $generator->create_grouping(array('courseid' => $course1->id));
1081          $c1group1 = $generator->create_group(array('courseid' => $course1->id));
1082          $c1group2 = $generator->create_group(array('courseid' => $course1->id));
1083          $c1group3 = $generator->create_group(array('courseid' => $course1->id));
1084          groups_assign_grouping($c1grouping1->id, $c1group1->id);
1085          groups_assign_grouping($c1grouping1->id, $c1group2->id);
1086          groups_assign_grouping($c1grouping2->id, $c1group3->id);
1087  
1088          // Create groupings and groups for course2.
1089          $c2grouping1 = $generator->create_grouping(array('courseid' => $course2->id));
1090          $c2group1 = $generator->create_group(array('courseid' => $course1->id));
1091          groups_assign_grouping($c2grouping1->id, $c2group1->id);
1092  
1093          // Assign users to groups.
1094          $generator->create_group_member(array('groupid' => $c1group1->id, 'userid' => $c1user1->id));
1095          $generator->create_group_member(array('groupid' => $c1group1->id, 'userid' => $c12user1->id));
1096          $generator->create_group_member(array('groupid' => $c1group2->id, 'userid' => $c12user2->id));
1097          $generator->create_group_member(array('groupid' => $c2group1->id, 'userid' => $c12user2->id));
1098  
1099          // Test without userid.
1100          $groups = groups_get_all_groups($course1->id, null, $c1grouping1->id, 'g.*', true);
1101  
1102          $this->assertEqualsCanonicalizing(
1103                  [$c1group1->id, $c1group2->id],
1104                  array_keys($groups)
1105          );
1106          $this->assertEquals(
1107                  [$c1user1->id => $c1user1->id, $c12user1->id => $c12user1->id],
1108                  $groups[$c1group1->id]->members
1109          );
1110          $this->assertEquals(
1111                  [$c12user2->id => $c12user2->id],
1112                  $groups[$c1group2->id]->members
1113          );
1114  
1115          // Test with userid.
1116          $groups = groups_get_all_groups($course1->id, $c1user1->id, $c1grouping1->id, 'g.*', true);
1117  
1118          $this->assertEquals([$c1group1->id], array_keys($groups));
1119          $this->assertEqualsCanonicalizing(
1120                  [$c1user1->id, $c12user1->id],
1121                  $groups[$c1group1->id]->members
1122          );
1123      }
1124  
1125      /**
1126       * Tests for groups_get_user_groups() method.
1127       */
1128      public function test_groups_get_user_groups() {
1129          $this->resetAfterTest(true);
1130          $generator = $this->getDataGenerator();
1131  
1132          // Create courses.
1133          $course1 = $generator->create_course();
1134          $course2 = $generator->create_course();
1135  
1136          // Create users.
1137          $user1 = $generator->create_user();
1138          $user2 = $generator->create_user();
1139          $user3 = $generator->create_user();
1140  
1141          // Enrol users.
1142          $generator->enrol_user($user1->id, $course1->id);
1143          $generator->enrol_user($user1->id, $course2->id);
1144          $generator->enrol_user($user2->id, $course2->id);
1145          $generator->enrol_user($user3->id, $course2->id);
1146  
1147          // Create groups.
1148          $group1 = $generator->create_group(array('courseid' => $course1->id));
1149          $group2 = $generator->create_group(array('courseid' => $course2->id));
1150          $group3 = $generator->create_group(array('courseid' => $course2->id));
1151  
1152          // Assign users to groups.
1153          $this->assertTrue($generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)));
1154          $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)));
1155  
1156          // Get user groups.
1157          $usergroups1 = groups_get_user_groups($course1->id, $user1->id);
1158          $usergroups2 = groups_get_user_groups($course2->id, $user2->id);;
1159  
1160          // Assert return data.
1161          $this->assertEquals($group1->id, $usergroups1[0][0]);
1162          $this->assertEquals($group2->id, $usergroups2[0][0]);
1163  
1164          // Now, test with groupings.
1165          $grouping1 = $generator->create_grouping(array('courseid' => $course1->id));
1166          $grouping2 = $generator->create_grouping(array('courseid' => $course2->id));
1167  
1168          // Assign the groups to grouping.
1169          groups_assign_grouping($grouping1->id, $group1->id);
1170          groups_assign_grouping($grouping2->id, $group2->id);
1171          groups_assign_grouping($grouping2->id, $group3->id);
1172  
1173          // Test with grouping.
1174          $usergroups1 = groups_get_user_groups($course1->id, $user1->id);
1175          $usergroups2 = groups_get_user_groups($course2->id, $user2->id);
1176          $this->assertArrayHasKey($grouping1->id, $usergroups1);
1177          $this->assertArrayHasKey($grouping2->id, $usergroups2);
1178  
1179          // Test user without a group.
1180          $usergroups1 = groups_get_user_groups($course2->id, $user3->id);
1181          $this->assertCount(0, $usergroups1[0]);
1182  
1183          // Test with userid = 0.
1184          $usergroups1 = groups_get_user_groups($course1->id, 0);
1185          $usergroups2 = groups_get_user_groups($course2->id, 0);
1186          $this->assertCount(0, $usergroups1[0]);
1187          $this->assertCount(0, $usergroups2[0]);
1188  
1189          // Test with courseid = 0.
1190          $usergroups1 = groups_get_user_groups(0, $user1->id);
1191          $usergroups2 = groups_get_user_groups(0, $user2->id);
1192          $this->assertCount(0, $usergroups1[0]);
1193          $this->assertCount(0, $usergroups2[0]);
1194      }
1195  
1196      /**
1197       * Create dummy groups array for use in menu tests
1198       * @param int $number
1199       * @return array
1200       */
1201      protected function make_group_list($number) {
1202          $testgroups = array();
1203          for ($a = 0; $a < $number; $a++) {
1204              $grp = new \stdClass();
1205              $grp->id = 100 + $a;
1206              $grp->name = 'test group ' . $grp->id;
1207              $testgroups[$grp->id] = $grp;
1208          }
1209          return $testgroups;
1210      }
1211  
1212      public function test_groups_sort_menu_options_empty() {
1213          $this->assertEquals(array(), groups_sort_menu_options(array(), array()));
1214      }
1215  
1216      public function test_groups_sort_menu_options_allowed_goups_only() {
1217          $this->assertEquals(array(
1218              100 => 'test group 100',
1219              101 => 'test group 101',
1220          ), groups_sort_menu_options($this->make_group_list(2), array()));
1221      }
1222  
1223      public function test_groups_sort_menu_options_user_goups_only() {
1224          $this->assertEquals(array(
1225              100 => 'test group 100',
1226              101 => 'test group 101',
1227          ), groups_sort_menu_options(array(), $this->make_group_list(2)));
1228      }
1229  
1230      public function test_groups_sort_menu_options_user_both() {
1231          $this->assertEquals(array(
1232              1 => array(get_string('mygroups', 'group') => array(
1233                  100 => 'test group 100',
1234                  101 => 'test group 101',
1235              )),
1236              2 => array(get_string('othergroups', 'group') => array(
1237                  102 => 'test group 102',
1238                  103 => 'test group 103',
1239              )),
1240          ), groups_sort_menu_options($this->make_group_list(4), $this->make_group_list(2)));
1241      }
1242  
1243      public function test_groups_sort_menu_options_user_both_many_groups() {
1244          $this->assertEquals(array(
1245              1 => array(get_string('mygroups', 'group') => array(
1246                  100 => 'test group 100',
1247                  101 => 'test group 101',
1248              )),
1249              2 => array (get_string('othergroups', 'group') => array(
1250                  102 => 'test group 102',
1251                  103 => 'test group 103',
1252                  104 => 'test group 104',
1253                  105 => 'test group 105',
1254                  106 => 'test group 106',
1255                  107 => 'test group 107',
1256                  108 => 'test group 108',
1257                  109 => 'test group 109',
1258                  110 => 'test group 110',
1259                  111 => 'test group 111',
1260                  112 => 'test group 112',
1261              )),
1262          ), groups_sort_menu_options($this->make_group_list(13), $this->make_group_list(2)));
1263      }
1264  
1265      /**
1266       * Tests for groups_user_groups_visible.
1267       */
1268      public function test_groups_user_groups_visible() {
1269          global $DB;
1270  
1271          $generator = $this->getDataGenerator();
1272          $this->resetAfterTest();
1273          $this->setAdminUser();
1274  
1275          // Create a course category, course and groups.
1276          $cat = $generator->create_category(array('parent' => 0));
1277          $course = $generator->create_course(array('category' => $cat->id));
1278          $coursecontext = \context_course::instance($course->id);
1279          $group1 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 1'));
1280          $group2 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 2'));
1281          $group3 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 3'));
1282          $group4 = $generator->create_group(array('courseid' => $course->id, 'name' => 'Group 4'));
1283  
1284          // Create cm.
1285          $assign = $generator->create_module("assign", array('course' => $course->id));
1286          $cm = get_coursemodule_from_instance("assign", $assign->id);
1287  
1288          // Create users.
1289          $user1 = $generator->create_user(); // Normal user.
1290          $user2 = $generator->create_user(); // Normal user.
1291          $user3 = $generator->create_user(); // Teacher, access all groups.
1292          $user4 = $generator->create_user(); // Normal user.
1293  
1294          // Enrol users into the course.
1295          $generator->enrol_user($user1->id, $course->id);
1296          $generator->enrol_user($user2->id, $course->id);
1297          $generator->enrol_user($user4->id, $course->id);
1298  
1299          // Assign groups.
1300          // User1 and User4 share groups.
1301          groups_add_member($group1, $user1);
1302          groups_add_member($group2, $user2);
1303          groups_add_member($group1, $user4);
1304  
1305          // Give capability at course level to the user to access all groups.
1306          $role = $DB->get_field("role", "id", array("shortname" => "manager"));
1307          $generator->enrol_user($user3->id, $course->id, $role);
1308          // Make sure the user has the capability.
1309          assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $role, $coursecontext->id);
1310  
1311          // Normal users in different groups.
1312          $this->setUser($user1);
1313  
1314          // No groups , not forced.
1315          $result = groups_user_groups_visible($course, $user2->id);
1316          $this->assertTrue($result);
1317  
1318          $cm->groupmode = NOGROUPS;
1319          $result = groups_user_groups_visible($course, $user2->id, $cm);
1320          $this->assertTrue($result); // Cm with no groups.
1321  
1322          $cm->groupmode = SEPARATEGROUPS;
1323          $result = groups_user_groups_visible($course, $user2->id, $cm);
1324          $this->assertFalse($result); // Cm with separate groups.
1325  
1326          $cm->groupmode = VISIBLEGROUPS;
1327          $result = groups_user_groups_visible($course, $user2->id, $cm);
1328          $this->assertTrue($result); // Cm with visible groups.
1329  
1330          // No groups, forced.
1331          $course->groupmode = NOGROUPS;
1332          $course->groupmodeforce = true;
1333          update_course($course);
1334          $result = groups_user_groups_visible($course, $user2->id);
1335          $this->assertTrue($result);
1336  
1337          $cm->groupmode = NOGROUPS;
1338          $result = groups_user_groups_visible($course, $user2->id, $cm);
1339          $this->assertTrue($result); // Cm with no groups.
1340  
1341          $cm->groupmode = SEPARATEGROUPS;
1342          $result = groups_user_groups_visible($course, $user2->id, $cm);
1343          $this->assertTrue($result); // Cm with separate groups.
1344  
1345          $cm->groupmode = SEPARATEGROUPS;
1346          $result = groups_user_groups_visible($course, $user2->id);
1347          $this->assertTrue($result); // Cm with visible groups.
1348  
1349          // Visible groups, forced.
1350          $course->groupmode = VISIBLEGROUPS;
1351          $course->groupmodeforce = true;
1352          update_course($course);
1353          $result = groups_user_groups_visible($course, $user2->id);
1354          $this->assertTrue($result);
1355  
1356          $cm->groupmode = NOGROUPS;
1357          $result = groups_user_groups_visible($course, $user2->id, $cm);
1358          $this->assertTrue($result); // Cm with no groups.
1359  
1360          $cm->groupmode = SEPARATEGROUPS;
1361          $result = groups_user_groups_visible($course, $user2->id, $cm);
1362          $this->assertTrue($result); // Cm with separate groups.
1363  
1364          $cm->groupmode = VISIBLEGROUPS;
1365          $result = groups_user_groups_visible($course, $user2->id, $cm);
1366          $this->assertTrue($result); // Cm with visible groups.
1367  
1368          // Visible groups, not forced.
1369          $course->groupmode = VISIBLEGROUPS;
1370          $course->groupmodeforce = false;
1371          update_course($course);
1372          $result = groups_user_groups_visible($course, $user2->id);
1373          $this->assertTrue($result);
1374  
1375          $cm->groupmode = NOGROUPS;
1376          $result = groups_user_groups_visible($course, $user2->id, $cm);
1377          $this->assertTrue($result); // Cm with no groups.
1378  
1379          $cm->groupmode = SEPARATEGROUPS;
1380          $result = groups_user_groups_visible($course, $user2->id, $cm);
1381          $this->assertFalse($result); // Cm with separate groups.
1382  
1383          $cm->groupmode = VISIBLEGROUPS;
1384          $result = groups_user_groups_visible($course, $user2->id, $cm);
1385          $this->assertTrue($result); // Cm with visible groups.
1386  
1387          // Separate groups, forced.
1388          $course->groupmode = SEPARATEGROUPS;
1389          $course->groupmodeforce = true;
1390          update_course($course);
1391          $result = groups_user_groups_visible($course, $user2->id);
1392          $this->assertFalse($result);
1393  
1394          $result = groups_user_groups_visible($course, $user3->id);
1395          $this->assertFalse($result); // Requesting all groups.
1396  
1397          $cm->groupmode = NOGROUPS;
1398          $result = groups_user_groups_visible($course, $user2->id, $cm);
1399          $this->assertFalse($result); // Cm with no groups.
1400  
1401          $cm->groupmode = SEPARATEGROUPS;
1402          $result = groups_user_groups_visible($course, $user2->id, $cm);
1403          $this->assertFalse($result); // Cm with separate groups.
1404  
1405          $result = groups_user_groups_visible($course, $user3->id, $cm);
1406          $this->assertTrue($result);
1407  
1408          $cm->groupmode = VISIBLEGROUPS;
1409          $result = groups_user_groups_visible($course, $user2->id, $cm);
1410          $this->assertFalse($result); // Cm with visible groups.
1411  
1412          // Separate groups, not forced.
1413          $course->groupmode = SEPARATEGROUPS;
1414          $course->groupmodeforce = false;
1415          update_course($course);
1416          $result = groups_user_groups_visible($course, $user2->id);
1417          $this->assertFalse($result);
1418  
1419          $result = groups_user_groups_visible($course, $user3->id);
1420          $this->assertFalse($result); // Requesting all groups.
1421  
1422          $cm->groupmode = NOGROUPS;
1423          $result = groups_user_groups_visible($course, $user2->id, $cm);
1424          $this->assertTrue($result); // Cm with no groups.
1425  
1426          $cm->groupmode = SEPARATEGROUPS;
1427          $result = groups_user_groups_visible($course, $user2->id, $cm);
1428          $this->assertFalse($result); // Cm with separate groups.
1429  
1430          $cm->groupmode = VISIBLEGROUPS;
1431          $result = groups_user_groups_visible($course, $user2->id, $cm);
1432          $this->assertTrue($result); // Cm with visible groups.
1433  
1434          // Users sharing groups.
1435  
1436          // No groups , not forced.
1437          $course->groupmode = NOGROUPS;
1438          $course->groupmodeforce = false;
1439          update_course($course);
1440  
1441          $result = groups_user_groups_visible($course, $user4->id);
1442          $this->assertTrue($result);
1443  
1444          $cm->groupmode = NOGROUPS;
1445          $result = groups_user_groups_visible($course, $user4->id, $cm);
1446          $this->assertTrue($result); // Cm with no groups.
1447  
1448          $cm->groupmode = SEPARATEGROUPS;
1449          $result = groups_user_groups_visible($course, $user4->id, $cm);
1450          $this->assertTrue($result); // Cm with separate groups.
1451  
1452          $cm->groupmode = VISIBLEGROUPS;
1453          $result = groups_user_groups_visible($course, $user4->id, $cm);
1454          $this->assertTrue($result); // Cm with visible groups.
1455  
1456          // No groups, forced.
1457          $course->groupmode = NOGROUPS;
1458          $course->groupmodeforce = true;
1459          update_course($course);
1460          $result = groups_user_groups_visible($course, $user4->id);
1461          $this->assertTrue($result);
1462  
1463          $cm->groupmode = NOGROUPS;
1464          $result = groups_user_groups_visible($course, $user4->id, $cm);
1465          $this->assertTrue($result); // Cm with no groups.
1466  
1467          $cm->groupmode = SEPARATEGROUPS;
1468          $result = groups_user_groups_visible($course, $user4->id, $cm);
1469          $this->assertTrue($result); // Cm with separate groups.
1470  
1471          $cm->groupmode = SEPARATEGROUPS;
1472          $result = groups_user_groups_visible($course, $user4->id, $cm);
1473          $this->assertTrue($result); // Cm with visible groups.
1474  
1475          // Visible groups, forced.
1476          $course->groupmode = VISIBLEGROUPS;
1477          $course->groupmodeforce = true;
1478          update_course($course);
1479          $result = groups_user_groups_visible($course, $user4->id);
1480          $this->assertTrue($result);
1481  
1482          $cm->groupmode = NOGROUPS;
1483          $result = groups_user_groups_visible($course, $user4->id, $cm);
1484          $this->assertTrue($result); // Cm with no groups.
1485  
1486          $cm->groupmode = SEPARATEGROUPS;
1487          $result = groups_user_groups_visible($course, $user4->id, $cm);
1488          $this->assertTrue($result); // Cm with separate groups.
1489  
1490          $cm->groupmode = VISIBLEGROUPS;
1491          $result = groups_user_groups_visible($course, $user4->id, $cm);
1492          $this->assertTrue($result); // Cm with visible groups.
1493  
1494          // Visible groups, not forced.
1495          $course->groupmode = VISIBLEGROUPS;
1496          $course->groupmodeforce = false;
1497          update_course($course);
1498          $result = groups_user_groups_visible($course, $user4->id);
1499          $this->assertTrue($result);
1500  
1501          $cm->groupmode = NOGROUPS;
1502          $result = groups_user_groups_visible($course, $user4->id, $cm);
1503          $this->assertTrue($result); // Cm with no groups.
1504  
1505          $cm->groupmode = SEPARATEGROUPS;
1506          $result = groups_user_groups_visible($course, $user4->id, $cm);
1507          $this->assertTrue($result); // Cm with separate groups.
1508  
1509          $cm->groupmode = VISIBLEGROUPS;
1510          $result = groups_user_groups_visible($course, $user4->id, $cm);
1511          $this->assertTrue($result); // Cm with visible groups.
1512  
1513          // Separate groups, forced.
1514          $course->groupmode = SEPARATEGROUPS;
1515          $course->groupmodeforce = true;
1516          update_course($course);
1517          $result = groups_user_groups_visible($course, $user4->id);
1518          $this->assertTrue($result);
1519  
1520          $result = groups_user_groups_visible($course, $user3->id);
1521          $this->assertFalse($result); // Requesting all groups.
1522  
1523          $cm->groupmode = NOGROUPS;
1524          $result = groups_user_groups_visible($course, $user4->id, $cm);
1525          $this->assertTrue($result); // Cm with no groups.
1526  
1527          $cm->groupmode = SEPARATEGROUPS;
1528          $result = groups_user_groups_visible($course, $user4->id, $cm);
1529          $this->assertTrue($result); // Cm with separate groups.
1530  
1531          $result = groups_user_groups_visible($course, $user3->id, $cm);
1532          $this->assertTrue($result);
1533  
1534          $cm->groupmode = VISIBLEGROUPS;
1535          $result = groups_user_groups_visible($course, $user4->id, $cm);
1536          $this->assertTrue($result); // Cm with visible groups.
1537  
1538          // Separate groups, not forced.
1539          $course->groupmode = SEPARATEGROUPS;
1540          $course->groupmodeforce = false;
1541          update_course($course);
1542          $result = groups_user_groups_visible($course, $user4->id);
1543          $this->assertTrue($result);
1544  
1545          $result = groups_user_groups_visible($course, $user3->id);
1546          $this->assertFalse($result); // Requesting all groups.
1547  
1548          $cm->groupmode = NOGROUPS;
1549          $result = groups_user_groups_visible($course, $user4->id, $cm);
1550          $this->assertTrue($result); // Cm with no groups.
1551  
1552          $cm->groupmode = SEPARATEGROUPS;
1553          $result = groups_user_groups_visible($course, $user4->id, $cm);
1554          $this->assertTrue($result); // Cm with separate groups.
1555  
1556          $cm->groupmode = VISIBLEGROUPS;
1557          $result = groups_user_groups_visible($course, $user4->id, $cm);
1558          $this->assertTrue($result); // Cm with visible groups.
1559  
1560          // For teacher with access all groups.
1561  
1562          // No groups , not forced.
1563          $course->groupmode = NOGROUPS;
1564          $course->groupmodeforce = false;
1565          update_course($course);
1566  
1567          $this->setUser($user3);
1568  
1569          $result = groups_user_groups_visible($course, $user1->id);
1570          $this->assertTrue($result);
1571          $result = groups_user_groups_visible($course, $user1->id);
1572          $this->assertTrue($result); // Requesting all groups.
1573  
1574          $cm->groupmode = NOGROUPS;
1575          $result = groups_user_groups_visible($course, $user1->id, $cm);
1576          $this->assertTrue($result); // Cm with no groups.
1577  
1578          $cm->groupmode = SEPARATEGROUPS;
1579          $result = groups_user_groups_visible($course, $user1->id, $cm);
1580          $this->assertTrue($result); // Cm with separate groups.
1581          $result = groups_user_groups_visible($course, $user2->id, $cm);
1582          $this->assertTrue($result); // Cm with separate groups.
1583  
1584          $cm->groupmode = VISIBLEGROUPS;
1585          $result = groups_user_groups_visible($course, $user1->id, $cm);
1586          $this->assertTrue($result); // Cm with visible groups.
1587  
1588          // No groups, forced.
1589          $course->groupmode = NOGROUPS;
1590          $course->groupmodeforce = true;
1591          update_course($course);
1592          $result = groups_user_groups_visible($course, $user1->id);
1593          $this->assertTrue($result);
1594          $result = groups_user_groups_visible($course, $user1->id);
1595          $this->assertTrue($result); // Requesting all groups.
1596  
1597          $cm->groupmode = NOGROUPS;
1598          $result = groups_user_groups_visible($course, $user1->id, $cm);
1599          $this->assertTrue($result); // Cm with no groups.
1600  
1601          $cm->groupmode = SEPARATEGROUPS;
1602          $result = groups_user_groups_visible($course, $user1->id, $cm);
1603          $this->assertTrue($result); // Cm with separate groups.
1604          $result = groups_user_groups_visible($course, $user2->id, $cm);
1605          $this->assertTrue($result); // Cm with separate groups.
1606  
1607          $cm->groupmode = SEPARATEGROUPS;
1608          $result = groups_user_groups_visible($course, $user1->id, $cm);
1609          $this->assertTrue($result); // Cm with visible groups.
1610  
1611          // Visible groups, forced.
1612          $course->groupmode = VISIBLEGROUPS;
1613          $course->groupmodeforce = true;
1614          update_course($course);
1615          $result = groups_user_groups_visible($course, $user1->id);
1616          $this->assertTrue($result);
1617          $result = groups_user_groups_visible($course, $user1->id);
1618          $this->assertTrue($result); // Requesting all groups.
1619  
1620          $cm->groupmode = NOGROUPS;
1621          $result = groups_user_groups_visible($course, $user1->id, $cm);
1622          $this->assertTrue($result); // Cm with no groups.
1623  
1624          $cm->groupmode = SEPARATEGROUPS;
1625          $result = groups_user_groups_visible($course, $user1->id, $cm);
1626          $this->assertTrue($result); // Cm with separate groups.
1627          $result = groups_user_groups_visible($course, $user2->id, $cm);
1628          $this->assertTrue($result); // Cm with separate groups.
1629  
1630          $cm->groupmode = VISIBLEGROUPS;
1631          $result = groups_user_groups_visible($course, $user1->id, $cm);
1632          $this->assertTrue($result); // Cm with visible groups.
1633  
1634          // Visible groups, not forced.
1635          $course->groupmode = VISIBLEGROUPS;
1636          $course->groupmodeforce = false;
1637          update_course($course);
1638          $result = groups_user_groups_visible($course, $user1->id);
1639          $this->assertTrue($result);
1640          $result = groups_user_groups_visible($course, $user1->id);
1641          $this->assertTrue($result); // Requesting all groups.
1642  
1643          $cm->groupmode = NOGROUPS;
1644          $result = groups_user_groups_visible($course, $user1->id, $cm);
1645          $this->assertTrue($result); // Cm with no groups.
1646  
1647          $cm->groupmode = SEPARATEGROUPS;
1648          $result = groups_user_groups_visible($course, $user1->id, $cm);
1649          $this->assertTrue($result); // Cm with separate groups.
1650          $result = groups_user_groups_visible($course, $user2->id, $cm);
1651          $this->assertTrue($result); // Cm with separate groups.
1652  
1653          $cm->groupmode = VISIBLEGROUPS;
1654          $result = groups_user_groups_visible($course, $user1->id, $cm);
1655          $this->assertTrue($result); // Cm with visible groups.
1656  
1657          // Separate groups, forced.
1658          $course->groupmode = SEPARATEGROUPS;
1659          $course->groupmodeforce = true;
1660          update_course($course);
1661          $result = groups_user_groups_visible($course, $user1->id);
1662          $this->assertTrue($result);
1663          $result = groups_user_groups_visible($course, $user2->id);
1664          $this->assertTrue($result);
1665          $result = groups_user_groups_visible($course, $user2->id);
1666          $this->assertTrue($result); // Requesting all groups.
1667          $result = groups_user_groups_visible($course, $user3->id);
1668          $this->assertTrue($result); // Requesting all groups.
1669          $result = groups_user_groups_visible($course, $user3->id);
1670          $this->assertTrue($result);
1671  
1672          $cm->groupmode = NOGROUPS;
1673          $result = groups_user_groups_visible($course, $user1->id, $cm);
1674          $this->assertTrue($result); // Cm with no groups.
1675  
1676          $cm->groupmode = SEPARATEGROUPS;
1677          $result = groups_user_groups_visible($course, $user1->id, $cm);
1678          $this->assertTrue($result); // Cm with separate groups.
1679          $result = groups_user_groups_visible($course, $user2->id, $cm);
1680          $this->assertTrue($result); // Cm with separate groups.
1681          $result = groups_user_groups_visible($course, $user3->id, $cm);
1682          $this->assertTrue($result);
1683  
1684          $cm->groupmode = VISIBLEGROUPS;
1685          $result = groups_user_groups_visible($course, $user1->id, $cm);
1686          $this->assertTrue($result); // Cm with visible groups.
1687  
1688          // Separate groups, not forced.
1689          $course->groupmode = SEPARATEGROUPS;
1690          $course->groupmodeforce = false;
1691          update_course($course);
1692          $result = groups_user_groups_visible($course, $user1->id);
1693          $this->assertTrue($result);
1694          $result = groups_user_groups_visible($course, $user2->id);
1695          $this->assertTrue($result);
1696          $result = groups_user_groups_visible($course, $user2->id);
1697          $this->assertTrue($result); // Requesting all groups.
1698          $result = groups_user_groups_visible($course, $user3->id);
1699          $this->assertTrue($result); // Requesting all groups.
1700  
1701          $cm->groupmode = NOGROUPS;
1702          $result = groups_user_groups_visible($course, $user1->id, $cm);
1703          $this->assertTrue($result); // Cm with no groups.
1704  
1705          $cm->groupmode = SEPARATEGROUPS;
1706          $result = groups_user_groups_visible($course, $user1->id, $cm);
1707          $this->assertTrue($result); // Cm with separate groups.
1708          $result = groups_user_groups_visible($course, $user2->id, $cm);
1709          $this->assertTrue($result); // Cm with separate groups.
1710  
1711          $cm->groupmode = VISIBLEGROUPS;
1712          $result = groups_user_groups_visible($course, $user1->id, $cm);
1713          $this->assertTrue($result); // Cm with visible groups.
1714      }
1715  
1716      /**
1717       * Tests for groups_get_groups_members() method.
1718       */
1719      public function test_groups_get_groups_members() {
1720          $this->resetAfterTest(true);
1721          $generator = $this->getDataGenerator();
1722  
1723          // Create courses.
1724          $course1 = $generator->create_course();
1725          $course2 = $generator->create_course();
1726  
1727          // Create users.
1728          $user1 = $generator->create_user();
1729          $user2 = $generator->create_user();
1730          $user3 = $generator->create_user();
1731  
1732          // Enrol users.
1733          $generator->enrol_user($user1->id, $course1->id);
1734          $generator->enrol_user($user1->id, $course2->id);
1735          $generator->enrol_user($user2->id, $course2->id);
1736          $generator->enrol_user($user3->id, $course2->id);
1737  
1738          // Create groups.
1739          $group1 = $generator->create_group(array('courseid' => $course1->id));
1740          $group2 = $generator->create_group(array('courseid' => $course2->id));
1741          $group3 = $generator->create_group(array('courseid' => $course2->id));
1742  
1743          // Assign users to groups.
1744          $this->assertTrue($generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id)));
1745          $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id)));
1746          $this->assertTrue($generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id)));
1747  
1748          // Test get_groups_members (with extra field and ordering).
1749          $members = groups_get_groups_members([$group1->id, $group2->id], ['lastaccess'], 'u.id ASC');
1750          $this->assertCount(2, $members);
1751          $this->assertEquals([$user1->id, $user2->id], array_keys($members));
1752          $this->assertTrue(isset($members[$user1->id]->lastaccess));
1753          $this->assertTrue(isset($members[$user2->id]->lastaccess));
1754  
1755          // Group with just one.
1756          $members = groups_get_groups_members([$group1->id]);
1757          $this->assertCount(1, $members);
1758          $this->assertEquals($user1->id, $members[$user1->id]->id);
1759  
1760          // Test the info matches group membership for the entire course.
1761          $groups  = groups_get_all_groups($course1->id, 0, 0, 'g.*', true);
1762          $group1withmembers = array_pop($groups);
1763  
1764          // Compare the sorted keys of both arrays (should be list of user ids).
1765          $members = array_keys($members);
1766          sort($members);
1767          $group1members = array_keys($group1withmembers->members);
1768          sort($group1members);
1769          $this->assertEquals($members, $group1members);
1770  
1771          // Group with just one plus empty group.
1772          $members = groups_get_groups_members([$group1->id, $group3->id]);
1773          $this->assertCount(1, $members);
1774          $this->assertEquals($user1->id, $members[$user1->id]->id);
1775  
1776          // Empty group.
1777          $members = groups_get_groups_members([$group3->id]);
1778          $this->assertCount(0, $members);
1779  
1780          // Test groups_get_members.
1781          $members = groups_get_members($group2->id, 'u.*', 'u.id ASC');
1782          $this->assertCount(2, $members);
1783          $this->assertEquals([$user1->id, $user2->id], array_keys($members));
1784  
1785          // Test the info matches group membership for the entire course.
1786          $groups  = groups_get_all_groups($course2->id, 0, 0, 'g.*', true);
1787          $group2withmembers = $groups[$group2->id];
1788  
1789          // Compare the sorted keys of both arrays (should be list of user ids).
1790          $members = array_keys($members);
1791          sort($members);
1792          $group2members = array_keys($group2withmembers->members);
1793          sort($group2members);
1794          $this->assertEquals($members, $group2members);
1795  
1796      }
1797  
1798      /**
1799       * Tests for groups_get_activity_shared_group_members() method.
1800       */
1801      public function test_groups_get_activity_shared_group_members() {
1802          $this->resetAfterTest(true);
1803          $generator = $this->getDataGenerator();
1804  
1805          // Create courses.
1806          $course = $generator->create_course();
1807  
1808          // Create cm.
1809          $assign = $generator->create_module("assign", array('course' => $course->id));
1810          $cm = get_coursemodule_from_instance("assign", $assign->id);
1811  
1812          // Create users.
1813          $user1 = $generator->create_user();
1814          $user2 = $generator->create_user();
1815          $user3 = $generator->create_user();
1816          $user4 = $generator->create_user();
1817  
1818          // Enrol users.
1819          $generator->enrol_user($user1->id, $course->id);
1820          $generator->enrol_user($user2->id, $course->id);
1821          $generator->enrol_user($user3->id, $course->id);
1822          $generator->enrol_user($user4->id, $course->id);
1823  
1824          // Create groups.
1825          $group1 = $generator->create_group(array('courseid' => $course->id));
1826          $group2 = $generator->create_group(array('courseid' => $course->id));
1827          $group3 = $generator->create_group(array('courseid' => $course->id));
1828  
1829          // Assign users to groups.
1830          $generator->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
1831          $generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
1832          $generator->create_group_member(array('groupid' => $group2->id, 'userid' => $user2->id));
1833          $generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user3->id));
1834  
1835          // Retrieve users sharing groups with user1.
1836          $members = groups_get_activity_shared_group_members($cm, $user1->id);
1837          $this->assertCount(2, $members);
1838          $this->assertEqualsCanonicalizing([$user1->id, $user2->id], array_keys($members));
1839  
1840          // Retrieve users sharing groups with user2.
1841          $members = groups_get_activity_shared_group_members($cm, $user2->id);
1842          $this->assertCount(2, $members);
1843          $this->assertEqualsCanonicalizing([$user1->id, $user2->id], array_keys($members));
1844  
1845          // Retrieve users sharing groups with user3.
1846          $members = groups_get_activity_shared_group_members($cm, $user3->id);
1847          $this->assertCount(1, $members);
1848          $this->assertEquals($user3->id, $members[$user3->id]->id);
1849  
1850          // Retrieve users sharing groups with user without groups (user4).
1851          $members = groups_get_activity_shared_group_members($cm, $user4->id);
1852          $this->assertCount(0, $members);
1853  
1854          // Now, create a different activity using groupings.
1855          $grouping = $generator->create_grouping(array('courseid' => $course->id, 'name' => 'Grouping 1'));
1856          // Skip group 2.
1857          groups_assign_grouping($grouping->id, $group1->id);
1858          groups_assign_grouping($grouping->id, $group3->id);
1859  
1860          $assign = $generator->create_module("assign", array('course' => $course->id, 'groupingid' => $grouping->id));
1861          $cm = get_coursemodule_from_instance("assign", $assign->id);
1862  
1863          // Since the activity is forced to groupings (groups 1 and 3), I don't see members of group 2.
1864          $members = groups_get_activity_shared_group_members($cm, $user1->id);
1865          $this->assertCount(1, $members);
1866          $this->assertEquals($user1->id, $members[$user1->id]->id);
1867  
1868          // Add user1 to group 3 (in the grouping).
1869          $generator->create_group_member(array('groupid' => $group3->id, 'userid' => $user1->id));
1870          $members = groups_get_activity_shared_group_members($cm, $user1->id);
1871          $this->assertCount(2, $members);    // Now I see members of group 3.
1872          $this->assertEqualsCanonicalizing([$user1->id, $user3->id], array_keys($members));
1873      }
1874  }