Search moodle.org's
Developer Documentation

See Release Notes

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

Differences Between: [Versions 310 and 311] [Versions 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  }