Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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   * Group external PHPunit tests
  19   *
  20   * @package    core_group
  21   * @category   external
  22   * @copyright  2012 Jerome Mouneyrac
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   * @since Moodle 2.4
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  
  29  global $CFG;
  30  
  31  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  32  require_once($CFG->dirroot . '/group/externallib.php');
  33  require_once($CFG->dirroot . '/group/lib.php');
  34  
  35  class core_group_externallib_testcase extends externallib_advanced_testcase {
  36  
  37      /**
  38       * Test create_groups
  39       */
  40      public function test_create_groups() {
  41          global $DB;
  42  
  43          $this->resetAfterTest(true);
  44  
  45          $course  = self::getDataGenerator()->create_course();
  46  
  47          $group1 = array();
  48          $group1['courseid'] = $course->id;
  49          $group1['name'] = 'Group Test 1';
  50          $group1['description'] = 'Group Test 1 description';
  51          $group1['descriptionformat'] = FORMAT_MOODLE;
  52          $group1['enrolmentkey'] = 'Test group enrol secret phrase';
  53          $group1['idnumber'] = 'TEST1';
  54          $group2 = array();
  55          $group2['courseid'] = $course->id;
  56          $group2['name'] = 'Group Test 2';
  57          $group2['description'] = 'Group Test 2 description';
  58          $group3 = array();
  59          $group3['courseid'] = $course->id;
  60          $group3['name'] = 'Group Test 3';
  61          $group3['description'] = 'Group Test 3 description';
  62          $group3['idnumber'] = 'TEST1';
  63          $group4 = array();
  64          $group4['courseid'] = $course->id;
  65          $group4['name'] = 'Group Test 4';
  66          $group4['description'] = 'Group Test 4 description';
  67  
  68          // Set the required capabilities by the external function
  69          $context = context_course::instance($course->id);
  70          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
  71          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
  72  
  73          // Call the external function.
  74          $groups = core_group_external::create_groups(array($group1, $group2));
  75  
  76          // We need to execute the return values cleaning process to simulate the web service server.
  77          $groups = external_api::clean_returnvalue(core_group_external::create_groups_returns(), $groups);
  78  
  79          // Checks against DB values
  80          $this->assertEquals(2, count($groups));
  81          foreach ($groups as $group) {
  82              $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
  83              switch ($dbgroup->name) {
  84                  case $group1['name']:
  85                      $groupdescription = $group1['description'];
  86                      $groupcourseid = $group1['courseid'];
  87                      $this->assertEquals($dbgroup->descriptionformat, $group1['descriptionformat']);
  88                      $this->assertEquals($dbgroup->enrolmentkey, $group1['enrolmentkey']);
  89                      $this->assertEquals($dbgroup->idnumber, $group1['idnumber']);
  90                      break;
  91                  case $group2['name']:
  92                      $groupdescription = $group2['description'];
  93                      $groupcourseid = $group2['courseid'];
  94                      break;
  95                  default:
  96                      throw new moodle_exception('unknowgroupname');
  97                      break;
  98              }
  99              $this->assertEquals($dbgroup->description, $groupdescription);
 100              $this->assertEquals($dbgroup->courseid, $groupcourseid);
 101          }
 102  
 103          try {
 104              $froups = core_group_external::create_groups(array($group3));
 105              $this->fail('Exception expected due to already existing idnumber.');
 106          } catch (moodle_exception $e) {
 107              $this->assertInstanceOf('moodle_exception', $e);
 108              $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
 109          }
 110  
 111          // Call without required capability
 112          $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
 113  
 114          $this->expectException(\required_capability_exception::class);
 115          $froups = core_group_external::create_groups(array($group4));
 116      }
 117  
 118      /**
 119       * Test update_groups
 120       */
 121      public function test_update_groups() {
 122          global $DB;
 123  
 124          $this->resetAfterTest(true);
 125  
 126          $course = self::getDataGenerator()->create_course();
 127  
 128          $group1data = array();
 129          $group1data['courseid'] = $course->id;
 130          $group1data['name'] = 'Group Test 1';
 131          $group1data['description'] = 'Group Test 1 description';
 132          $group1data['descriptionformat'] = FORMAT_MOODLE;
 133          $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
 134          $group1data['idnumber'] = 'TEST1';
 135          $group2data = array();
 136          $group2data['courseid'] = $course->id;
 137          $group2data['name'] = 'Group Test 2';
 138          $group2data['description'] = 'Group Test 2 description';
 139          $group2data['idnumber'] = 'TEST2';
 140  
 141          // Set the required capabilities by the external function.
 142          $context = context_course::instance($course->id);
 143          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 144          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 145  
 146          // Create the test groups.
 147          $group1 = self::getDataGenerator()->create_group($group1data);
 148          $group2 = self::getDataGenerator()->create_group($group2data);
 149  
 150          $group1data['id'] = $group1->id;
 151          unset($group1data['courseid']);
 152          $group2data['id'] = $group2->id;
 153          unset($group2data['courseid']);
 154  
 155          // No exceptions should be triggered.
 156          $group1data['idnumber'] = 'CHANGED';
 157          core_group_external::update_groups(array($group1data));
 158          $group2data['description'] = 'Group Test 2 description CHANGED';
 159          core_group_external::update_groups(array($group2data));
 160  
 161          foreach ([$group1, $group2] as $group) {
 162              $dbgroup = $DB->get_record('groups', array('id' => $group->id), '*', MUST_EXIST);
 163              switch ($dbgroup->name) {
 164                  case $group1data['name']:
 165                      $this->assertEquals($dbgroup->idnumber, $group1data['idnumber']);
 166                      $groupdescription = $group1data['description'];
 167                      break;
 168                  case $group2data['name']:
 169                      $this->assertEquals($dbgroup->idnumber, $group2data['idnumber']);
 170                      $groupdescription = $group2data['description'];
 171                      break;
 172                  default:
 173                      throw new moodle_exception('unknowngroupname');
 174                      break;
 175              }
 176              $this->assertEquals($dbgroup->description, $groupdescription);
 177          }
 178  
 179          // Taken idnumber exception.
 180          $group1data['idnumber'] = 'TEST2';
 181          try {
 182              $groups = core_group_external::update_groups(array($group1data));
 183              $this->fail('Exception expected due to already existing idnumber.');
 184          } catch (moodle_exception $e) {
 185              $this->assertInstanceOf('moodle_exception', $e);
 186              $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
 187          }
 188  
 189          // Call without required capability.
 190          $group1data['idnumber'] = 'TEST1';
 191          $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
 192  
 193          $this->expectException(\required_capability_exception::class);
 194          $groups = core_group_external::update_groups(array($group1data));
 195      }
 196  
 197      /**
 198       * Test get_groups
 199       */
 200      public function test_get_groups() {
 201          global $DB;
 202  
 203          $this->resetAfterTest(true);
 204  
 205          $course = self::getDataGenerator()->create_course();
 206          $group1data = array();
 207          $group1data['courseid'] = $course->id;
 208          $group1data['name'] = 'Group Test 1';
 209          $group1data['description'] = 'Group Test 1 description';
 210          $group1data['descriptionformat'] = FORMAT_MOODLE;
 211          $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
 212          $group1data['idnumber'] = 'TEST1';
 213          $group2data = array();
 214          $group2data['courseid'] = $course->id;
 215          $group2data['name'] = 'Group Test 2';
 216          $group2data['description'] = 'Group Test 2 description';
 217          $group1 = self::getDataGenerator()->create_group($group1data);
 218          $group2 = self::getDataGenerator()->create_group($group2data);
 219  
 220          // Set the required capabilities by the external function
 221          $context = context_course::instance($course->id);
 222          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 223          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 224  
 225          // Call the external function.
 226          $groups = core_group_external::get_groups(array($group1->id, $group2->id));
 227  
 228          // We need to execute the return values cleaning process to simulate the web service server.
 229          $groups = external_api::clean_returnvalue(core_group_external::get_groups_returns(), $groups);
 230  
 231          // Checks against DB values
 232          $this->assertEquals(2, count($groups));
 233          foreach ($groups as $group) {
 234              $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
 235              switch ($dbgroup->name) {
 236                  case $group1->name:
 237                      $groupdescription = $group1->description;
 238                      $groupcourseid = $group1->courseid;
 239                      $this->assertEquals($dbgroup->descriptionformat, $group1->descriptionformat);
 240                      $this->assertEquals($dbgroup->enrolmentkey, $group1->enrolmentkey);
 241                      $this->assertEquals($dbgroup->idnumber, $group1->idnumber);
 242                      break;
 243                  case $group2->name:
 244                      $groupdescription = $group2->description;
 245                      $groupcourseid = $group2->courseid;
 246                      break;
 247                  default:
 248                      throw new moodle_exception('unknowgroupname');
 249                      break;
 250              }
 251              $this->assertEquals($dbgroup->description, $groupdescription);
 252              $this->assertEquals($dbgroup->courseid, $groupcourseid);
 253          }
 254  
 255          // Call without required capability
 256          $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
 257  
 258          $this->expectException(\required_capability_exception::class);
 259          $groups = core_group_external::get_groups(array($group1->id, $group2->id));
 260      }
 261  
 262      /**
 263       * Test delete_groups
 264       */
 265      public function test_delete_groups() {
 266          global $DB;
 267  
 268          $this->resetAfterTest(true);
 269  
 270          $course = self::getDataGenerator()->create_course();
 271          $group1data = array();
 272          $group1data['courseid'] = $course->id;
 273          $group1data['name'] = 'Group Test 1';
 274          $group1data['description'] = 'Group Test 1 description';
 275          $group1data['descriptionformat'] = FORMAT_MOODLE;
 276          $group1data['enrolmentkey'] = 'Test group enrol secret phrase';
 277          $group2data = array();
 278          $group2data['courseid'] = $course->id;
 279          $group2data['name'] = 'Group Test 2';
 280          $group2data['description'] = 'Group Test 2 description';
 281          $group3data['courseid'] = $course->id;
 282          $group3data['name'] = 'Group Test 3';
 283          $group3data['description'] = 'Group Test 3 description';
 284          $group1 = self::getDataGenerator()->create_group($group1data);
 285          $group2 = self::getDataGenerator()->create_group($group2data);
 286          $group3 = self::getDataGenerator()->create_group($group3data);
 287  
 288          // Set the required capabilities by the external function
 289          $context = context_course::instance($course->id);
 290          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 291          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 292  
 293          // Checks against DB values
 294          $groupstotal = $DB->count_records('groups', array());
 295          $this->assertEquals(3, $groupstotal);
 296  
 297          // Call the external function.
 298          core_group_external::delete_groups(array($group1->id, $group2->id));
 299  
 300          // Checks against DB values
 301          $groupstotal = $DB->count_records('groups', array());
 302          $this->assertEquals(1, $groupstotal);
 303  
 304          // Call without required capability
 305          $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
 306  
 307          $this->expectException(\required_capability_exception::class);
 308          $froups = core_group_external::delete_groups(array($group3->id));
 309      }
 310  
 311      /**
 312       * Test create and update groupings.
 313       * @return void
 314       */
 315      public function test_create_update_groupings() {
 316          global $DB;
 317  
 318          $this->resetAfterTest(true);
 319  
 320          $this->setAdminUser();
 321  
 322          $course = self::getDataGenerator()->create_course();
 323  
 324          $grouping1data = array();
 325          $grouping1data['courseid'] = $course->id;
 326          $grouping1data['name'] = 'Grouping 1 Test';
 327          $grouping1data['description'] = 'Grouping 1 Test description';
 328          $grouping1data['descriptionformat'] = FORMAT_MOODLE;
 329          $grouping1data['idnumber'] = 'TEST';
 330  
 331          $grouping1 = self::getDataGenerator()->create_grouping($grouping1data);
 332  
 333          $grouping1data['name'] = 'Another group';
 334  
 335          try {
 336              $groupings = core_group_external::create_groupings(array($grouping1data));
 337              $this->fail('Exception expected due to already existing idnumber.');
 338          } catch (moodle_exception $e) {
 339              $this->assertInstanceOf('moodle_exception', $e);
 340              $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
 341          }
 342  
 343          // No exception should be triggered.
 344          $grouping1data['id'] = $grouping1->id;
 345          $grouping1data['idnumber'] = 'CHANGED';
 346          unset($grouping1data['courseid']);
 347          core_group_external::update_groupings(array($grouping1data));
 348  
 349          $grouping2data = array();
 350          $grouping2data['courseid'] = $course->id;
 351          $grouping2data['name'] = 'Grouping 2 Test';
 352          $grouping2data['description'] = 'Grouping 2 Test description';
 353          $grouping2data['descriptionformat'] = FORMAT_MOODLE;
 354          $grouping2data['idnumber'] = 'TEST';
 355  
 356          $grouping2 = self::getDataGenerator()->create_grouping($grouping2data);
 357  
 358          $grouping2data['id'] = $grouping2->id;
 359          $grouping2data['idnumber'] = 'CHANGED';
 360          unset($grouping2data['courseid']);
 361          try {
 362              $groupings = core_group_external::update_groupings(array($grouping2data));
 363              $this->fail('Exception expected due to already existing idnumber.');
 364          } catch (moodle_exception $e) {
 365              $this->assertInstanceOf('moodle_exception', $e);
 366              $this->assertEquals(get_string('idnumbertaken', 'error'), $e->getMessage());
 367          }
 368      }
 369  
 370      /**
 371       * Test get_groupings
 372       */
 373      public function test_get_groupings() {
 374          global $DB;
 375  
 376          $this->resetAfterTest(true);
 377  
 378          $course = self::getDataGenerator()->create_course();
 379  
 380          $groupingdata = array();
 381          $groupingdata['courseid'] = $course->id;
 382          $groupingdata['name'] = 'Grouping Test';
 383          $groupingdata['description'] = 'Grouping Test description';
 384          $groupingdata['descriptionformat'] = FORMAT_MOODLE;
 385  
 386          $grouping = self::getDataGenerator()->create_grouping($groupingdata);
 387  
 388          // Set the required capabilities by the external function.
 389          $context = context_course::instance($course->id);
 390          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 391          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 392  
 393          // Call the external function without specifying the optional parameter.
 394          $groupings = core_group_external::get_groupings(array($grouping->id));
 395          // We need to execute the return values cleaning process to simulate the web service server.
 396          $groupings = external_api::clean_returnvalue(core_group_external::get_groupings_returns(), $groupings);
 397  
 398          $this->assertEquals(1, count($groupings));
 399  
 400          $group1data = array();
 401          $group1data['courseid'] = $course->id;
 402          $group1data['name'] = 'Group Test 1';
 403          $group1data['description'] = 'Group Test 1 description';
 404          $group1data['descriptionformat'] = FORMAT_MOODLE;
 405          $group2data = array();
 406          $group2data['courseid'] = $course->id;
 407          $group2data['name'] = 'Group Test 2';
 408          $group2data['description'] = 'Group Test 2 description';
 409          $group2data['descriptionformat'] = FORMAT_MOODLE;
 410  
 411          $group1 = self::getDataGenerator()->create_group($group1data);
 412          $group2 = self::getDataGenerator()->create_group($group2data);
 413  
 414          groups_assign_grouping($grouping->id, $group1->id);
 415          groups_assign_grouping($grouping->id, $group2->id);
 416  
 417          // Call the external function specifying that groups are returned.
 418          $groupings = core_group_external::get_groupings(array($grouping->id), true);
 419          // We need to execute the return values cleaning process to simulate the web service server.
 420          $groupings = external_api::clean_returnvalue(core_group_external::get_groupings_returns(), $groupings);
 421          $this->assertEquals(1, count($groupings));
 422          $this->assertEquals(2, count($groupings[0]['groups']));
 423          foreach ($groupings[0]['groups'] as $group) {
 424              $dbgroup = $DB->get_record('groups', array('id' => $group['id']), '*', MUST_EXIST);
 425              $dbgroupinggroups = $DB->get_record('groupings_groups',
 426                                                  array('groupingid' => $groupings[0]['id'],
 427                                                        'groupid' => $group['id']),
 428                                                  '*', MUST_EXIST);
 429              switch ($dbgroup->name) {
 430                  case $group1->name:
 431                      $groupdescription = $group1->description;
 432                      $groupcourseid = $group1->courseid;
 433                      break;
 434                  case $group2->name:
 435                      $groupdescription = $group2->description;
 436                      $groupcourseid = $group2->courseid;
 437                      break;
 438                  default:
 439                      throw new moodle_exception('unknowgroupname');
 440                      break;
 441              }
 442              $this->assertEquals($dbgroup->description, $groupdescription);
 443              $this->assertEquals($dbgroup->courseid, $groupcourseid);
 444          }
 445      }
 446  
 447      /**
 448       * Test delete_groupings.
 449       */
 450      public function test_delete_groupings() {
 451          global $DB;
 452  
 453          $this->resetAfterTest(true);
 454  
 455          $course = self::getDataGenerator()->create_course();
 456  
 457          $groupingdata1 = array();
 458          $groupingdata1['courseid'] = $course->id;
 459          $groupingdata1['name'] = 'Grouping Test';
 460          $groupingdata1['description'] = 'Grouping Test description';
 461          $groupingdata1['descriptionformat'] = FORMAT_MOODLE;
 462          $groupingdata2 = array();
 463          $groupingdata2['courseid'] = $course->id;
 464          $groupingdata2['name'] = 'Grouping Test';
 465          $groupingdata2['description'] = 'Grouping Test description';
 466          $groupingdata2['descriptionformat'] = FORMAT_MOODLE;
 467          $groupingdata3 = array();
 468          $groupingdata3['courseid'] = $course->id;
 469          $groupingdata3['name'] = 'Grouping Test';
 470          $groupingdata3['description'] = 'Grouping Test description';
 471          $groupingdata3['descriptionformat'] = FORMAT_MOODLE;
 472  
 473          $grouping1 = self::getDataGenerator()->create_grouping($groupingdata1);
 474          $grouping2 = self::getDataGenerator()->create_grouping($groupingdata2);
 475          $grouping3 = self::getDataGenerator()->create_grouping($groupingdata3);
 476  
 477          // Set the required capabilities by the external function.
 478          $context = context_course::instance($course->id);
 479          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 480          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 481  
 482          // Checks against DB values.
 483          $groupingstotal = $DB->count_records('groupings', array());
 484          $this->assertEquals(3, $groupingstotal);
 485  
 486          // Call the external function.
 487          core_group_external::delete_groupings(array($grouping1->id, $grouping2->id));
 488  
 489          // Checks against DB values.
 490          $groupingstotal = $DB->count_records('groupings', array());
 491          $this->assertEquals(1, $groupingstotal);
 492  
 493          // Call without required capability.
 494          $this->unassignUserCapability('moodle/course:managegroups', $context->id, $roleid);
 495  
 496          $this->expectException(\required_capability_exception::class);
 497          core_group_external::delete_groupings(array($grouping3->id));
 498      }
 499  
 500      /**
 501       * Test get_groups
 502       */
 503      public function test_get_course_user_groups() {
 504          global $DB;
 505  
 506          $this->resetAfterTest(true);
 507  
 508          $student1 = self::getDataGenerator()->create_user();
 509          $student2 = self::getDataGenerator()->create_user();
 510          $teacher = self::getDataGenerator()->create_user();
 511  
 512          $course = self::getDataGenerator()->create_course();
 513          $anothercourse = self::getDataGenerator()->create_course();
 514          $emptycourse = self::getDataGenerator()->create_course();
 515  
 516          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 517          $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
 518          $this->getDataGenerator()->enrol_user($student1->id, $anothercourse->id, $studentrole->id);
 519          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
 520  
 521          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 522          $this->getDataGenerator()->enrol_user($teacher->id, $course->id, $teacherrole->id);
 523          $this->getDataGenerator()->enrol_user($teacher->id, $emptycourse->id, $teacherrole->id);
 524  
 525          $group1data = array();
 526          $group1data['courseid'] = $course->id;
 527          $group1data['name'] = 'Group Test 1';
 528          $group1data['description'] = 'Group Test 1 description';
 529          $group1data['idnumber'] = 'TEST1';
 530          $group2data = array();
 531          $group2data['courseid'] = $course->id;
 532          $group2data['name'] = 'Group Test 2';
 533          $group2data['description'] = 'Group Test 2 description';
 534          $group3data = array();
 535          $group3data['courseid'] = $anothercourse->id;
 536          $group3data['name'] = 'Group Test 3';
 537          $group3data['description'] = 'Group Test 3 description';
 538          $group3data['idnumber'] = 'TEST3';
 539          $group1 = self::getDataGenerator()->create_group($group1data);
 540          $group2 = self::getDataGenerator()->create_group($group2data);
 541          $group3 = self::getDataGenerator()->create_group($group3data);
 542  
 543          groups_add_member($group1->id, $student1->id);
 544          groups_add_member($group1->id, $student2->id);
 545          groups_add_member($group2->id, $student1->id);
 546          groups_add_member($group3->id, $student1->id);
 547  
 548          // Create a grouping.
 549          $groupingdata = array();
 550          $groupingdata['courseid'] = $course->id;
 551          $groupingdata['name'] = 'Grouping Test';
 552          $groupingdata['description'] = 'Grouping Test description';
 553          $groupingdata['descriptionformat'] = FORMAT_MOODLE;
 554  
 555          $grouping = self::getDataGenerator()->create_grouping($groupingdata);
 556          // Grouping only containing group1.
 557          groups_assign_grouping($grouping->id, $group1->id);
 558  
 559          $this->setUser($student1);
 560  
 561          $groups = core_group_external::get_course_user_groups($course->id, $student1->id);
 562          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 563          // Check that I see my groups.
 564          $this->assertCount(2, $groups['groups']);
 565          $this->assertEquals($course->id, $groups['groups'][0]['courseid']);
 566          $this->assertEquals($course->id, $groups['groups'][1]['courseid']);
 567  
 568          // Check that I only see my groups inside the given grouping.
 569          $groups = core_group_external::get_course_user_groups($course->id, $student1->id, $grouping->id);
 570          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 571          // Check that I see my groups in the grouping.
 572          $this->assertCount(1, $groups['groups']);
 573          $this->assertEquals($group1->id, $groups['groups'][0]['id']);
 574  
 575  
 576          // Check optional parameters (all student 1 courses and current user).
 577          $groups = core_group_external::get_course_user_groups();
 578          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 579          // Check that I see my groups in all my courses.
 580          $this->assertCount(3, $groups['groups']);
 581  
 582          $this->setUser($student2);
 583          $groups = core_group_external::get_course_user_groups($course->id, $student2->id);
 584          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 585          // Check that I see my groups.
 586          $this->assertCount(1, $groups['groups']);
 587  
 588          $this->assertEquals($group1data['name'], $groups['groups'][0]['name']);
 589          $this->assertEquals($group1data['description'], $groups['groups'][0]['description']);
 590          $this->assertEquals($group1data['idnumber'], $groups['groups'][0]['idnumber']);
 591  
 592          $this->setUser($teacher);
 593          $groups = core_group_external::get_course_user_groups($course->id, $student1->id);
 594          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 595          // Check that a teacher can see student groups in given course.
 596          $this->assertCount(2, $groups['groups']);
 597  
 598          $groups = core_group_external::get_course_user_groups($course->id, $student2->id);
 599          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 600          // Check that a teacher can see student groups in given course.
 601          $this->assertCount(1, $groups['groups']);
 602  
 603          $groups = core_group_external::get_course_user_groups(0, $student1->id);
 604          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 605          // Check that a teacher can see student groups in all the user courses if the teacher is enrolled in the course.
 606          $this->assertCount(2, $groups['groups']); // Teacher only see groups in first course.
 607          $this->assertCount(1, $groups['warnings']); // Enrolment warnings.
 608          $this->assertEquals('1', $groups['warnings'][0]['warningcode']);
 609  
 610          // Enrol teacher in second course.
 611          $this->getDataGenerator()->enrol_user($teacher->id, $anothercourse->id, $teacherrole->id);
 612          $groups = core_group_external::get_course_user_groups(0, $student1->id);
 613          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 614          // Check that a teacher can see student groups in all the user courses if the teacher is enrolled in the course.
 615          $this->assertCount(3, $groups['groups']);
 616  
 617          // Check permissions.
 618          $this->setUser($student1);
 619  
 620          // Student can's see other students group.
 621          $groups = core_group_external::get_course_user_groups($course->id, $student2->id);
 622          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 623          $this->assertCount(1, $groups['warnings']);
 624          $this->assertEquals('cannotmanagegroups', $groups['warnings'][0]['warningcode']);
 625  
 626          // Not enrolled course.
 627          $groups = core_group_external::get_course_user_groups($emptycourse->id, $student2->id);
 628          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 629          $this->assertCount(1, $groups['warnings']);
 630          $this->assertEquals('1', $groups['warnings'][0]['warningcode']);
 631  
 632          $this->setUser($teacher);
 633          // Check user checking not enrolled in given course.
 634          $groups = core_group_external::get_course_user_groups($emptycourse->id, $student1->id);
 635          $groups = external_api::clean_returnvalue(core_group_external::get_course_user_groups_returns(), $groups);
 636          $this->assertCount(1, $groups['warnings']);
 637          $this->assertEquals('notenrolled', $groups['warnings'][0]['warningcode']);
 638      }
 639  
 640      /**
 641       * Test get_activity_allowed_groups
 642       */
 643      public function test_get_activity_allowed_groups() {
 644          global $DB;
 645  
 646          $this->resetAfterTest(true);
 647  
 648          $generator = self::getDataGenerator();
 649  
 650          $student = $generator->create_user();
 651          $otherstudent = $generator->create_user();
 652          $teacher = $generator->create_user();
 653          $course = $generator->create_course();
 654          $othercourse = $generator->create_course();
 655  
 656          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 657          $teacherrole = $DB->get_record('role', array('shortname' => 'editingteacher'));
 658          $generator->enrol_user($student->id, $course->id, $studentrole->id);
 659          $generator->enrol_user($otherstudent->id, $othercourse->id, $studentrole->id);
 660          $generator->enrol_user($teacher->id, $course->id, $teacherrole->id);
 661  
 662          $forum1 = $generator->create_module("forum", array('course' => $course->id), array('groupmode' => VISIBLEGROUPS));
 663          $forum2 = $generator->create_module("forum", array('course' => $othercourse->id));
 664          $forum3 = $generator->create_module("forum", array('course' => $course->id), array('visible' => 0));
 665  
 666          // Request data for tests.
 667          $cm1 = get_coursemodule_from_instance("forum", $forum1->id);
 668          $cm2 = get_coursemodule_from_instance("forum", $forum2->id);
 669          $cm3 = get_coursemodule_from_instance("forum", $forum3->id);
 670  
 671          $group1data = array();
 672          $group1data['courseid'] = $course->id;
 673          $group1data['name'] = 'Group Test 1';
 674          $group1data['description'] = 'Group Test 1 description';
 675          $group1data['idnumber'] = 'TEST1';
 676          $group2data = array();
 677          $group2data['courseid'] = $course->id;
 678          $group2data['name'] = 'Group Test 2';
 679          $group2data['description'] = 'Group Test 2 description';
 680          $group2data['idnumber'] = 'TEST2';
 681          $group1 = $generator->create_group($group1data);
 682          $group2 = $generator->create_group($group2data);
 683  
 684          groups_add_member($group1->id, $student->id);
 685          groups_add_member($group2->id, $student->id);
 686  
 687          $this->setUser($student);
 688  
 689          // First try possible errors.
 690          try {
 691              $data = core_group_external::get_activity_allowed_groups($cm2->id);
 692          } catch (moodle_exception $e) {
 693              $this->assertEquals('requireloginerror', $e->errorcode);
 694          }
 695  
 696          try {
 697              $data = core_group_external::get_activity_allowed_groups($cm3->id);
 698          } catch (moodle_exception $e) {
 699              $this->assertEquals('requireloginerror', $e->errorcode);
 700          }
 701  
 702          // Retrieve my groups.
 703          $groups = core_group_external::get_activity_allowed_groups($cm1->id);
 704          $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
 705          $this->assertCount(2, $groups['groups']);
 706          $this->assertFalse($groups['canaccessallgroups']);
 707  
 708          foreach ($groups['groups'] as $group) {
 709              if ($group['name'] == $group1data['name']) {
 710                  $this->assertEquals($group1data['description'], $group['description']);
 711                  $this->assertEquals($group1data['idnumber'], $group['idnumber']);
 712              } else {
 713                  $this->assertEquals($group2data['description'], $group['description']);
 714                  $this->assertEquals($group2data['idnumber'], $group['idnumber']);
 715              }
 716          }
 717  
 718          $this->setUser($teacher);
 719          // Retrieve other users groups.
 720          $groups = core_group_external::get_activity_allowed_groups($cm1->id, $student->id);
 721          $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
 722          $this->assertCount(2, $groups['groups']);
 723          // We are checking the $student passed as parameter so this will return false.
 724          $this->assertFalse($groups['canaccessallgroups']);
 725  
 726          // Check warnings. Trying to get groups for a user not enrolled in course.
 727          $groups = core_group_external::get_activity_allowed_groups($cm1->id, $otherstudent->id);
 728          $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
 729          $this->assertCount(1, $groups['warnings']);
 730          $this->assertFalse($groups['canaccessallgroups']);
 731  
 732          // Checking teacher groups.
 733          $groups = core_group_external::get_activity_allowed_groups($cm1->id);
 734          $groups = external_api::clean_returnvalue(core_group_external::get_activity_allowed_groups_returns(), $groups);
 735          $this->assertCount(2, $groups['groups']);
 736          // Teachers by default can access all groups.
 737          $this->assertTrue($groups['canaccessallgroups']);
 738      }
 739  
 740      /**
 741       * Test get_activity_groupmode
 742       */
 743      public function test_get_activity_groupmode() {
 744          global $DB;
 745  
 746          $this->resetAfterTest(true);
 747  
 748          $generator = self::getDataGenerator();
 749  
 750          $student = $generator->create_user();
 751          $course = $generator->create_course();
 752          $othercourse = $generator->create_course();
 753  
 754          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 755          $generator->enrol_user($student->id, $course->id, $studentrole->id);
 756  
 757          $forum1 = $generator->create_module("forum", array('course' => $course->id), array('groupmode' => VISIBLEGROUPS));
 758          $forum2 = $generator->create_module("forum", array('course' => $othercourse->id));
 759          $forum3 = $generator->create_module("forum", array('course' => $course->id), array('visible' => 0));
 760  
 761          // Request data for tests.
 762          $cm1 = get_coursemodule_from_instance("forum", $forum1->id);
 763          $cm2 = get_coursemodule_from_instance("forum", $forum2->id);
 764          $cm3 = get_coursemodule_from_instance("forum", $forum3->id);
 765  
 766          $this->setUser($student);
 767  
 768          $data = core_group_external::get_activity_groupmode($cm1->id);
 769          $data = external_api::clean_returnvalue(core_group_external::get_activity_groupmode_returns(), $data);
 770          $this->assertEquals(VISIBLEGROUPS, $data['groupmode']);
 771  
 772          try {
 773              $data = core_group_external::get_activity_groupmode($cm2->id);
 774          } catch (moodle_exception $e) {
 775              $this->assertEquals('requireloginerror', $e->errorcode);
 776          }
 777  
 778          try {
 779              $data = core_group_external::get_activity_groupmode($cm3->id);
 780          } catch (moodle_exception $e) {
 781              $this->assertEquals('requireloginerror', $e->errorcode);
 782          }
 783  
 784      }
 785  
 786      /**
 787       * Test add_group_members.
 788       */
 789      public function test_add_group_members() {
 790          global $DB;
 791  
 792          $this->resetAfterTest(true);
 793  
 794          $student1 = self::getDataGenerator()->create_user();
 795          $student2 = self::getDataGenerator()->create_user();
 796          $student3 = self::getDataGenerator()->create_user();
 797  
 798          $course = self::getDataGenerator()->create_course();
 799  
 800          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 801          $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
 802          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
 803          $this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id);
 804  
 805          $group1data = array();
 806          $group1data['courseid'] = $course->id;
 807          $group1data['name'] = 'Group Test 1';
 808          $group1data['description'] = 'Group Test 1 description';
 809          $group1data['idnumber'] = 'TEST1';
 810          $group1 = self::getDataGenerator()->create_group($group1data);
 811  
 812          // Checks against DB values.
 813          $memberstotal = $DB->count_records('groups_members', ['groupid' => $group1->id]);
 814          $this->assertEquals(0, $memberstotal);
 815  
 816          // Set the required capabilities by the external function.
 817          $context = context_course::instance($course->id);
 818          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 819          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 820  
 821          core_group_external::add_group_members([
 822              'members' => [
 823                  'groupid' => $group1->id,
 824                  'userid' => $student1->id,
 825              ]
 826          ]);
 827          core_group_external::add_group_members([
 828              'members' => [
 829                  'groupid' => $group1->id,
 830                  'userid' => $student2->id,
 831              ]
 832          ]);
 833          core_group_external::add_group_members([
 834              'members' => [
 835                  'groupid' => $group1->id,
 836                  'userid' => $student3->id,
 837              ]
 838          ]);
 839  
 840          // Checks against DB values.
 841          $memberstotal = $DB->count_records('groups_members', ['groupid' => $group1->id]);
 842          $this->assertEquals(3, $memberstotal);
 843      }
 844  
 845      /**
 846       * Test delete_group_members.
 847       */
 848      public function test_delete_group_members() {
 849          global $DB;
 850  
 851          $this->resetAfterTest(true);
 852  
 853          $student1 = self::getDataGenerator()->create_user();
 854          $student2 = self::getDataGenerator()->create_user();
 855          $student3 = self::getDataGenerator()->create_user();
 856  
 857          $course = self::getDataGenerator()->create_course();
 858  
 859          $studentrole = $DB->get_record('role', array('shortname' => 'student'));
 860          $this->getDataGenerator()->enrol_user($student1->id, $course->id, $studentrole->id);
 861          $this->getDataGenerator()->enrol_user($student2->id, $course->id, $studentrole->id);
 862          $this->getDataGenerator()->enrol_user($student3->id, $course->id, $studentrole->id);
 863  
 864          $group1data = array();
 865          $group1data['courseid'] = $course->id;
 866          $group1data['name'] = 'Group Test 1';
 867          $group1data['description'] = 'Group Test 1 description';
 868          $group1data['idnumber'] = 'TEST1';
 869          $group1 = self::getDataGenerator()->create_group($group1data);
 870  
 871          groups_add_member($group1->id, $student1->id);
 872          groups_add_member($group1->id, $student2->id);
 873          groups_add_member($group1->id, $student3->id);
 874  
 875          // Checks against DB values.
 876          $memberstotal = $DB->count_records('groups_members', ['groupid' => $group1->id]);
 877          $this->assertEquals(3, $memberstotal);
 878  
 879          // Set the required capabilities by the external function.
 880          $context = context_course::instance($course->id);
 881          $roleid = $this->assignUserCapability('moodle/course:managegroups', $context->id);
 882          $this->assignUserCapability('moodle/course:view', $context->id, $roleid);
 883  
 884          core_group_external::delete_group_members([
 885              'members' => [
 886                  'groupid' => $group1->id,
 887                  'userid' => $student2->id,
 888              ]
 889          ]);
 890  
 891          // Checks against DB values.
 892          $memberstotal = $DB->count_records('groups_members', ['groupid' => $group1->id]);
 893          $this->assertEquals(2, $memberstotal);
 894      }
 895  }