Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.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   * Data provider tests.
  19   *
  20   * @package    logstore_legacy
  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 logstore_legacy\privacy;
  27  
  28  defined('MOODLE_INTERNAL') || die();
  29  global $CFG;
  30  
  31  use core_privacy\tests\provider_testcase;
  32  use core_privacy\local\request\contextlist;
  33  use core_privacy\local\request\approved_contextlist;
  34  use core_privacy\local\request\transform;
  35  use core_privacy\local\request\writer;
  36  use logstore_legacy\privacy\provider;
  37  use logstore_legacy\event\unittest_executed;
  38  
  39  require_once (__DIR__ . '/../fixtures/event.php');
  40  
  41  /**
  42   * Data provider testcase class.
  43   *
  44   * @package    logstore_legacy
  45   * @category   test
  46   * @copyright  2018 Frédéric Massart
  47   * @author     Frédéric Massart <fred@branchup.tech>
  48   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  49   */
  50  class provider_test extends provider_testcase {
  51  
  52      public function setUp(): void {
  53          $this->resetAfterTest();
  54      }
  55  
  56      public function test_get_contexts_for_userid() {
  57          $u1 = $this->getDataGenerator()->create_user();
  58          $u2 = $this->getDataGenerator()->create_user();
  59          $u3 = $this->getDataGenerator()->create_user();
  60          $c1 = $this->getDataGenerator()->create_course();
  61          $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
  62          $sysctx = \context_system::instance();
  63          $c1ctx = \context_course::instance($c1->id);
  64          $cm1ctx = \context_module::instance($cm1->cmid);
  65  
  66          $this->enable_logging();
  67          $manager = get_log_manager(true);
  68  
  69          // User 1 is the author.
  70          $this->setUser($u1);
  71          $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), []);
  72          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 1]]);
  73          $e->trigger();
  74          $this->assert_contextlist_equals($this->get_contextlist_for_user($u1), [$cm1ctx]);
  75  
  76          // User 2 is the author.
  77          $this->setUser($u2);
  78          $this->assert_contextlist_equals($this->get_contextlist_for_user($u2), []);
  79          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 2]]);
  80          $e->trigger();
  81          $this->assert_contextlist_equals($this->get_contextlist_for_user($u2), [$cm1ctx]);
  82  
  83          // User 3 is the author.
  84          $this->setUser($u3);
  85          $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), []);
  86          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 3]]);
  87          $e->trigger();
  88          $this->assert_contextlist_equals($this->get_contextlist_for_user($u3), [$sysctx]);
  89      }
  90  
  91      /**
  92       * Test returning user IDs for a given context.
  93       */
  94      public function test_add_userids_for_context() {
  95          $u1 = $this->getDataGenerator()->create_user();
  96          $u2 = $this->getDataGenerator()->create_user();
  97          $u3 = $this->getDataGenerator()->create_user();
  98          $course = $this->getDataGenerator()->create_course();
  99          $module = $this->getDataGenerator()->create_module('url', ['course' => $course]);
 100          $sysctx = \context_system::instance();
 101          $c1ctx = \context_course::instance($course->id);
 102          $cm1ctx = \context_module::instance($module->cmid);
 103  
 104          $userctx = \context_user::instance($u1->id);
 105  
 106          $this->enable_logging();
 107          $manager = get_log_manager(true);
 108  
 109          $this->setUser($u1);
 110          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 1]]);
 111          $e->trigger();
 112          $this->setUser($u2);
 113          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 2]]);
 114          $e->trigger();
 115          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 3]]);
 116          $e->trigger();
 117          $this->setUser($u3);
 118          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 4]]);
 119          $e->trigger();
 120          $this->setUser($u1);
 121          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 5]]);
 122          $e->trigger();
 123          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 6]]);
 124          $e->trigger();
 125          $this->setUser($u2);
 126          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 7]]);
 127          $e->trigger();
 128          $this->setUser($u3);
 129          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 8]]);
 130          $e->trigger();
 131  
 132          // Start with system and check that each of the contexts returns what we expected.
 133          $userlist = new \core_privacy\local\request\userlist($sysctx, 'logstore_legacy');
 134          provider::add_userids_for_context($userlist);
 135          $systemuserids = $userlist->get_userids();
 136          $this->assertCount(2, $systemuserids);
 137          $this->assertNotFalse(array_search($u1->id, $systemuserids));
 138          $this->assertNotFalse(array_search($u2->id, $systemuserids));
 139          // Check the course context.
 140          $userlist = new \core_privacy\local\request\userlist($c1ctx, 'logstore_legacy');
 141          provider::add_userids_for_context($userlist);
 142          $courseuserids = $userlist->get_userids();
 143          $this->assertCount(2, $courseuserids);
 144          $this->assertNotFalse(array_search($u1->id, $courseuserids));
 145          $this->assertNotFalse(array_search($u3->id, $courseuserids));
 146          // Check the module context.
 147          $userlist = new \core_privacy\local\request\userlist($cm1ctx, 'logstore_legacy');
 148          provider::add_userids_for_context($userlist);
 149          $moduleuserids = $userlist->get_userids();
 150          $this->assertCount(3, $moduleuserids);
 151          $this->assertNotFalse(array_search($u1->id, $moduleuserids));
 152          $this->assertNotFalse(array_search($u2->id, $moduleuserids));
 153          $this->assertNotFalse(array_search($u3->id, $moduleuserids));
 154      }
 155  
 156      public function test_delete_data_for_user() {
 157          global $DB;
 158  
 159          $u1 = $this->getDataGenerator()->create_user();
 160          $u2 = $this->getDataGenerator()->create_user();
 161          $u3 = $this->getDataGenerator()->create_user();
 162          $c1 = $this->getDataGenerator()->create_course();
 163          $c2 = $this->getDataGenerator()->create_course();
 164          $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
 165          $sysctx = \context_system::instance();
 166          $c1ctx = \context_course::instance($c1->id);
 167          $c2ctx = \context_course::instance($c2->id);
 168          $cm1ctx = \context_module::instance($cm1->cmid);
 169  
 170          $this->enable_logging();
 171          $manager = get_log_manager(true);
 172  
 173          // User 1 is the author.
 174          $this->setUser($u1);
 175          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 1]]);
 176          $e->trigger();
 177          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 2]]);
 178          $e->trigger();
 179          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 3]]);
 180          $e->trigger();
 181          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 4]]);
 182          $e->trigger();
 183  
 184          // User 2 is the author.
 185          $this->setUser($u2);
 186          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 5]]);
 187          $e->trigger();
 188          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 6]]);
 189          $e->trigger();
 190          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 7]]);
 191          $e->trigger();
 192  
 193          // Assert what we have.
 194          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => $cm1->cmid, 'course' => $c1->id]));
 195          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => $c1->id]));
 196          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => 0]));
 197          $this->assertEquals(4, $DB->count_records('log', ['userid' => $u1->id]));
 198          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 199  
 200          // Delete other context.
 201          provider::delete_data_for_user(new approved_contextlist($u1, 'logstore_legacy', [$c2ctx->id]));
 202          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => $cm1->cmid, 'course' => $c1->id]));
 203          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => $c1->id]));
 204          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => 0]));
 205          $this->assertEquals(4, $DB->count_records('log', ['userid' => $u1->id]));
 206          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 207  
 208          // Delete system.
 209          provider::delete_data_for_user(new approved_contextlist($u1, 'logstore_legacy', [$sysctx->id]));
 210          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => $cm1->cmid, 'course' => $c1->id]));
 211          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => $c1->id]));
 212          $this->assertFalse($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => 0]));
 213          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u1->id]));
 214          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 215  
 216          // Delete course.
 217          provider::delete_data_for_user(new approved_contextlist($u1, 'logstore_legacy', [$c1ctx->id]));
 218          $this->assertTrue($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => $cm1->cmid, 'course' => $c1->id]));
 219          $this->assertFalse($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => $c1->id]));
 220          $this->assertFalse($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => 0]));
 221          $this->assertEquals(2, $DB->count_records('log', ['userid' => $u1->id]));
 222          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 223  
 224          // Delete course.
 225          provider::delete_data_for_user(new approved_contextlist($u1, 'logstore_legacy', [$cm1ctx->id]));
 226          $this->assertFalse($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => $cm1->cmid, 'course' => $c1->id]));
 227          $this->assertFalse($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => $c1->id]));
 228          $this->assertFalse($DB->record_exists('log', ['userid' => $u1->id, 'cmid' => 0, 'course' => 0]));
 229          $this->assertEquals(0, $DB->count_records('log', ['userid' => $u1->id]));
 230          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 231      }
 232  
 233      public function test_delete_data_for_all_users_in_context() {
 234          global $DB;
 235  
 236          $u1 = $this->getDataGenerator()->create_user();
 237          $u2 = $this->getDataGenerator()->create_user();
 238          $u3 = $this->getDataGenerator()->create_user();
 239          $c1 = $this->getDataGenerator()->create_course();
 240          $c2 = $this->getDataGenerator()->create_course();
 241          $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
 242          $sysctx = \context_system::instance();
 243          $c1ctx = \context_course::instance($c1->id);
 244          $c2ctx = \context_course::instance($c2->id);
 245          $cm1ctx = \context_module::instance($cm1->cmid);
 246  
 247          $this->enable_logging();
 248          $manager = get_log_manager(true);
 249  
 250          // User 1 is the author.
 251          $this->setUser($u1);
 252          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 1]]);
 253          $e->trigger();
 254          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 2]]);
 255          $e->trigger();
 256          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 3]]);
 257          $e->trigger();
 258          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 4]]);
 259          $e->trigger();
 260  
 261          // User 2 is the author.
 262          $this->setUser($u2);
 263          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 5]]);
 264          $e->trigger();
 265          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 6]]);
 266          $e->trigger();
 267          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 7]]);
 268          $e->trigger();
 269  
 270          // Assert what we have.
 271          $this->assertTrue($DB->record_exists('log', ['cmid' => $cm1->cmid, 'course' => $c1->id]));
 272          $this->assertTrue($DB->record_exists('log', ['cmid' => 0, 'course' => $c1->id]));
 273          $this->assertTrue($DB->record_exists('log', ['cmid' => 0, 'course' => 0]));
 274          $this->assertEquals(4, $DB->count_records('log', ['userid' => $u1->id]));
 275          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 276  
 277          // Delete other context.
 278          provider::delete_data_for_all_users_in_context($c2ctx);
 279          $this->assertTrue($DB->record_exists('log', ['cmid' => $cm1->cmid, 'course' => $c1->id]));
 280          $this->assertTrue($DB->record_exists('log', ['cmid' => 0, 'course' => $c1->id]));
 281          $this->assertTrue($DB->record_exists('log', ['cmid' => 0, 'course' => 0]));
 282          $this->assertEquals(4, $DB->count_records('log', ['userid' => $u1->id]));
 283          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u2->id]));
 284  
 285          // Delete system.
 286          provider::delete_data_for_all_users_in_context($sysctx);
 287          $this->assertTrue($DB->record_exists('log', ['cmid' => $cm1->cmid, 'course' => $c1->id]));
 288          $this->assertTrue($DB->record_exists('log', ['cmid' => 0, 'course' => $c1->id]));
 289          $this->assertFalse($DB->record_exists('log', ['cmid' => 0, 'course' => 0]));
 290          $this->assertEquals(3, $DB->count_records('log', ['userid' => $u1->id]));
 291          $this->assertEquals(2, $DB->count_records('log', ['userid' => $u2->id]));
 292  
 293          // Delete course.
 294          provider::delete_data_for_all_users_in_context($c1ctx);
 295          $this->assertTrue($DB->record_exists('log', ['cmid' => $cm1->cmid, 'course' => $c1->id]));
 296          $this->assertFalse($DB->record_exists('log', ['cmid' => 0, 'course' => $c1->id]));
 297          $this->assertFalse($DB->record_exists('log', ['cmid' => 0, 'course' => 0]));
 298          $this->assertEquals(2, $DB->count_records('log', ['userid' => $u1->id]));
 299          $this->assertEquals(1, $DB->count_records('log', ['userid' => $u2->id]));
 300  
 301          // Delete course.
 302          provider::delete_data_for_all_users_in_context($cm1ctx);
 303          $this->assertFalse($DB->record_exists('log', ['cmid' => $cm1->cmid, 'course' => $c1->id]));
 304          $this->assertFalse($DB->record_exists('log', ['cmid' => 0, 'course' => $c1->id]));
 305          $this->assertFalse($DB->record_exists('log', ['cmid' => 0, 'course' => 0]));
 306          $this->assertEquals(0, $DB->count_records('log', ['userid' => $u1->id]));
 307          $this->assertEquals(0, $DB->count_records('log', ['userid' => $u2->id]));
 308      }
 309  
 310      /**
 311       * Test the deletion of data for a list of users in a context.
 312       */
 313      public function test_delete_data_for_userlist() {
 314          global $DB;
 315  
 316          $u1 = $this->getDataGenerator()->create_user();
 317          $u2 = $this->getDataGenerator()->create_user();
 318          $u3 = $this->getDataGenerator()->create_user();
 319          $course = $this->getDataGenerator()->create_course();
 320          $module = $this->getDataGenerator()->create_module('url', ['course' => $course]);
 321          $sysctx = \context_system::instance();
 322          $c1ctx = \context_course::instance($course->id);
 323          $cm1ctx = \context_module::instance($module->cmid);
 324  
 325          $userctx = \context_user::instance($u1->id);
 326  
 327          $this->enable_logging();
 328          $manager = get_log_manager(true);
 329  
 330          $this->setUser($u1);
 331          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 1]]);
 332          $e->trigger();
 333          $this->setUser($u2);
 334          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 2]]);
 335          $e->trigger();
 336          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 3]]);
 337          $e->trigger();
 338          $this->setUser($u3);
 339          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 4]]);
 340          $e->trigger();
 341          $this->setUser($u1);
 342          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 5]]);
 343          $e->trigger();
 344          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 6]]);
 345          $e->trigger();
 346          $this->setUser($u2);
 347          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 7]]);
 348          $e->trigger();
 349          $this->setUser($u3);
 350          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 8]]);
 351          $e->trigger();
 352  
 353          // System context deleting one user.
 354          $this->assertEquals(3, $DB->count_records('log', ['cmid' => 0, 'course' => 0]));
 355          $userlist = new \core_privacy\local\request\approved_userlist($sysctx, 'logstore_legacy', [$u2->id]);
 356          provider::delete_data_for_userlist($userlist);
 357          $this->assertEquals(1, $DB->count_records('log', ['cmid' => 0, 'course' => 0]));
 358  
 359          // Course context deleting one user.
 360          $this->assertEquals(2, $DB->count_records('log', ['cmid' => 0, 'course' => $course->id]));
 361          $userlist = new \core_privacy\local\request\approved_userlist($c1ctx, 'logstore_legacy', [$u1->id]);
 362          provider::delete_data_for_userlist($userlist);
 363          $this->assertEquals(1, $DB->count_records('log', ['cmid' => 0, 'course' => $course->id]));
 364  
 365          // Module context deleting two users.
 366          $this->assertEquals(3, $DB->count_records('log', ['cmid' => $module->cmid, 'course' => $course->id]));
 367          $userlist = new \core_privacy\local\request\approved_userlist($cm1ctx, 'logstore_legacy', [$u1->id, $u3->id]);
 368          provider::delete_data_for_userlist($userlist);
 369          $this->assertEquals(1, $DB->count_records('log', ['cmid' => $module->cmid, 'course' => $course->id]));
 370      }
 371  
 372      public function test_export_data_for_user() {
 373          global $DB;
 374  
 375          $u1 = $this->getDataGenerator()->create_user();
 376          $u2 = $this->getDataGenerator()->create_user();
 377          $u3 = $this->getDataGenerator()->create_user();
 378          $c1 = $this->getDataGenerator()->create_course();
 379          $c2 = $this->getDataGenerator()->create_course();
 380          $cm1 = $this->getDataGenerator()->create_module('url', ['course' => $c1]);
 381          $sysctx = \context_system::instance();
 382          $c1ctx = \context_course::instance($c1->id);
 383          $c2ctx = \context_course::instance($c2->id);
 384          $cm1ctx = \context_module::instance($cm1->cmid);
 385  
 386          $this->enable_logging();
 387          $manager = get_log_manager(true);
 388          $path = [get_string('privacy:path:logs', 'tool_log'), get_string('pluginname', 'logstore_legacy')];
 389  
 390          // User 1 is the author.
 391          $this->setUser($u1);
 392          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 1]]);
 393          $e->trigger();
 394          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 2]]);
 395          $e->trigger();
 396          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 3]]);
 397          $e->trigger();
 398          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 4]]);
 399          $e->trigger();
 400  
 401          // User 2 is the author.
 402          $this->setUser($u2);
 403          $e = unittest_executed::create(['context' => $cm1ctx, 'other' => ['sample' => 5]]);
 404          $e->trigger();
 405          $e = unittest_executed::create(['context' => $c1ctx, 'other' => ['sample' => 6]]);
 406          $e->trigger();
 407          $e = unittest_executed::create(['context' => $sysctx, 'other' => ['sample' => 7]]);
 408          $e->trigger();
 409  
 410          // Test export.
 411          provider::export_user_data(new approved_contextlist($u1, 'logstore_legacy', [$cm1ctx->id]));
 412          $data = writer::with_context($c1ctx)->get_data($path);
 413          $this->assertEmpty($data);
 414          $data = writer::with_context($cm1ctx)->get_data($path);
 415          $this->assertCount(2, $data->logs);
 416  
 417          writer::reset();
 418          provider::export_user_data(new approved_contextlist($u1, 'logstore_legacy', [$c1ctx->id]));
 419          $data = writer::with_context($cm1ctx)->get_data($path);
 420          $this->assertEmpty($data);
 421          $data = writer::with_context($c1ctx)->get_data($path);
 422          $this->assertCount(1, $data->logs);
 423  
 424          writer::reset();
 425          provider::export_user_data(new approved_contextlist($u1, 'logstore_legacy', [$sysctx->id]));
 426          $data = writer::with_context($sysctx)->get_data($path);
 427          $this->assertCount(1, $data->logs);
 428      }
 429  
 430      /**
 431       * Assert the content of a context list.
 432       *
 433       * @param contextlist $contextlist The collection.
 434       * @param array $expected List of expected contexts or IDs.
 435       * @return void
 436       */
 437      protected function assert_contextlist_equals($contextlist, array $expected) {
 438          $expectedids = array_map(function($context) {
 439              if (is_object($context)) {
 440                  return $context->id;
 441              }
 442              return $context;
 443          }, $expected);
 444          $contextids = array_map('intval', $contextlist->get_contextids());
 445          sort($contextids);
 446          sort($expectedids);
 447          $this->assertEquals($expectedids, $contextids);
 448      }
 449  
 450      /**
 451       * Enable logging.
 452       *
 453       * @return void
 454       */
 455      protected function enable_logging() {
 456          set_config('enabled_stores', 'logstore_legacy', 'tool_log');
 457          set_config('loglegacy', 1, 'logstore_legacy');
 458          get_log_manager(true);
 459      }
 460  
 461      /**
 462       * Get the contextlist for a user.
 463       *
 464       * @param object $user The user.
 465       * @return contextlist
 466       */
 467      protected function get_contextlist_for_user($user) {
 468          $contextlist = new contextlist();
 469          provider::add_contexts_for_userid($contextlist, $user->id);
 470          return $contextlist;
 471      }
 472  }