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.

Differences Between: [Versions 39 and 310]

   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   * Tests for privacy functions.
  19   *
  20   * @package    report_stats
  21   * @copyright  2018 Adrian Greeve <adriangreeve.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
  23   */
  24  
  25  use \report_stats\privacy\provider;
  26  use \core_privacy\local\request\approved_userlist;
  27  use \core_privacy\tests\provider_testcase;
  28  
  29  /**
  30   * Class report_stats_privacy_testcase
  31   *
  32   * @package    report_stats
  33   * @copyright  2018 Adrian Greeve <adriangreeve.com>
  34   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later.
  35   */
  36  class report_stats_privacy_testcase extends provider_testcase {
  37  
  38      /**
  39       * Convenience function to create stats.
  40       *
  41       * @param int $courseid Course ID for this record.
  42       * @param int $userid User ID for this record.
  43       * @param string $table Stat table to insert into.
  44       */
  45      protected function create_stats($courseid, $userid, $table) {
  46          global $DB;
  47  
  48          $data = (object) [
  49              'courseid' => $courseid,
  50              'userid' => $userid,
  51              'roleid' => 0,
  52              'timeend' => time(),
  53              'statsreads' => rand(1, 50),
  54              'statswrites' => rand(1, 50),
  55              'stattype' => 'activity'
  56          ];
  57          $DB->insert_record($table, $data);
  58      }
  59  
  60      /**
  61       * Get all of the contexts related to a user and stat tables.
  62       */
  63      public function test_get_contexts_for_userid() {
  64          $this->resetAfterTest();
  65          $user1 = $this->getDataGenerator()->create_user();
  66          $user2 = $this->getDataGenerator()->create_user();
  67          $user3 = $this->getDataGenerator()->create_user();
  68  
  69          $course1 = $this->getDataGenerator()->create_course();
  70          $course2 = $this->getDataGenerator()->create_course();
  71          $course3 = $this->getDataGenerator()->create_course();
  72  
  73          $context1 = context_course::instance($course1->id);
  74          $context2 = context_course::instance($course2->id);
  75          $context3 = context_course::instance($course3->id);
  76  
  77          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
  78          $this->create_stats($course2->id, $user1->id, 'stats_user_monthly');
  79          $this->create_stats($course1->id, $user2->id, 'stats_user_weekly');
  80  
  81          $contextlist = provider::get_contexts_for_userid($user1->id);
  82          $this->assertCount(2, $contextlist->get_contextids());
  83          foreach ($contextlist->get_contexts() as $context) {
  84              $this->assertEquals(CONTEXT_COURSE, $context->contextlevel);
  85              $this->assertNotEquals($context3, $context);
  86          }
  87          $contextlist = provider::get_contexts_for_userid($user2->id);
  88          $this->assertCount(1, $contextlist->get_contextids());
  89          $this->assertEquals($context1, $contextlist->current());
  90      }
  91  
  92      /**
  93       * Test that stat data is exported as required.
  94       */
  95      public function test_export_user_data() {
  96          $this->resetAfterTest();
  97          $user = $this->getDataGenerator()->create_user();
  98          $course1 = $this->getDataGenerator()->create_course();
  99          $course2 = $this->getDataGenerator()->create_course();
 100          $context1 = context_course::instance($course1->id);
 101          $context2 = context_course::instance($course2->id);
 102          $this->create_stats($course1->id, $user->id, 'stats_user_daily');
 103          $this->create_stats($course1->id, $user->id, 'stats_user_daily');
 104          $this->create_stats($course2->id, $user->id, 'stats_user_weekly');
 105          $this->create_stats($course2->id, $user->id, 'stats_user_monthly');
 106          $this->create_stats($course1->id, $user->id, 'stats_user_monthly');
 107  
 108          $approvedlist = new \core_privacy\local\request\approved_contextlist($user, 'report_stats', [$context1->id, $context2->id]);
 109  
 110          provider::export_user_data($approvedlist);
 111          $writer = \core_privacy\local\request\writer::with_context($context1);
 112          $dailystats = (array) $writer->get_data([get_string('privacy:dailypath', 'report_stats')]);
 113          $this->assertCount(2, $dailystats);
 114          $monthlystats = (array) $writer->get_data([get_string('privacy:monthlypath', 'report_stats')]);
 115          $this->assertCount(1, $monthlystats);
 116          $data = array_shift($monthlystats);
 117          $this->assertEquals($course1->fullname, $data['course']);
 118          $writer = \core_privacy\local\request\writer::with_context($context2);
 119          $monthlystats = (array) $writer->get_data([get_string('privacy:monthlypath', 'report_stats')]);
 120          $this->assertCount(1, $monthlystats);
 121          $data = array_shift($monthlystats);
 122          $this->assertEquals($course2->fullname, $data['course']);
 123          $weeklystats = (array) $writer->get_data([get_string('privacy:weeklypath', 'report_stats')]);
 124          $this->assertCount(1, $weeklystats);
 125          $data = array_shift($weeklystats);
 126          $this->assertEquals($course2->fullname, $data['course']);
 127      }
 128  
 129      /**
 130       * Test that stat data is deleted for a whole context.
 131       */
 132      public function test_delete_data_for_all_users_in_context() {
 133          global $DB;
 134  
 135          $this->resetAfterTest();
 136          $user1 = $this->getDataGenerator()->create_user();
 137          $user2 = $this->getDataGenerator()->create_user();
 138  
 139          $course1 = $this->getDataGenerator()->create_course();
 140          $course2 = $this->getDataGenerator()->create_course();
 141          $context1 = context_course::instance($course1->id);
 142          $context2 = context_course::instance($course2->id);
 143          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
 144          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
 145          $this->create_stats($course1->id, $user1->id, 'stats_user_monthly');
 146          $this->create_stats($course1->id, $user2->id, 'stats_user_weekly');
 147          $this->create_stats($course2->id, $user2->id, 'stats_user_daily');
 148          $this->create_stats($course2->id, $user2->id, 'stats_user_weekly');
 149          $this->create_stats($course2->id, $user2->id, 'stats_user_monthly');
 150  
 151          $dailyrecords = $DB->get_records('stats_user_daily');
 152          $this->assertCount(3, $dailyrecords);
 153          $weeklyrecords = $DB->get_records('stats_user_weekly');
 154          $this->assertCount(2, $weeklyrecords);
 155          $monthlyrecords = $DB->get_records('stats_user_monthly');
 156          $this->assertCount(2, $monthlyrecords);
 157  
 158          // Delete all user data for course 1.
 159          provider::delete_data_for_all_users_in_context($context1);
 160          $dailyrecords = $DB->get_records('stats_user_daily');
 161          $this->assertCount(1, $dailyrecords);
 162          $weeklyrecords = $DB->get_records('stats_user_weekly');
 163          $this->assertCount(1, $weeklyrecords);
 164          $monthlyrecords = $DB->get_records('stats_user_monthly');
 165          $this->assertCount(1, $monthlyrecords);
 166      }
 167  
 168      /**
 169       * Test that stats are deleted for one user.
 170       */
 171      public function test_delete_data_for_user() {
 172          global $DB;
 173  
 174          $this->resetAfterTest();
 175          $user1 = $this->getDataGenerator()->create_user();
 176          $user2 = $this->getDataGenerator()->create_user();
 177  
 178          $course1 = $this->getDataGenerator()->create_course();
 179          $course2 = $this->getDataGenerator()->create_course();
 180          $context1 = context_course::instance($course1->id);
 181          $context2 = context_course::instance($course2->id);
 182          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
 183          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
 184          $this->create_stats($course1->id, $user1->id, 'stats_user_monthly');
 185          $this->create_stats($course1->id, $user2->id, 'stats_user_weekly');
 186          $this->create_stats($course2->id, $user2->id, 'stats_user_daily');
 187          $this->create_stats($course2->id, $user2->id, 'stats_user_weekly');
 188          $this->create_stats($course2->id, $user2->id, 'stats_user_monthly');
 189  
 190          $dailyrecords = $DB->get_records('stats_user_daily');
 191          $this->assertCount(3, $dailyrecords);
 192          $weeklyrecords = $DB->get_records('stats_user_weekly');
 193          $this->assertCount(2, $weeklyrecords);
 194          $monthlyrecords = $DB->get_records('stats_user_monthly');
 195          $this->assertCount(2, $monthlyrecords);
 196  
 197          // Delete all user data for course 1.
 198          $approvedlist = new \core_privacy\local\request\approved_contextlist($user1, 'report_stats', [$context1->id]);
 199          provider::delete_data_for_user($approvedlist);
 200          $dailyrecords = $DB->get_records('stats_user_daily');
 201          $this->assertCount(1, $dailyrecords);
 202          $weeklyrecords = $DB->get_records('stats_user_weekly');
 203          $this->assertCount(2, $weeklyrecords);
 204          $monthlyrecords = $DB->get_records('stats_user_monthly');
 205          $this->assertCount(1, $monthlyrecords);
 206      }
 207  
 208      /**
 209       * Test that only users within a course context are fetched.
 210       */
 211      public function test_get_users_in_context() {
 212          $this->resetAfterTest();
 213  
 214          $component = 'report_stats';
 215  
 216          // Create user1.
 217          $user1 = $this->getDataGenerator()->create_user();
 218          // Create user2.
 219          $user2 = $this->getDataGenerator()->create_user();
 220          // Create course1.
 221          $course1 = $this->getDataGenerator()->create_course();
 222          $coursecontext1 = context_course::instance($course1->id);
 223          // Create course2.
 224          $course2 = $this->getDataGenerator()->create_course();
 225          $coursecontext2 = context_course::instance($course2->id);
 226  
 227          $userlist1 = new \core_privacy\local\request\userlist($coursecontext1, $component);
 228          provider::get_users_in_context($userlist1);
 229          $this->assertCount(0, $userlist1);
 230  
 231          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 232          provider::get_users_in_context($userlist2);
 233          $this->assertCount(0, $userlist2);
 234  
 235          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
 236          $this->create_stats($course2->id, $user1->id, 'stats_user_monthly');
 237          $this->create_stats($course1->id, $user2->id, 'stats_user_weekly');
 238  
 239          // The list of users within the course context should contain users.
 240          provider::get_users_in_context($userlist1);
 241          $this->assertCount(2, $userlist1);
 242          $this->assertTrue(in_array($user1->id, $userlist1->get_userids()));
 243          $this->assertTrue(in_array($user2->id, $userlist1->get_userids()));
 244  
 245          provider::get_users_in_context($userlist2);
 246          $this->assertCount(1, $userlist2);
 247          $this->assertTrue(in_array($user1->id, $userlist2->get_userids()));
 248  
 249          // The list of users within other contexts than course should be empty.
 250          $systemcontext = context_system::instance();
 251          $userlist3 = new \core_privacy\local\request\userlist($systemcontext, $component);
 252          provider::get_users_in_context($userlist3);
 253          $this->assertCount(0, $userlist3);
 254      }
 255  
 256      /**
 257       * Test that data for users in approved userlist is deleted.
 258       */
 259      public function test_delete_data_for_users() {
 260          $this->resetAfterTest();
 261  
 262          $component = 'report_stats';
 263  
 264          // Create user1.
 265          $user1 = $this->getDataGenerator()->create_user();
 266          // Create user2.
 267          $user2 = $this->getDataGenerator()->create_user();
 268          // Create user3.
 269          $user3 = $this->getDataGenerator()->create_user();
 270          // Create course1.
 271          $course1 = $this->getDataGenerator()->create_course();
 272          $coursecontext1 = context_course::instance($course1->id);
 273          // Create course2.
 274          $course2 = $this->getDataGenerator()->create_course();
 275          $coursecontext2 = context_course::instance($course2->id);
 276  
 277          $this->create_stats($course1->id, $user1->id, 'stats_user_daily');
 278          $this->create_stats($course2->id, $user1->id, 'stats_user_monthly');
 279          $this->create_stats($course1->id, $user2->id, 'stats_user_weekly');
 280          $this->create_stats($course1->id, $user3->id, 'stats_user_weekly');
 281  
 282          $userlist1 = new \core_privacy\local\request\userlist($coursecontext1, $component);
 283          provider::get_users_in_context($userlist1);
 284          $this->assertCount(3, $userlist1);
 285  
 286          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 287          provider::get_users_in_context($userlist2);
 288          $this->assertCount(1, $userlist2);
 289  
 290          // Convert $userlist1 into an approved_contextlist.
 291          $approvedlist1 = new approved_userlist($coursecontext1, $component, [$user1->id, $user2->id]);
 292          // Delete using delete_data_for_user.
 293          provider::delete_data_for_users($approvedlist1);
 294  
 295          // Re-fetch users in coursecontext1.
 296          $userlist1 = new \core_privacy\local\request\userlist($coursecontext1, $component);
 297          provider::get_users_in_context($userlist1);
 298          // The approved user data in coursecontext1 should be deleted.
 299          // The user list should still return user3.
 300          $this->assertCount(1, $userlist1);
 301          $this->assertTrue(in_array($user3->id, $userlist1->get_userids()));
 302          // Re-fetch users in coursecontext2.
 303          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 304          provider::get_users_in_context($userlist2);
 305          // The user data in coursecontext2 should be still present.
 306          $this->assertCount(1, $userlist2);
 307  
 308          // Convert $userlist2 into an approved_contextlist in the system context.
 309          $systemcontext = context_system::instance();
 310          $approvedlist2 = new approved_userlist($systemcontext, $component, $userlist2->get_userids());
 311          // Delete using delete_data_for_user.
 312          provider::delete_data_for_users($approvedlist2);
 313          // Re-fetch users in coursecontext2.
 314          $userlist2 = new \core_privacy\local\request\userlist($coursecontext2, $component);
 315          provider::get_users_in_context($userlist2);
 316          // The user data in systemcontext should not be deleted.
 317          $this->assertCount(1, $userlist2);
 318      }
 319  }