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