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 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   * Unit tests for group lib.
      19   *
      20   * @package    core_group
      21   * @copyright  2013 Frédéric Massart
      22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      23   */
      24  namespace core_group;
      25  
      26  defined('MOODLE_INTERNAL') || die();
      27  
      28  global $CFG;
      29  require_once($CFG->dirroot . '/group/lib.php');
      30  
      31  /**
      32   * Group lib testcase.
      33   *
      34   * @package    core_group
      35   * @copyright  2013 Frédéric Massart
      36   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      37   */
      38  class lib_test extends \advanced_testcase {
      39  
      40      public function test_member_added_event() {
      41          $this->resetAfterTest();
      42  
      43          $this->setAdminUser();
      44          $course = $this->getDataGenerator()->create_course();
      45          $user = $this->getDataGenerator()->create_user();
      46          $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
      47          $this->getDataGenerator()->enrol_user($user->id, $course->id);
      48  
      49          $sink = $this->redirectEvents();
      50          groups_add_member($group->id, $user->id, 'mod_workshop', '123');
      51          $events = $sink->get_events();
      52          $this->assertCount(1, $events);
      53          $event = reset($events);
      54  
      55          $expected = new \stdClass();
      56          $expected->groupid = $group->id;
      57          $expected->userid  = $user->id;
      58          $expected->component = 'mod_workshop';
      59          $expected->itemid = '123';
      60          $this->assertEventLegacyData($expected, $event);
      61          $this->assertSame('groups_member_added', $event->get_legacy_eventname());
      62          $this->assertInstanceOf('\core\event\group_member_added', $event);
      63          $this->assertEquals($user->id, $event->relateduserid);
      64          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
      65          $this->assertEquals($group->id, $event->objectid);
      66          $url = new \moodle_url('/group/members.php', array('group' => $event->objectid));
      67          $this->assertEquals($url, $event->get_url());
      68      }
      69  
      70      public function test_member_removed_event() {
      71          $this->resetAfterTest();
      72  
      73          $this->setAdminUser();
      74          $course = $this->getDataGenerator()->create_course();
      75          $user = $this->getDataGenerator()->create_user();
      76          $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
      77          $this->getDataGenerator()->enrol_user($user->id, $course->id);
      78          $this->getDataGenerator()->create_group_member(array('userid' => $user->id, 'groupid' => $group->id));
      79  
      80          $sink = $this->redirectEvents();
      81          groups_remove_member($group->id, $user->id);
      82          $events = $sink->get_events();
      83          $this->assertCount(1, $events);
      84          $event = reset($events);
      85  
      86          $expected = new \stdClass();
      87          $expected->groupid = $group->id;
      88          $expected->userid  = $user->id;
      89          $this->assertEventLegacyData($expected, $event);
      90          $this->assertSame('groups_member_removed', $event->get_legacy_eventname());
      91          $this->assertInstanceOf('\core\event\group_member_removed', $event);
      92          $this->assertEquals($user->id, $event->relateduserid);
      93          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
      94          $this->assertEquals($group->id, $event->objectid);
      95          $url = new \moodle_url('/group/members.php', array('group' => $event->objectid));
      96          $this->assertEquals($url, $event->get_url());
      97      }
      98  
      99      public function test_group_created_event() {
     100          $this->resetAfterTest();
     101  
     102          $this->setAdminUser();
     103          $course = $this->getDataGenerator()->create_course();
     104  
     105          $sink = $this->redirectEvents();
     106          $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     107          $events = $sink->get_events();
     108          $this->assertCount(1, $events);
     109          $event = reset($events);
     110  
     111          $this->assertInstanceOf('\core\event\group_created', $event);
     112          $this->assertEventLegacyData($group, $event);
     113          $this->assertSame('groups_group_created', $event->get_legacy_eventname());
     114          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     115          $this->assertEquals($group->id, $event->objectid);
     116          $url = new \moodle_url('/group/index.php', array('id' => $event->courseid));
     117          $this->assertEquals($url, $event->get_url());
     118      }
     119  
     120      public function test_grouping_created_event() {
     121          $this->resetAfterTest();
     122  
     123          $this->setAdminUser();
     124          $course = $this->getDataGenerator()->create_course();
     125  
     126          $sink = $this->redirectEvents();
     127          $group = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     128          $events = $sink->get_events();
     129          $this->assertCount(1, $events);
     130          $event = reset($events);
     131  
     132          $this->assertInstanceOf('\core\event\grouping_created', $event);
     133  
     134          $this->assertEventLegacyData($group, $event);
     135          $this->assertSame('groups_grouping_created', $event->get_legacy_eventname());
     136  
     137          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     138          $this->assertEquals($group->id, $event->objectid);
     139          $url = new \moodle_url('/group/groupings.php', array('id' => $event->courseid));
     140          $this->assertEquals($url, $event->get_url());
     141      }
     142  
     143      public function test_group_updated_event() {
     144          global $DB;
     145  
     146          $this->resetAfterTest();
     147  
     148          $course = $this->getDataGenerator()->create_course();
     149          $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     150  
     151          $sink = $this->redirectEvents();
     152          $data = new \stdClass();
     153          $data->id = $group->id;
     154          $data->courseid = $course->id;
     155          $data->name = 'Backend team';
     156          $this->setCurrentTimeStart();
     157          groups_update_group($data);
     158          $group = $DB->get_record('groups', array('id'=>$group->id)); // Fetch record with modified timestamp.
     159          $events = $sink->get_events();
     160          $this->assertCount(1, $events);
     161          $event = reset($events);
     162          $this->assertTimeCurrent($group->timemodified);
     163  
     164          $this->assertInstanceOf('\core\event\group_updated', $event);
     165          $group->name = $data->name;
     166          $this->assertEventLegacyData($group, $event);
     167          $this->assertSame('groups_group_updated', $event->get_legacy_eventname());
     168          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     169          $this->assertEquals($group->id, $event->objectid);
     170          $url = new \moodle_url('/group/group.php', array('id' => $event->objectid));
     171          $this->assertEquals($url, $event->get_url());
     172      }
     173  
     174      public function test_group_updated_event_does_not_require_names() {
     175          global $DB;
     176  
     177          $this->resetAfterTest();
     178  
     179          $course = $this->getDataGenerator()->create_course();
     180          $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     181  
     182          $sink = $this->redirectEvents();
     183          $data = new \stdClass();
     184          $data->id = $group->id;
     185          $data->courseid = $course->id;
     186          $this->setCurrentTimeStart();
     187          groups_update_group($data);
     188          $group = $DB->get_record('groups', array('id'=>$group->id)); // Fetch record with modified timestamp.
     189          $events = $sink->get_events();
     190          $this->assertCount(1, $events);
     191          $event = reset($events);
     192          $this->assertTimeCurrent($group->timemodified);
     193  
     194          $this->assertInstanceOf('\core\event\group_updated', $event);
     195          $this->assertEventLegacyData($group, $event);
     196          $this->assertSame('groups_group_updated', $event->get_legacy_eventname());
     197          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     198          $this->assertEquals($group->id, $event->objectid);
     199          $url = new \moodle_url('/group/group.php', array('id' => $event->objectid));
     200          $this->assertEquals($url, $event->get_url());
     201      }
     202  
     203      public function test_grouping_updated_event() {
     204          global $DB;
     205  
     206          $this->resetAfterTest();
     207  
     208          $course = $this->getDataGenerator()->create_course();
     209          $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     210  
     211          $sink = $this->redirectEvents();
     212          $data = new \stdClass();
     213          $data->id = $grouping->id;
     214          $data->courseid = $course->id;
     215          $data->name = 'Backend team';
     216          $this->setCurrentTimeStart();
     217          groups_update_grouping($data);
     218          $events = $sink->get_events();
     219          $this->assertCount(1, $events);
     220          $event = reset($events);
     221  
     222          $this->assertInstanceOf('\core\event\grouping_updated', $event);
     223  
     224          // Get the timemodified from DB for comparison with snapshot.
     225          $data->timemodified = $DB->get_field('groupings', 'timemodified', array('id'=>$grouping->id));
     226          $this->assertTimeCurrent($data->timemodified);
     227          // Following fields were not updated so the snapshot should have them the same as in original group.
     228          $data->description = $grouping->description;
     229          $data->descriptionformat = $grouping->descriptionformat;
     230          $data->configdata = $grouping->configdata;
     231          $data->idnumber = $grouping->idnumber;
     232          $data->timecreated = $grouping->timecreated;
     233          // Assert legacy event data.
     234          $this->assertEventLegacyData($data, $event);
     235          $this->assertSame('groups_grouping_updated', $event->get_legacy_eventname());
     236  
     237          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     238          $this->assertEquals($grouping->id, $event->objectid);
     239          $url = new \moodle_url('/group/grouping.php', array('id' => $event->objectid));
     240          $this->assertEquals($url, $event->get_url());
     241      }
     242  
     243      public function test_grouping_updated_event_does_not_require_names() {
     244          global $DB;
     245  
     246          $this->resetAfterTest();
     247  
     248          $course = $this->getDataGenerator()->create_course();
     249          $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     250  
     251          $sink = $this->redirectEvents();
     252          $data = new \stdClass();
     253          $data->id = $grouping->id;
     254          $data->courseid = $course->id;
     255          $this->setCurrentTimeStart();
     256          groups_update_grouping($data);
     257          $events = $sink->get_events();
     258          $this->assertCount(1, $events);
     259          $event = reset($events);
     260  
     261          $this->assertInstanceOf('\core\event\grouping_updated', $event);
     262  
     263          // Get the timemodified from DB for comparison with snapshot.
     264          $data->timemodified = $DB->get_field('groupings', 'timemodified', array('id'=>$grouping->id));
     265          $this->assertTimeCurrent($data->timemodified);
     266          // Following fields were not updated so the snapshot should have them the same as in original group.
     267          $data->description = $grouping->description;
     268          $data->descriptionformat = $grouping->descriptionformat;
     269          $data->configdata = $grouping->configdata;
     270          $data->idnumber = $grouping->idnumber;
     271          $data->name = $grouping->name;
     272          $data->timecreated = $grouping->timecreated;
     273          // Assert legacy event data.
     274          $this->assertEventLegacyData($data, $event);
     275          $this->assertSame('groups_grouping_updated', $event->get_legacy_eventname());
     276  
     277          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     278          $this->assertEquals($grouping->id, $event->objectid);
     279          $url = new \moodle_url('/group/grouping.php', array('id' => $event->objectid));
     280          $this->assertEquals($url, $event->get_url());
     281      }
     282  
     283      public function test_group_deleted_event() {
     284          $this->resetAfterTest();
     285  
     286          $course = $this->getDataGenerator()->create_course();
     287          $group = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     288  
     289          $sink = $this->redirectEvents();
     290          groups_delete_group($group->id);
     291          $events = $sink->get_events();
     292          $this->assertCount(1, $events);
     293          $event = reset($events);
     294  
     295          $this->assertInstanceOf('\core\event\group_deleted', $event);
     296          $this->assertEventLegacyData($group, $event);
     297          $this->assertSame('groups_group_deleted', $event->get_legacy_eventname());
     298          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     299          $this->assertEquals($group->id, $event->objectid);
     300          $url = new \moodle_url('/group/index.php', array('id' => $event->courseid));
     301          $this->assertEquals($url, $event->get_url());
     302      }
     303  
     304      public function test_grouping_deleted_event() {
     305          $this->resetAfterTest();
     306  
     307          $course = $this->getDataGenerator()->create_course();
     308          $group = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     309  
     310          $sink = $this->redirectEvents();
     311          groups_delete_grouping($group->id);
     312          $events = $sink->get_events();
     313          $this->assertCount(1, $events);
     314          $event = reset($events);
     315  
     316          $this->assertInstanceOf('\core\event\grouping_deleted', $event);
     317          $this->assertEventLegacyData($group, $event);
     318          $this->assertSame('groups_grouping_deleted', $event->get_legacy_eventname());
     319          $this->assertEquals(\context_course::instance($course->id), $event->get_context());
     320          $this->assertEquals($group->id, $event->objectid);
     321          $url = new \moodle_url('/group/groupings.php', array('id' => $event->courseid));
     322          $this->assertEquals($url, $event->get_url());
     323      }
     324  
     325      public function test_groups_delete_group_members() {
     326          global $DB;
     327          $this->resetAfterTest();
     328  
     329          $course = $this->getDataGenerator()->create_course();
     330          $user1 = $this->getDataGenerator()->create_user();
     331          $user2 = $this->getDataGenerator()->create_user();
     332          $this->getDataGenerator()->enrol_user($user1->id, $course->id);
     333          $this->getDataGenerator()->enrol_user($user2->id, $course->id);
     334          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     335          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     336  
     337          // Test deletion of all the users.
     338          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     339          $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
     340          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     341  
     342          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     343          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     344          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     345          groups_delete_group_members($course->id);
     346          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     347          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     348          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     349  
     350          // Test deletion of a specific user.
     351          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     352          $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
     353          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     354  
     355          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     356          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     357          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     358          groups_delete_group_members($course->id, $user2->id);
     359          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     360          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     361          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     362      }
     363  
     364      public function test_groups_remove_member() {
     365          global $DB;
     366          $this->resetAfterTest();
     367  
     368          $course = $this->getDataGenerator()->create_course();
     369          $user1 = $this->getDataGenerator()->create_user();
     370          $user2 = $this->getDataGenerator()->create_user();
     371          $this->getDataGenerator()->enrol_user($user1->id, $course->id);
     372          $this->getDataGenerator()->enrol_user($user2->id, $course->id);
     373          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     374          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     375  
     376          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     377          $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user1->id));
     378          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     379  
     380          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     381          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     382          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     383          groups_remove_member($group1->id, $user1->id);
     384          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     385          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     386          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     387          groups_remove_member($group1->id, $user2->id);
     388          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     389          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user2->id)));
     390          groups_remove_member($group2->id, $user1->id);
     391          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group2->id, 'userid' => $user1->id)));
     392      }
     393  
     394      public function test_groups_delete_groupings_groups() {
     395          global $DB;
     396          $this->resetAfterTest();
     397  
     398          $course = $this->getDataGenerator()->create_course();
     399          $course2 = $this->getDataGenerator()->create_course();
     400          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     401          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     402          $group1c2 = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
     403          $grouping1 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     404          $grouping2 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     405          $grouping1c2 = $this->getDataGenerator()->create_grouping(array('courseid' => $course2->id));
     406  
     407          $this->getDataGenerator()->create_grouping_group(array('groupingid' => $grouping1->id, 'groupid' => $group1->id));
     408          $this->getDataGenerator()->create_grouping_group(array('groupingid' => $grouping1->id, 'groupid' => $group2->id));
     409          $this->getDataGenerator()->create_grouping_group(array('groupingid' => $grouping2->id, 'groupid' => $group1->id));
     410          $this->getDataGenerator()->create_grouping_group(array('groupingid' => $grouping1c2->id, 'groupid' => $group1c2->id));
     411          $this->assertTrue($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping1->id)));
     412          $this->assertTrue($DB->record_exists('groupings_groups', array('groupid' => $group2->id, 'groupingid' => $grouping1->id)));
     413          $this->assertTrue($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping2->id)));
     414          $this->assertTrue($DB->record_exists('groupings_groups',
     415              array('groupid' => $group1c2->id, 'groupingid' => $grouping1c2->id)));
     416          groups_delete_groupings_groups($course->id);
     417          $this->assertFalse($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping1->id)));
     418          $this->assertFalse($DB->record_exists('groupings_groups', array('groupid' => $group2->id, 'groupingid' => $grouping1->id)));
     419          $this->assertFalse($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping2->id)));
     420          $this->assertTrue($DB->record_exists('groupings_groups',
     421              array('groupid' => $group1c2->id, 'groupingid' => $grouping1c2->id)));
     422      }
     423  
     424      public function test_groups_delete_groups() {
     425          global $DB;
     426          $this->resetAfterTest();
     427  
     428          $course = $this->getDataGenerator()->create_course();
     429          $course2 = $this->getDataGenerator()->create_course();
     430          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     431          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     432          $group1c2 = $this->getDataGenerator()->create_group(array('courseid' => $course2->id));
     433          $grouping1 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     434          $grouping2 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     435          $user1 = $this->getDataGenerator()->create_user();
     436          $this->getDataGenerator()->enrol_user($user1->id, $course->id);
     437          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     438          $this->getDataGenerator()->create_grouping_group(array('groupid' => $group1->id, 'groupingid' => $grouping1->id));
     439  
     440          $this->assertTrue($DB->record_exists('groups', array('id' => $group1->id, 'courseid' => $course->id)));
     441          $this->assertTrue($DB->record_exists('groups', array('id' => $group2->id, 'courseid' => $course->id)));
     442          $this->assertTrue($DB->record_exists('groups', array('id' => $group1c2->id, 'courseid' => $course2->id)));
     443          $this->assertTrue($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     444          $this->assertTrue($DB->record_exists('groupings', array('id' => $grouping1->id, 'courseid' => $course->id)));
     445          $this->assertTrue($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping1->id)));
     446          groups_delete_groups($course->id);
     447          $this->assertFalse($DB->record_exists('groups', array('id' => $group1->id, 'courseid' => $course->id)));
     448          $this->assertFalse($DB->record_exists('groups', array('id' => $group2->id, 'courseid' => $course->id)));
     449          $this->assertTrue($DB->record_exists('groups', array('id' => $group1c2->id, 'courseid' => $course2->id)));
     450          $this->assertFalse($DB->record_exists('groups_members', array('groupid' => $group1->id, 'userid' => $user1->id)));
     451          $this->assertTrue($DB->record_exists('groupings', array('id' => $grouping1->id, 'courseid' => $course->id)));
     452          $this->assertFalse($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping1->id)));
     453      }
     454  
     455      public function test_groups_delete_groupings() {
     456          global $DB;
     457          $this->resetAfterTest();
     458  
     459          $course = $this->getDataGenerator()->create_course();
     460          $course2 = $this->getDataGenerator()->create_course();
     461          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     462          $grouping1 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     463          $grouping2 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     464          $grouping1c2 = $this->getDataGenerator()->create_grouping(array('courseid' => $course2->id));
     465          $this->getDataGenerator()->create_grouping_group(array('groupid' => $group1->id, 'groupingid' => $grouping1->id));
     466  
     467          $this->assertTrue($DB->record_exists('groups', array('id' => $group1->id, 'courseid' => $course->id)));
     468          $this->assertTrue($DB->record_exists('groupings', array('id' => $grouping1->id, 'courseid' => $course->id)));
     469          $this->assertTrue($DB->record_exists('groupings', array('id' => $grouping2->id, 'courseid' => $course->id)));
     470          $this->assertTrue($DB->record_exists('groupings', array('id' => $grouping1c2->id, 'courseid' => $course2->id)));
     471          $this->assertTrue($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping1->id)));
     472          groups_delete_groupings($course->id);
     473          $this->assertTrue($DB->record_exists('groups', array('id' => $group1->id, 'courseid' => $course->id)));
     474          $this->assertFalse($DB->record_exists('groupings', array('id' => $grouping1->id, 'courseid' => $course->id)));
     475          $this->assertFalse($DB->record_exists('groupings', array('id' => $grouping2->id, 'courseid' => $course->id)));
     476          $this->assertTrue($DB->record_exists('groupings', array('id' => $grouping1c2->id, 'courseid' => $course2->id)));
     477          $this->assertFalse($DB->record_exists('groupings_groups', array('groupid' => $group1->id, 'groupingid' => $grouping1->id)));
     478      }
     479  
     480      public function test_groups_create_autogroups () {
     481          global $DB;
     482          $this->resetAfterTest();
     483  
     484          $course = $this->getDataGenerator()->create_course();
     485          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     486          $group2 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     487          $group3 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     488          $grouping1 = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     489          $this->getDataGenerator()->create_grouping_group(array('groupid' => $group2->id, 'groupingid' => $grouping1->id));
     490          $this->getDataGenerator()->create_grouping_group(array('groupid' => $group3->id, 'groupingid' => $grouping1->id));
     491          $user1 = $this->getDataGenerator()->create_user();
     492          $user2 = $this->getDataGenerator()->create_user();
     493          $user3 = $this->getDataGenerator()->create_user();
     494          $user4 = $this->getDataGenerator()->create_user();
     495          $this->getDataGenerator()->enrol_user($user1->id, $course->id);
     496          $this->getDataGenerator()->enrol_user($user2->id, $course->id);
     497          $this->getDataGenerator()->enrol_user($user3->id, $course->id);
     498          $this->getDataGenerator()->enrol_user($user4->id, $course->id);
     499          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     500          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     501          $this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $user3->id));
     502          $this->getDataGenerator()->create_group_member(array('groupid' => $group3->id, 'userid' => $user4->id));
     503  
     504          // Test autocreate group based on all course users.
     505          $users = groups_get_potential_members($course->id);
     506          $group4 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     507          foreach ($users as $user) {
     508              $this->getDataGenerator()->create_group_member(array('groupid' => $group4->id, 'userid' => $user->id));
     509          }
     510          $this->assertEquals(4, $DB->count_records('groups_members', array('groupid' => $group4->id)));
     511  
     512          // Test autocreate group based on existing group.
     513          $source = array();
     514          $source['groupid'] = $group1->id;
     515          $users = groups_get_potential_members($course->id, 0, $source);
     516          $group5 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     517          foreach ($users as $user) {
     518              $this->getDataGenerator()->create_group_member(array('groupid' => $group5->id, 'userid' => $user->id));
     519          }
     520          $this->assertEquals(2, $DB->count_records('groups_members', array('groupid' => $group5->id)));
     521  
     522          // Test autocreate group based on existing grouping.
     523          $source = array();
     524          $source['groupingid'] = $grouping1->id;
     525          $users = groups_get_potential_members($course->id, 0, $source);
     526          $group6 = $this->getDataGenerator()->create_group(array('courseid' => $course->id));
     527          foreach ($users as $user) {
     528              $this->getDataGenerator()->create_group_member(array('groupid' => $group6->id, 'userid' => $user->id));
     529          }
     530          $this->assertEquals(2, $DB->count_records('groups_members', array('groupid' => $group6->id)));
     531      }
     532  
     533      /**
     534       * Test groups_create_group enabling a group conversation.
     535       */
     536      public function test_groups_create_group_with_conversation() {
     537          global $DB;
     538  
     539          $this->resetAfterTest();
     540          $this->setAdminUser();
     541          $course1 = $this->getDataGenerator()->create_course();
     542          $coursecontext1 = \context_course::instance($course1->id);
     543  
     544          // Create two groups and only one group with enablemessaging = 1.
     545          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
     546          $group1b = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 0));
     547  
     548          $conversations = $DB->get_records('message_conversations',
     549              [
     550                  'contextid' => $coursecontext1->id,
     551                  'component' => 'core_group',
     552                  'itemtype' => 'groups',
     553                  'enabled' => \core_message\api::MESSAGE_CONVERSATION_ENABLED
     554              ]
     555          );
     556          $this->assertCount(1, $conversations);
     557  
     558          $conversation = reset($conversations);
     559          // Check groupid was stored in itemid on conversation area.
     560          $this->assertEquals($group1a->id, $conversation->itemid);
     561  
     562          $conversations = $DB->get_records('message_conversations', ['id' => $conversation->id]);
     563          $this->assertCount(1, $conversations);
     564  
     565          $conversation = reset($conversations);
     566  
     567          // Check group name was stored in conversation.
     568          $this->assertEquals($group1a->name, $conversation->name);
     569      }
     570  
     571      /**
     572       * Test groups_update_group enabling and disabling a group conversation.
     573       */
     574      public function test_groups_update_group_conversation() {
     575          global $DB;
     576  
     577          $this->resetAfterTest();
     578          $this->setAdminUser();
     579          $course1 = $this->getDataGenerator()->create_course();
     580          $coursecontext1 = \context_course::instance($course1->id);
     581  
     582          // Create two groups and only one group with enablemessaging = 1.
     583          $group1a = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
     584          $group1b = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 0));
     585  
     586          $conversations = $DB->get_records('message_conversations',
     587              [
     588                  'contextid' => $coursecontext1->id,
     589                  'component' => 'core_group',
     590                  'itemtype' => 'groups',
     591                  'enabled' => \core_message\api::MESSAGE_CONVERSATION_ENABLED
     592              ]
     593          );
     594          $this->assertCount(1, $conversations);
     595  
     596          // Check that the conversation area is created when group messaging is enabled in the course group.
     597          $group1b->enablemessaging = 1;
     598          groups_update_group($group1b);
     599  
     600          $conversations = $DB->get_records('message_conversations',
     601              [
     602                  'contextid' => $coursecontext1->id,
     603                  'component' => 'core_group',
     604                  'itemtype' => 'groups',
     605                  'enabled' => \core_message\api::MESSAGE_CONVERSATION_ENABLED
     606              ],
     607          'id ASC');
     608          $this->assertCount(2, $conversations);
     609  
     610          $conversation1a = array_shift($conversations);
     611          $conversation1b = array_shift($conversations);
     612  
     613          $conversation1b = $DB->get_record('message_conversations', ['id' => $conversation1b->id]);
     614  
     615          // Check for group1b that group name was stored in conversation.
     616          $this->assertEquals($group1b->name, $conversation1b->name);
     617  
     618          $group1b->enablemessaging = 0;
     619          groups_update_group($group1b);
     620          $this->assertEquals(0, $DB->get_field("message_conversations", "enabled", ['id' => $conversation1b->id]));
     621  
     622          // Check that the name of the conversation is changed when the name of the course group is updated.
     623          $group1b->name = 'New group name';
     624          groups_update_group($group1b);
     625          $conversation1b = $DB->get_record('message_conversations', ['id' => $conversation1b->id]);
     626          $this->assertEquals($group1b->name, $conversation1b->name);
     627      }
     628  
     629      /**
     630       * Test groups_add_member to conversation.
     631       */
     632      public function test_groups_add_member_conversation() {
     633          global $DB;
     634          $this->resetAfterTest();
     635  
     636          $this->setAdminUser();
     637  
     638          $course1 = $this->getDataGenerator()->create_course();
     639          $coursecontext1 = \context_course::instance($course1->id);
     640  
     641          $user1 = $this->getDataGenerator()->create_user();
     642          $user2 = $this->getDataGenerator()->create_user();
     643          $user3 = $this->getDataGenerator()->create_user();
     644  
     645          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
     646          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
     647          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
     648  
     649          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
     650  
     651          // Add users to group1.
     652          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     653          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     654  
     655          $conversation = \core_message\api::get_conversation_by_area(
     656              'core_group',
     657              'groups',
     658              $group1->id,
     659              $coursecontext1->id
     660          );
     661  
     662          // Check if the users has been added to the conversation.
     663          $this->assertEquals(2, $DB->count_records('message_conversation_members', ['conversationid' => $conversation->id]));
     664  
     665          // Check if the user has been added to the conversation when the conversation is disabled.
     666          \core_message\api::disable_conversation($conversation->id);
     667          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user3->id));
     668          $this->assertEquals(3, $DB->count_records('message_conversation_members', ['conversationid' => $conversation->id]));
     669      }
     670  
     671      /**
     672       * Test groups_remove_member to conversation.
     673       */
     674      public function test_groups_remove_member_conversation() {
     675          global $DB;
     676  
     677          $this->resetAfterTest();
     678  
     679          $this->setAdminUser();
     680  
     681          $course1 = $this->getDataGenerator()->create_course();
     682          $coursecontext1 = \context_course::instance($course1->id);
     683  
     684          $user1 = $this->getDataGenerator()->create_user();
     685          $user2 = $this->getDataGenerator()->create_user();
     686          $user3 = $this->getDataGenerator()->create_user();
     687  
     688          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
     689          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
     690          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
     691  
     692          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 1));
     693  
     694          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     695          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     696          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user3->id));
     697  
     698          $conversation = \core_message\api::get_conversation_by_area(
     699              'core_group',
     700              'groups',
     701              $group1->id,
     702              $coursecontext1->id
     703          );
     704  
     705          // Check if there are three users in the conversation.
     706          $this->assertEquals(3, $DB->count_records('message_conversation_members', ['conversationid' => $conversation->id]));
     707  
     708          // Check if after removing one member in the conversation there are two members.
     709          groups_remove_member($group1->id, $user1->id);
     710          $this->assertEquals(2, $DB->count_records('message_conversation_members', ['conversationid' => $conversation->id]));
     711  
     712          // Check if the user has been removed from the conversation when the conversation is disabled.
     713          \core_message\api::disable_conversation($conversation->id);
     714          groups_remove_member($group1->id, $user2->id);
     715          $this->assertEquals(1, $DB->count_records('message_conversation_members', ['conversationid' => $conversation->id]));
     716      }
     717  
     718      /**
     719       * Test if you enable group messaging in a group with members these are added to the conversation.
     720       */
     721      public function test_add_members_group_updated_conversation_enabled() {
     722          global $DB;
     723  
     724          $this->resetAfterTest();
     725  
     726          $this->setAdminUser();
     727  
     728          $course1 = $this->getDataGenerator()->create_course();
     729          $coursecontext1 = \context_course::instance($course1->id);
     730  
     731          $user1 = $this->getDataGenerator()->create_user();
     732          $user2 = $this->getDataGenerator()->create_user();
     733          $user3 = $this->getDataGenerator()->create_user();
     734  
     735          $this->getDataGenerator()->enrol_user($user1->id, $course1->id);
     736          $this->getDataGenerator()->enrol_user($user2->id, $course1->id);
     737          $this->getDataGenerator()->enrol_user($user3->id, $course1->id);
     738  
     739          $group1 = $this->getDataGenerator()->create_group(array('courseid' => $course1->id, 'enablemessaging' => 0));
     740  
     741          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user1->id));
     742          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user2->id));
     743          $this->getDataGenerator()->create_group_member(array('groupid' => $group1->id, 'userid' => $user3->id));
     744  
     745          $conversation = \core_message\api::get_conversation_by_area(
     746              'core_group',
     747              'groups',
     748              $group1->id,
     749              $coursecontext1->id
     750          );
     751  
     752          // No conversation should exist as 'enablemessaging' was set to 0.
     753          $this->assertFalse($conversation);
     754  
     755          // Check that the three users are in the conversation when group messaging is enabled in the course group.
     756          $group1->enablemessaging = 1;
     757          groups_update_group($group1);
     758  
     759          $conversation = \core_message\api::get_conversation_by_area(
     760              'core_group',
     761              'groups',
     762              $group1->id,
     763              $coursecontext1->id
     764          );
     765  
     766          $this->assertEquals(3, $DB->count_records('message_conversation_members', ['conversationid' => $conversation->id]));
     767      }
     768  
     769      public function test_groups_get_members_by_role(): void {
     770          $this->resetAfterTest();
     771  
     772          $this->setAdminUser();
     773  
     774          $course1 = $this->getDataGenerator()->create_course();
     775  
     776          $user1 = $this->getDataGenerator()->create_user(['username' => 'user1', 'idnumber' => 1]);
     777          $user2 = $this->getDataGenerator()->create_user(['username' => 'user2', 'idnumber' => 2]);
     778          $user3 = $this->getDataGenerator()->create_user(['username' => 'user3', 'idnumber' => 3]);
     779  
     780          $this->getDataGenerator()->enrol_user($user1->id, $course1->id, 0);
     781          $this->getDataGenerator()->enrol_user($user2->id, $course1->id, 1);
     782          $this->getDataGenerator()->enrol_user($user3->id, $course1->id, 1);
     783  
     784          $group1 = $this->getDataGenerator()->create_group(['courseid' => $course1->id]);
     785  
     786          $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $user1->id]);
     787          $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $user2->id]);
     788          $this->getDataGenerator()->create_group_member(['groupid' => $group1->id, 'userid' => $user3->id]);
     789  
     790          // Test basic usage.
     791          $result = groups_get_members_by_role($group1->id, $course1->id);
     792          $this->assertEquals(1, count($result[0]->users));
     793          $this->assertEquals(2, count($result[1]->users));
     794          $this->assertEquals($user1->firstname, reset($result[0]->users)->firstname);
     795          $this->assertEquals($user1->username, reset($result[0]->users)->username);
     796  
     797          // Test with specified fields.
     798          $result = groups_get_members_by_role($group1->id, $course1->id, 'u.firstname, u.lastname');
     799          $this->assertEquals(1, count($result[0]->users));
     800          $this->assertEquals($user1->firstname, reset($result[0]->users)->firstname);
     801          $this->assertEquals($user1->lastname, reset($result[0]->users)->lastname);
     802          $this->assertEquals(false, isset(reset($result[0]->users)->username));
     803  
     804          // Test with sorting.
     805          $result = groups_get_members_by_role($group1->id, $course1->id, 'u.username', 'u.username DESC');
     806          $this->assertEquals(1, count($result[0]->users));
     807          $this->assertEquals($user3->username, reset($result[1]->users)->username);
     808          $result = groups_get_members_by_role($group1->id, $course1->id, 'u.username', 'u.username ASC');
     809          $this->assertEquals(1, count($result[0]->users));
     810          $this->assertEquals($user2->username, reset($result[1]->users)->username);
     811  
     812          // Test with extra WHERE.
     813          $result = groups_get_members_by_role(
     814              $group1->id,
     815              $course1->id,
     816              'u.username',
     817              null,
     818              'u.idnumber > :number',
     819              ['number' => 2]);
     820          $this->assertEquals(1, count($result));
     821          $this->assertEquals(1, count($result[1]->users));
     822          $this->assertEquals($user3->username, reset($result[1]->users)->username);
     823  
     824          // Test with join.
     825          set_user_preference('reptile', 'snake', $user1);
     826          $result = groups_get_members_by_role($group1->id, $course1->id, 'u.username, up.value', null, 'up.name = :prefname',
     827                  ['prefname' => 'reptile'], 'JOIN {user_preferences} up ON up.userid = u.id');
     828          $this->assertEquals('snake', reset($result[0]->users)->value);
     829      }
     830  }