Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.10.x will end 8 November 2021 (12 months).
  • Bug fixes for security issues in 3.10.x will end 9 May 2022 (18 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 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 and 403] [Versions 39 and 310]

   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   * External cohort API
  19   *
  20   * @package    core_cohort
  21   * @category   external
  22   * @copyright  MediaTouch 2000 srl
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  
  26  defined('MOODLE_INTERNAL') || die();
  27  
  28  global $CFG;
  29  
  30  require_once($CFG->dirroot . '/webservice/tests/helpers.php');
  31  require_once($CFG->dirroot . '/cohort/externallib.php');
  32  
  33  class core_cohort_externallib_testcase extends externallib_advanced_testcase {
  34  
  35      /**
  36       * Test create_cohorts
  37       */
  38      public function test_create_cohorts() {
  39          global $USER, $CFG, $DB;
  40  
  41          $this->resetAfterTest(true);
  42  
  43          set_config('allowcohortthemes', 1);
  44  
  45          $contextid = context_system::instance()->id;
  46          $category = $this->getDataGenerator()->create_category();
  47  
  48          $cohort1 = array(
  49              'categorytype' => array('type' => 'id', 'value' => $category->id),
  50              'name' => 'cohort test 1',
  51              'idnumber' => 'cohorttest1',
  52              'description' => 'This is a description for cohorttest1',
  53              'theme' => 'classic'
  54              );
  55  
  56          $cohort2 = array(
  57              'categorytype' => array('type' => 'system', 'value' => ''),
  58              'name' => 'cohort test 2',
  59              'idnumber' => 'cohorttest2',
  60              'description' => 'This is a description for cohorttest2',
  61              'visible' => 0
  62              );
  63  
  64          $cohort3 = array(
  65              'categorytype' => array('type' => 'id', 'value' => $category->id),
  66              'name' => 'cohort test 3',
  67              'idnumber' => 'cohorttest3',
  68              'description' => 'This is a description for cohorttest3'
  69              );
  70          $roleid = $this->assignUserCapability('moodle/cohort:manage', $contextid);
  71  
  72          $cohort4 = array(
  73              'categorytype' => array('type' => 'id', 'value' => $category->id),
  74              'name' => 'cohort test 4',
  75              'idnumber' => 'cohorttest4',
  76              'description' => 'This is a description for cohorttest4',
  77              'theme' => 'classic'
  78              );
  79  
  80          // Call the external function.
  81          $this->setCurrentTimeStart();
  82          $createdcohorts = core_cohort_external::create_cohorts(array($cohort1, $cohort2));
  83          $createdcohorts = external_api::clean_returnvalue(core_cohort_external::create_cohorts_returns(), $createdcohorts);
  84  
  85          // Check we retrieve the good total number of created cohorts + no error on capability.
  86          $this->assertEquals(2, count($createdcohorts));
  87  
  88          foreach ($createdcohorts as $createdcohort) {
  89              $dbcohort = $DB->get_record('cohort', array('id' => $createdcohort['id']));
  90              if ($createdcohort['idnumber'] == $cohort1['idnumber']) {
  91                  $conid = $DB->get_field('context', 'id', array('instanceid' => $cohort1['categorytype']['value'],
  92                          'contextlevel' => CONTEXT_COURSECAT));
  93                  $this->assertEquals($dbcohort->contextid, $conid);
  94                  $this->assertEquals($dbcohort->name, $cohort1['name']);
  95                  $this->assertEquals($dbcohort->description, $cohort1['description']);
  96                  $this->assertEquals($dbcohort->visible, 1); // Field was not specified, ensure it is visible by default.
  97                  // As $CFG->allowcohortthemes is enabled, theme must be initialised.
  98                  $this->assertEquals($dbcohort->theme, $cohort1['theme']);
  99              } else if ($createdcohort['idnumber'] == $cohort2['idnumber']) {
 100                  $this->assertEquals($dbcohort->contextid, context_system::instance()->id);
 101                  $this->assertEquals($dbcohort->name, $cohort2['name']);
 102                  $this->assertEquals($dbcohort->description, $cohort2['description']);
 103                  $this->assertEquals($dbcohort->visible, $cohort2['visible']);
 104                  // Although $CFG->allowcohortthemes is enabled, no theme is defined for this cohort.
 105                  $this->assertEquals($dbcohort->theme, '');
 106              } else {
 107                  $this->fail('Unrecognised cohort found');
 108              }
 109              $this->assertTimeCurrent($dbcohort->timecreated);
 110              $this->assertTimeCurrent($dbcohort->timemodified);
 111          }
 112  
 113          // Call when $CFG->allowcohortthemes is disabled.
 114          set_config('allowcohortthemes', 0);
 115          $createdcohorts = core_cohort_external::create_cohorts(array($cohort4));
 116          $createdcohorts = external_api::clean_returnvalue(core_cohort_external::create_cohorts_returns(), $createdcohorts);
 117          foreach ($createdcohorts as $createdcohort) {
 118              $dbcohort = $DB->get_record('cohort', array('id' => $createdcohort['id']));
 119              if ($createdcohort['idnumber'] == $cohort4['idnumber']) {
 120                  $conid = $DB->get_field('context', 'id', array('instanceid' => $cohort4['categorytype']['value'],
 121                          'contextlevel' => CONTEXT_COURSECAT));
 122                  $this->assertEquals($dbcohort->contextid, $conid);
 123                  $this->assertEquals($dbcohort->name, $cohort4['name']);
 124                  $this->assertEquals($dbcohort->description, $cohort4['description']);
 125                  $this->assertEquals($dbcohort->visible, 1); // Field was not specified, ensure it is visible by default.
 126                  $this->assertEquals($dbcohort->theme, ''); // As $CFG->allowcohortthemes is disabled, theme must be empty.
 127              }
 128          }
 129  
 130          // Call without required capability.
 131          $this->unassignUserCapability('moodle/cohort:manage', $contextid, $roleid);
 132          $this->expectException(required_capability_exception::class);
 133          $createdcohorts = core_cohort_external::create_cohorts(array($cohort3));
 134      }
 135  
 136      /**
 137       * Test delete_cohorts
 138       */
 139      public function test_delete_cohorts() {
 140          global $USER, $CFG, $DB;
 141  
 142          $this->resetAfterTest(true);
 143  
 144          $cohort1 = self::getDataGenerator()->create_cohort();
 145          $cohort2 = self::getDataGenerator()->create_cohort();
 146          // Check the cohorts were correctly created.
 147          $this->assertEquals(2, $DB->count_records_select('cohort', ' (id = :cohortid1 OR id = :cohortid2)',
 148                  array('cohortid1' => $cohort1->id, 'cohortid2' => $cohort2->id)));
 149  
 150          $contextid = $cohort1->contextid;
 151          $roleid = $this->assignUserCapability('moodle/cohort:manage', $contextid);
 152  
 153          // Call the external function.
 154          core_cohort_external::delete_cohorts(array($cohort1->id, $cohort2->id));
 155  
 156          // Check we retrieve no cohorts + no error on capability.
 157          $this->assertEquals(0, $DB->count_records_select('cohort', ' (id = :cohortid1 OR id = :cohortid2)',
 158                  array('cohortid1' => $cohort1->id, 'cohortid2' => $cohort2->id)));
 159  
 160          // Call without required capability.
 161          $cohort1 = self::getDataGenerator()->create_cohort();
 162          $cohort2 = self::getDataGenerator()->create_cohort();
 163          $this->unassignUserCapability('moodle/cohort:manage', $contextid, $roleid);
 164          $this->expectException(required_capability_exception::class);
 165          core_cohort_external::delete_cohorts(array($cohort1->id, $cohort2->id));
 166      }
 167  
 168      /**
 169       * Test get_cohorts
 170       */
 171      public function test_get_cohorts() {
 172          global $USER, $CFG;
 173  
 174          $this->resetAfterTest(true);
 175  
 176          set_config('allowcohortthemes', 1);
 177  
 178          $cohort1 = array(
 179              'contextid' => 1,
 180              'name' => 'cohortnametest1',
 181              'idnumber' => 'idnumbertest1',
 182              'description' => 'This is a description for cohort 1',
 183              'theme' => 'classic'
 184              );
 185          $cohort1 = self::getDataGenerator()->create_cohort($cohort1);
 186          $cohort2 = self::getDataGenerator()->create_cohort();
 187  
 188          $context = context_system::instance();
 189          $roleid = $this->assignUserCapability('moodle/cohort:view', $context->id);
 190  
 191          // Call the external function.
 192          $returnedcohorts = core_cohort_external::get_cohorts(array(
 193              $cohort1->id, $cohort2->id));
 194          $returnedcohorts = external_api::clean_returnvalue(core_cohort_external::get_cohorts_returns(), $returnedcohorts);
 195  
 196          // Check we retrieve the good total number of enrolled cohorts + no error on capability.
 197          $this->assertEquals(2, count($returnedcohorts));
 198  
 199          foreach ($returnedcohorts as $enrolledcohort) {
 200              if ($enrolledcohort['idnumber'] == $cohort1->idnumber) {
 201                  $this->assertEquals($cohort1->name, $enrolledcohort['name']);
 202                  $this->assertEquals($cohort1->description, $enrolledcohort['description']);
 203                  $this->assertEquals($cohort1->visible, $enrolledcohort['visible']);
 204                  $this->assertEquals($cohort1->theme, $enrolledcohort['theme']);
 205              }
 206          }
 207  
 208          // Check that a user with cohort:manage can see the cohort.
 209          $this->unassignUserCapability('moodle/cohort:view', $context->id, $roleid);
 210          $roleid = $this->assignUserCapability('moodle/cohort:manage', $context->id, $roleid);
 211          // Call the external function.
 212          $returnedcohorts = core_cohort_external::get_cohorts(array(
 213              $cohort1->id, $cohort2->id));
 214          $returnedcohorts = external_api::clean_returnvalue(core_cohort_external::get_cohorts_returns(), $returnedcohorts);
 215  
 216          // Check we retrieve the good total number of enrolled cohorts + no error on capability.
 217          $this->assertEquals(2, count($returnedcohorts));
 218  
 219          // Check when allowcohortstheme is disabled, theme is not returned.
 220          set_config('allowcohortthemes', 0);
 221          $returnedcohorts = core_cohort_external::get_cohorts(array(
 222              $cohort1->id));
 223          $returnedcohorts = external_api::clean_returnvalue(core_cohort_external::get_cohorts_returns(), $returnedcohorts);
 224          foreach ($returnedcohorts as $enrolledcohort) {
 225              if ($enrolledcohort['idnumber'] == $cohort1->idnumber) {
 226                  $this->assertNull($enrolledcohort['theme']);
 227              }
 228          }
 229      }
 230  
 231      /**
 232       * Test update_cohorts
 233       */
 234      public function test_update_cohorts() {
 235          global $USER, $CFG, $DB;
 236  
 237          $this->resetAfterTest(true);
 238  
 239          set_config('allowcohortthemes', 0);
 240  
 241          $cohort1 = self::getDataGenerator()->create_cohort(array('visible' => 0));
 242  
 243          $cohort1 = array(
 244              'id' => $cohort1->id,
 245              'categorytype' => array('type' => 'id', 'value' => '1'),
 246              'name' => 'cohortnametest1',
 247              'idnumber' => 'idnumbertest1',
 248              'description' => 'This is a description for cohort 1',
 249              'theme' => 'classic'
 250              );
 251  
 252          $context = context_system::instance();
 253          $roleid = $this->assignUserCapability('moodle/cohort:manage', $context->id);
 254  
 255          // Call the external function.
 256          core_cohort_external::update_cohorts(array($cohort1));
 257  
 258          $dbcohort = $DB->get_record('cohort', array('id' => $cohort1['id']));
 259          $contextid = $DB->get_field('context', 'id', array('instanceid' => $cohort1['categorytype']['value'],
 260          'contextlevel' => CONTEXT_COURSECAT));
 261          $this->assertEquals($dbcohort->contextid, $contextid);
 262          $this->assertEquals($dbcohort->name, $cohort1['name']);
 263          $this->assertEquals($dbcohort->idnumber, $cohort1['idnumber']);
 264          $this->assertEquals($dbcohort->description, $cohort1['description']);
 265          $this->assertEquals($dbcohort->visible, 0);
 266          $this->assertEmpty($dbcohort->theme);
 267  
 268          // Since field 'visible' was added in 2.8, make sure that update works correctly with and without this parameter.
 269          core_cohort_external::update_cohorts(array($cohort1 + array('visible' => 1)));
 270          $dbcohort = $DB->get_record('cohort', array('id' => $cohort1['id']));
 271          $this->assertEquals(1, $dbcohort->visible);
 272          core_cohort_external::update_cohorts(array($cohort1));
 273          $dbcohort = $DB->get_record('cohort', array('id' => $cohort1['id']));
 274          $this->assertEquals(1, $dbcohort->visible);
 275  
 276          // Call when $CFG->allowcohortthemes is enabled.
 277          set_config('allowcohortthemes', 1);
 278          core_cohort_external::update_cohorts(array($cohort1 + array('theme' => 'classic')));
 279          $dbcohort = $DB->get_record('cohort', array('id' => $cohort1['id']));
 280          $this->assertEquals('classic', $dbcohort->theme);
 281  
 282          // Call when $CFG->allowcohortthemes is disabled.
 283          set_config('allowcohortthemes', 0);
 284          core_cohort_external::update_cohorts(array($cohort1 + array('theme' => 'boost')));
 285          $dbcohort = $DB->get_record('cohort', array('id' => $cohort1['id']));
 286          $this->assertEquals('classic', $dbcohort->theme);
 287  
 288          // Call without required capability.
 289          $this->unassignUserCapability('moodle/cohort:manage', $context->id, $roleid);
 290          $this->expectException(required_capability_exception::class);
 291          core_cohort_external::update_cohorts(array($cohort1));
 292      }
 293  
 294      /**
 295       * Verify handling of 'id' param.
 296       */
 297      public function test_update_cohorts_invalid_id_param() {
 298          $this->resetAfterTest(true);
 299          $cohort = self::getDataGenerator()->create_cohort();
 300  
 301          $cohort1 = array(
 302              'id' => 'THIS IS NOT AN ID',
 303              'name' => 'Changed cohort name',
 304              'categorytype' => array('type' => 'id', 'value' => '1'),
 305              'idnumber' => $cohort->idnumber,
 306          );
 307  
 308          try {
 309              core_cohort_external::update_cohorts(array($cohort1));
 310              $this->fail('Expecting invalid_parameter_exception exception, none occured');
 311          } catch (invalid_parameter_exception $e1) {
 312              $this->assertStringContainsString('Invalid external api parameter: the value is "THIS IS NOT AN ID"', $e1->debuginfo);
 313          }
 314  
 315          $cohort1['id'] = 9.999; // Also not a valid id of a cohort.
 316          try {
 317              core_cohort_external::update_cohorts(array($cohort1));
 318              $this->fail('Expecting invalid_parameter_exception exception, none occured');
 319          } catch (invalid_parameter_exception $e2) {
 320              $this->assertStringContainsString('Invalid external api parameter: the value is "9.999"', $e2->debuginfo);
 321          }
 322      }
 323  
 324      /**
 325       * Test update_cohorts without permission on the dest category.
 326       */
 327      public function test_update_cohorts_missing_dest() {
 328          global $USER, $CFG, $DB;
 329  
 330          $this->resetAfterTest(true);
 331  
 332          $category1 = self::getDataGenerator()->create_category(array(
 333              'name' => 'Test category 1'
 334          ));
 335          $category2 = self::getDataGenerator()->create_category(array(
 336              'name' => 'Test category 2'
 337          ));
 338          $context1 = context_coursecat::instance($category1->id);
 339          $context2 = context_coursecat::instance($category2->id);
 340  
 341          $cohort = array(
 342              'contextid' => $context1->id,
 343              'name' => 'cohortnametest1',
 344              'idnumber' => 'idnumbertest1',
 345              'description' => 'This is a description for cohort 1'
 346              );
 347          $cohort1 = self::getDataGenerator()->create_cohort($cohort);
 348  
 349          $roleid = $this->assignUserCapability('moodle/cohort:manage', $context1->id);
 350  
 351          $cohortupdate = array(
 352              'id' => $cohort1->id,
 353              'categorytype' => array('type' => 'id', 'value' => $category2->id),
 354              'name' => 'cohort update',
 355              'idnumber' => 'idnumber update',
 356              'description' => 'This is a description update'
 357              );
 358  
 359          // Call the external function.
 360          // Should fail because we don't have permission on the dest category
 361          $this->expectException(required_capability_exception::class);
 362          core_cohort_external::update_cohorts(array($cohortupdate));
 363      }
 364  
 365      /**
 366       * Test update_cohorts without permission on the src category.
 367       */
 368      public function test_update_cohorts_missing_src() {
 369          global $USER, $CFG, $DB;
 370  
 371          $this->resetAfterTest(true);
 372  
 373          $category1 = self::getDataGenerator()->create_category(array(
 374              'name' => 'Test category 1'
 375          ));
 376          $category2 = self::getDataGenerator()->create_category(array(
 377              'name' => 'Test category 2'
 378          ));
 379          $context1 = context_coursecat::instance($category1->id);
 380          $context2 = context_coursecat::instance($category2->id);
 381  
 382          $cohort = array(
 383              'contextid' => $context1->id,
 384              'name' => 'cohortnametest1',
 385              'idnumber' => 'idnumbertest1',
 386              'description' => 'This is a description for cohort 1'
 387              );
 388          $cohort1 = self::getDataGenerator()->create_cohort($cohort);
 389  
 390          $roleid = $this->assignUserCapability('moodle/cohort:manage', $context2->id);
 391  
 392          $cohortupdate = array(
 393              'id' => $cohort1->id,
 394              'categorytype' => array('type' => 'id', 'value' => $category2->id),
 395              'name' => 'cohort update',
 396              'idnumber' => 'idnumber update',
 397              'description' => 'This is a description update'
 398              );
 399  
 400          // Call the external function.
 401          // Should fail because we don't have permission on the src category
 402          $this->expectException(required_capability_exception::class);
 403          core_cohort_external::update_cohorts(array($cohortupdate));
 404      }
 405  
 406      /**
 407       * Test add_cohort_members
 408       */
 409      public function test_add_cohort_members() {
 410          global $DB;
 411  
 412          $this->resetAfterTest(true); // Reset all changes automatically after this test.
 413  
 414          $contextid = context_system::instance()->id;
 415  
 416          $cohort = array(
 417              'contextid' => $contextid,
 418              'name' => 'cohortnametest1',
 419              'idnumber' => 'idnumbertest1',
 420              'description' => 'This is a description for cohort 1'
 421              );
 422          $cohort0 = self::getDataGenerator()->create_cohort($cohort);
 423          // Check the cohorts were correctly created.
 424          $this->assertEquals(1, $DB->count_records_select('cohort', ' (id = :cohortid0)',
 425              array('cohortid0' => $cohort0->id)));
 426  
 427          $cohort1 = array(
 428              'cohorttype' => array('type' => 'id', 'value' => $cohort0->id),
 429              'usertype' => array('type' => 'id', 'value' => '1')
 430              );
 431  
 432          $roleid = $this->assignUserCapability('moodle/cohort:assign', $contextid);
 433  
 434          // Call the external function.
 435          $addcohortmembers = core_cohort_external::add_cohort_members(array($cohort1));
 436          $addcohortmembers = external_api::clean_returnvalue(core_cohort_external::add_cohort_members_returns(), $addcohortmembers);
 437  
 438          // Check we retrieve the good total number of created cohorts + no error on capability.
 439          $this->assertEquals(1, count($addcohortmembers));
 440  
 441          foreach ($addcohortmembers as $addcohortmember) {
 442              $dbcohort = $DB->get_record('cohort_members', array('cohortid' => $cohort0->id));
 443              $this->assertEquals($dbcohort->cohortid, $cohort1['cohorttype']['value']);
 444              $this->assertEquals($dbcohort->userid, $cohort1['usertype']['value']);
 445          }
 446  
 447          // Call without required capability.
 448          $cohort2 = array(
 449              'cohorttype' => array('type' => 'id', 'value' => $cohort0->id),
 450              'usertype' => array('type' => 'id', 'value' => '2')
 451              );
 452          $this->unassignUserCapability('moodle/cohort:assign', $contextid, $roleid);
 453          $this->expectException(required_capability_exception::class);
 454          $addcohortmembers = core_cohort_external::add_cohort_members(array($cohort2));
 455      }
 456  
 457      /**
 458       * Test delete_cohort_members
 459       */
 460      public function test_delete_cohort_members() {
 461          global $DB;
 462  
 463          $this->resetAfterTest(true); // Reset all changes automatically after this test.
 464  
 465          $cohort1 = self::getDataGenerator()->create_cohort();
 466          $user1 = self::getDataGenerator()->create_user();
 467          $cohort2 = self::getDataGenerator()->create_cohort();
 468          $user2 = self::getDataGenerator()->create_user();
 469  
 470          $context = context_system::instance();
 471          $roleid = $this->assignUserCapability('moodle/cohort:assign', $context->id);
 472  
 473          $cohortaddmember1 = array(
 474              'cohorttype' => array('type' => 'id', 'value' => $cohort1->id),
 475              'usertype' => array('type' => 'id', 'value' => $user1->id)
 476              );
 477          $cohortmembers1 = core_cohort_external::add_cohort_members(array($cohortaddmember1));
 478          $cohortmembers1 = external_api::clean_returnvalue(core_cohort_external::add_cohort_members_returns(), $cohortmembers1);
 479  
 480          $cohortaddmember2 = array(
 481              'cohorttype' => array('type' => 'id', 'value' => $cohort2->id),
 482              'usertype' => array('type' => 'id', 'value' => $user2->id)
 483              );
 484          $cohortmembers2 = core_cohort_external::add_cohort_members(array($cohortaddmember2));
 485          $cohortmembers2 = external_api::clean_returnvalue(core_cohort_external::add_cohort_members_returns(), $cohortmembers2);
 486  
 487          // Check we retrieve no cohorts + no error on capability.
 488          $this->assertEquals(2, $DB->count_records_select('cohort_members', ' ((cohortid = :idcohort1 AND userid = :iduser1)
 489              OR (cohortid = :idcohort2 AND userid = :iduser2))',
 490              array('idcohort1' => $cohort1->id, 'iduser1' => $user1->id, 'idcohort2' => $cohort2->id, 'iduser2' => $user2->id)));
 491  
 492          // Call the external function.
 493           $cohortdel1 = array(
 494              'cohortid' => $cohort1->id,
 495              'userid' => $user1->id
 496              );
 497           $cohortdel2 = array(
 498              'cohortid' => $cohort2->id,
 499              'userid' => $user2->id
 500              );
 501          core_cohort_external::delete_cohort_members(array($cohortdel1, $cohortdel2));
 502  
 503          // Check we retrieve no cohorts + no error on capability.
 504          $this->assertEquals(0, $DB->count_records_select('cohort_members', ' ((cohortid = :idcohort1 AND userid = :iduser1)
 505              OR (cohortid = :idcohort2 AND userid = :iduser2))',
 506              array('idcohort1' => $cohort1->id, 'iduser1' => $user1->id, 'idcohort2' => $cohort2->id, 'iduser2' => $user2->id)));
 507  
 508          // Call without required capability.
 509          $this->unassignUserCapability('moodle/cohort:assign', $context->id, $roleid);
 510          $this->expectException(required_capability_exception::class);
 511          core_cohort_external::delete_cohort_members(array($cohortdel1, $cohortdel2));
 512      }
 513  
 514      /**
 515       * Search cohorts.
 516       */
 517      public function test_search_cohorts() {
 518          global $DB, $CFG;
 519          $this->resetAfterTest(true);
 520  
 521          $creator = $this->getDataGenerator()->create_user();
 522          $user = $this->getDataGenerator()->create_user();
 523          $catuser = $this->getDataGenerator()->create_user();
 524          $catcreator = $this->getDataGenerator()->create_user();
 525          $courseuser = $this->getDataGenerator()->create_user();
 526          $category = $this->getDataGenerator()->create_category();
 527          $othercategory = $this->getDataGenerator()->create_category();
 528          $course = $this->getDataGenerator()->create_course();
 529          $syscontext = context_system::instance();
 530          $catcontext = context_coursecat::instance($category->id);
 531          $coursecontext = context_course::instance($course->id);
 532  
 533          // Fetching default authenticated user role.
 534          $authrole = $DB->get_record('role', array('id' => $CFG->defaultuserroleid));
 535  
 536          // Reset all default authenticated users permissions.
 537          unassign_capability('moodle/cohort:manage', $authrole->id);
 538  
 539          // Creating specific roles.
 540          $creatorrole = create_role('Creator role', 'creatorrole', 'creator role description');
 541          $userrole = create_role('User role', 'userrole', 'user role description');
 542          $courserole = create_role('Course user role', 'courserole', 'course user role description');
 543  
 544          assign_capability('moodle/cohort:manage', CAP_ALLOW, $creatorrole, $syscontext->id);
 545          assign_capability('moodle/cohort:view', CAP_ALLOW, $courserole, $syscontext->id);
 546  
 547          // Check for parameter $includes = 'parents'.
 548          role_assign($creatorrole, $creator->id, $syscontext->id);
 549          role_assign($creatorrole, $catcreator->id, $catcontext->id);
 550          role_assign($userrole, $user->id, $syscontext->id);
 551          role_assign($userrole, $catuser->id, $catcontext->id);
 552  
 553          // Enrol user in the course.
 554          $this->getDataGenerator()->enrol_user($courseuser->id, $course->id, 'courserole');
 555  
 556          $syscontext = array('contextid' => context_system::instance()->id);
 557          $catcontext = array('contextid' => context_coursecat::instance($category->id)->id);
 558          $othercatcontext = array('contextid' => context_coursecat::instance($othercategory->id)->id);
 559          $coursecontext = array('contextid' => context_course::instance($course->id)->id);
 560  
 561          $cohort1 = $this->getDataGenerator()->create_cohort(array_merge($syscontext, array('name' => 'Cohortsearch 1')));
 562          $cohort2 = $this->getDataGenerator()->create_cohort(array_merge($catcontext, array('name' => 'Cohortsearch 2')));
 563          $cohort3 = $this->getDataGenerator()->create_cohort(array_merge($othercatcontext, array('name' => 'Cohortsearch 3')));
 564  
 565          // A user without permission in the system.
 566          $this->setUser($user);
 567          try {
 568              $result = core_cohort_external::search_cohorts("Cohortsearch", $syscontext, 'parents');
 569              $this->fail('Invalid permissions in system');
 570          } catch (required_capability_exception $e) {
 571              // All good.
 572          }
 573  
 574          // A user without permission in a category.
 575          $this->setUser($catuser);
 576          try {
 577              $result = core_cohort_external::search_cohorts("Cohortsearch", $catcontext, 'parents');
 578              $this->fail('Invalid permissions in category');
 579          } catch (required_capability_exception $e) {
 580              // All good.
 581          }
 582  
 583          // A user with permissions in the system.
 584          $this->setUser($creator);
 585          $result = core_cohort_external::search_cohorts("Cohortsearch", $syscontext, 'parents');
 586          $this->assertEquals(1, count($result['cohorts']));
 587          $this->assertEquals('Cohortsearch 1', $result['cohorts'][$cohort1->id]->name);
 588  
 589          // A user with permissions in the category.
 590          $this->setUser($catcreator);
 591          $result = core_cohort_external::search_cohorts("Cohortsearch", $catcontext, 'parents');
 592          $this->assertEquals(2, count($result['cohorts']));
 593          $cohorts = array();
 594          foreach ($result['cohorts'] as $cohort) {
 595              $cohorts[] = $cohort->name;
 596          }
 597          $this->assertTrue(in_array('Cohortsearch 1', $cohorts));
 598  
 599          // Check for parameter $includes = 'self'.
 600          $this->setUser($creator);
 601          $result = core_cohort_external::search_cohorts("Cohortsearch", $othercatcontext, 'self');
 602          $this->assertEquals(1, count($result['cohorts']));
 603          $this->assertEquals('Cohortsearch 3', $result['cohorts'][$cohort3->id]->name);
 604  
 605          // Check for parameter $includes = 'all'.
 606          $this->setUser($creator);
 607          $result = core_cohort_external::search_cohorts("Cohortsearch", $syscontext, 'all');
 608          $this->assertEquals(3, count($result['cohorts']));
 609  
 610          // A user in the course context with the system cohort:view capability. Check that all the system cohorts are returned.
 611          $this->setUser($courseuser);
 612          $result = core_cohort_external::search_cohorts("Cohortsearch", $coursecontext, 'all');
 613          $this->assertEquals(1, count($result['cohorts']));
 614          $this->assertEquals('Cohortsearch 1', $result['cohorts'][$cohort1->id]->name);
 615  
 616          // Detect invalid parameter $includes.
 617          $this->setUser($creator);
 618          try {
 619              $result = core_cohort_external::search_cohorts("Cohortsearch", $syscontext, 'invalid');
 620              $this->fail('Invalid parameter includes');
 621          } catch (coding_exception $e) {
 622              // All good.
 623          }
 624      }
 625  }