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.
   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   * Unit tests for the tool_cohortroles implementation of the privacy API.
  19   *
  20   * @package    tool_cohortroles
  21   * @category   test
  22   * @copyright  2018 Zig Tan <zig@moodle.com>
  23   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  24   */
  25  namespace tool_cohortroles\privacy;
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  global $CFG;
  29  
  30  use core_privacy\local\request\writer;
  31  use core_privacy\local\request\approved_contextlist;
  32  use tool_cohortroles\api;
  33  use tool_cohortroles\privacy\provider;
  34  use core_privacy\local\request\approved_userlist;
  35  
  36  /**
  37   * Unit tests for the tool_cohortroles implementation of the privacy API.
  38   *
  39   * @copyright  2018 Zig Tan <zig@moodle.com>
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class provider_test extends \core_privacy\tests\provider_testcase {
  43  
  44      /**
  45       * Overriding setUp() function to always reset after tests.
  46       */
  47      public function setUp(): void {
  48          $this->resetAfterTest(true);
  49      }
  50  
  51      /**
  52       * Test for provider::get_contexts_for_userid().
  53       */
  54      public function test_get_contexts_for_userid() {
  55          global $DB;
  56  
  57          // Test setup.
  58          $user = $this->getDataGenerator()->create_user();
  59          $this->setUser($user);
  60          $this->setAdminUser();
  61  
  62          // Create course category.
  63          $coursecategory = $this->getDataGenerator()->create_category();
  64          $coursecategoryctx = \context_coursecat::instance($coursecategory->id);
  65          $systemctx = \context_system::instance();
  66          // Create course.
  67          $course = $this->getDataGenerator()->create_course();
  68          $coursectx = \context_course::instance($course->id);
  69  
  70          $this->setup_test_scenario_data($user->id, $systemctx, 1);
  71          $this->setup_test_scenario_data($user->id, $coursecategoryctx, 1, 'Sausage roll 2',
  72              'sausageroll2');
  73          $this->setup_test_scenario_data($user->id, $coursectx, 1, 'Sausage roll 3',
  74              'sausageroll3');
  75  
  76          // Test the User's assigned cohortroles matches 3.
  77          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
  78          $this->assertCount(3, $cohortroles);
  79  
  80          // Test the User's retrieved contextlist returns only the system and course category context.
  81          $contextlist = provider::get_contexts_for_userid($user->id);
  82          $contexts = $contextlist->get_contexts();
  83          $this->assertCount(2, $contexts);
  84  
  85          $contextlevels = array_column($contexts, 'contextlevel');
  86          $expected = [
  87              CONTEXT_SYSTEM,
  88              CONTEXT_COURSECAT
  89          ];
  90          // Test the User's contexts equal the system and course category context.
  91          $this->assertEqualsCanonicalizing($expected, $contextlevels);
  92      }
  93  
  94      /**
  95       * Test for provider::export_user_data().
  96       */
  97      public function test_export_user_data() {
  98          // Test setup.
  99          $user = $this->getDataGenerator()->create_user();
 100          $this->setUser($user);
 101          $this->setAdminUser();
 102  
 103          // Create course category.
 104          $coursecategory = $this->getDataGenerator()->create_category();
 105          $coursecategoryctx = \context_coursecat::instance($coursecategory->id);
 106          $systemctx = \context_system::instance();
 107          // Create course.
 108          $course = $this->getDataGenerator()->create_course();
 109          $coursectx = \context_course::instance($course->id);
 110  
 111          $this->setup_test_scenario_data($user->id, $systemctx, 1);
 112          $this->setup_test_scenario_data($user->id, $coursecategoryctx, 1, 'Sausage roll 2',
 113              'sausageroll2');
 114          $this->setup_test_scenario_data($user->id, $coursectx, 1, 'Sausage roll 3',
 115              'sausageroll3');
 116  
 117          // Test the User's retrieved contextlist contains two contexts.
 118          $contextlist = provider::get_contexts_for_userid($user->id);
 119          $contexts = $contextlist->get_contexts();
 120          $this->assertCount(2, $contexts);
 121  
 122          // Add a system, course category and course context to the approved context list.
 123          $approvedcontextids = [
 124              $systemctx->id,
 125              $coursecategoryctx->id,
 126              $coursectx->id
 127          ];
 128  
 129          // Retrieve the User's tool_cohortroles data.
 130          $approvedcontextlist = new approved_contextlist($user, 'tool_cohortroles', $approvedcontextids);
 131          provider::export_user_data($approvedcontextlist);
 132  
 133          // Test the tool_cohortroles data is exported at the system context level.
 134          $writer = writer::with_context($systemctx);
 135          $this->assertTrue($writer->has_any_data());
 136          // Test the tool_cohortroles data is exported at the course category context level.
 137          $writer = writer::with_context($coursecategoryctx);
 138          $this->assertTrue($writer->has_any_data());
 139          // Test the tool_cohortroles data is not exported at the course context level.
 140          $writer = writer::with_context($coursectx);
 141          $this->assertFalse($writer->has_any_data());
 142      }
 143  
 144      /**
 145       * Test for provider::delete_data_for_all_users_in_context().
 146       */
 147      public function test_delete_data_for_all_users_in_context() {
 148          global $DB;
 149  
 150          // Test setup.
 151          $user = $this->getDataGenerator()->create_user();
 152          $this->setUser($user);
 153          $this->setAdminUser();
 154  
 155          // Create course category.
 156          $coursecategory = $this->getDataGenerator()->create_category();
 157          $coursecategoryctx = \context_coursecat::instance($coursecategory->id);
 158          $systemctx = \context_system::instance();
 159  
 160          $this->setup_test_scenario_data($user->id, $systemctx, 1);
 161          $this->setup_test_scenario_data($user->id, $coursecategoryctx, 1, 'Sausage roll 2',
 162              'sausageroll2');
 163  
 164          // Test the User's assigned cohortroles matches 2.
 165          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
 166          $this->assertCount(2, $cohortroles);
 167  
 168          // Test the User's retrieved contextlist contains two contexts.
 169          $contextlist = provider::get_contexts_for_userid($user->id);
 170          $contexts = $contextlist->get_contexts();
 171          $this->assertCount(2, $contexts);
 172  
 173          // Make sure the user data is only being deleted in within the system and course category context.
 174          $usercontext = \context_user::instance($user->id);
 175          // Delete all the User's records in mdl_tool_cohortroles table by the user context.
 176          provider::delete_data_for_all_users_in_context($usercontext);
 177  
 178          // Test the cohort roles records in mdl_tool_cohortroles table is still present.
 179          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
 180          $this->assertCount(2, $cohortroles);
 181  
 182          // Delete all the User's records in mdl_tool_cohortroles table by the specified system context.
 183          provider::delete_data_for_all_users_in_context($systemctx);
 184  
 185          // The user data in the system context should be deleted.
 186          // Test the User's retrieved contextlist contains one context (course category).
 187          $contextlist = provider::get_contexts_for_userid($user->id);
 188          $contexts = $contextlist->get_contexts();
 189          $this->assertCount(1, $contexts);
 190  
 191          // Delete all the User's records in mdl_tool_cohortroles table by the specified course category context.
 192          provider::delete_data_for_all_users_in_context($coursecategoryctx);
 193  
 194          // Test the cohort roles records in mdl_tool_cohortroles table is equals zero.
 195          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
 196          $this->assertCount(0, $cohortroles);
 197  
 198          $contextlist = provider::get_contexts_for_userid($user->id);
 199          $contexts = $contextlist->get_contexts();
 200          $this->assertCount(0, $contexts);
 201      }
 202  
 203      /**
 204       * Test for provider::delete_data_for_user().
 205       */
 206      public function test_delete_data_for_user() {
 207          global $DB;
 208  
 209          // Test setup.
 210          $user = $this->getDataGenerator()->create_user();
 211          $this->setUser($user);
 212          $this->setAdminUser();
 213  
 214          // Create course category.
 215          $coursecategory = $this->getDataGenerator()->create_category();
 216          $coursecategoryctx = \context_coursecat::instance($coursecategory->id);
 217          $systemctx = \context_system::instance();
 218  
 219          $this->setup_test_scenario_data($user->id, $systemctx, 1);
 220          $this->setup_test_scenario_data($user->id, $coursecategoryctx, 1, 'Sausage roll 2',
 221              'sausageroll2');
 222  
 223          // Test the User's assigned cohortroles matches 2.
 224          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
 225          $this->assertCount(2, $cohortroles);
 226  
 227          // Test the User's retrieved contextlist contains two contexts.
 228          $contextlist = provider::get_contexts_for_userid($user->id);
 229          $contexts = $contextlist->get_contexts();
 230          $this->assertCount(2, $contexts);
 231  
 232          // Make sure the user data is only being deleted in within the system and the course category contexts.
 233          $usercontext = \context_user::instance($user->id);
 234          // Delete all the User's records in mdl_tool_cohortroles table by the specified approved context list.
 235          $approvedcontextlist = new approved_contextlist($user, 'tool_cohortroles', [$usercontext->id]);
 236          provider::delete_data_for_user($approvedcontextlist);
 237  
 238          // Test the cohort roles records in mdl_tool_cohortroles table are still present.
 239          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
 240          $this->assertCount(2, $cohortroles);
 241  
 242          // Delete all the User's records in mdl_tool_cohortroles table by the specified approved context list.
 243          $approvedcontextlist = new approved_contextlist($user, 'tool_cohortroles', $contextlist->get_contextids());
 244          provider::delete_data_for_user($approvedcontextlist);
 245  
 246          // Test the records in mdl_tool_cohortroles table is equals zero.
 247          $cohortroles = $DB->get_records('tool_cohortroles', ['userid' => $user->id]);
 248          $this->assertCount(0, $cohortroles);
 249      }
 250  
 251      /**
 252       * Test that only users within a course context are fetched.
 253       */
 254      public function test_get_users_in_context() {
 255          $component = 'tool_cohortroles';
 256  
 257          // Create a user.
 258          $user = $this->getDataGenerator()->create_user();
 259          $usercontext = \context_user::instance($user->id);
 260  
 261          // Create course category.
 262          $coursecategory = $this->getDataGenerator()->create_category();
 263          $coursecategoryctx = \context_coursecat::instance($coursecategory->id);
 264          $systemctx = \context_system::instance();
 265  
 266          $this->setAdminUser();
 267  
 268          $userlist = new \core_privacy\local\request\userlist($systemctx, $component);
 269          provider::get_users_in_context($userlist);
 270          $this->assertCount(0, $userlist);
 271  
 272          $this->setup_test_scenario_data($user->id, $systemctx, 1);
 273          $this->setup_test_scenario_data($user->id, $coursecategoryctx, 1, 'Sausage roll 2',
 274              'sausageroll2');
 275  
 276          // The list of users within the system context should contain user.
 277          provider::get_users_in_context($userlist);
 278          $this->assertCount(1, $userlist);
 279          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 280  
 281          // The list of users within the course category context should contain user.
 282          $userlist = new \core_privacy\local\request\userlist($coursecategoryctx, $component);
 283          provider::get_users_in_context($userlist);
 284          $this->assertCount(1, $userlist);
 285          $this->assertTrue(in_array($user->id, $userlist->get_userids()));
 286  
 287          // The list of users within the user context should be empty.
 288          $userlist2 = new \core_privacy\local\request\userlist($usercontext, $component);
 289          provider::get_users_in_context($userlist2);
 290          $this->assertCount(0, $userlist2);
 291      }
 292  
 293      /**
 294       * Test that data for users in approved userlist is deleted.
 295       */
 296      public function test_delete_data_for_users() {
 297          $component = 'tool_cohortroles';
 298  
 299          // Create user1.
 300          $user1 = $this->getDataGenerator()->create_user();
 301          // Create user2.
 302          $user2 = $this->getDataGenerator()->create_user();
 303          // Create user3.
 304          $user3 = $this->getDataGenerator()->create_user();
 305          $usercontext3 = \context_user::instance($user3->id);
 306  
 307          // Create course category.
 308          $coursecategory = $this->getDataGenerator()->create_category();
 309          $coursecategoryctx = \context_coursecat::instance($coursecategory->id);
 310          $systemctx = \context_system::instance();
 311  
 312          $this->setAdminUser();
 313  
 314          $this->setup_test_scenario_data($user1->id, $systemctx, 1);
 315          $this->setup_test_scenario_data($user2->id, $systemctx, 1, 'Sausage roll 2',
 316                  'sausageroll2');
 317          $this->setup_test_scenario_data($user3->id, $coursecategoryctx, 1, 'Sausage roll 3',
 318                  'sausageroll3');
 319  
 320          $userlist1 = new \core_privacy\local\request\userlist($systemctx, $component);
 321          provider::get_users_in_context($userlist1);
 322          $this->assertCount(2, $userlist1);
 323          $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
 324          $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
 325  
 326          // Convert $userlist1 into an approved_contextlist.
 327          $approvedlist1 = new approved_userlist($systemctx, $component, [$user1->id]);
 328          // Delete using delete_data_for_user.
 329          provider::delete_data_for_users($approvedlist1);
 330  
 331          // Re-fetch users in systemcontext.
 332          $userlist1 = new \core_privacy\local\request\userlist($systemctx, $component);
 333          provider::get_users_in_context($userlist1);
 334          // The user data of user1in systemcontext should be deleted.
 335          // The user data of user2 in systemcontext should be still present.
 336          $this->assertCount(1, $userlist1);
 337          $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
 338  
 339          // Convert $userlist1 into an approved_contextlist in the user context.
 340          $approvedlist2 = new approved_userlist($usercontext3, $component, $userlist1->get_userids());
 341          // Delete using delete_data_for_user.
 342          provider::delete_data_for_users($approvedlist2);
 343          // Re-fetch users in systemcontext.
 344          $userlist1 = new \core_privacy\local\request\userlist($systemctx, $component);
 345          provider::get_users_in_context($userlist1);
 346          // The user data in systemcontext should not be deleted.
 347          $this->assertCount(1, $userlist1);
 348      }
 349  
 350      /**
 351       * Helper function to setup tool_cohortroles records for testing a specific user.
 352       *
 353       * @param int $userid           The ID of the user used for testing.
 354       * @param int $nocohortroles    The number of tool_cohortroles to create for the user.
 355       * @param string $rolename      The name of the role to be created.
 356       * @param string $roleshortname The short name of the role to be created.
 357       * @throws \core_competency\invalid_persistent_exception
 358       * @throws coding_exception
 359       */
 360      protected function setup_test_scenario_data($userid, $context, $nocohortroles, $rolename = 'Sausage Roll',
 361                                                  $roleshortname = 'sausageroll') {
 362          $roleid = create_role($rolename, $roleshortname, 'mmmm');
 363  
 364          $result = new \stdClass();
 365          $result->contextid = $context->id;
 366  
 367          for ($c = 0; $c < $nocohortroles; $c++) {
 368              $cohort = $this->getDataGenerator()->create_cohort($result);
 369  
 370              $params = (object)array(
 371                  'userid' => $userid,
 372                  'roleid' => $roleid,
 373                  'cohortid' => $cohort->id
 374              );
 375  
 376              api::create_cohort_role_assignment($params);
 377          }
 378      }
 379  
 380  }