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