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.
   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   * Privacy test for the core_enrol implementation of the privacy API.
  18   *
  19   * @package    core_enrol
  20   * @category   test
  21   * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  defined('MOODLE_INTERNAL') || die();
  26  
  27  use core_enrol\privacy\provider;
  28  use core_privacy\local\request\approved_contextlist;
  29  use core_privacy\local\request\writer;
  30  use core_privacy\tests\provider_testcase;
  31  use \core_privacy\local\request\transform;
  32  use \core_privacy\local\request\approved_userlist;
  33  
  34  /**
  35   * Privacy test for the core_enrol.
  36   *
  37   * @package    core_enrol
  38   * @category   test
  39   * @copyright  2018 Carlos Escobedo <carlos@moodle.com>
  40   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  41   */
  42  class core_enrol_privacy_testcase extends provider_testcase {
  43      /**
  44       * Check that a course context is returned if there is any user data for this user.
  45       */
  46      public function test_get_contexts_for_userid() {
  47          $this->resetAfterTest();
  48          $user1 = $this->getDataGenerator()->create_user();
  49          $course1 = $this->getDataGenerator()->create_course();
  50          $this->assertEmpty(provider::get_contexts_for_userid($user1->id));
  51          // Enrol user into courses and check contextlist.
  52          $this->getDataGenerator()->enrol_user($user1->id, $course1->id,  null, 'manual');
  53          $contextlist = provider::get_contexts_for_userid($user1->id);
  54          // Check that we only get back two context.
  55          $this->assertCount(1, $contextlist);
  56          // Check that the context is returned is the expected.
  57          $coursecontext1 = \context_course::instance($course1->id);
  58          $this->assertEquals($coursecontext1->id, $contextlist->get_contextids()[0]);
  59      }
  60      /**
  61       * Test that user data is exported correctly.
  62       */
  63      public function test_export_user_data() {
  64          global $DB;
  65  
  66          $this->resetAfterTest();
  67          $user1 = $this->getDataGenerator()->create_user();
  68          $course1 = $this->getDataGenerator()->create_course();
  69          $course2 = $this->getDataGenerator()->create_course();
  70          $this->getDataGenerator()->enrol_user($user1->id, $course1->id,  null, 'manual');
  71          $this->getDataGenerator()->enrol_user($user1->id, $course1->id,  null, 'self');
  72          $this->getDataGenerator()->enrol_user($user1->id, $course2->id,  null, 'manual');
  73          $subcontexts = [
  74              get_string('privacy:metadata:user_enrolments', 'core_enrol')
  75          ];
  76          $coursecontext1 = \context_course::instance($course1->id);
  77          $coursecontext2 = \context_course::instance($course2->id);
  78          $this->setUser($user1);
  79          $writer = writer::with_context($coursecontext1);
  80          $this->assertFalse($writer->has_any_data());
  81          $this->export_context_data_for_user($user1->id, $coursecontext1, 'core_enrol');
  82          $data = $writer->get_related_data($subcontexts);
  83          $this->assertCount(2, (array)$data);
  84  
  85          $sql = "SELECT ue.id,
  86                         ue.status,
  87                         ue.timestart,
  88                         ue.timeend,
  89                         ue.timecreated,
  90                         ue.timemodified
  91                    FROM {user_enrolments} ue
  92                    JOIN {enrol} e
  93                      ON e.id = ue.enrolid
  94                     AND e.courseid = :courseid
  95                   WHERE ue.userid = :userid";
  96          $enrolmentcouse2 = $DB->get_record_sql($sql, array('userid' => $user1->id, 'courseid' => $course2->id));
  97          writer::reset();
  98          $writer = writer::with_context($coursecontext2);
  99          $this->export_context_data_for_user($user1->id, $coursecontext2, 'core_enrol');
 100          $data = $writer->get_related_data($subcontexts, 'manual');
 101          $this->assertEquals($enrolmentcouse2->status, reset($data)->status);
 102          $this->assertEquals(transform::datetime($enrolmentcouse2->timestart), reset($data)->timestart);
 103          $this->assertEquals(transform::datetime($enrolmentcouse2->timeend), reset($data)->timeend);
 104          $this->assertEquals(transform::datetime($enrolmentcouse2->timecreated), reset($data)->timecreated);
 105          $this->assertEquals(transform::datetime($enrolmentcouse2->timemodified), reset($data)->timemodified);
 106      }
 107      /**
 108       * Test deleting all user data for a specific context.
 109       */
 110      public function test_delete_data_for_all_users_in_context() {
 111          global $DB;
 112  
 113          $this->resetAfterTest();
 114          $user1 = $this->getDataGenerator()->create_user();
 115          $user2 = $this->getDataGenerator()->create_user();
 116          $user3 = $this->getDataGenerator()->create_user();
 117          $course1 = $this->getDataGenerator()->create_course();
 118          $course2 = $this->getDataGenerator()->create_course();
 119          $this->getDataGenerator()->enrol_user($user1->id, $course1->id,  null, 'manual');
 120          $this->getDataGenerator()->enrol_user($user2->id, $course1->id,  null, 'manual');
 121          $this->getDataGenerator()->enrol_user($user3->id, $course1->id,  null, 'manual');
 122          $this->getDataGenerator()->enrol_user($user1->id, $course2->id,  null, 'manual');
 123          $this->getDataGenerator()->enrol_user($user2->id, $course2->id,  null, 'manual');
 124          // Get all user enrolments.
 125          $userenrolments = $DB->get_records('user_enrolments', array());
 126          $this->assertCount(5, $userenrolments);
 127          // Get all user enrolments match with course1.
 128          $sql = "SELECT ue.id
 129                    FROM {user_enrolments} ue
 130                    JOIN {enrol} e
 131                      ON e.id = ue.enrolid
 132                     AND e.courseid = :courseid";
 133          $userenrolments = $DB->get_records_sql($sql, array('courseid' => $course1->id));
 134          $this->assertCount(3, $userenrolments);
 135          // Delete everything for the first course context.
 136          $coursecontext1 = \context_course::instance($course1->id);
 137          provider::delete_data_for_all_users_in_context($coursecontext1);
 138          // Get all user enrolments match with this course contest.
 139          $userenrolments = $DB->get_records_sql($sql, array('courseid' => $course1->id));
 140          $this->assertCount(0, $userenrolments);
 141          // Get all user enrolments.
 142          $userenrolments = $DB->get_records('user_enrolments', array());
 143          $this->assertCount(2, $userenrolments);
 144      }
 145      /**
 146       * This should work identical to the above test.
 147       */
 148      public function test_delete_data_for_user() {
 149          global $DB;
 150  
 151          $this->resetAfterTest();
 152          $user1 = $this->getDataGenerator()->create_user();
 153          $user2 = $this->getDataGenerator()->create_user();
 154          $user3 = $this->getDataGenerator()->create_user();
 155          $course1 = $this->getDataGenerator()->create_course();
 156          $course2 = $this->getDataGenerator()->create_course();
 157          $this->getDataGenerator()->enrol_user($user1->id, $course1->id,  null, 'manual');
 158          $this->getDataGenerator()->enrol_user($user2->id, $course1->id,  null, 'manual');
 159          $this->getDataGenerator()->enrol_user($user3->id, $course1->id,  null, 'manual');
 160          $this->getDataGenerator()->enrol_user($user1->id, $course2->id,  null, 'manual');
 161  
 162          // Get all user enrolments.
 163          $userenrolments = $DB->get_records('user_enrolments', array());
 164          $this->assertCount(4, $userenrolments);
 165          // Get all user enrolments match with user1.
 166          $userenrolments = $DB->get_records('user_enrolments', array('userid' => $user1->id));
 167          $this->assertCount(2, $userenrolments);
 168          // Delete everything for the user1 in the context course 1.
 169          $coursecontext1 = \context_course::instance($course1->id);
 170          $approvedlist = new approved_contextlist($user1, 'core_enrol', [$coursecontext1->id]);
 171          provider::delete_data_for_user($approvedlist);
 172          // Get all user enrolments match with user.
 173          $userenrolments = $DB->get_records('user_enrolments', ['userid' => $user1->id]);
 174          $this->assertCount(1, $userenrolments);
 175          // Get all user enrolments accounts.
 176          $userenrolments = $DB->get_records('user_enrolments', array());
 177          $this->assertCount(3, $userenrolments);
 178      }
 179  
 180      /**
 181       * Test that only users within a course context are fetched.
 182       */
 183      public function test_get_users_in_context() {
 184          $this->resetAfterTest();
 185  
 186          $component = 'core_enrol';
 187  
 188          $user = $this->getDataGenerator()->create_user();
 189          $usercontext = context_user::instance($user->id);
 190          $course = $this->getDataGenerator()->create_course();
 191          $coursecontext = context_course::instance($course->id);
 192  
 193          $userlist1 = new \core_privacy\local\request\userlist($coursecontext, $component);
 194          provider::get_users_in_context($userlist1);
 195          $this->assertCount(0, $userlist1);
 196  
 197          // Enrol user into course.
 198          $this->getDataGenerator()->enrol_user($user->id, $course->id,  null, 'manual');
 199  
 200          // The list of users within the course context should contain user.
 201          provider::get_users_in_context($userlist1);
 202          $this->assertCount(1, $userlist1);
 203          $expected = [$user->id];
 204          $actual = $userlist1->get_userids();
 205          $this->assertEquals($expected, $actual);
 206  
 207          // The list of users within the user context should be empty.
 208          $userlist2 = new \core_privacy\local\request\userlist($usercontext, $component);
 209          provider::get_users_in_context($userlist2);
 210          $this->assertCount(0, $userlist2);
 211      }
 212  
 213      /**
 214       * Test that data for users in approved userlist is deleted.
 215       */
 216      public function test_delete_data_for_users() {
 217          $this->resetAfterTest();
 218  
 219          $component = 'core_enrol';
 220  
 221          $user1 = $this->getDataGenerator()->create_user();
 222          $user2 = $this->getDataGenerator()->create_user();
 223          $user3 = $this->getDataGenerator()->create_user();
 224          $course1 = $this->getDataGenerator()->create_course();
 225          $course2 = $this->getDataGenerator()->create_course();
 226          $coursecontext1 = context_course::instance($course1->id);
 227          $coursecontext2 = context_course::instance($course2->id);
 228          $systemcontext = context_system::instance();
 229  
 230          // Enrol user1 into course1.
 231          $this->getDataGenerator()->enrol_user($user1->id, $course1->id,  null, 'manual');
 232          // Enrol user2 into course1.
 233          $this->getDataGenerator()->enrol_user($user2->id, $course1->id,  null, 'manual');
 234          // Enrol user3 into course2.
 235          $this->getDataGenerator()->enrol_user($user3->id, $course2->id,  null, 'manual');
 236  
 237          $userlist1 = new \core_privacy\local\request\userlist($coursecontext1, $component);
 238          provider::get_users_in_context($userlist1);
 239          $this->assertCount(2, $userlist1);
 240  
 241          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 242          provider::get_users_in_context($userlist2);
 243          $this->assertCount(1, $userlist2);
 244  
 245          // Convert $userlist1 into an approved_contextlist.
 246          $approvedlist1 = new approved_userlist($coursecontext1, $component, $userlist1->get_userids());
 247          // Delete using delete_data_for_user.
 248          provider::delete_data_for_users($approvedlist1);
 249          // Re-fetch users in coursecontext1.
 250          $userlist1 = new \core_privacy\local\request\userlist($coursecontext1, $component);
 251          provider::get_users_in_context($userlist1);
 252          // The user data in coursecontext1 should be deleted.
 253          $this->assertCount(0, $userlist1);
 254  
 255          // Re-fetch users in coursecontext2.
 256          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 257          provider::get_users_in_context($userlist2);
 258          // The user data in coursecontext2 should be still present.
 259          $this->assertCount(1, $userlist2);
 260  
 261          // Convert $userlist2 into an approved_contextlist in the system context.
 262          $approvedlist2 = new approved_userlist($systemcontext, $component, $userlist2->get_userids());
 263          // Delete using delete_data_for_user.
 264          provider::delete_data_for_users($approvedlist2);
 265          // Re-fetch users in coursecontext1.
 266          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 267          provider::get_users_in_context($userlist2);
 268          // The user data in systemcontext should not be deleted.
 269          $this->assertCount(1, $userlist2);
 270      }
 271  }