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   * Data provider tests.
  19   *
  20   * @package    core_block
  21   * @category   test
  22   * @copyright  2018 Frédéric Massart
  23   * @author     Frédéric Massart <fred@branchup.tech>
  24   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  defined('MOODLE_INTERNAL') || die();
  28  global $CFG;
  29  
  30  use core_privacy\tests\provider_testcase;
  31  use core_privacy\local\request\approved_contextlist;
  32  use core_privacy\local\request\transform;
  33  use core_privacy\local\request\writer;
  34  use core_block\privacy\provider;
  35  
  36  /**
  37   * Data provider testcase class.
  38   *
  39   * @package    core_block
  40   * @category   test
  41   * @copyright  2018 Frédéric Massart
  42   * @author     Frédéric Massart <fred@branchup.tech>
  43   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  44   */
  45  class core_block_privacy_testcase extends provider_testcase {
  46  
  47      public function setUp(): void {
  48          $this->resetAfterTest();
  49      }
  50  
  51      public function test_get_contexts_for_userid() {
  52          $dg = $this->getDataGenerator();
  53          $c1 = $dg->create_course();
  54          $c2 = $dg->create_course();
  55          $u1 = $dg->create_user();
  56          $u2 = $dg->create_user();
  57          $c1ctx = context_course::instance($c1->id);
  58          $c2ctx = context_course::instance($c2->id);
  59          $u1ctx = context_user::instance($u1->id);
  60          $u2ctx = context_user::instance($u2->id);
  61  
  62          $manager = $this->get_block_manager(['region-a'], $c1ctx);
  63          $manager->add_block('myprofile', 'region-a', 0, false);
  64          $manager->load_blocks();
  65          $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
  66  
  67          $manager = $this->get_block_manager(['region-a'], $c2ctx);
  68          $manager->add_block('login', 'region-a', 0, false);
  69          $manager->add_block('mentees', 'region-a', 1, false);
  70          $manager->load_blocks();
  71          list($blocklogin, $blockmentees) = $manager->get_blocks_for_region('region-a');
  72  
  73          $manager = $this->get_block_manager(['region-a'], $u1ctx);
  74          $manager->add_block('private_files', 'region-a', 0, false);
  75          $manager->load_blocks();
  76          $blockprivatefiles = $manager->get_blocks_for_region('region-a')[0];
  77  
  78          $this->set_hidden_pref($blocklogin, true, $u1->id);
  79          $this->set_hidden_pref($blockprivatefiles, true, $u1->id);
  80          $this->set_docked_pref($blockmyprofile, true, $u1->id);
  81          $this->set_docked_pref($blockmentees, true, $u1->id);
  82          $this->set_docked_pref($blockmentees, true, $u2->id);
  83  
  84          $contextids = provider::get_contexts_for_userid($u1->id)->get_contextids();
  85          $this->assertCount(4, $contextids);
  86          $this->assertTrue(in_array($blocklogin->context->id, $contextids));
  87          $this->assertTrue(in_array($blockprivatefiles->context->id, $contextids));
  88          $this->assertTrue(in_array($blockmyprofile->context->id, $contextids));
  89          $this->assertTrue(in_array($blockmentees->context->id, $contextids));
  90  
  91          $contextids = provider::get_contexts_for_userid($u2->id)->get_contextids();
  92          $this->assertCount(1, $contextids);
  93          $this->assertTrue(in_array($blockmentees->context->id, $contextids));
  94      }
  95  
  96      /**
  97       * Test that user IDs are returned for a given context.
  98       */
  99      public function test_get_users_in_context() {
 100          global $DB;
 101          $u1 = $this->getDataGenerator()->create_user();
 102          $u2 = $this->getDataGenerator()->create_user();
 103          $u3 = $this->getDataGenerator()->create_user();
 104  
 105          $course = $this->getDataGenerator()->create_course();
 106  
 107          $manager = $this->get_block_manager(['region-a'], context_course::instance($course->id));
 108          $manager->add_block('myprofile', 'region-a', 0, false);
 109          $manager->load_blocks();
 110          $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
 111  
 112          $this->set_hidden_pref($blockmyprofile, true, $u1->id);
 113          $this->set_hidden_pref($blockmyprofile, true, $u3->id);
 114          $this->set_docked_pref($blockmyprofile, true, $u2->id);
 115          $this->set_docked_pref($blockmyprofile, true, $u3->id);
 116  
 117          $records = $DB->get_records('block_instances', ['blockname' => 'myprofile']);
 118          $record = array_shift($records);
 119          $blockcontext = context_block::instance($record->id);
 120  
 121          $userlist = new \core_privacy\local\request\userlist($blockcontext, 'core_block');
 122          provider::get_users_in_context($userlist);
 123          $this->assertCount(3, $userlist->get_userids());
 124      }
 125  
 126  
 127      public function test_delete_data_for_user() {
 128          global $DB;
 129          $dg = $this->getDataGenerator();
 130          $c1 = $dg->create_course();
 131          $c2 = $dg->create_course();
 132          $u1 = $dg->create_user();
 133          $u2 = $dg->create_user();
 134          $c1ctx = context_course::instance($c1->id);
 135          $c2ctx = context_course::instance($c2->id);
 136          $u1ctx = context_user::instance($u1->id);
 137          $u2ctx = context_user::instance($u2->id);
 138  
 139          $manager = $this->get_block_manager(['region-a'], $c1ctx);
 140          $manager->add_block('myprofile', 'region-a', 0, false);
 141          $manager->load_blocks();
 142          $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
 143  
 144          $manager = $this->get_block_manager(['region-a'], $c2ctx);
 145          $manager->add_block('login', 'region-a', 0, false);
 146          $manager->add_block('mentees', 'region-a', 1, false);
 147          $manager->load_blocks();
 148          list($blocklogin, $blockmentees) = $manager->get_blocks_for_region('region-a');
 149  
 150          $manager = $this->get_block_manager(['region-a'], $u1ctx);
 151          $manager->add_block('private_files', 'region-a', 0, false);
 152          $manager->load_blocks();
 153          $blockprivatefiles = $manager->get_blocks_for_region('region-a')[0];
 154  
 155          $this->set_hidden_pref($blocklogin, true, $u1->id);
 156          $this->set_hidden_pref($blocklogin, true, $u2->id);
 157          $this->set_hidden_pref($blockprivatefiles, true, $u1->id);
 158          $this->set_hidden_pref($blockmyprofile, true, $u1->id);
 159          $this->set_docked_pref($blockmyprofile, true, $u1->id);
 160          $this->set_docked_pref($blockmentees, true, $u1->id);
 161          $this->set_docked_pref($blockmentees, true, $u2->id);
 162  
 163          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 164              'name' => "block{$blocklogin->instance->id}hidden"]));
 165          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 166              'name' => "block{$blocklogin->instance->id}hidden"]));
 167          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 168              'name' => "block{$blockprivatefiles->instance->id}hidden"]));
 169          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 170              'name' => "block{$blockmyprofile->instance->id}hidden"]));
 171          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 172              'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
 173          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 174              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 175          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 176              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 177  
 178          provider::delete_data_for_user(new approved_contextlist($u1, 'core_block', [$blocklogin->context->id,
 179              $blockmyprofile->context->id, $blockmentees->context->id]));
 180  
 181          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 182              'name' => "block{$blocklogin->instance->id}hidden"]));
 183          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 184              'name' => "block{$blocklogin->instance->id}hidden"]));
 185          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 186              'name' => "block{$blockprivatefiles->instance->id}hidden"]));
 187          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 188              'name' => "block{$blockmyprofile->instance->id}hidden"]));
 189          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 190              'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
 191          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 192              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 193          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 194              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 195      }
 196  
 197      public function test_delete_data_for_all_users_in_context() {
 198          global $DB;
 199          $dg = $this->getDataGenerator();
 200          $c1 = $dg->create_course();
 201          $c2 = $dg->create_course();
 202          $u1 = $dg->create_user();
 203          $u2 = $dg->create_user();
 204          $c1ctx = context_course::instance($c1->id);
 205          $c2ctx = context_course::instance($c2->id);
 206          $u1ctx = context_user::instance($u1->id);
 207          $u2ctx = context_user::instance($u2->id);
 208  
 209          $manager = $this->get_block_manager(['region-a'], $c1ctx);
 210          $manager->add_block('myprofile', 'region-a', 0, false);
 211          $manager->load_blocks();
 212          $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
 213  
 214          $manager = $this->get_block_manager(['region-a'], $c2ctx);
 215          $manager->add_block('login', 'region-a', 0, false);
 216          $manager->add_block('mentees', 'region-a', 1, false);
 217          $manager->load_blocks();
 218          list($blocklogin, $blockmentees) = $manager->get_blocks_for_region('region-a');
 219  
 220          $manager = $this->get_block_manager(['region-a'], $u1ctx);
 221          $manager->add_block('private_files', 'region-a', 0, false);
 222          $manager->load_blocks();
 223          $blockprivatefiles = $manager->get_blocks_for_region('region-a')[0];
 224  
 225          $this->set_hidden_pref($blocklogin, true, $u1->id);
 226          $this->set_hidden_pref($blocklogin, true, $u2->id);
 227          $this->set_hidden_pref($blockprivatefiles, true, $u1->id);
 228          $this->set_hidden_pref($blockmyprofile, true, $u1->id);
 229          $this->set_docked_pref($blockmyprofile, true, $u1->id);
 230          $this->set_docked_pref($blockmentees, true, $u1->id);
 231          $this->set_docked_pref($blockmentees, true, $u2->id);
 232  
 233          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 234              'name' => "block{$blocklogin->instance->id}hidden"]));
 235          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 236              'name' => "block{$blocklogin->instance->id}hidden"]));
 237          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 238              'name' => "block{$blockprivatefiles->instance->id}hidden"]));
 239          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 240              'name' => "block{$blockmyprofile->instance->id}hidden"]));
 241          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 242              'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
 243          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 244              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 245          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 246              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 247  
 248          // Nothing happens.
 249          provider::delete_data_for_all_users_in_context($c1ctx);
 250          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 251              'name' => "block{$blocklogin->instance->id}hidden"]));
 252          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 253              'name' => "block{$blocklogin->instance->id}hidden"]));
 254          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 255              'name' => "block{$blockprivatefiles->instance->id}hidden"]));
 256          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 257              'name' => "block{$blockmyprofile->instance->id}hidden"]));
 258          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 259              'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
 260          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 261              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 262          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 263              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 264  
 265          // Delete one block.
 266          provider::delete_data_for_all_users_in_context($blocklogin->context);
 267          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 268              'name' => "block{$blocklogin->instance->id}hidden"]));
 269          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u2->id,
 270              'name' => "block{$blocklogin->instance->id}hidden"]));
 271          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 272              'name' => "block{$blockprivatefiles->instance->id}hidden"]));
 273          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 274              'name' => "block{$blockmyprofile->instance->id}hidden"]));
 275          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 276              'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
 277          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 278              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 279          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 280              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 281  
 282          // Delete another block.
 283          provider::delete_data_for_all_users_in_context($blockmyprofile->context);
 284          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 285              'name' => "block{$blocklogin->instance->id}hidden"]));
 286          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u2->id,
 287              'name' => "block{$blocklogin->instance->id}hidden"]));
 288          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 289              'name' => "block{$blockprivatefiles->instance->id}hidden"]));
 290          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 291              'name' => "block{$blockmyprofile->instance->id}hidden"]));
 292          $this->assertFalse($DB->record_exists('user_preferences', ['userid' => $u1->id,
 293              'name' => "docked_block_instance_{$blockmyprofile->instance->id}"]));
 294          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u1->id,
 295              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 296          $this->assertTrue($DB->record_exists('user_preferences', ['userid' => $u2->id,
 297              'name' => "docked_block_instance_{$blockmentees->instance->id}"]));
 298      }
 299  
 300      /**
 301       * Test the deletion of data related to a context and a list of users.
 302       */
 303      public function test_delete_data_for_users() {
 304          global $DB;
 305          $u1 = $this->getDataGenerator()->create_user();
 306          $u2 = $this->getDataGenerator()->create_user();
 307          $u3 = $this->getDataGenerator()->create_user();
 308  
 309          $course = $this->getDataGenerator()->create_course();
 310  
 311          $manager = $this->get_block_manager(['region-a'], context_course::instance($course->id));
 312          $manager->add_block('myprofile', 'region-a', 0, false);
 313          $manager->load_blocks();
 314          $blockmyprofile = $manager->get_blocks_for_region('region-a')[0];
 315  
 316          $this->set_hidden_pref($blockmyprofile, true, $u1->id);
 317          $this->set_hidden_pref($blockmyprofile, true, $u3->id);
 318          $this->set_docked_pref($blockmyprofile, true, $u2->id);
 319          $this->set_docked_pref($blockmyprofile, true, $u3->id);
 320  
 321          $records = $DB->get_records('block_instances', ['blockname' => 'myprofile']);
 322          $record = array_shift($records);
 323          $blockcontext = context_block::instance($record->id);
 324  
 325          $userlist = new \core_privacy\local\request\userlist($blockcontext, 'core_block');
 326          provider::get_users_in_context($userlist);
 327          $this->assertCount(3, $userlist->get_userids());
 328  
 329          // Delete preferences for user 1 and 3 for the my profile block.
 330          $userlist = new \core_privacy\local\request\approved_userlist($blockcontext, 'core_block', [$u1->id, $u3->id]);
 331          provider::delete_data_for_users($userlist);
 332  
 333          // Only user 2's preference is left.
 334          $this->assertCount(1, $DB->get_records('user_preferences',
 335                  ['name' => "docked_block_instance_{$blockcontext->instanceid}"]));
 336          // All of these are gone.
 337          $this->assertEmpty($DB->get_records('user_preferences',
 338                  ['name' => "block{$blockcontext->instanceid}hidden"]));
 339      }
 340  
 341      public function test_export_data_for_user() {
 342          global $DB;
 343          $dg = $this->getDataGenerator();
 344          $c1 = $dg->create_course();
 345          $c2 = $dg->create_course();
 346          $u1 = $dg->create_user();
 347          $u2 = $dg->create_user();
 348          $c1ctx = context_course::instance($c1->id);
 349          $c2ctx = context_course::instance($c2->id);
 350          $u1ctx = context_user::instance($u1->id);
 351          $u2ctx = context_user::instance($u2->id);
 352          $yes = transform::yesno(true);
 353          $no = transform::yesno(false);
 354  
 355          $manager = $this->get_block_manager(['region-a'], $c1ctx);
 356          $manager->add_block('myprofile', 'region-a', 0, false);
 357          $manager->add_block('login', 'region-a', 1, false);
 358          $manager->add_block('mentees', 'region-a', 2, false);
 359          $manager->add_block('private_files', 'region-a', 3, false);
 360          $manager->load_blocks();
 361          list($bmyprofile, $blogin, $bmentees, $bprivatefiles) = $manager->get_blocks_for_region('region-a');
 362  
 363          // Set some user preferences.
 364          $this->set_hidden_pref($blogin, true, $u1->id);
 365          $this->set_docked_pref($blogin, false, $u1->id);
 366          $this->set_docked_pref($blogin, true, $u2->id);
 367          $this->set_hidden_pref($bprivatefiles, false, $u1->id);
 368          $this->set_docked_pref($bprivatefiles, true, $u2->id);
 369          $this->set_docked_pref($bmyprofile, true, $u1->id);
 370          $this->set_docked_pref($bmentees, true, $u2->id);
 371  
 372          // Export data.
 373          provider::export_user_data(new approved_contextlist($u1, 'core_block', [$bmyprofile->context->id, $blogin->context->id,
 374              $bmentees->context->id, $bprivatefiles->context->id]));
 375          $prefs = writer::with_context($bmentees->context)->get_user_context_preferences('core_block');
 376          $this->assertEmpty((array) $prefs);
 377  
 378          $prefs = writer::with_context($blogin->context)->get_user_context_preferences('core_block');
 379          $this->assertEquals($no, $prefs->block_is_docked->value);
 380          $this->assertEquals($yes, $prefs->block_is_hidden->value);
 381  
 382          $prefs = writer::with_context($bprivatefiles->context)->get_user_context_preferences('core_block');
 383          $this->assertObjectNotHasAttribute('block_is_docked', $prefs);
 384          $this->assertEquals($no, $prefs->block_is_hidden->value);
 385  
 386          $prefs = writer::with_context($bmyprofile->context)->get_user_context_preferences('core_block');
 387          $this->assertEquals($yes, $prefs->block_is_docked->value);
 388          $this->assertObjectNotHasAttribute('block_is_hidden', $prefs);
 389      }
 390  
 391      /**
 392       * Get the block manager.
 393       *
 394       * @param array $regions The regions.
 395       * @param context $context The context.
 396       * @param string $pagetype The page type.
 397       * @param string $subpage The sub page.
 398       * @return block_manager
 399       */
 400      protected function get_block_manager($regions, $context, $pagetype = 'page-type', $subpage = '') {
 401          $page = new moodle_page();
 402          $page->set_context($context);
 403          $page->set_pagetype($pagetype);
 404          $page->set_subpage($subpage);
 405          $page->set_url(new moodle_url('/'));
 406  
 407          $blockmanager = new block_manager($page);
 408          $blockmanager->add_regions($regions, false);
 409          $blockmanager->set_default_region($regions[0]);
 410  
 411          return $blockmanager;
 412      }
 413  
 414      /**
 415       * Set a docked preference.
 416       *
 417       * @param block_base $block The block.
 418       * @param bool $value The value.
 419       * @param int $userid The user ID.
 420       */
 421      protected function set_docked_pref($block, $value, $userid) {
 422          set_user_preference("docked_block_instance_{$block->instance->id}", $value, $userid);
 423      }
 424  
 425      /**
 426       * Set a hidden preference.
 427       *
 428       * @param block_base $block The block.
 429       * @param bool $value The value.
 430       * @param int $userid The user ID.
 431       */
 432      protected function set_hidden_pref($block, $value, $userid) {
 433          set_user_preference("block{$block->instance->id}hidden", $value, $userid);
 434      }
 435  
 436  }