Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.3.x will end 7 October 2024 (12 months).
  • Bug fixes for security issues in 4.3.x will end 21 April 2025 (18 months).
  • PHP version: minimum PHP 8.0.0 Note: minimum PHP version has increased since Moodle 4.1. PHP 8.2.x is supported too.

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