Search moodle.org's
Developer Documentation

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