Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 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  namespace tool_cohortroles;
  18  
  19  /**
  20   * API tests.
  21   *
  22   * @package    tool_cohortroles
  23   * @copyright  2015 Damyon Wiese
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  class api_test extends \advanced_testcase {
  27      /** @var \stdClass $cohort */
  28      protected $cohort = null;
  29  
  30      /** @var \stdClass $userassignto */
  31      protected $userassignto = null;
  32  
  33      /** @var \stdClass $userassignover */
  34      protected $userassignover = null;
  35  
  36      /** @var \stdClass $role */
  37      protected $role = null;
  38  
  39      /**
  40       * Setup function- we will create a course and add an assign instance to it.
  41       */
  42      protected function setUp(): void {
  43          $this->resetAfterTest(true);
  44  
  45          // Create some users.
  46          $this->cohort = $this->getDataGenerator()->create_cohort();
  47          $this->userassignto = $this->getDataGenerator()->create_user();
  48          $this->userassignover = $this->getDataGenerator()->create_user();
  49          $this->roleid = create_role('Sausage Roll', 'sausageroll', 'mmmm');
  50          cohort_add_member($this->cohort->id, $this->userassignover->id);
  51      }
  52  
  53      public function test_create_cohort_role_assignment_without_permission() {
  54          $this->setUser($this->userassignto);
  55          $params = (object) array(
  56              'userid' => $this->userassignto->id,
  57              'roleid' => $this->roleid,
  58              'cohortid' => $this->cohort->id
  59          );
  60          $this->expectException(\required_capability_exception::class);
  61          api::create_cohort_role_assignment($params);
  62      }
  63  
  64      public function test_create_cohort_role_assignment_with_invalid_data() {
  65          $this->setAdminUser();
  66          $params = (object) array(
  67              'userid' => $this->userassignto->id,
  68              'roleid' => -8,
  69              'cohortid' => $this->cohort->id
  70          );
  71          $this->expectException(\core_competency\invalid_persistent_exception::class);
  72          api::create_cohort_role_assignment($params);
  73      }
  74  
  75      public function test_create_cohort_role_assignment() {
  76          $this->setAdminUser();
  77          $params = (object) array(
  78              'userid' => $this->userassignto->id,
  79              'roleid' => $this->roleid,
  80              'cohortid' => $this->cohort->id
  81          );
  82          $result = api::create_cohort_role_assignment($params);
  83          $this->assertNotEmpty($result->get('id'));
  84          $this->assertEquals($result->get('userid'), $this->userassignto->id);
  85          $this->assertEquals($result->get('roleid'), $this->roleid);
  86          $this->assertEquals($result->get('cohortid'), $this->cohort->id);
  87      }
  88  
  89      public function test_delete_cohort_role_assignment_without_permission() {
  90          $this->setAdminUser();
  91          $params = (object) array(
  92              'userid' => $this->userassignto->id,
  93              'roleid' => $this->roleid,
  94              'cohortid' => $this->cohort->id
  95          );
  96          $result = api::create_cohort_role_assignment($params);
  97          $this->setUser($this->userassignto);
  98          $this->expectException(\required_capability_exception::class);
  99          api::delete_cohort_role_assignment($result->get('id'));
 100      }
 101  
 102      public function test_delete_cohort_role_assignment_with_invalid_data() {
 103          $this->setAdminUser();
 104          $params = (object) array(
 105              'userid' => $this->userassignto->id,
 106              'roleid' => $this->roleid,
 107              'cohortid' => $this->cohort->id
 108          );
 109          $result = api::create_cohort_role_assignment($params);
 110          $this->expectException(\dml_missing_record_exception::class);
 111          api::delete_cohort_role_assignment($result->get('id') + 1);
 112      }
 113  
 114      public function test_delete_cohort_role_assignment() {
 115          $this->setAdminUser();
 116          // Create a cohort role assigment.
 117          $params = (object) [
 118              'userid' => $this->userassignto->id,
 119              'roleid' => $this->roleid,
 120              'cohortid' => $this->cohort->id
 121          ];
 122          $cohortroleassignment = api::create_cohort_role_assignment($params);
 123          $sync = api::sync_all_cohort_roles();
 124          $rolesadded = [
 125              [
 126                  'useridassignedto' => $this->userassignto->id,
 127                  'useridassignedover' => $this->userassignover->id,
 128                  'roleid' => $this->roleid
 129              ]
 130          ];
 131          $expected = [
 132              'rolesadded' => $rolesadded,
 133              'rolesremoved' => []
 134          ];
 135          $this->assertEquals($sync, $expected);
 136  
 137          // Delete the cohort role assigment and confirm the roles are removed.
 138          $result = api::delete_cohort_role_assignment($cohortroleassignment->get('id'));
 139          $this->assertTrue($result);
 140          $sync = api::sync_all_cohort_roles();
 141          $expected = [
 142              'rolesadded' => [],
 143              'rolesremoved' => $rolesadded
 144          ];
 145          $this->assertEquals($expected, $sync);
 146      }
 147  
 148      /**
 149       * Test case verifying that syncing won't remove role assignments if they are valid for another cohort role assignment.
 150       */
 151      public function test_delete_cohort_role_assignment_cohorts_having_same_members() {
 152          $this->setAdminUser();
 153  
 154          // Create 2 cohorts, with a 1 user (user1) present in both,
 155          // and user2 and user3 members of 1 cohort each.
 156          $cohort1 = $this->getDataGenerator()->create_cohort();
 157          $cohort2 = $this->getDataGenerator()->create_cohort();
 158          $user1 = $this->getDataGenerator()->create_user();
 159          $user2 = $this->getDataGenerator()->create_user();
 160          $user3 = $this->getDataGenerator()->create_user();
 161          cohort_add_member($cohort1->id, $user1->id);
 162          cohort_add_member($cohort1->id, $user2->id);
 163          cohort_add_member($cohort2->id, $user1->id);
 164          cohort_add_member($cohort2->id, $user3->id);
 165  
 166          // And a role and a user to assign that role to.
 167          $user4 = $this->getDataGenerator()->create_user(); // A cohort manager, for example.
 168          $roleid = create_role('Role 1', 'myrole', 'test');
 169  
 170          // Assign the role for user4 in both cohorts.
 171          $params = (object) [
 172              'userid' => $user4->id,
 173              'roleid' => $roleid,
 174              'cohortid' => $cohort1->id
 175          ];
 176          $cohort1roleassignment = api::create_cohort_role_assignment($params);
 177          $params->cohortid = $cohort2->id;
 178          $cohort2roleassignment = api::create_cohort_role_assignment($params);
 179  
 180          $sync = api::sync_all_cohort_roles();
 181  
 182          // There is no guarantee about the order of roles assigned.
 183          // so confirm we have 3 role assignments, and they are for the users 1, 2 and 3.
 184          $this->assertCount(3, $sync['rolesadded']);
 185          $addedusers = array_column($sync['rolesadded'], 'useridassignedover');
 186          $this->assertContains($user1->id, $addedusers);
 187          $this->assertContains($user2->id, $addedusers);
 188          $this->assertContains($user3->id, $addedusers);
 189  
 190          // Remove the role assignment for user4/cohort1.
 191          // Verify only 1 role is unassigned as the others are still valid for the other cohort role assignment.
 192          $result = api::delete_cohort_role_assignment($cohort1roleassignment->get('id'));
 193          $this->assertTrue($result);
 194  
 195          $sync = api::sync_all_cohort_roles();
 196  
 197          $this->assertCount(0, $sync['rolesadded']);
 198          $this->assertCount(1, $sync['rolesremoved']);
 199          $removedusers = array_column($sync['rolesremoved'], 'useridassignedover');
 200          $this->assertContains($user2->id, $removedusers);
 201      }
 202  
 203      public function test_list_cohort_role_assignments() {
 204          $this->setAdminUser();
 205          $params = (object) array(
 206              'userid' => $this->userassignto->id,
 207              'roleid' => $this->roleid,
 208              'cohortid' => $this->cohort->id
 209          );
 210          $result = api::create_cohort_role_assignment($params);
 211  
 212          $list = api::list_cohort_role_assignments();
 213          $list[0]->is_valid();
 214          $this->assertEquals($list[0], $result);
 215      }
 216  
 217      public function test_count_cohort_role_assignments() {
 218          $this->setAdminUser();
 219          $params = (object) array(
 220              'userid' => $this->userassignto->id,
 221              'roleid' => $this->roleid,
 222              'cohortid' => $this->cohort->id
 223          );
 224          $result = api::create_cohort_role_assignment($params);
 225  
 226          $count = api::count_cohort_role_assignments();
 227          $this->assertEquals($count, 1);
 228      }
 229  
 230      public function test_sync_all_cohort_roles() {
 231          $this->setAdminUser();
 232          $params = (object) array(
 233              'userid' => $this->userassignto->id,
 234              'roleid' => $this->roleid,
 235              'cohortid' => $this->cohort->id
 236          );
 237          $result = api::create_cohort_role_assignment($params);
 238  
 239          // Verify roles are assigned when users enter the cohort.
 240          $sync = api::sync_all_cohort_roles();
 241  
 242          $rolesadded = array(array(
 243              'useridassignedto' => $this->userassignto->id,
 244              'useridassignedover' => $this->userassignover->id,
 245              'roleid' => $this->roleid
 246          ));
 247          $rolesremoved = array();
 248          $expected = array('rolesadded' => $rolesadded,
 249                            'rolesremoved' => $rolesremoved);
 250          $this->assertEquals($sync, $expected);
 251  
 252          // Verify roles are removed when users leave the cohort.
 253          cohort_remove_member($this->cohort->id, $this->userassignover->id);
 254          $sync = api::sync_all_cohort_roles();
 255  
 256          $rolesadded = array();
 257          $rolesremoved = array(array(
 258              'useridassignedto' => $this->userassignto->id,
 259              'useridassignedover' => $this->userassignover->id,
 260              'roleid' => $this->roleid
 261          ));
 262          $expected = array('rolesadded' => $rolesadded,
 263                            'rolesremoved' => $rolesremoved);
 264          $this->assertEquals($sync, $expected);
 265  
 266          // Verify roles assigned by any other component are not removed.
 267          $usercontext = \context_user::instance($this->userassignover->id);
 268          role_assign($this->roleid, $this->userassignto->id, $usercontext->id);
 269          $sync = api::sync_all_cohort_roles();
 270  
 271          $rolesadded = array();
 272          $rolesremoved = array();
 273          $expected = array('rolesadded' => $rolesadded,
 274                            'rolesremoved' => $rolesremoved);
 275          $this->assertEquals($sync, $expected);
 276  
 277          // Remove manual role assignment.
 278          role_unassign($this->roleid, $this->userassignto->id, $usercontext->id);
 279          // Add someone to the cohort again...
 280          cohort_add_member($this->cohort->id, $this->userassignover->id);
 281          $sync = api::sync_all_cohort_roles();
 282          $rolesadded = array(array(
 283              'useridassignedto' => $this->userassignto->id,
 284              'useridassignedover' => $this->userassignover->id,
 285              'roleid' => $this->roleid
 286          ));
 287          $rolesremoved = array();
 288          $expected = array('rolesadded' => $rolesadded,
 289                            'rolesremoved' => $rolesremoved);
 290          $this->assertEquals($sync, $expected);
 291  
 292          // Verify no fatal errors when a cohort is deleted.
 293          cohort_delete_cohort($this->cohort);
 294          $sync = api::sync_all_cohort_roles();
 295  
 296          $rolesadded = array();
 297          $rolesremoved = array(array(
 298              'useridassignedto' => $this->userassignto->id,
 299              'useridassignedover' => $this->userassignover->id,
 300              'roleid' => $this->roleid
 301          ));
 302          $expected = array('rolesadded' => $rolesadded,
 303                            'rolesremoved' => $rolesremoved);
 304          $this->assertEquals($sync, $expected);
 305      }
 306  
 307  }